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.
Files changed (325) hide show
  1. calc_terminal/__init__.py +14 -0
  2. calc_terminal/__main__.py +14 -0
  3. calc_terminal/activity.py +1334 -0
  4. calc_terminal/agent.py +3387 -0
  5. calc_terminal/agent_runtime.py +519 -0
  6. calc_terminal/ai_context.py +447 -0
  7. calc_terminal/ai_modes.py +752 -0
  8. calc_terminal/ai_personalization.py +286 -0
  9. calc_terminal/ai_preview_feedback.py +213 -0
  10. calc_terminal/aicore.py +2572 -0
  11. calc_terminal/anim.py +367 -0
  12. calc_terminal/app.py +3685 -0
  13. calc_terminal/art.py +639 -0
  14. calc_terminal/atomsim.py +368 -0
  15. calc_terminal/attachments.py +743 -0
  16. calc_terminal/benchmark_system.py +414 -0
  17. calc_terminal/browser/__init__.py +36 -0
  18. calc_terminal/browser/browser_state.py +346 -0
  19. calc_terminal/browser/devserver.py +176 -0
  20. calc_terminal/browser/engine.py +494 -0
  21. calc_terminal/browser/navigation.py +84 -0
  22. calc_terminal/browser/preview.py +429 -0
  23. calc_terminal/browser/preview_entry.py +95 -0
  24. calc_terminal/browser/project_detector.py +144 -0
  25. calc_terminal/browser/server.py +449 -0
  26. calc_terminal/browser/state.py +75 -0
  27. calc_terminal/browser/watcher.py +99 -0
  28. calc_terminal/browser_gui/__init__.py +1 -0
  29. calc_terminal/browser_gui/__main__.py +3 -0
  30. calc_terminal/browser_gui/launcher.py +173 -0
  31. calc_terminal/browser_gui/playwright_browser.py +117 -0
  32. calc_terminal/browser_gui/qt_browser.py +1501 -0
  33. calc_terminal/browser_gui/webview_browser.py +57 -0
  34. calc_terminal/capabilities/__init__.py +35 -0
  35. calc_terminal/capabilities/adapters/__init__.py +33 -0
  36. calc_terminal/capabilities/adapters/bioinformatics.py +204 -0
  37. calc_terminal/capabilities/adapters/browser_adapter.py +205 -0
  38. calc_terminal/capabilities/adapters/filesystem.py +206 -0
  39. calc_terminal/capabilities/adapters/git_adapter.py +202 -0
  40. calc_terminal/capabilities/adapters/jupyter_adapter.py +138 -0
  41. calc_terminal/capabilities/adapters/ml_frameworks.py +158 -0
  42. calc_terminal/capabilities/adapters/platforms.py +200 -0
  43. calc_terminal/capabilities/adapters/python_exec.py +93 -0
  44. calc_terminal/capabilities/adapters/quantum_adapter.py +150 -0
  45. calc_terminal/capabilities/adapters/scientific_comp.py +123 -0
  46. calc_terminal/capabilities/adapters/structural_bio.py +161 -0
  47. calc_terminal/capabilities/adapters/terminal.py +99 -0
  48. calc_terminal/capabilities/bus.py +178 -0
  49. calc_terminal/capabilities/discovery.py +207 -0
  50. calc_terminal/capabilities/schema.py +221 -0
  51. calc_terminal/cat.ico +0 -0
  52. calc_terminal/cat_browser.py +2018 -0
  53. calc_terminal/chat_store.py +703 -0
  54. calc_terminal/cli.py +1178 -0
  55. calc_terminal/code_editor.py +640 -0
  56. calc_terminal/collaboration.py +723 -0
  57. calc_terminal/commands_data.py +139 -0
  58. calc_terminal/compatibility_engine.py +352 -0
  59. calc_terminal/compute/__init__.py +31 -0
  60. calc_terminal/compute/fabric.py +350 -0
  61. calc_terminal/config.py +227 -0
  62. calc_terminal/core/__init__.py +41 -0
  63. calc_terminal/core/checkpoint.py +156 -0
  64. calc_terminal/core/input/__init__.py +45 -0
  65. calc_terminal/core/mode_registry.py +300 -0
  66. calc_terminal/core/project_graph.py +172 -0
  67. calc_terminal/core/recovery.py +129 -0
  68. calc_terminal/core/security_layer.py +112 -0
  69. calc_terminal/core/task_graph.py +202 -0
  70. calc_terminal/core/unified_runtime.py +184 -0
  71. calc_terminal/core/verification.py +257 -0
  72. calc_terminal/customization.py +1566 -0
  73. calc_terminal/derivations.py +153 -0
  74. calc_terminal/device_control.py +263 -0
  75. calc_terminal/diagnostics/__init__.py +27 -0
  76. calc_terminal/diagnostics/doctor_engine.py +382 -0
  77. calc_terminal/diagnostics/self_test.py +247 -0
  78. calc_terminal/doctor.py +519 -0
  79. calc_terminal/easter_eggs.py +274 -0
  80. calc_terminal/editor/__init__.py +1 -0
  81. calc_terminal/editor/actions.py +263 -0
  82. calc_terminal/editor/commands.py +160 -0
  83. calc_terminal/editor/shortcuts.py +226 -0
  84. calc_terminal/engine.py +259 -0
  85. calc_terminal/errors.py +120 -0
  86. calc_terminal/event_stream.py +146 -0
  87. calc_terminal/eventbus.py +133 -0
  88. calc_terminal/extensions.py +733 -0
  89. calc_terminal/fallback_cli.py +1321 -0
  90. calc_terminal/first_run.py +265 -0
  91. calc_terminal/fomoji_auth.py +1043 -0
  92. calc_terminal/formulas.py +82 -0
  93. calc_terminal/fs_cache.py +121 -0
  94. calc_terminal/fs_watcher.py +277 -0
  95. calc_terminal/game.py +193 -0
  96. calc_terminal/gen1.py +5 -0
  97. calc_terminal/generators.py +245 -0
  98. calc_terminal/gestures/__init__.py +42 -0
  99. calc_terminal/gestures/bindings.py +175 -0
  100. calc_terminal/gestures/manager.py +477 -0
  101. calc_terminal/goodbye.py +363 -0
  102. calc_terminal/gpu3d.py +290 -0
  103. calc_terminal/graphs.py +358 -0
  104. calc_terminal/hardware_analyzer.py +440 -0
  105. calc_terminal/host/__init__.py +30 -0
  106. calc_terminal/host/browser_manager.py +187 -0
  107. calc_terminal/host/desktop.py +1386 -0
  108. calc_terminal/host/launcher.py +395 -0
  109. calc_terminal/host/terminal.py +279 -0
  110. calc_terminal/identity.py +216 -0
  111. calc_terminal/input/__init__.py +54 -0
  112. calc_terminal/input/capabilities.py +258 -0
  113. calc_terminal/input/focus.py +87 -0
  114. calc_terminal/input/gestures.py +64 -0
  115. calc_terminal/input/pointer.py +114 -0
  116. calc_terminal/input/touch.py +345 -0
  117. calc_terminal/keys.py +84 -0
  118. calc_terminal/live_automation.py +165 -0
  119. calc_terminal/mathtext.py +433 -0
  120. calc_terminal/mcp.py +386 -0
  121. calc_terminal/memory.py +337 -0
  122. calc_terminal/memory_v2.py +479 -0
  123. calc_terminal/metrics.py +333 -0
  124. calc_terminal/mode_detection.py +146 -0
  125. calc_terminal/model.py +2431 -0
  126. calc_terminal/model_router.py +665 -0
  127. calc_terminal/models/__init__.py +0 -0
  128. calc_terminal/models/active_state.py +187 -0
  129. calc_terminal/models/dynamic_registry.py +584 -0
  130. calc_terminal/models/manager.py +781 -0
  131. calc_terminal/models/model_metadata.json +3526 -0
  132. calc_terminal/models/profiles.py +194 -0
  133. calc_terminal/models/registry.py +265 -0
  134. calc_terminal/models/schema.py +197 -0
  135. calc_terminal/models/validator.py +287 -0
  136. calc_terminal/models/verification_engine.py +368 -0
  137. calc_terminal/native_picker.py +215 -0
  138. calc_terminal/ollama_catalog.py +279 -0
  139. calc_terminal/ollama_download.py +233 -0
  140. calc_terminal/orchestrator.py +304 -0
  141. calc_terminal/package_research.py +322 -0
  142. calc_terminal/packages.py +1024 -0
  143. calc_terminal/pc_specs.py +116 -0
  144. calc_terminal/permissions.py +334 -0
  145. calc_terminal/pet.py +106 -0
  146. calc_terminal/pipeline.py +505 -0
  147. calc_terminal/platform/__init__.py +491 -0
  148. calc_terminal/platform/desktop.py +491 -0
  149. calc_terminal/platform/web.py +781 -0
  150. calc_terminal/preview/__init__.py +1 -0
  151. calc_terminal/preview/dev_server.py +303 -0
  152. calc_terminal/preview/diagnostics.py +131 -0
  153. calc_terminal/preview/live_reload.py +66 -0
  154. calc_terminal/preview/manager.py +129 -0
  155. calc_terminal/project_stats.py +209 -0
  156. calc_terminal/projects.py +328 -0
  157. calc_terminal/providers/__init__.py +0 -0
  158. calc_terminal/providers/adapters/__init__.py +80 -0
  159. calc_terminal/providers/adapters/anthropic_adapter.py +127 -0
  160. calc_terminal/providers/adapters/base.py +106 -0
  161. calc_terminal/providers/adapters/chinese_adapters.py +420 -0
  162. calc_terminal/providers/adapters/gemini_adapter.py +101 -0
  163. calc_terminal/providers/adapters/ollama_adapter.py +83 -0
  164. calc_terminal/providers/adapters/openai_adapter.py +159 -0
  165. calc_terminal/providers/adapters/other_adapters.py +246 -0
  166. calc_terminal/providers/anthropic_provider.py +172 -0
  167. calc_terminal/providers/auto_update.py +416 -0
  168. calc_terminal/providers/base_provider.py +105 -0
  169. calc_terminal/providers/discovery_manager.py +207 -0
  170. calc_terminal/providers/gemini_provider.py +178 -0
  171. calc_terminal/providers/lifecycle.py +767 -0
  172. calc_terminal/providers/ollama_adapter.py +707 -0
  173. calc_terminal/providers/openai_provider.py +254 -0
  174. calc_terminal/providers/provider_manager.py +1827 -0
  175. calc_terminal/providers/providers.json +4075 -0
  176. calc_terminal/reactionsim.py +279 -0
  177. calc_terminal/registry.py +337 -0
  178. calc_terminal/report.py +162 -0
  179. calc_terminal/research/__init__.py +45 -0
  180. calc_terminal/research/artifact_intel.py +126 -0
  181. calc_terminal/research/data_lineage.py +123 -0
  182. calc_terminal/research/experiment_ledger.py +303 -0
  183. calc_terminal/research/reproducibility.py +131 -0
  184. calc_terminal/resilience/__init__.py +47 -0
  185. calc_terminal/resilience/agent_state.py +121 -0
  186. calc_terminal/resilience/capability_matcher.py +174 -0
  187. calc_terminal/resilience/circuit_breaker.py +158 -0
  188. calc_terminal/resilience/failover_engine.py +230 -0
  189. calc_terminal/resilience/health_monitor.py +192 -0
  190. calc_terminal/resilience/ollama_adapter.py +125 -0
  191. calc_terminal/resilience/orchestrator.py +312 -0
  192. calc_terminal/resilience/types.py +134 -0
  193. calc_terminal/sandbox.py +98 -0
  194. calc_terminal/scires.py +558 -0
  195. calc_terminal/security_scanner.py +126 -0
  196. calc_terminal/session.py +294 -0
  197. calc_terminal/sim3d.py +206 -0
  198. calc_terminal/solver.py +276 -0
  199. calc_terminal/sound.py +127 -0
  200. calc_terminal/task_reports.py +287 -0
  201. calc_terminal/terminal_host.py +201 -0
  202. calc_terminal/terminal_identity.py +411 -0
  203. calc_terminal/test_ai_mode_reliability.py +344 -0
  204. calc_terminal/test_browser.py +368 -0
  205. calc_terminal/test_code_editor_upgrade.py +485 -0
  206. calc_terminal/test_customization.py +1148 -0
  207. calc_terminal/test_customization_ui.py +612 -0
  208. calc_terminal/test_dynamic_registry.py +304 -0
  209. calc_terminal/test_extensions.py +436 -0
  210. calc_terminal/test_overhaul.py +557 -0
  211. calc_terminal/test_project_detect.py +255 -0
  212. calc_terminal/test_root_cause_fix.py +527 -0
  213. calc_terminal/test_stability.py +532 -0
  214. calc_terminal/test_terminal_identity.py +132 -0
  215. calc_terminal/test_v079_speed.py +460 -0
  216. calc_terminal/theme.py +1107 -0
  217. calc_terminal/timeline.py +139 -0
  218. calc_terminal/todos.py +246 -0
  219. calc_terminal/tool_call_normalizer.py +419 -0
  220. calc_terminal/tui.py +104 -0
  221. calc_terminal/ui/__init__.py +8 -0
  222. calc_terminal/ui/activity_panel.py +231 -0
  223. calc_terminal/ui/activity_stream_panel.py +238 -0
  224. calc_terminal/ui/animations.py +122 -0
  225. calc_terminal/ui/app.py +7271 -0
  226. calc_terminal/ui/attach_panel.py +597 -0
  227. calc_terminal/ui/attachments.py +424 -0
  228. calc_terminal/ui/backup_panel.py +810 -0
  229. calc_terminal/ui/browser_shell.py +887 -0
  230. calc_terminal/ui/cat_agent.py +357 -0
  231. calc_terminal/ui/chats_panel.py +899 -0
  232. calc_terminal/ui/command_palette.py +125 -0
  233. calc_terminal/ui/command_palette_modal.py +166 -0
  234. calc_terminal/ui/composer.py +1141 -0
  235. calc_terminal/ui/context_menu.py +197 -0
  236. calc_terminal/ui/conversation.py +1435 -0
  237. calc_terminal/ui/customization_panel.py +1229 -0
  238. calc_terminal/ui/dashboard.py +404 -0
  239. calc_terminal/ui/design_system.py +557 -0
  240. calc_terminal/ui/diff_panel.py +213 -0
  241. calc_terminal/ui/editor.py +2102 -0
  242. calc_terminal/ui/empty_state.py +302 -0
  243. calc_terminal/ui/events.py +487 -0
  244. calc_terminal/ui/extensions_panel.py +815 -0
  245. calc_terminal/ui/footer.py +166 -0
  246. calc_terminal/ui/gestures_panel.py +383 -0
  247. calc_terminal/ui/goodbye_screen.py +100 -0
  248. calc_terminal/ui/header.py +1034 -0
  249. calc_terminal/ui/help_panel.py +254 -0
  250. calc_terminal/ui/live_activities.py +914 -0
  251. calc_terminal/ui/mcp_panel.py +570 -0
  252. calc_terminal/ui/memory_center.py +524 -0
  253. calc_terminal/ui/mode_colors_panel.py +525 -0
  254. calc_terminal/ui/nav_screens.py +747 -0
  255. calc_terminal/ui/ollama_panel.py +536 -0
  256. calc_terminal/ui/palette.py +221 -0
  257. calc_terminal/ui/permission_panel.py +269 -0
  258. calc_terminal/ui/personalization_panel.py +517 -0
  259. calc_terminal/ui/personalize_center.py +1568 -0
  260. calc_terminal/ui/preview_panel.py +441 -0
  261. calc_terminal/ui/resizers.py +402 -0
  262. calc_terminal/ui/sidebar.py +1285 -0
  263. calc_terminal/ui/statusbar.py +168 -0
  264. calc_terminal/ui/theme_css.py +1396 -0
  265. calc_terminal/ui/thinking.py +226 -0
  266. calc_terminal/ui/timeline_panel.py +102 -0
  267. calc_terminal/ui/todo_panel.py +193 -0
  268. calc_terminal/ui/viewport.py +136 -0
  269. calc_terminal/ui/vision_panel.py +489 -0
  270. calc_terminal/ui/welcome_modal.py +343 -0
  271. calc_terminal/ui/widgets.py +160 -0
  272. calc_terminal/ui/workspace.py +831 -0
  273. calc_terminal/viewers/__init__.py +1 -0
  274. calc_terminal/viewers/document_viewer.py +252 -0
  275. calc_terminal/viewers/image_viewer.py +241 -0
  276. calc_terminal/viewers/pdf_viewer.py +203 -0
  277. calc_terminal/viewers/presentation_viewer.py +164 -0
  278. calc_terminal/viewers/registry.py +120 -0
  279. calc_terminal/viewers/spreadsheet_viewer.py +204 -0
  280. calc_terminal/vision/__init__.py +89 -0
  281. calc_terminal/vision/analysis.py +194 -0
  282. calc_terminal/vision/annotations.py +297 -0
  283. calc_terminal/vision/capture.py +171 -0
  284. calc_terminal/vision/context.py +231 -0
  285. calc_terminal/vision/correlation.py +169 -0
  286. calc_terminal/vision/cursor.py +258 -0
  287. calc_terminal/vision/events.py +66 -0
  288. calc_terminal/vision/frame_pipeline.py +259 -0
  289. calc_terminal/vision/priority.py +218 -0
  290. calc_terminal/vision/provider.py +180 -0
  291. calc_terminal/vision/safety.py +149 -0
  292. calc_terminal/vision/session.py +281 -0
  293. calc_terminal/vision/verify.py +162 -0
  294. calc_terminal/vision.py +514 -0
  295. calc_terminal/vscode_integration.py +113 -0
  296. calc_terminal/web/__init__.py +8 -0
  297. calc_terminal/web/cat_runtime.py +710 -0
  298. calc_terminal/web/server.py +2891 -0
  299. calc_terminal/web/static/css/app.css +3152 -0
  300. calc_terminal/web/static/icons/badge-72.png +0 -0
  301. calc_terminal/web/static/icons/cat.ico +0 -0
  302. calc_terminal/web/static/icons/icon-128.png +0 -0
  303. calc_terminal/web/static/icons/icon-144.png +0 -0
  304. calc_terminal/web/static/icons/icon-152.png +0 -0
  305. calc_terminal/web/static/icons/icon-192.png +0 -0
  306. calc_terminal/web/static/icons/icon-384.png +0 -0
  307. calc_terminal/web/static/icons/icon-512.png +0 -0
  308. calc_terminal/web/static/icons/icon-72.png +0 -0
  309. calc_terminal/web/static/icons/icon-96.png +0 -0
  310. calc_terminal/web/static/icons/icon.svg +34 -0
  311. calc_terminal/web/static/icons/new-project.png +0 -0
  312. calc_terminal/web/static/icons/open-project.png +0 -0
  313. calc_terminal/web/static/index.html +734 -0
  314. calc_terminal/web/static/js/app.js +2403 -0
  315. calc_terminal/web/static/manifest.json +88 -0
  316. calc_terminal/web/static/sw.js +230 -0
  317. calc_terminal/workflow_engine.py +769 -0
  318. calc_terminal/workspace.py +593 -0
  319. calc_terminal/workspace_index.py +385 -0
  320. cct_cli-0.7.9.0.dist-info/METADATA +210 -0
  321. cct_cli-0.7.9.0.dist-info/RECORD +325 -0
  322. cct_cli-0.7.9.0.dist-info/WHEEL +5 -0
  323. cct_cli-0.7.9.0.dist-info/entry_points.txt +4 -0
  324. cct_cli-0.7.9.0.dist-info/licenses/LICENSE +21 -0
  325. cct_cli-0.7.9.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,385 @@
1
+ """
2
+ CCT — workspace_index.py: AI Workspace Understanding (v0.7.7 Workspace
3
+ Management Preview, spec section 6).
4
+
5
+ Whenever the workspace changes, CCT indexes it: scans the file tree,
6
+ reads the README and configuration files, detects the programming
7
+ language(s) and package managers, understands dependencies, and builds
8
+ a compact project context the AI (and the header) can use.
9
+
10
+ The scan is honest and bounded:
11
+
12
+ - Never follows .git / node_modules / venv / __pycache__ / dist /
13
+ build (the classic noise folders);
14
+ - file/dir counts are capped; the structure sample is capped;
15
+ - dependency parsing reads real manifests (requirements.txt,
16
+ package.json, Cargo.toml, go.mod, pyproject.toml) and takes the
17
+ top-level names only;
18
+ - every failure degrades to "unknown/empty" — no fabricated data.
19
+
20
+ Progress is reported through an optional `on_progress(stage,
21
+ message)` callback with the spec's exact stages:
22
+ "scanning" -> "Reading Files..." -> "building" -> "ready".
23
+ """
24
+
25
+ if __name__ == "__main__":
26
+ print("This is a library file and is not meant to be run directly.")
27
+ import sys
28
+ sys.exit(1)
29
+
30
+ import os
31
+
32
+ PROGRESS_STAGES = ("scanning", "reading", "building", "ready")
33
+
34
+ STAGE_LABELS = {
35
+ "scanning": "\U0001f50d Scanning Workspace...",
36
+ "reading": "\U0001f4d6 Reading Files...",
37
+ "building": "\U0001f9f1 Building Context...",
38
+ "ready": "\u2705 Ready",
39
+ }
40
+
41
+ _SKIP_DIRS = {
42
+ ".git", "node_modules", "__pycache__", ".venv", "venv", "env",
43
+ "dist", "build", ".idea", ".vscode", ".tox", ".mypy_cache",
44
+ ".pytest_cache", "target", "bin", "obj", ".next", "out",
45
+ }
46
+
47
+ _LANGUAGE_BY_EXT = {
48
+ ".py": "Python", ".pyw": "Python", ".ipynb": "Python",
49
+ ".js": "JavaScript", ".jsx": "JavaScript", ".mjs": "JavaScript",
50
+ ".ts": "TypeScript", ".tsx": "TypeScript",
51
+ ".html": "HTML", ".css": "CSS", ".scss": "SCSS", ".sass": "Sass",
52
+ ".json": "JSON", ".yaml": "YAML", ".yml": "YAML", ".toml": "TOML",
53
+ ".xml": "XML", ".md": "Markdown", ".rst": "reStructuredText",
54
+ ".c": "C", ".h": "C", ".cpp": "C++", ".cc": "C++", ".hpp": "C++",
55
+ ".cs": "C#", ".java": "Java", ".kt": "Kotlin", ".kts": "Kotlin",
56
+ ".go": "Go", ".rs": "Rust", ".rb": "Ruby", ".php": "PHP",
57
+ ".swift": "Swift", ".m": "Objective-C", ".scala": "Scala",
58
+ ".sh": "Shell", ".bat": "Batch", ".ps1": "PowerShell",
59
+ ".sql": "SQL", ".r": "R", ".lua": "Lua", ".pl": "Perl",
60
+ ".dart": "Dart", ".vue": "Vue", ".svelte": "Svelte",
61
+ ".ex": "Elixir", ".exs": "Elixir", ".erl": "Erlang",
62
+ ".hs": "Haskell", ".clj": "Clojure", ".zig": "Zig",
63
+ }
64
+
65
+ # Top-level manifest files that reveal package managers / deps.
66
+ _CONFIG_FILES = {
67
+ "pyproject.toml": "pyproject.toml (PEP 621)",
68
+ "requirements.txt": "requirements.txt",
69
+ "setup.py": "setup.py",
70
+ "setup.cfg": "setup.cfg",
71
+ "Pipfile": "Pipfile",
72
+ "poetry.lock": "poetry.lock",
73
+ "uv.lock": "uv.lock",
74
+ "package.json": "package.json",
75
+ "package-lock.json": "package-lock.json",
76
+ "pnpm-lock.yaml": "pnpm-lock.yaml",
77
+ "yarn.lock": "yarn.lock",
78
+ "Cargo.toml": "Cargo.toml",
79
+ "go.mod": "go.mod",
80
+ "composer.json": "composer.json",
81
+ "Gemfile": "Gemfile",
82
+ "build.gradle": "build.gradle",
83
+ "pom.xml": "pom.xml",
84
+ "Dockerfile": "Dockerfile",
85
+ "docker-compose.yml": "docker-compose.yml",
86
+ "Makefile": "Makefile",
87
+ ".env.example": ".env.example",
88
+ ".editorconfig": ".editorconfig",
89
+ "tsconfig.json": "tsconfig.json",
90
+ ".eslintrc": ".eslintrc",
91
+ "vite.config.js": "vite.config.js",
92
+ "vite.config.ts": "vite.config.ts",
93
+ }
94
+
95
+ _README_NAMES = ("README.md", "README", "Readme.md", "readme.md",
96
+ "README.txt", "README.rst")
97
+
98
+ _MAX_SCAN_FILES = 20000
99
+ _MAX_DEPENDENCIES = 40
100
+ _MAX_STRUCTURE = 40
101
+ _MAX_README_CHARS = 2000
102
+
103
+
104
+ def _scan(path, on_progress=None):
105
+ """Walks the tree once, collecting counts, extension histogram,
106
+ top-level structure, config files, and readmes."""
107
+ file_count = 0
108
+ dir_count = 0
109
+ total_size = 0
110
+ ext_counts = {}
111
+ structure = []
112
+ configs = []
113
+ readme_path = None
114
+ root = path
115
+ for base, dirs, files in os.walk(path):
116
+ dirs[:] = sorted(d for d in dirs if d not in _SKIP_DIRS)
117
+ rel = os.path.relpath(base, root)
118
+ if rel != ".":
119
+ dir_count += 1
120
+ if rel != "." and len(structure) < _MAX_STRUCTURE:
121
+ structure.append({"type": "dir", "path": rel})
122
+ for name in sorted(files):
123
+ full = os.path.join(base, name)
124
+ try:
125
+ size = os.path.getsize(full)
126
+ except OSError:
127
+ continue
128
+ total_size += size
129
+ file_count += 1
130
+ ext = os.path.splitext(name)[1].lower()
131
+ ext_counts[ext] = ext_counts.get(ext, 0) + 1
132
+ if file_count > _MAX_SCAN_FILES:
133
+ return None
134
+ rel_name = name if rel == "." else os.path.join(rel, name)
135
+ if rel == "." and name in _CONFIG_FILES:
136
+ configs.append(name)
137
+ if len(structure) < _MAX_STRUCTURE and rel == "." and name:
138
+ structure.append({"type": "file", "path": name})
139
+ if readme_path is None and name in _README_NAMES:
140
+ readme_path = full
141
+ return {
142
+ "file_count": file_count,
143
+ "dir_count": dir_count,
144
+ "total_size": total_size,
145
+ "ext_counts": ext_counts,
146
+ "structure": structure,
147
+ "configs": sorted(set(configs)),
148
+ "readme_path": readme_path,
149
+ }
150
+
151
+
152
+ def _languages(ext_counts):
153
+ by_lang = {}
154
+ for ext, count in ext_counts.items():
155
+ lang = _LANGUAGE_BY_EXT.get(ext)
156
+ if lang:
157
+ by_lang[lang] = by_lang.get(lang, 0) + count
158
+ ordered = sorted(by_lang.items(), key=lambda kv: -kv[1])
159
+ return [lang for lang, _n in ordered[:6]]
160
+
161
+
162
+ def _read_readme(readme_path):
163
+ if not readme_path:
164
+ return None
165
+ try:
166
+ with open(readme_path, "r", encoding="utf-8", errors="replace") as f:
167
+ text = f.read(200000)
168
+ lines = [ln.strip() for ln in text.splitlines() if ln.strip()]
169
+ summary_lines = []
170
+ for ln in lines:
171
+ if ln.startswith("#"):
172
+ continue
173
+ if ln.startswith("```"):
174
+ break
175
+ summary_lines.append(ln)
176
+ if len(summary_lines) >= 6:
177
+ break
178
+ snippet = " \u00b7 ".join(summary_lines)
179
+ return snippet[:_MAX_README_CHARS] if snippet else None
180
+ except Exception:
181
+ return None
182
+
183
+
184
+ def _dependencies(path):
185
+ """Top-level dependency names from real manifests. Capped, honest:
186
+ only names that can actually be parsed are listed."""
187
+ deps = []
188
+
189
+ def _reqs(full):
190
+ try:
191
+ with open(full, "r", encoding="utf-8", errors="replace") as f:
192
+ for line in f:
193
+ line = line.split("#")[0].strip()
194
+ if not line:
195
+ continue
196
+ name = line.split("==")[0].split(">=")[0].split("<")[0] \
197
+ .split("[")[0].strip().replace("_", "-")
198
+ if name and name not in deps:
199
+ deps.append(name)
200
+ except Exception:
201
+ pass
202
+
203
+ def _json(full, keys):
204
+ try:
205
+ with open(full, "r", encoding="utf-8", errors="replace") as f:
206
+ import json
207
+ data = json.load(f)
208
+ for key in keys:
209
+ block = data.get(key) or {}
210
+ if isinstance(block, dict):
211
+ for name in block:
212
+ if name and name not in deps:
213
+ deps.append(name)
214
+ except Exception:
215
+ pass
216
+
217
+ _METADATA_KEYS = {
218
+ "name", "version", "description", "requires-python",
219
+ "authors", "maintainers", "license", "readme", "homepage",
220
+ "repository", "keywords", "classifiers", "dependencies",
221
+ "optional-dependencies", "url", "author", "license-file",
222
+ "documentation", "issues", "changelog", "build-backend",
223
+ "requires", "build-system", "module", "bin", "edition",
224
+ "rust-version", "publish", "go", "toolchain",
225
+ }
226
+
227
+ def _kv(full):
228
+ try:
229
+ with open(full, "r", encoding="utf-8", errors="replace") as f:
230
+ for line in f:
231
+ line = line.strip()
232
+ if line.startswith("[") or not line or "=" not in line:
233
+ continue
234
+ key = line.split("=")[0].strip().strip('"')
235
+ if not key or key in _METADATA_KEYS or key.startswith("."):
236
+ continue
237
+ if key not in deps:
238
+ deps.append(key)
239
+ except Exception:
240
+ pass
241
+
242
+ for name, full in (("requirements.txt", None), ("pyproject.toml", None)):
243
+ p = os.path.join(path, name)
244
+ if os.path.isfile(p):
245
+ _reqs(p) if name == "requirements.txt" else _kv(p)
246
+ pkg = os.path.join(path, "package.json")
247
+ if os.path.isfile(pkg):
248
+ _json(pkg, ("dependencies", "devDependencies", "peerDependencies"))
249
+ go_mod = os.path.join(path, "go.mod")
250
+ if os.path.isfile(go_mod):
251
+ _kv(go_mod)
252
+ cargo = os.path.join(path, "Cargo.toml")
253
+ if os.path.isfile(cargo):
254
+ _kv(cargo)
255
+ return deps[:_MAX_DEPENDENCIES]
256
+
257
+
258
+ def _package_managers(path):
259
+ found = []
260
+ names = set(os.listdir(path)) if os.path.isdir(path) else set()
261
+ if "requirements.txt" in names or "pyproject.toml" in names or "setup.py" in names:
262
+ found.append("pip")
263
+ if "Pipfile" in names or "poetry.lock" in names:
264
+ found.append("poetry")
265
+ if "uv.lock" in names:
266
+ found.append("uv")
267
+ if "package.json" in names or "yarn.lock" in names or "pnpm-lock.yaml" in names:
268
+ found.append("npm")
269
+ if "Cargo.toml" in names or "Cargo.lock" in names:
270
+ found.append("cargo")
271
+ if "go.mod" in names:
272
+ found.append("go")
273
+ if "composer.json" in names:
274
+ found.append("composer")
275
+ if "Gemfile" in names:
276
+ found.append("bundler")
277
+ if "pom.xml" in names or "build.gradle" in names:
278
+ found.append("maven")
279
+ return found
280
+
281
+
282
+ def index_project(path, on_progress=None):
283
+ """Builds the project context for `path` (spec section 6). Returns
284
+ a dict with keys: languages, file_count, dir_count, structure,
285
+ configs, readme, package_managers, dependencies, git, description.
286
+ `on_progress(stage, message)` fires once per stage in order:
287
+ scanning -> reading -> building -> ready. Never raises for
288
+ filesystem problems — a broken path yields an honest minimal
289
+ context."""
290
+ import time
291
+
292
+ def _progress(stage):
293
+ if on_progress:
294
+ try:
295
+ on_progress(stage, STAGE_LABELS[stage])
296
+ except Exception:
297
+ pass
298
+
299
+ ctx = {"path": os.path.abspath(path), "ok": False,
300
+ "languages": [], "file_count": 0, "dir_count": 0,
301
+ "structure": [], "configs": [], "readme": None,
302
+ "package_managers": [], "dependencies": [],
303
+ "git": None, "description": "", "elapsed": 0.0}
304
+ if not os.path.isdir(path):
305
+ return ctx
306
+ _progress("scanning")
307
+ t0 = time.time()
308
+ scan = _scan(path, on_progress)
309
+ if scan is None:
310
+ scan = {"file_count": 0, "dir_count": 0, "total_size": 0,
311
+ "ext_counts": {}, "structure": [], "configs": [],
312
+ "readme_path": None}
313
+ _progress("reading")
314
+ readme = _read_readme(scan["readme_path"])
315
+ _progress("building")
316
+ from . import workspace as ws
317
+ branch = ws.git_branch(path)
318
+ git_status = ws.git_status_summary(path)
319
+ ctx.update({
320
+ "ok": True,
321
+ "languages": _languages(scan["ext_counts"]),
322
+ "file_count": scan["file_count"],
323
+ "dir_count": scan["dir_count"],
324
+ "total_size": scan["total_size"],
325
+ "structure": [s["path"] for s in scan["structure"]],
326
+ "configs": scan["configs"],
327
+ "readme": readme,
328
+ "package_managers": _package_managers(path),
329
+ "dependencies": _dependencies(path),
330
+ "git": {"branch": branch, "status": git_status},
331
+ "elapsed": round(time.time() - t0, 2),
332
+ })
333
+ _progress("ready")
334
+ return ctx
335
+
336
+
337
+ def describe(ctx):
338
+ """One-line human description of an indexed project, for the
339
+ header and the 'Ready' summary."""
340
+ if not ctx or not ctx.get("ok"):
341
+ return "Workspace not indexed"
342
+ langs = ", ".join(ctx["languages"][:3]) if ctx["languages"] else "unknown"
343
+ deps = len(ctx["dependencies"])
344
+ files = ctx["file_count"]
345
+ branch = (ctx.get("git") or {}).get("branch")
346
+ bits = [f"{langs} \u00b7 {files} files"]
347
+ if deps:
348
+ bits.append(f"{deps} dependencies")
349
+ if branch:
350
+ bits.append(f"\U0001f33f {branch}")
351
+ return " \u00b7 ".join(bits)
352
+
353
+
354
+ def summarize_context(ctx):
355
+ """A compact markdown block the AI/chat can show after indexing
356
+ (spec section 6's 'Ready' state, with real content)."""
357
+ if not ctx or not ctx.get("ok"):
358
+ return ("*\u26a0 Couldn't index this workspace (missing or unreadable folder). "
359
+ "The AI will work without project context.*")
360
+ lines = ["\U0001f4c2 **Project Context** \u2014 ready", ""]
361
+ lines.append(f"- **Files**: {ctx['file_count']} files, {ctx['dir_count']} folders")
362
+ if ctx["languages"]:
363
+ lines.append("- **Languages**: " + ", ".join(ctx["languages"]))
364
+ if ctx["package_managers"]:
365
+ lines.append("- **Package managers**: " + ", ".join(ctx["package_managers"]))
366
+ if ctx["dependencies"]:
367
+ deps = ", ".join(ctx["dependencies"][:12])
368
+ more = f" (+{len(ctx['dependencies']) - 12} more)" if len(ctx["dependencies"]) > 12 else ""
369
+ lines.append(f"- **Dependencies**: {deps}{more}")
370
+ if ctx["configs"]:
371
+ lines.append("- **Config files**: " + ", ".join(ctx["configs"][:8]))
372
+ if ctx["readme"]:
373
+ lines.append(f"- **README**: {ctx['readme']}")
374
+ git = ctx.get("git") or {}
375
+ if git.get("branch"):
376
+ lines.append(f"- **Git**: branch `{git['branch']}`")
377
+ st = git.get("status")
378
+ if st:
379
+ summary = f"{st['changed']} modified, {st['added']} added, {st['deleted']} deleted"
380
+ lines.append(f"- **Git status**: {summary}")
381
+ if ctx["structure"]:
382
+ top = ", ".join(ctx["structure"][:12])
383
+ lines.append(f"- **Structure**: {top}")
384
+ lines.append(f"- **Indexed in**: {ctx['elapsed']}s")
385
+ return "\n".join(lines)
@@ -0,0 +1,210 @@
1
+ Metadata-Version: 2.4
2
+ Name: cct-cli
3
+ Version: 0.7.9.0
4
+ Summary: CAT v0.7.9.0 — Coding Agent Terminal / terminal AI coding agent
5
+ Author: Kazi Zillani
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/kazizillani-oss/CAT_v0.7.9
8
+ Project-URL: Repository, https://github.com/kazizillani-oss/CAT_v0.7.9
9
+ Project-URL: Changelog, https://github.com/kazizillani-oss/CAT_v0.7.9/blob/main/CAT_v0.7.4/CHANGELOG_v0.7.9.md
10
+ Keywords: cat,cct-cli,cct,ai,agent,terminal,tui,cli,coding-agent
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Operating System :: Microsoft :: Windows
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Operating System :: MacOS
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Software Development
23
+ Classifier: Topic :: Scientific/Engineering
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: textual[syntax]>=0.60
28
+ Requires-Dist: rich>=13.0
29
+ Requires-Dist: requests>=2.31.0
30
+ Requires-Dist: colorama>=0.4.6; sys_platform == "win32"
31
+ Requires-Dist: watchdog>=4.0
32
+ Requires-Dist: plyer>=2.1
33
+ Provides-Extra: web
34
+ Requires-Dist: fastapi>=0.100.0; extra == "web"
35
+ Requires-Dist: uvicorn>=0.20.0; extra == "web"
36
+ Requires-Dist: pydantic>=2.0; extra == "web"
37
+ Requires-Dist: python-multipart>=0.0.6; extra == "web"
38
+ Provides-Extra: science
39
+ Requires-Dist: sympy>=1.12; extra == "science"
40
+ Requires-Dist: matplotlib>=3.7; extra == "science"
41
+ Requires-Dist: numpy>=1.24; extra == "science"
42
+ Requires-Dist: reportlab>=4.0; extra == "science"
43
+ Requires-Dist: pyperclip>=1.8.2; extra == "science"
44
+ Requires-Dist: prompt_toolkit>=3.0.43; extra == "science"
45
+ Provides-Extra: host
46
+ Requires-Dist: PySide6>=6.6; extra == "host"
47
+ Provides-Extra: browser
48
+ Requires-Dist: PySide6>=6.6; extra == "browser"
49
+ Requires-Dist: pywebview>=4.4; extra == "browser"
50
+ Requires-Dist: playwright>=1.40; extra == "browser"
51
+ Provides-Extra: all
52
+ Requires-Dist: cct-cli[browser,science,web]; extra == "all"
53
+ Dynamic: license-file
54
+
55
+ # Coding Agent Terminal (CAT)
56
+
57
+ <div align="center">
58
+
59
+ ```
60
+ ██████╗ █████╗ ████████╗
61
+ ██╔════╝██╔══██╗╚══██╔══╝
62
+ ██║ ███████║ ██║
63
+ ██║ ██╔══██║ ██║
64
+ ╚██████╗██║ ██║ ██║
65
+ ╚═════╝╚═╝ ╚═╝ ╚═╝
66
+
67
+ CODING AGENT TERMINAL · v0.7.9.0
68
+ ```
69
+
70
+ [![CI](https://github.com/kazizillani-oss/CAT_v0.7.9/actions/workflows/ci.yml/badge.svg)](https://github.com/kazizillani-oss/CAT_v0.7.9/actions/workflows/ci.yml)
71
+ [![Version](https://img.shields.io/badge/version-0.7.9.0-blue.svg)](https://github.com/kazizillani-oss/CAT_v0.7.9)
72
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
73
+ [![Platforms](https://img.shields.io/badge/platforms-Windows%20%7C%20macOS%20%7C%20Linux-lightgrey.svg)]()
74
+
75
+ *An autonomous AI developer terminal and chemical computation environment styled like OpenCode, Claude Code, and Warp in the Tokyo Night theme.*
76
+
77
+ </div>
78
+
79
+ ---
80
+
81
+ ## ⚡ Quick Install
82
+
83
+ CAT is distributed across multiple channels. Choose the method that best fits your workflow:
84
+
85
+ ### Option 1: Install from PyPI (Recommended for most users)
86
+
87
+ CAT is published as `cct-cli` on PyPI. The PyPI distribution name and the
88
+ terminal command are intentionally different:
89
+
90
+ ```text
91
+ PyPI package: cct-cli
92
+ CLI command: cat (plus aliases catx and cct)
93
+ ```
94
+
95
+ Install and launch from any terminal (no need to clone the repository):
96
+
97
+ ```powershell
98
+ python -m pip install cct-cli
99
+ cat --version
100
+ cat
101
+ ```
102
+
103
+ Notes:
104
+
105
+ - `cat` is the canonical command. `catx` is provided for Unix systems where
106
+ `cat` collides with GNU coreutils, and for Windows PowerShell where `cat`
107
+ is a built-in alias for `Get-Content` (use `cat.exe` or `catx` if `cat`
108
+ resolves to the alias in your shell).
109
+ - `cct` is kept as a historic alias so existing installs and docs keep working.
110
+ - Branding is CAT everywhere. Never install anything named `cot-ai-ide`
111
+ (typo) — the only official PyPI distribution is `cct-cli`.
112
+ - Optional extras: `pip install "cct-cli[web]"` (Fatty CAT web server),
113
+ `pip install "cct-cli[science]"` (calculator/graph/export features),
114
+ `pip install "cct-cli[browser]"` (embedded browser), or
115
+ `pip install "cct-cli[all]"` for everything.
116
+ - Requires Python 3.10 or newer (tested on 3.10–3.13).
117
+
118
+ ### Option 2: Windows Installer (Native Windows experience)
119
+
120
+ Download and run the native installer:
121
+ - **`CAT-Setup.exe`** from [Latest Releases](https://github.com/kazizillani-oss/CAT_v0.7.9/releases/latest).
122
+ - Per-user installation to `%LOCALAPPDATA%\Programs\CAT` (no administrator privileges required).
123
+ - Automatically adds `cat`, `catx`, and `cct` to your `PATH` and configures PowerShell aliases cleanly.
124
+
125
+ Or via PowerShell:
126
+ ```powershell
127
+ powershell -ExecutionPolicy Bypass -File installer/windows/scripts/install.ps1 -Install
128
+ ```
129
+
130
+ ### Option 3: Local Development / Editable Install
131
+ If you are developing or running from source:
132
+ ```bash
133
+ git clone https://github.com/kazizillani-oss/CAT_v0.7.9.git
134
+ cd CAT_v0.7.9
135
+ pip install -e .
136
+ cat
137
+ ```
138
+
139
+ For contributors, install with test/build tooling:
140
+
141
+ ```bash
142
+ pip install -e ".[web,science]"
143
+ pip install build twine pytest
144
+ python -m build
145
+ python -m twine check dist/*
146
+ ```
147
+
148
+ ---
149
+
150
+ ## 🚀 CLI Commands & Subcommands
151
+
152
+ | Command | Purpose |
153
+ | :--- | :--- |
154
+ | `cat` / `catx` / `cct` | Launch the interactive CAT terminal & UI. |
155
+ | `cat update` | Check for and install the latest CAT version from GitHub Releases. |
156
+ | `cat update --check` | Check if a newer version is available without installing. |
157
+ | `cat rollback` | Roll back to the previously installed version. |
158
+ | `cat repair` | Self-heal corrupted configurations, repair directory structures and file permissions. |
159
+ | `cat --debug` | Display detailed environment, paths, platform, and runtime debugging information. |
160
+ | `cat --doctor` | Run diagnostic health checks across Python, terminal capabilities, and AI providers. |
161
+ | `cat --version` | Display the current installed CAT version. |
162
+
163
+ ---
164
+
165
+ ## 🛠️ Key Features
166
+
167
+ - **Tokyo Night Terminal UI**: Rich ASCII styling, 24-bit ANSI colors, split-pane Textual layout, animated spinners, and sound effects.
168
+ - **Autonomous Development & Workspace Management**: Detects git roots, VS Code workspaces, parses manifests, and indexes files with live progress indicators.
169
+ - **Universal Formula & Science Calculator**: 39+ symbolic formulas, 2D/3D animated graphs, and live Bohr/quantum orbital simulations.
170
+ - **Multi-Provider AI Orchestrator**: Supports OpenAI, Anthropic, Gemini, Groq, OpenRouter, and Ollama with automatic failover and tool execution.
171
+ - **Extensible Architecture**: `.cat` chats store and `.catxt` extension registry for custom modules and extensions.
172
+ - **Fomoji Server Integration**: Optional bundled local web services with automated lifecycle management.
173
+
174
+ ---
175
+
176
+ ## 📦 Universal Distribution Architecture
177
+
178
+ CAT's distribution system decouples lightweight public launchers from private source code:
179
+ - **Zero Source Leakage**: npm and PyPI packages contain strictly minimal launchers (~4 kB) that pull platform-native binaries verified by SHA256 checksums from `release/manifest/releases.json`.
180
+ - **Atomic Updates & Rollbacks**: Update artifacts are validated against signed manifests before replacing running binaries, with automated snapshotting into `~/.cat/versions/`.
181
+ - **Command Collision Prevention**: Provides both `cat` and `catx` commands to prevent collisions with GNU coreutils `cat` on Unix and handles PowerShell's built-in `Get-Content` alias automatically.
182
+
183
+ For detailed documentation:
184
+ - [Distribution Architecture](docs/DISTRIBUTION.md)
185
+ - [Maintainer Releasing Guide](docs/RELEASING.md)
186
+
187
+ ---
188
+
189
+ ## 🧪 Testing & Verification
190
+
191
+ Run the test suite locally:
192
+
193
+ ```bash
194
+ # Verify release isolation, security, and version sync
195
+ python scripts/verify_release.py
196
+
197
+ # Run distribution integration unit tests
198
+ python scripts/test_distribution.py
199
+
200
+ # Test runtime builder in dry-run mode
201
+ python scripts/build_runtime.py --dry-run
202
+ ```
203
+
204
+ ---
205
+
206
+ ## 📄 License
207
+
208
+ MIT © [Kazi Zillani](https://github.com/kazizillani-oss)
209
+
210
+