cct-cli 0.7.9.0__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.
- calc_terminal/__init__.py +14 -0
- calc_terminal/__main__.py +14 -0
- calc_terminal/activity.py +1334 -0
- calc_terminal/agent.py +3387 -0
- calc_terminal/agent_runtime.py +519 -0
- calc_terminal/ai_context.py +447 -0
- calc_terminal/ai_modes.py +752 -0
- calc_terminal/ai_personalization.py +286 -0
- calc_terminal/ai_preview_feedback.py +213 -0
- calc_terminal/aicore.py +2572 -0
- calc_terminal/anim.py +367 -0
- calc_terminal/app.py +3685 -0
- calc_terminal/art.py +639 -0
- calc_terminal/atomsim.py +368 -0
- calc_terminal/attachments.py +743 -0
- calc_terminal/benchmark_system.py +414 -0
- calc_terminal/browser/__init__.py +36 -0
- calc_terminal/browser/browser_state.py +346 -0
- calc_terminal/browser/devserver.py +176 -0
- calc_terminal/browser/engine.py +494 -0
- calc_terminal/browser/navigation.py +84 -0
- calc_terminal/browser/preview.py +429 -0
- calc_terminal/browser/preview_entry.py +95 -0
- calc_terminal/browser/project_detector.py +144 -0
- calc_terminal/browser/server.py +449 -0
- calc_terminal/browser/state.py +75 -0
- calc_terminal/browser/watcher.py +99 -0
- calc_terminal/browser_gui/__init__.py +1 -0
- calc_terminal/browser_gui/__main__.py +3 -0
- calc_terminal/browser_gui/launcher.py +173 -0
- calc_terminal/browser_gui/playwright_browser.py +117 -0
- calc_terminal/browser_gui/qt_browser.py +1501 -0
- calc_terminal/browser_gui/webview_browser.py +57 -0
- calc_terminal/capabilities/__init__.py +35 -0
- calc_terminal/capabilities/adapters/__init__.py +33 -0
- calc_terminal/capabilities/adapters/bioinformatics.py +204 -0
- calc_terminal/capabilities/adapters/browser_adapter.py +205 -0
- calc_terminal/capabilities/adapters/filesystem.py +206 -0
- calc_terminal/capabilities/adapters/git_adapter.py +202 -0
- calc_terminal/capabilities/adapters/jupyter_adapter.py +138 -0
- calc_terminal/capabilities/adapters/ml_frameworks.py +158 -0
- calc_terminal/capabilities/adapters/platforms.py +200 -0
- calc_terminal/capabilities/adapters/python_exec.py +93 -0
- calc_terminal/capabilities/adapters/quantum_adapter.py +150 -0
- calc_terminal/capabilities/adapters/scientific_comp.py +123 -0
- calc_terminal/capabilities/adapters/structural_bio.py +161 -0
- calc_terminal/capabilities/adapters/terminal.py +99 -0
- calc_terminal/capabilities/bus.py +178 -0
- calc_terminal/capabilities/discovery.py +207 -0
- calc_terminal/capabilities/schema.py +221 -0
- calc_terminal/cat.ico +0 -0
- calc_terminal/cat_browser.py +2018 -0
- calc_terminal/chat_store.py +703 -0
- calc_terminal/cli.py +1178 -0
- calc_terminal/code_editor.py +640 -0
- calc_terminal/collaboration.py +723 -0
- calc_terminal/commands_data.py +139 -0
- calc_terminal/compatibility_engine.py +352 -0
- calc_terminal/compute/__init__.py +31 -0
- calc_terminal/compute/fabric.py +350 -0
- calc_terminal/config.py +227 -0
- calc_terminal/core/__init__.py +41 -0
- calc_terminal/core/checkpoint.py +156 -0
- calc_terminal/core/input/__init__.py +45 -0
- calc_terminal/core/mode_registry.py +300 -0
- calc_terminal/core/project_graph.py +172 -0
- calc_terminal/core/recovery.py +129 -0
- calc_terminal/core/security_layer.py +112 -0
- calc_terminal/core/task_graph.py +202 -0
- calc_terminal/core/unified_runtime.py +184 -0
- calc_terminal/core/verification.py +257 -0
- calc_terminal/customization.py +1566 -0
- calc_terminal/derivations.py +153 -0
- calc_terminal/device_control.py +263 -0
- calc_terminal/diagnostics/__init__.py +27 -0
- calc_terminal/diagnostics/doctor_engine.py +382 -0
- calc_terminal/diagnostics/self_test.py +247 -0
- calc_terminal/doctor.py +519 -0
- calc_terminal/easter_eggs.py +274 -0
- calc_terminal/editor/__init__.py +1 -0
- calc_terminal/editor/actions.py +263 -0
- calc_terminal/editor/commands.py +160 -0
- calc_terminal/editor/shortcuts.py +226 -0
- calc_terminal/engine.py +259 -0
- calc_terminal/errors.py +120 -0
- calc_terminal/event_stream.py +146 -0
- calc_terminal/eventbus.py +133 -0
- calc_terminal/extensions.py +733 -0
- calc_terminal/fallback_cli.py +1321 -0
- calc_terminal/first_run.py +265 -0
- calc_terminal/fomoji_auth.py +1043 -0
- calc_terminal/formulas.py +82 -0
- calc_terminal/fs_cache.py +121 -0
- calc_terminal/fs_watcher.py +277 -0
- calc_terminal/game.py +193 -0
- calc_terminal/gen1.py +5 -0
- calc_terminal/generators.py +245 -0
- calc_terminal/gestures/__init__.py +42 -0
- calc_terminal/gestures/bindings.py +175 -0
- calc_terminal/gestures/manager.py +477 -0
- calc_terminal/goodbye.py +363 -0
- calc_terminal/gpu3d.py +290 -0
- calc_terminal/graphs.py +358 -0
- calc_terminal/hardware_analyzer.py +440 -0
- calc_terminal/host/__init__.py +30 -0
- calc_terminal/host/browser_manager.py +187 -0
- calc_terminal/host/desktop.py +1386 -0
- calc_terminal/host/launcher.py +395 -0
- calc_terminal/host/terminal.py +279 -0
- calc_terminal/identity.py +216 -0
- calc_terminal/input/__init__.py +54 -0
- calc_terminal/input/capabilities.py +258 -0
- calc_terminal/input/focus.py +87 -0
- calc_terminal/input/gestures.py +64 -0
- calc_terminal/input/pointer.py +114 -0
- calc_terminal/input/touch.py +345 -0
- calc_terminal/keys.py +84 -0
- calc_terminal/live_automation.py +165 -0
- calc_terminal/mathtext.py +433 -0
- calc_terminal/mcp.py +386 -0
- calc_terminal/memory.py +337 -0
- calc_terminal/memory_v2.py +479 -0
- calc_terminal/metrics.py +333 -0
- calc_terminal/mode_detection.py +146 -0
- calc_terminal/model.py +2431 -0
- calc_terminal/model_router.py +665 -0
- calc_terminal/models/__init__.py +0 -0
- calc_terminal/models/active_state.py +187 -0
- calc_terminal/models/dynamic_registry.py +584 -0
- calc_terminal/models/manager.py +781 -0
- calc_terminal/models/model_metadata.json +3526 -0
- calc_terminal/models/profiles.py +194 -0
- calc_terminal/models/registry.py +265 -0
- calc_terminal/models/schema.py +197 -0
- calc_terminal/models/validator.py +287 -0
- calc_terminal/models/verification_engine.py +368 -0
- calc_terminal/native_picker.py +215 -0
- calc_terminal/ollama_catalog.py +279 -0
- calc_terminal/ollama_download.py +233 -0
- calc_terminal/orchestrator.py +304 -0
- calc_terminal/package_research.py +322 -0
- calc_terminal/packages.py +1024 -0
- calc_terminal/pc_specs.py +116 -0
- calc_terminal/permissions.py +334 -0
- calc_terminal/pet.py +106 -0
- calc_terminal/pipeline.py +505 -0
- calc_terminal/platform/__init__.py +491 -0
- calc_terminal/platform/desktop.py +491 -0
- calc_terminal/platform/web.py +781 -0
- calc_terminal/preview/__init__.py +1 -0
- calc_terminal/preview/dev_server.py +303 -0
- calc_terminal/preview/diagnostics.py +131 -0
- calc_terminal/preview/live_reload.py +66 -0
- calc_terminal/preview/manager.py +129 -0
- calc_terminal/project_stats.py +209 -0
- calc_terminal/projects.py +328 -0
- calc_terminal/providers/__init__.py +0 -0
- calc_terminal/providers/adapters/__init__.py +80 -0
- calc_terminal/providers/adapters/anthropic_adapter.py +127 -0
- calc_terminal/providers/adapters/base.py +106 -0
- calc_terminal/providers/adapters/chinese_adapters.py +420 -0
- calc_terminal/providers/adapters/gemini_adapter.py +101 -0
- calc_terminal/providers/adapters/ollama_adapter.py +83 -0
- calc_terminal/providers/adapters/openai_adapter.py +159 -0
- calc_terminal/providers/adapters/other_adapters.py +246 -0
- calc_terminal/providers/anthropic_provider.py +172 -0
- calc_terminal/providers/auto_update.py +416 -0
- calc_terminal/providers/base_provider.py +105 -0
- calc_terminal/providers/discovery_manager.py +207 -0
- calc_terminal/providers/gemini_provider.py +178 -0
- calc_terminal/providers/lifecycle.py +767 -0
- calc_terminal/providers/ollama_adapter.py +707 -0
- calc_terminal/providers/openai_provider.py +254 -0
- calc_terminal/providers/provider_manager.py +1827 -0
- calc_terminal/providers/providers.json +4075 -0
- calc_terminal/reactionsim.py +279 -0
- calc_terminal/registry.py +337 -0
- calc_terminal/report.py +162 -0
- calc_terminal/research/__init__.py +45 -0
- calc_terminal/research/artifact_intel.py +126 -0
- calc_terminal/research/data_lineage.py +123 -0
- calc_terminal/research/experiment_ledger.py +303 -0
- calc_terminal/research/reproducibility.py +131 -0
- calc_terminal/resilience/__init__.py +47 -0
- calc_terminal/resilience/agent_state.py +121 -0
- calc_terminal/resilience/capability_matcher.py +174 -0
- calc_terminal/resilience/circuit_breaker.py +158 -0
- calc_terminal/resilience/failover_engine.py +230 -0
- calc_terminal/resilience/health_monitor.py +192 -0
- calc_terminal/resilience/ollama_adapter.py +125 -0
- calc_terminal/resilience/orchestrator.py +312 -0
- calc_terminal/resilience/types.py +134 -0
- calc_terminal/sandbox.py +98 -0
- calc_terminal/scires.py +558 -0
- calc_terminal/security_scanner.py +126 -0
- calc_terminal/session.py +294 -0
- calc_terminal/sim3d.py +206 -0
- calc_terminal/solver.py +276 -0
- calc_terminal/sound.py +127 -0
- calc_terminal/task_reports.py +287 -0
- calc_terminal/terminal_host.py +201 -0
- calc_terminal/terminal_identity.py +411 -0
- calc_terminal/test_ai_mode_reliability.py +344 -0
- calc_terminal/test_browser.py +368 -0
- calc_terminal/test_code_editor_upgrade.py +485 -0
- calc_terminal/test_customization.py +1148 -0
- calc_terminal/test_customization_ui.py +612 -0
- calc_terminal/test_dynamic_registry.py +304 -0
- calc_terminal/test_extensions.py +436 -0
- calc_terminal/test_overhaul.py +557 -0
- calc_terminal/test_project_detect.py +255 -0
- calc_terminal/test_root_cause_fix.py +527 -0
- calc_terminal/test_stability.py +532 -0
- calc_terminal/test_terminal_identity.py +132 -0
- calc_terminal/test_v079_speed.py +460 -0
- calc_terminal/theme.py +1107 -0
- calc_terminal/timeline.py +139 -0
- calc_terminal/todos.py +246 -0
- calc_terminal/tool_call_normalizer.py +419 -0
- calc_terminal/tui.py +104 -0
- calc_terminal/ui/__init__.py +8 -0
- calc_terminal/ui/activity_panel.py +231 -0
- calc_terminal/ui/activity_stream_panel.py +238 -0
- calc_terminal/ui/animations.py +122 -0
- calc_terminal/ui/app.py +7271 -0
- calc_terminal/ui/attach_panel.py +597 -0
- calc_terminal/ui/attachments.py +424 -0
- calc_terminal/ui/backup_panel.py +810 -0
- calc_terminal/ui/browser_shell.py +887 -0
- calc_terminal/ui/cat_agent.py +357 -0
- calc_terminal/ui/chats_panel.py +899 -0
- calc_terminal/ui/command_palette.py +125 -0
- calc_terminal/ui/command_palette_modal.py +166 -0
- calc_terminal/ui/composer.py +1141 -0
- calc_terminal/ui/context_menu.py +197 -0
- calc_terminal/ui/conversation.py +1435 -0
- calc_terminal/ui/customization_panel.py +1229 -0
- calc_terminal/ui/dashboard.py +404 -0
- calc_terminal/ui/design_system.py +557 -0
- calc_terminal/ui/diff_panel.py +213 -0
- calc_terminal/ui/editor.py +2102 -0
- calc_terminal/ui/empty_state.py +302 -0
- calc_terminal/ui/events.py +487 -0
- calc_terminal/ui/extensions_panel.py +815 -0
- calc_terminal/ui/footer.py +166 -0
- calc_terminal/ui/gestures_panel.py +383 -0
- calc_terminal/ui/goodbye_screen.py +100 -0
- calc_terminal/ui/header.py +1034 -0
- calc_terminal/ui/help_panel.py +254 -0
- calc_terminal/ui/live_activities.py +914 -0
- calc_terminal/ui/mcp_panel.py +570 -0
- calc_terminal/ui/memory_center.py +524 -0
- calc_terminal/ui/mode_colors_panel.py +525 -0
- calc_terminal/ui/nav_screens.py +747 -0
- calc_terminal/ui/ollama_panel.py +536 -0
- calc_terminal/ui/palette.py +221 -0
- calc_terminal/ui/permission_panel.py +269 -0
- calc_terminal/ui/personalization_panel.py +517 -0
- calc_terminal/ui/personalize_center.py +1568 -0
- calc_terminal/ui/preview_panel.py +441 -0
- calc_terminal/ui/resizers.py +402 -0
- calc_terminal/ui/sidebar.py +1285 -0
- calc_terminal/ui/statusbar.py +168 -0
- calc_terminal/ui/theme_css.py +1396 -0
- calc_terminal/ui/thinking.py +226 -0
- calc_terminal/ui/timeline_panel.py +102 -0
- calc_terminal/ui/todo_panel.py +193 -0
- calc_terminal/ui/viewport.py +136 -0
- calc_terminal/ui/vision_panel.py +489 -0
- calc_terminal/ui/welcome_modal.py +343 -0
- calc_terminal/ui/widgets.py +160 -0
- calc_terminal/ui/workspace.py +831 -0
- calc_terminal/viewers/__init__.py +1 -0
- calc_terminal/viewers/document_viewer.py +252 -0
- calc_terminal/viewers/image_viewer.py +241 -0
- calc_terminal/viewers/pdf_viewer.py +203 -0
- calc_terminal/viewers/presentation_viewer.py +164 -0
- calc_terminal/viewers/registry.py +120 -0
- calc_terminal/viewers/spreadsheet_viewer.py +204 -0
- calc_terminal/vision/__init__.py +89 -0
- calc_terminal/vision/analysis.py +194 -0
- calc_terminal/vision/annotations.py +297 -0
- calc_terminal/vision/capture.py +171 -0
- calc_terminal/vision/context.py +231 -0
- calc_terminal/vision/correlation.py +169 -0
- calc_terminal/vision/cursor.py +258 -0
- calc_terminal/vision/events.py +66 -0
- calc_terminal/vision/frame_pipeline.py +259 -0
- calc_terminal/vision/priority.py +218 -0
- calc_terminal/vision/provider.py +180 -0
- calc_terminal/vision/safety.py +149 -0
- calc_terminal/vision/session.py +281 -0
- calc_terminal/vision/verify.py +162 -0
- calc_terminal/vision.py +514 -0
- calc_terminal/vscode_integration.py +113 -0
- calc_terminal/web/__init__.py +8 -0
- calc_terminal/web/cat_runtime.py +710 -0
- calc_terminal/web/server.py +2891 -0
- calc_terminal/web/static/css/app.css +3152 -0
- calc_terminal/web/static/icons/badge-72.png +0 -0
- calc_terminal/web/static/icons/cat.ico +0 -0
- calc_terminal/web/static/icons/icon-128.png +0 -0
- calc_terminal/web/static/icons/icon-144.png +0 -0
- calc_terminal/web/static/icons/icon-152.png +0 -0
- calc_terminal/web/static/icons/icon-192.png +0 -0
- calc_terminal/web/static/icons/icon-384.png +0 -0
- calc_terminal/web/static/icons/icon-512.png +0 -0
- calc_terminal/web/static/icons/icon-72.png +0 -0
- calc_terminal/web/static/icons/icon-96.png +0 -0
- calc_terminal/web/static/icons/icon.svg +34 -0
- calc_terminal/web/static/icons/new-project.png +0 -0
- calc_terminal/web/static/icons/open-project.png +0 -0
- calc_terminal/web/static/index.html +734 -0
- calc_terminal/web/static/js/app.js +2403 -0
- calc_terminal/web/static/manifest.json +88 -0
- calc_terminal/web/static/sw.js +230 -0
- calc_terminal/workflow_engine.py +769 -0
- calc_terminal/workspace.py +593 -0
- calc_terminal/workspace_index.py +385 -0
- cct_cli-0.7.9.0.dist-info/METADATA +210 -0
- cct_cli-0.7.9.0.dist-info/RECORD +325 -0
- cct_cli-0.7.9.0.dist-info/WHEEL +5 -0
- cct_cli-0.7.9.0.dist-info/entry_points.txt +4 -0
- cct_cli-0.7.9.0.dist-info/licenses/LICENSE +21 -0
- cct_cli-0.7.9.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CCT UI — diff_panel.py: Live Diff Viewer (v0.7.10 spec section 14).
|
|
3
|
+
|
|
4
|
+
Shows before/after changes for files modified by the AI or user.
|
|
5
|
+
Displays inline diff with color-coded additions/deletions.
|
|
6
|
+
|
|
7
|
+
Lives in the right pane as a modal screen or inline panel.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
if __name__ == "__main__":
|
|
11
|
+
print("This is a library file and is not meant to be run directly.")
|
|
12
|
+
import sys
|
|
13
|
+
sys.exit(1)
|
|
14
|
+
|
|
15
|
+
TEXTUAL_AVAILABLE = True
|
|
16
|
+
try:
|
|
17
|
+
from textual.containers import Vertical, Horizontal, VerticalScroll
|
|
18
|
+
from textual.screen import Screen
|
|
19
|
+
from textual.widgets import Static, Button
|
|
20
|
+
except Exception:
|
|
21
|
+
TEXTUAL_AVAILABLE = False
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _format_diff_lines(diff_lines):
|
|
25
|
+
"""Format diff lines with color coding."""
|
|
26
|
+
formatted = []
|
|
27
|
+
for line in diff_lines:
|
|
28
|
+
if line.startswith('+++') or line.startswith('---'):
|
|
29
|
+
# File headers
|
|
30
|
+
formatted.append(f"[b]{line}[/b]")
|
|
31
|
+
elif line.startswith('@@'):
|
|
32
|
+
# Hunk headers
|
|
33
|
+
formatted.append(f"[b cyan]{line}[/cyan]")
|
|
34
|
+
elif line.startswith('+'):
|
|
35
|
+
# Additions
|
|
36
|
+
formatted.append(f"[green]{line}[/green]")
|
|
37
|
+
elif line.startswith('-'):
|
|
38
|
+
# Deletions
|
|
39
|
+
formatted.append(f"[red]{line}[/red]")
|
|
40
|
+
else:
|
|
41
|
+
# Context lines
|
|
42
|
+
formatted.append(line)
|
|
43
|
+
return "\n".join(formatted)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
if TEXTUAL_AVAILABLE:
|
|
47
|
+
|
|
48
|
+
class DiffViewerPanel(Screen):
|
|
49
|
+
"""Live Diff Viewer panel showing before/after changes."""
|
|
50
|
+
|
|
51
|
+
CSS = """
|
|
52
|
+
DiffViewerPanel { align: center middle; background: $app-background 60%; }
|
|
53
|
+
#cct-diff-box {
|
|
54
|
+
width: 90%; height: 85%; background: $surface;
|
|
55
|
+
border: round $border; padding: 1 2;
|
|
56
|
+
}
|
|
57
|
+
#cct-diff-header { height: 1; padding: 0 0 1 0; }
|
|
58
|
+
#cct-diff-file { width: 1fr; }
|
|
59
|
+
#cct-diff-stats { height: 1; padding: 0 0 1 0; }
|
|
60
|
+
#cct-diff-content { height: 1fr; }
|
|
61
|
+
#cct-diff-content Static { width: 100%; }
|
|
62
|
+
#cct-diff-actions { height: 3; padding-top: 1; }
|
|
63
|
+
#cct-diff-actions Button { margin-right: 1; }
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
def __init__(self, path="", diff_lines=None, original="", current=""):
|
|
67
|
+
super().__init__()
|
|
68
|
+
self._path = path
|
|
69
|
+
self._diff_lines = diff_lines or []
|
|
70
|
+
self._original = original
|
|
71
|
+
self._current = current
|
|
72
|
+
|
|
73
|
+
def compose(self):
|
|
74
|
+
with Vertical(id="cct-diff-box"):
|
|
75
|
+
with Horizontal(id="cct-diff-header"):
|
|
76
|
+
yield Static("[b]Live Diff Viewer[/b]", id="cct-diff-title")
|
|
77
|
+
yield Button("Close", id="cct-diff-close")
|
|
78
|
+
yield Static(f"File: {self._path}", id="cct-diff-file")
|
|
79
|
+
with Horizontal(id="cct-diff-stats"):
|
|
80
|
+
yield Static(self._compute_stats(), id="cct-diff-stats-text")
|
|
81
|
+
yield VerticalScroll(
|
|
82
|
+
Static(self._format_content(), id="cct-diff-text"),
|
|
83
|
+
id="cct-diff-content"
|
|
84
|
+
)
|
|
85
|
+
with Horizontal(id="cct-diff-actions"):
|
|
86
|
+
yield Button("Copy Diff", id="cct-diff-copy")
|
|
87
|
+
yield Button("Revert Changes", id="cct-diff-revert")
|
|
88
|
+
|
|
89
|
+
def _compute_stats(self):
|
|
90
|
+
"""Compute diff statistics."""
|
|
91
|
+
additions = sum(1 for line in self._diff_lines if line.startswith('+'))
|
|
92
|
+
deletions = sum(1 for line in self._diff_lines if line.startswith('-'))
|
|
93
|
+
return f"[green]+{additions}[/green] [red]-{deletions}[/red] lines changed"
|
|
94
|
+
|
|
95
|
+
def _format_content(self):
|
|
96
|
+
"""Format diff content with syntax highlighting."""
|
|
97
|
+
if not self._diff_lines:
|
|
98
|
+
return "[italic]No changes detected[/italic]"
|
|
99
|
+
return _format_diff_lines(self._diff_lines)
|
|
100
|
+
|
|
101
|
+
def on_button_pressed(self, event):
|
|
102
|
+
if event.button.id == "cct-diff-close":
|
|
103
|
+
self.dismiss(None)
|
|
104
|
+
elif event.button.id == "cct-diff-copy":
|
|
105
|
+
self._copy_diff()
|
|
106
|
+
elif event.button.id == "cct-diff-revert":
|
|
107
|
+
self._revert_changes()
|
|
108
|
+
|
|
109
|
+
def _copy_diff(self):
|
|
110
|
+
"""Copy diff to clipboard."""
|
|
111
|
+
try:
|
|
112
|
+
import pyperclip
|
|
113
|
+
diff_text = "\n".join(self._diff_lines)
|
|
114
|
+
pyperclip.copy(diff_text)
|
|
115
|
+
except Exception:
|
|
116
|
+
pass
|
|
117
|
+
|
|
118
|
+
def _revert_changes(self):
|
|
119
|
+
"""Revert file to original content."""
|
|
120
|
+
if self._path and self._original:
|
|
121
|
+
try:
|
|
122
|
+
with open(self._path, "w", encoding="utf-8") as f:
|
|
123
|
+
f.write(self._original)
|
|
124
|
+
self.dismiss("reverted")
|
|
125
|
+
except Exception:
|
|
126
|
+
pass
|
|
127
|
+
|
|
128
|
+
def on_key(self, event):
|
|
129
|
+
if event.key == "escape":
|
|
130
|
+
self.dismiss(None)
|
|
131
|
+
|
|
132
|
+
def on_click(self, event):
|
|
133
|
+
"""Gesture on diff → before/after (spec 23). Double-click diff toggles view."""
|
|
134
|
+
import time as _t
|
|
135
|
+
try:
|
|
136
|
+
now = _t.time()
|
|
137
|
+
last = getattr(self, "_last_diff_click", 0)
|
|
138
|
+
if now - last < 0.35:
|
|
139
|
+
self._last_diff_click = 0
|
|
140
|
+
try:
|
|
141
|
+
from ..gestures.manager import handle_gesture
|
|
142
|
+
if handle_gesture("double_click", "diff", app=getattr(self, "app", None), context={"path": self._path}):
|
|
143
|
+
event.stop()
|
|
144
|
+
return
|
|
145
|
+
except Exception:
|
|
146
|
+
pass
|
|
147
|
+
# Fallback: toggle before/after view if available
|
|
148
|
+
try:
|
|
149
|
+
self._show_before_after()
|
|
150
|
+
event.stop()
|
|
151
|
+
except Exception:
|
|
152
|
+
pass
|
|
153
|
+
else:
|
|
154
|
+
self._last_diff_click = now
|
|
155
|
+
except Exception:
|
|
156
|
+
pass
|
|
157
|
+
|
|
158
|
+
def _show_before_after(self):
|
|
159
|
+
"""Toggle before/after view."""
|
|
160
|
+
try:
|
|
161
|
+
from textual.containers import Vertical
|
|
162
|
+
from textual.widgets import Static
|
|
163
|
+
# Simple before/after toggle: show original vs current
|
|
164
|
+
content = self.query_one("#cct-diff-text", Static)
|
|
165
|
+
if hasattr(self, "_showing_before") and self._showing_before:
|
|
166
|
+
content.update(_format_diff_lines(self._diff_lines))
|
|
167
|
+
self._showing_before = False
|
|
168
|
+
else:
|
|
169
|
+
# Show before and after stacked
|
|
170
|
+
before = self._original or "[no original]"
|
|
171
|
+
after = self._current or "[no current]"
|
|
172
|
+
content.update(f"[b]BEFORE[/b]\n{before}\n\n[b]AFTER[/b]\n{after}")
|
|
173
|
+
self._showing_before = True
|
|
174
|
+
except Exception:
|
|
175
|
+
pass
|
|
176
|
+
|
|
177
|
+
class InlineDiffViewer(Vertical):
|
|
178
|
+
"""Inline diff viewer widget for showing changes in the editor."""
|
|
179
|
+
|
|
180
|
+
CSS = """
|
|
181
|
+
InlineDiffViewer { height: auto; max-height: 50%; }
|
|
182
|
+
.cct-inline-diff-line { height: 1; width: 100%; }
|
|
183
|
+
.cct-inline-diff-add { background: $success 20%; }
|
|
184
|
+
.cct-inline-diff-del { background: $error 20%; }
|
|
185
|
+
.cct-inline-diff-hunk { background: $accent 20%; }
|
|
186
|
+
"""
|
|
187
|
+
|
|
188
|
+
def __init__(self, diff_lines=None, **kwargs):
|
|
189
|
+
super().__init__(**kwargs)
|
|
190
|
+
self._diff_lines = diff_lines or []
|
|
191
|
+
|
|
192
|
+
def show_diff(self, diff_lines):
|
|
193
|
+
"""Display diff lines."""
|
|
194
|
+
self._diff_lines = diff_lines
|
|
195
|
+
self._render()
|
|
196
|
+
|
|
197
|
+
def _render(self):
|
|
198
|
+
"""Render diff lines."""
|
|
199
|
+
for child in list(self.children):
|
|
200
|
+
child.remove()
|
|
201
|
+
for line in self._diff_lines[:50]: # Limit to 50 lines
|
|
202
|
+
css_class = ""
|
|
203
|
+
if line.startswith('+'):
|
|
204
|
+
css_class = "cct-inline-diff-add"
|
|
205
|
+
elif line.startswith('-'):
|
|
206
|
+
css_class = "cct-inline-diff-del"
|
|
207
|
+
elif line.startswith('@@'):
|
|
208
|
+
css_class = "cct-inline-diff-hunk"
|
|
209
|
+
self.mount(Static(line, classes=f"cct-inline-diff-line {css_class}"))
|
|
210
|
+
|
|
211
|
+
else:
|
|
212
|
+
DiffViewerPanel = None
|
|
213
|
+
InlineDiffViewer = None
|