crabcode 0.1.6__py3-none-win_amd64.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 (205) hide show
  1. crabcode-0.1.6.dist-info/METADATA +63 -0
  2. crabcode-0.1.6.dist-info/RECORD +205 -0
  3. crabcode-0.1.6.dist-info/WHEEL +4 -0
  4. crabcode-0.1.6.dist-info/entry_points.txt +2 -0
  5. crabcode_cli/__init__.py +7 -0
  6. crabcode_cli/__main__.py +4 -0
  7. crabcode_cli/_native/crabcode-computer-use-host.exe +0 -0
  8. crabcode_cli/_native/runtime.json +6 -0
  9. crabcode_cli/app.py +776 -0
  10. crabcode_cli/banner.py +39 -0
  11. crabcode_cli/computer_use.py +286 -0
  12. crabcode_cli/model_manager.py +649 -0
  13. crabcode_cli/model_picker.py +168 -0
  14. crabcode_cli/pipe.py +148 -0
  15. crabcode_cli/render/__init__.py +0 -0
  16. crabcode_cli/render/messages.py +19 -0
  17. crabcode_cli/repl.py +4841 -0
  18. crabcode_cli/session_picker.py +239 -0
  19. crabcode_core/__init__.py +7 -0
  20. crabcode_core/_version.py +3 -0
  21. crabcode_core/_windows_process.py +68 -0
  22. crabcode_core/agent_manager.py +1731 -0
  23. crabcode_core/api/__init__.py +20 -0
  24. crabcode_core/api/anthropic_adapter.py +648 -0
  25. crabcode_core/api/azure_adapter.py +69 -0
  26. crabcode_core/api/base.py +233 -0
  27. crabcode_core/api/codex_adapter.py +1327 -0
  28. crabcode_core/api/error_logging.py +132 -0
  29. crabcode_core/api/gemini_adapter.py +26 -0
  30. crabcode_core/api/model_info.py +257 -0
  31. crabcode_core/api/network.py +62 -0
  32. crabcode_core/api/ollama_adapter.py +27 -0
  33. crabcode_core/api/openai_adapter.py +323 -0
  34. crabcode_core/api/registry.py +58 -0
  35. crabcode_core/command_line.py +18 -0
  36. crabcode_core/compact/__init__.py +17 -0
  37. crabcode_core/compact/compact.py +514 -0
  38. crabcode_core/compact/context_tokens.py +165 -0
  39. crabcode_core/computer_use_mode.py +38 -0
  40. crabcode_core/computer_use_observation.py +144 -0
  41. crabcode_core/config/__init__.py +3 -0
  42. crabcode_core/config/claudemd.py +61 -0
  43. crabcode_core/config/manager.py +237 -0
  44. crabcode_core/config/model_catalog.py +256 -0
  45. crabcode_core/events.py +4896 -0
  46. crabcode_core/file_lock.py +81 -0
  47. crabcode_core/filesystem.py +22 -0
  48. crabcode_core/goal.py +149 -0
  49. crabcode_core/hooks/__init__.py +5 -0
  50. crabcode_core/hooks/manager.py +290 -0
  51. crabcode_core/image_io.py +111 -0
  52. crabcode_core/io_worker.py +211 -0
  53. crabcode_core/logging_utils.py +168 -0
  54. crabcode_core/lsp/__init__.py +6 -0
  55. crabcode_core/lsp/client.py +786 -0
  56. crabcode_core/lsp/diagnostics.py +150 -0
  57. crabcode_core/lsp/manager.py +583 -0
  58. crabcode_core/mcp/__init__.py +4 -0
  59. crabcode_core/mcp/client.py +169 -0
  60. crabcode_core/mcp/config.py +57 -0
  61. crabcode_core/path_validation.py +34 -0
  62. crabcode_core/paths.py +24 -0
  63. crabcode_core/peer/__init__.py +10 -0
  64. crabcode_core/peer/runtime.py +518 -0
  65. crabcode_core/permissions/__init__.py +7 -0
  66. crabcode_core/permissions/ai_reviewer.py +184 -0
  67. crabcode_core/permissions/manager.py +187 -0
  68. crabcode_core/plan/__init__.py +5 -0
  69. crabcode_core/plan/executor.py +270 -0
  70. crabcode_core/plan/types.py +169 -0
  71. crabcode_core/prompts/__init__.py +0 -0
  72. crabcode_core/prompts/blocks.py +10 -0
  73. crabcode_core/prompts/context.py +229 -0
  74. crabcode_core/prompts/library.py +92 -0
  75. crabcode_core/prompts/profile.py +79 -0
  76. crabcode_core/prompts/system.py +356 -0
  77. crabcode_core/prompts/templates.py +104 -0
  78. crabcode_core/query/__init__.py +0 -0
  79. crabcode_core/query/computer_use_history.py +83 -0
  80. crabcode_core/query/loop.py +2446 -0
  81. crabcode_core/query/retry.py +116 -0
  82. crabcode_core/schedule/__init__.py +13 -0
  83. crabcode_core/schedule/manager.py +631 -0
  84. crabcode_core/schedule/models.py +204 -0
  85. crabcode_core/schedule/store.py +558 -0
  86. crabcode_core/schedule/timing.py +287 -0
  87. crabcode_core/session/__init__.py +12 -0
  88. crabcode_core/session/export.py +141 -0
  89. crabcode_core/session/meta_db.py +684 -0
  90. crabcode_core/session/storage.py +2032 -0
  91. crabcode_core/session/title_gen.py +52 -0
  92. crabcode_core/skills/__init__.py +6 -0
  93. crabcode_core/skills/context.py +23 -0
  94. crabcode_core/skills/loader.py +214 -0
  95. crabcode_core/skills/matcher.py +203 -0
  96. crabcode_core/snapshot/__init__.py +21 -0
  97. crabcode_core/snapshot/snapshot.py +436 -0
  98. crabcode_core/snapshot/tracker.py +359 -0
  99. crabcode_core/subprocess_utils.py +260 -0
  100. crabcode_core/team/__init__.py +27 -0
  101. crabcode_core/team/bridge.py +66 -0
  102. crabcode_core/team/inbox.py +237 -0
  103. crabcode_core/team/manager.py +1660 -0
  104. crabcode_core/team/message_bus.py +821 -0
  105. crabcode_core/team/models.py +191 -0
  106. crabcode_core/team/recovery.py +192 -0
  107. crabcode_core/text_io.py +52 -0
  108. crabcode_core/tools/__init__.py +112 -0
  109. crabcode_core/tools/_input_helpers.py +39 -0
  110. crabcode_core/tools/_input_schema.py +130 -0
  111. crabcode_core/tools/agent.py +413 -0
  112. crabcode_core/tools/apply_patch.py +587 -0
  113. crabcode_core/tools/ask_user.py +122 -0
  114. crabcode_core/tools/bash.py +154 -0
  115. crabcode_core/tools/browser.py +678 -0
  116. crabcode_core/tools/checklist.py +241 -0
  117. crabcode_core/tools/checkpoint.py +78 -0
  118. crabcode_core/tools/computer_use.py +599 -0
  119. crabcode_core/tools/diff_utils.py +123 -0
  120. crabcode_core/tools/file_edit.py +240 -0
  121. crabcode_core/tools/file_read.py +187 -0
  122. crabcode_core/tools/file_write.py +154 -0
  123. crabcode_core/tools/glob.py +123 -0
  124. crabcode_core/tools/goal.py +134 -0
  125. crabcode_core/tools/grep.py +247 -0
  126. crabcode_core/tools/image.py +173 -0
  127. crabcode_core/tools/image_generate.py +115 -0
  128. crabcode_core/tools/lint.py +388 -0
  129. crabcode_core/tools/loading.py +187 -0
  130. crabcode_core/tools/memory.py +456 -0
  131. crabcode_core/tools/monitor.py +677 -0
  132. crabcode_core/tools/peer.py +103 -0
  133. crabcode_core/tools/revert.py +90 -0
  134. crabcode_core/tools/schedule.py +683 -0
  135. crabcode_core/tools/skill.py +108 -0
  136. crabcode_core/tools/switch_mode.py +213 -0
  137. crabcode_core/tools/team.py +329 -0
  138. crabcode_core/tools/tool_search.py +64 -0
  139. crabcode_core/tools/web_search.py +444 -0
  140. crabcode_core/turn_details.py +64 -0
  141. crabcode_core/types/__init__.py +95 -0
  142. crabcode_core/types/config.py +434 -0
  143. crabcode_core/types/event.py +334 -0
  144. crabcode_core/types/message.py +263 -0
  145. crabcode_core/types/tool.py +208 -0
  146. crabcode_core/usage.py +289 -0
  147. crabcode_core/utf8_sanitize.py +29 -0
  148. crabcode_debugger/__init__.py +5 -0
  149. crabcode_debugger/adapters.py +332 -0
  150. crabcode_debugger/dap.py +304 -0
  151. crabcode_debugger/memory.py +1806 -0
  152. crabcode_debugger/process.py +707 -0
  153. crabcode_debugger/runtime.py +58 -0
  154. crabcode_debugger/sessions.py +387 -0
  155. crabcode_debugger/tool.py +731 -0
  156. crabcode_gateway/__init__.py +18 -0
  157. crabcode_gateway/acp/__init__.py +13 -0
  158. crabcode_gateway/acp/agent.py +1581 -0
  159. crabcode_gateway/acp/session.py +114 -0
  160. crabcode_gateway/acp/transport.py +39 -0
  161. crabcode_gateway/acp/types.py +90 -0
  162. crabcode_gateway/adapter.py +30 -0
  163. crabcode_gateway/auth.py +139 -0
  164. crabcode_gateway/computer_use.py +364 -0
  165. crabcode_gateway/document_engine.py +637 -0
  166. crabcode_gateway/document_worker.py +301 -0
  167. crabcode_gateway/event_bus.py +655 -0
  168. crabcode_gateway/grpc/__init__.py +0 -0
  169. crabcode_gateway/grpc/crabcode_pb2.py +70 -0
  170. crabcode_gateway/grpc/crabcode_pb2_grpc.py +474 -0
  171. crabcode_gateway/grpc/proto/crabcode.proto +160 -0
  172. crabcode_gateway/grpc/server.py +765 -0
  173. crabcode_gateway/middleware.py +344 -0
  174. crabcode_gateway/protocol.py +17 -0
  175. crabcode_gateway/routes/__init__.py +0 -0
  176. crabcode_gateway/routes/agent.py +392 -0
  177. crabcode_gateway/routes/auth.py +150 -0
  178. crabcode_gateway/routes/computer_use.py +101 -0
  179. crabcode_gateway/routes/config.py +1698 -0
  180. crabcode_gateway/routes/document.py +1810 -0
  181. crabcode_gateway/routes/event.py +3801 -0
  182. crabcode_gateway/routes/git_review.py +232 -0
  183. crabcode_gateway/routes/health.py +14 -0
  184. crabcode_gateway/routes/peer.py +78 -0
  185. crabcode_gateway/routes/permission.py +121 -0
  186. crabcode_gateway/routes/schedule.py +300 -0
  187. crabcode_gateway/routes/session.py +1496 -0
  188. crabcode_gateway/routes/snapshot.py +211 -0
  189. crabcode_gateway/routes/tasks.py +318 -0
  190. crabcode_gateway/routes/team.py +392 -0
  191. crabcode_gateway/routes/usage.py +49 -0
  192. crabcode_gateway/routes/workspace.py +299 -0
  193. crabcode_gateway/safe_file.py +63 -0
  194. crabcode_gateway/schemas.py +1820 -0
  195. crabcode_gateway/server.py +514 -0
  196. crabcode_gateway/session_registry.py +36 -0
  197. crabcode_gateway/task_registry.py +708 -0
  198. crabcode_gateway/turn_details.py +60 -0
  199. crabcode_search/__init__.py +11 -0
  200. crabcode_search/background.py +368 -0
  201. crabcode_search/chunker.py +517 -0
  202. crabcode_search/embedder.py +497 -0
  203. crabcode_search/indexer.py +215 -0
  204. crabcode_search/store.py +222 -0
  205. crabcode_search/tool.py +268 -0
@@ -0,0 +1,150 @@
1
+ """LSP diagnostics formatting utilities.
2
+
3
+ Format LSP diagnostics as XML blocks that get appended to file tool results,
4
+ so the LLM can see compilation/type errors immediately after writing code.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import asyncio
10
+ import os
11
+ from typing import Any
12
+
13
+ # Maximum diagnostics blocks for non-current files
14
+ MAX_PROJECT_DIAGNOSTICS_FILES = 5
15
+ # Maximum diagnostics per file
16
+ MAX_DIAGNOSTICS_PER_FILE = 20
17
+ # Diagnostics are advisory and run after a write has already succeeded. Never
18
+ # keep a completed file tool in the "Running" state because an LSP server is
19
+ # slow to start, fails to initialize, or stops responding.
20
+ LSP_DIAGNOSTICS_TIMEOUT_SECONDS = 5.0
21
+
22
+ # LSP DiagnosticSeverity enum values
23
+ _SEVERITY_ERROR = 1
24
+ _SEVERITY_WARNING = 2
25
+ _SEVERITY_INFO = 3
26
+ _SEVERITY_HINT = 4
27
+
28
+ _SEVERITY_LABELS = {
29
+ 1: "ERROR",
30
+ 2: "WARN",
31
+ 3: "INFO",
32
+ 4: "HINT",
33
+ }
34
+
35
+
36
+ def _format_diagnostic(diag: dict[str, Any]) -> str:
37
+ """Format a single LSP diagnostic as a one-liner."""
38
+ severity = diag.get("severity", 1)
39
+ label = _SEVERITY_LABELS.get(severity, "ERROR")
40
+ line = diag.get("range", {}).get("start", {}).get("line", 0) + 1
41
+ col = diag.get("range", {}).get("start", {}).get("character", 0) + 1
42
+ message = diag.get("message", "unknown error")
43
+ source = diag.get("source", "")
44
+ code = diag.get("code", "")
45
+ suffix = f" [{source}{' ' + str(code) if code else ''}]" if source else ""
46
+ return f"{label} [{line}:{col}] {message}{suffix}"
47
+
48
+
49
+ def format_diagnostics_block(file_path: str, diagnostics: list[dict[str, Any]]) -> str:
50
+ """Format diagnostics for a single file as an XML block.
51
+
52
+ Only reports errors (severity=1). Returns empty string if no errors.
53
+ """
54
+ errors = [d for d in diagnostics if d.get("severity", 1) == _SEVERITY_ERROR]
55
+ if not errors:
56
+ return ""
57
+
58
+ limited = errors[:MAX_DIAGNOSTICS_PER_FILE]
59
+ more = len(errors) - MAX_DIAGNOSTICS_PER_FILE
60
+ suffix = f"\n... and {more} more" if more > 0 else ""
61
+ lines = "\n".join(_format_diagnostic(d) for d in limited)
62
+ return f'<diagnostics file="{file_path}">\n{lines}{suffix}\n</diagnostics>'
63
+
64
+
65
+ async def collect_and_format_diagnostics(
66
+ lsp_manager: Any,
67
+ file_path: str,
68
+ ) -> str:
69
+ """Touch the file in LSP, wait for diagnostics, and format the result.
70
+
71
+ Returns a string to append to the tool result, or empty string if no errors.
72
+ """
73
+ try:
74
+ return await asyncio.wait_for(
75
+ _collect_and_format_diagnostics(lsp_manager, file_path),
76
+ timeout=LSP_DIAGNOSTICS_TIMEOUT_SECONDS,
77
+ )
78
+ except asyncio.TimeoutError:
79
+ # Diagnostics are best-effort. In particular, a hung LSP must not hide
80
+ # the successful result of an Edit, Write, or apply_patch operation.
81
+ return ""
82
+
83
+
84
+ async def _collect_and_format_diagnostics(
85
+ lsp_manager: Any,
86
+ file_path: str,
87
+ ) -> str:
88
+ from crabcode_core.lsp.client import _path_to_uri, _uri_to_path
89
+
90
+ try:
91
+ # Touch the file so the LSP server re-analyses it
92
+ await lsp_manager.touch_file(file_path)
93
+
94
+ # Collect diagnostics from all matching clients
95
+ clients = await lsp_manager.get_clients(file_path)
96
+ if not clients:
97
+ return ""
98
+
99
+ # Wait briefly for diagnostics to arrive
100
+ all_diagnostics: dict[str, list[dict[str, Any]]] = {}
101
+ for client in clients:
102
+ try:
103
+ diags = await client.wait_for_diagnostics(
104
+ file_path, timeout=3.0, debounce=0.15,
105
+ )
106
+ uri = _path_to_uri(str(file_path))
107
+ existing = all_diagnostics.get(uri, [])
108
+ existing.extend(diags)
109
+ all_diagnostics[uri] = existing
110
+ except Exception:
111
+ pass
112
+
113
+ if not all_diagnostics:
114
+ return ""
115
+
116
+ # Normalize the file path for comparison
117
+ normalized = os.path.normcase(os.path.abspath(file_path))
118
+
119
+ # Format diagnostics
120
+ parts: list[str] = []
121
+ project_diag_count = 0
122
+
123
+ for uri, diags in all_diagnostics.items():
124
+ try:
125
+ diag_path = _uri_to_path(uri)
126
+ except Exception:
127
+ diag_path = uri
128
+
129
+ is_current = os.path.normcase(os.path.abspath(diag_path)) == normalized
130
+ block = format_diagnostics_block(diag_path, diags)
131
+ if not block:
132
+ continue
133
+
134
+ if is_current:
135
+ parts.append(
136
+ f"\n\nLSP errors detected in this file, please fix:\n{block}"
137
+ )
138
+ else:
139
+ if project_diag_count >= MAX_PROJECT_DIAGNOSTICS_FILES:
140
+ continue
141
+ project_diag_count += 1
142
+ parts.append(
143
+ f"\n\nLSP errors detected in other files:\n{block}"
144
+ )
145
+
146
+ return "".join(parts)
147
+
148
+ except Exception:
149
+ # Never let LSP failures break the write operation
150
+ return ""