code-context-control 2.28.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 (150) hide show
  1. cli/__init__.py +1 -0
  2. cli/_hook_utils.py +99 -0
  3. cli/c3.py +6152 -0
  4. cli/commands/__init__.py +1 -0
  5. cli/commands/common.py +312 -0
  6. cli/commands/parser.py +286 -0
  7. cli/docs.html +3178 -0
  8. cli/edits.html +878 -0
  9. cli/hook_auto_snapshot.py +142 -0
  10. cli/hook_c3_signal.py +61 -0
  11. cli/hook_c3read.py +116 -0
  12. cli/hook_edit_ledger.py +213 -0
  13. cli/hook_edit_unlock.py +170 -0
  14. cli/hook_filter.py +130 -0
  15. cli/hook_ghost_files.py +238 -0
  16. cli/hook_pretool_enforce.py +334 -0
  17. cli/hook_read.py +200 -0
  18. cli/hook_session_stats.py +62 -0
  19. cli/hook_terse_advisor.py +190 -0
  20. cli/hub.html +3764 -0
  21. cli/hub_server.py +1619 -0
  22. cli/mcp_proxy.py +428 -0
  23. cli/mcp_server.py +660 -0
  24. cli/server.py +2985 -0
  25. cli/tools/__init__.py +4 -0
  26. cli/tools/_helpers.py +65 -0
  27. cli/tools/agent.py +1165 -0
  28. cli/tools/compress.py +215 -0
  29. cli/tools/delegate.py +1184 -0
  30. cli/tools/edit.py +313 -0
  31. cli/tools/edits.py +118 -0
  32. cli/tools/filter.py +285 -0
  33. cli/tools/impact.py +163 -0
  34. cli/tools/memory.py +469 -0
  35. cli/tools/read.py +224 -0
  36. cli/tools/search.py +337 -0
  37. cli/tools/session.py +95 -0
  38. cli/tools/shell.py +193 -0
  39. cli/tools/status.py +306 -0
  40. cli/tools/validate.py +310 -0
  41. cli/ui/api.js +36 -0
  42. cli/ui/app.js +207 -0
  43. cli/ui/components/chat.js +758 -0
  44. cli/ui/components/dashboard.js +689 -0
  45. cli/ui/components/edits.js +220 -0
  46. cli/ui/components/instructions.js +481 -0
  47. cli/ui/components/memory.js +626 -0
  48. cli/ui/components/sessions.js +606 -0
  49. cli/ui/components/settings.js +1404 -0
  50. cli/ui/components/sidebar.js +156 -0
  51. cli/ui/icons.js +51 -0
  52. cli/ui/shared.js +119 -0
  53. cli/ui/theme.js +22 -0
  54. cli/ui.html +168 -0
  55. cli/ui_legacy.html +6797 -0
  56. cli/ui_nano.html +503 -0
  57. code_context_control-2.28.0.dist-info/METADATA +248 -0
  58. code_context_control-2.28.0.dist-info/RECORD +150 -0
  59. code_context_control-2.28.0.dist-info/WHEEL +5 -0
  60. code_context_control-2.28.0.dist-info/entry_points.txt +4 -0
  61. code_context_control-2.28.0.dist-info/licenses/LICENSE +201 -0
  62. code_context_control-2.28.0.dist-info/top_level.txt +5 -0
  63. core/__init__.py +75 -0
  64. core/config.py +269 -0
  65. core/ide.py +188 -0
  66. oracle/__init__.py +1 -0
  67. oracle/config.py +75 -0
  68. oracle/oracle.html +3900 -0
  69. oracle/oracle_server.py +663 -0
  70. oracle/services/__init__.py +1 -0
  71. oracle/services/c3_bridge.py +210 -0
  72. oracle/services/chat_engine.py +1103 -0
  73. oracle/services/chat_store.py +155 -0
  74. oracle/services/cross_memory.py +154 -0
  75. oracle/services/federated_graph.py +463 -0
  76. oracle/services/health_checker.py +117 -0
  77. oracle/services/insight_engine.py +307 -0
  78. oracle/services/memory_reader.py +106 -0
  79. oracle/services/memory_writer.py +182 -0
  80. oracle/services/ollama_bridge.py +332 -0
  81. oracle/services/project_scanner.py +87 -0
  82. oracle/services/review_agent.py +206 -0
  83. services/__init__.py +1 -0
  84. services/activity_log.py +93 -0
  85. services/agent_base.py +124 -0
  86. services/agents.py +1529 -0
  87. services/auto_memory.py +407 -0
  88. services/bench/__init__.py +6 -0
  89. services/bench/external/__init__.py +29 -0
  90. services/bench/external/aider_polyglot.py +405 -0
  91. services/bench/external/swe_bench.py +485 -0
  92. services/benchmark_dashboard.py +596 -0
  93. services/claude_md.py +785 -0
  94. services/compressor.py +592 -0
  95. services/context_snapshot.py +356 -0
  96. services/conversation_store.py +870 -0
  97. services/doc_index.py +537 -0
  98. services/e2e_benchmark.py +2884 -0
  99. services/e2e_evaluator.py +396 -0
  100. services/e2e_tasks.py +743 -0
  101. services/edit_ledger.py +459 -0
  102. services/embedding_index.py +341 -0
  103. services/error_reporting.py +123 -0
  104. services/file_memory.py +734 -0
  105. services/hub_service.py +585 -0
  106. services/indexer.py +712 -0
  107. services/memory.py +318 -0
  108. services/memory_consolidator.py +538 -0
  109. services/memory_graph.py +382 -0
  110. services/memory_grounder.py +304 -0
  111. services/memory_scorer.py +246 -0
  112. services/metrics.py +86 -0
  113. services/notifications.py +209 -0
  114. services/ollama_client.py +201 -0
  115. services/output_filter.py +488 -0
  116. services/parser.py +1238 -0
  117. services/project_manager.py +579 -0
  118. services/protocol.py +306 -0
  119. services/proxy_state.py +152 -0
  120. services/retrieval_broker.py +129 -0
  121. services/router.py +414 -0
  122. services/runtime.py +326 -0
  123. services/session_benchmark.py +1945 -0
  124. services/session_manager.py +1026 -0
  125. services/session_preloader.py +251 -0
  126. services/text_index.py +90 -0
  127. services/tool_classifier.py +176 -0
  128. services/transcript_index.py +340 -0
  129. services/validation_cache.py +155 -0
  130. services/vector_store.py +299 -0
  131. services/version_tracker.py +271 -0
  132. services/watcher.py +192 -0
  133. tui/__init__.py +0 -0
  134. tui/backend.py +59 -0
  135. tui/main.py +145 -0
  136. tui/screens/__init__.py +1 -0
  137. tui/screens/benchmark_view.py +109 -0
  138. tui/screens/claudemd_view.py +46 -0
  139. tui/screens/compress_view.py +52 -0
  140. tui/screens/index_view.py +74 -0
  141. tui/screens/init_view.py +82 -0
  142. tui/screens/mcp_view.py +73 -0
  143. tui/screens/optimize_view.py +41 -0
  144. tui/screens/pipe_view.py +46 -0
  145. tui/screens/projects_view.py +355 -0
  146. tui/screens/search_view.py +55 -0
  147. tui/screens/session_view.py +143 -0
  148. tui/screens/stats.py +158 -0
  149. tui/screens/ui_view.py +54 -0
  150. tui/theme.tcss +335 -0
cli/__init__.py ADDED
@@ -0,0 +1 @@
1
+ """C3 CLI package."""
cli/_hook_utils.py ADDED
@@ -0,0 +1,99 @@
1
+ """Shared utilities for C3 hook scripts — supports Claude Code and Gemini CLI."""
2
+ import json
3
+ import sys
4
+ import traceback
5
+ from datetime import datetime, timezone
6
+ from pathlib import Path
7
+
8
+ # Max size of hook_errors.log before it is rotated (50 KB)
9
+ _LOG_MAX_BYTES = 50 * 1024
10
+
11
+
12
+ def log_hook_error(hook_name: str, exc: BaseException) -> None:
13
+ """Append a timestamped error entry to .c3/hook_errors.log.
14
+
15
+ Never raises — hook scripts must not crash the IDE even in the error logger.
16
+ Rotates the log (renames to hook_errors.log.bak) when it exceeds 50 KB.
17
+ """
18
+ try:
19
+ c3_dir = Path.cwd() / ".c3"
20
+ if not c3_dir.exists():
21
+ return
22
+ log_file = c3_dir / "hook_errors.log"
23
+ # Rotate if too large
24
+ try:
25
+ if log_file.exists() and log_file.stat().st_size > _LOG_MAX_BYTES:
26
+ log_file.replace(c3_dir / "hook_errors.log.bak")
27
+ except Exception:
28
+ pass
29
+ ts = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
30
+ tb = traceback.format_exc().strip()
31
+ line = f"[{ts}] [{hook_name}] {type(exc).__name__}: {exc}\n{tb}\n---\n"
32
+ with open(log_file, "a", encoding="utf-8") as f:
33
+ f.write(line)
34
+ except Exception:
35
+ pass # Absolutely must not propagate
36
+
37
+ # Map Gemini CLI built-in tool names → canonical Claude Code equivalents
38
+ GEMINI_TOOL_MAP = {
39
+ "run_shell_command": "Bash",
40
+ "read_file": "Read",
41
+ "edit_file": "Edit",
42
+ "write_file": "Write",
43
+ "list_directory": "FindFiles",
44
+ "find_files": "FindFiles",
45
+ "grep": "SearchText",
46
+ "search_in_files_content": "SearchText",
47
+ "find_in_files": "SearchText",
48
+ }
49
+
50
+
51
+ def normalize_tool_name(tool_name: str) -> str:
52
+ """Normalize Gemini CLI tool names to their Claude Code equivalents."""
53
+ return GEMINI_TOOL_MAP.get(tool_name, tool_name)
54
+
55
+
56
+ def get_tool_output(data: dict) -> tuple:
57
+ """Extract the output text and detect IDE format from hook stdin data.
58
+
59
+ Returns (output_text: str, is_gemini: bool).
60
+ Claude passes tool_response as a plain string.
61
+ Gemini wraps it in {llmContent, returnDisplay}.
62
+ """
63
+ resp = data.get("tool_response", "")
64
+ if isinstance(resp, dict):
65
+ content = resp.get("llmContent", "") or resp.get("returnDisplay", "")
66
+ if isinstance(content, list):
67
+ # llmContent can be a list of content-part dicts like {text: "..."}
68
+ content = "\n".join(
69
+ p.get("text", str(p)) if isinstance(p, dict) else str(p)
70
+ for p in content
71
+ )
72
+ return str(content) if content is not None else "", True
73
+ return resp if isinstance(resp, str) else "", False
74
+
75
+
76
+ def get_tool_input_path(data: dict) -> str:
77
+ """Extract file path from tool_input, handling both Claude (file_path) and Gemini (path)."""
78
+ tool_input = data.get("tool_input", {})
79
+ return tool_input.get("file_path", "") or tool_input.get("path", "")
80
+
81
+
82
+ def emit_additional_context(text: str, is_gemini: bool) -> None:
83
+ """Write additionalContext JSON to stdout in the correct format for the IDE."""
84
+ if is_gemini:
85
+ sys.stdout.write(json.dumps({"hookSpecificOutput": {"additionalContext": text}}))
86
+ else:
87
+ sys.stdout.write(json.dumps({"additionalContext": text}))
88
+
89
+
90
+ def emit_filtered_output(filtered: str, is_gemini: bool) -> None:
91
+ """Write filtered tool output to stdout.
92
+
93
+ Claude Code: replaces the tool result entirely via tool_result.
94
+ Gemini CLI: no direct replacement — appends as additionalContext instead.
95
+ """
96
+ if is_gemini:
97
+ sys.stdout.write(json.dumps({"hookSpecificOutput": {"additionalContext": filtered}}))
98
+ else:
99
+ sys.stdout.write(json.dumps({"tool_result": filtered}))