crabcode 0.1.4__tar.gz → 0.1.5__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.
Files changed (297) hide show
  1. crabcode-0.1.5/.github/workflows/document-engine-wheels.yml +40 -0
  2. crabcode-0.1.5/.github/workflows/windows-compat.yml +52 -0
  3. {crabcode-0.1.4 → crabcode-0.1.5}/.gitignore +4 -1
  4. {crabcode-0.1.4 → crabcode-0.1.5}/PKG-INFO +12 -1
  5. {crabcode-0.1.4 → crabcode-0.1.5}/README.md +300 -14
  6. {crabcode-0.1.4 → crabcode-0.1.5}/README.zh-CN.md +283 -14
  7. crabcode-0.1.5/docs/windows-compatibility-fixes.md +58 -0
  8. {crabcode-0.1.4 → crabcode-0.1.5}/packages/cli/crabcode_cli/app.py +221 -9
  9. {crabcode-0.1.4 → crabcode-0.1.5}/packages/cli/crabcode_cli/banner.py +11 -14
  10. crabcode-0.1.5/packages/cli/crabcode_cli/model_picker.py +168 -0
  11. {crabcode-0.1.4 → crabcode-0.1.5}/packages/cli/crabcode_cli/repl.py +971 -186
  12. crabcode-0.1.5/packages/cli/crabcode_cli/session_picker.py +239 -0
  13. {crabcode-0.1.4 → crabcode-0.1.5}/packages/cli/pyproject.toml +2 -2
  14. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/_version.py +1 -1
  15. crabcode-0.1.5/packages/core/crabcode_core/_windows_process.py +68 -0
  16. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/agent_manager.py +7 -0
  17. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/api/anthropic_adapter.py +32 -7
  18. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/api/base.py +44 -2
  19. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/api/codex_adapter.py +285 -28
  20. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/api/model_info.py +89 -0
  21. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/api/openai_adapter.py +27 -27
  22. crabcode-0.1.5/packages/core/crabcode_core/command_line.py +18 -0
  23. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/compact/compact.py +19 -7
  24. crabcode-0.1.5/packages/core/crabcode_core/compact/context_tokens.py +139 -0
  25. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/config/claudemd.py +2 -2
  26. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/config/manager.py +77 -8
  27. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/events.py +225 -9
  28. crabcode-0.1.5/packages/core/crabcode_core/file_lock.py +81 -0
  29. crabcode-0.1.5/packages/core/crabcode_core/filesystem.py +22 -0
  30. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/hooks/manager.py +17 -6
  31. crabcode-0.1.5/packages/core/crabcode_core/io_worker.py +209 -0
  32. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/logging_utils.py +60 -2
  33. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/lsp/client.py +49 -20
  34. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/lsp/diagnostics.py +3 -3
  35. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/lsp/manager.py +2 -1
  36. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/mcp/config.py +1 -1
  37. crabcode-0.1.5/packages/core/crabcode_core/path_validation.py +34 -0
  38. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/peer/runtime.py +58 -37
  39. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/prompts/context.py +16 -8
  40. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/prompts/system.py +35 -3
  41. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/prompts/templates.py +5 -3
  42. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/query/loop.py +445 -114
  43. crabcode-0.1.5/packages/core/crabcode_core/schedule/__init__.py +13 -0
  44. crabcode-0.1.5/packages/core/crabcode_core/schedule/manager.py +617 -0
  45. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/schedule/store.py +215 -7
  46. crabcode-0.1.5/packages/core/crabcode_core/schedule/timing.py +287 -0
  47. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/session/meta_db.py +71 -5
  48. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/session/storage.py +273 -72
  49. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/snapshot/snapshot.py +17 -3
  50. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/snapshot/tracker.py +112 -5
  51. crabcode-0.1.5/packages/core/crabcode_core/subprocess_utils.py +260 -0
  52. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/team/inbox.py +48 -101
  53. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/team/message_bus.py +47 -104
  54. crabcode-0.1.5/packages/core/crabcode_core/text_io.py +52 -0
  55. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/__init__.py +20 -0
  56. crabcode-0.1.5/packages/core/crabcode_core/tools/_input_schema.py +130 -0
  57. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/bash.py +45 -32
  58. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/browser.py +15 -1
  59. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/checkpoint.py +14 -2
  60. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/file_edit.py +44 -5
  61. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/file_read.py +13 -3
  62. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/file_write.py +25 -4
  63. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/glob.py +8 -3
  64. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/grep.py +107 -20
  65. crabcode-0.1.5/packages/core/crabcode_core/tools/image.py +166 -0
  66. crabcode-0.1.5/packages/core/crabcode_core/tools/image_generate.py +115 -0
  67. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/lint.py +17 -8
  68. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/monitor.py +12 -26
  69. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/schedule.py +142 -71
  70. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/types/__init__.py +4 -0
  71. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/types/config.py +94 -2
  72. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/types/event.py +30 -0
  73. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/types/message.py +14 -0
  74. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/types/tool.py +47 -0
  75. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/pyproject.toml +1 -1
  76. {crabcode-0.1.4 → crabcode-0.1.5}/packages/debugger/crabcode_debugger/adapters.py +7 -1
  77. {crabcode-0.1.4 → crabcode-0.1.5}/packages/debugger/crabcode_debugger/dap.py +88 -15
  78. {crabcode-0.1.4 → crabcode-0.1.5}/packages/debugger/crabcode_debugger/memory.py +157 -42
  79. {crabcode-0.1.4 → crabcode-0.1.5}/packages/debugger/crabcode_debugger/process.py +52 -17
  80. crabcode-0.1.5/packages/debugger/crabcode_debugger/runtime.py +58 -0
  81. {crabcode-0.1.4 → crabcode-0.1.5}/packages/debugger/crabcode_debugger/sessions.py +112 -68
  82. {crabcode-0.1.4 → crabcode-0.1.5}/packages/debugger/crabcode_debugger/tool.py +79 -8
  83. {crabcode-0.1.4 → crabcode-0.1.5}/packages/debugger/pyproject.toml +2 -2
  84. crabcode-0.1.5/packages/desktop/README.md +47 -0
  85. crabcode-0.1.5/packages/desktop/THEMES.md +68 -0
  86. crabcode-0.1.5/packages/desktop/index.html +13 -0
  87. crabcode-0.1.5/packages/desktop/package-lock.json +5201 -0
  88. crabcode-0.1.5/packages/desktop/package.json +38 -0
  89. crabcode-0.1.5/packages/desktop/src/App.test.tsx +1518 -0
  90. crabcode-0.1.5/packages/desktop/src/App.tsx +6832 -0
  91. crabcode-0.1.5/packages/desktop/src/ComposerEditor.test.tsx +286 -0
  92. crabcode-0.1.5/packages/desktop/src/ComposerEditor.tsx +680 -0
  93. crabcode-0.1.5/packages/desktop/src/CopyButton.tsx +68 -0
  94. crabcode-0.1.5/packages/desktop/src/DocumentWorkspace.blog.test.tsx +98 -0
  95. crabcode-0.1.5/packages/desktop/src/DocumentWorkspace.selection.test.tsx +64 -0
  96. crabcode-0.1.5/packages/desktop/src/DocumentWorkspace.test.ts +329 -0
  97. crabcode-0.1.5/packages/desktop/src/DocumentWorkspace.toolbar.test.tsx +86 -0
  98. crabcode-0.1.5/packages/desktop/src/DocumentWorkspace.tsx +2648 -0
  99. crabcode-0.1.5/packages/desktop/src/ModelSettingsPanel.tsx +730 -0
  100. crabcode-0.1.5/packages/desktop/src/ProjectFilesWorkspace.test.tsx +293 -0
  101. crabcode-0.1.5/packages/desktop/src/ProjectFilesWorkspace.tsx +688 -0
  102. crabcode-0.1.5/packages/desktop/src/RuntimeSettingsPanel.tsx +292 -0
  103. crabcode-0.1.5/packages/desktop/src/SettingsView.test.tsx +808 -0
  104. crabcode-0.1.5/packages/desktop/src/SettingsView.tsx +1587 -0
  105. crabcode-0.1.5/packages/desktop/src/TrajectoryView.test.tsx +71 -0
  106. crabcode-0.1.5/packages/desktop/src/TrajectoryView.tsx +383 -0
  107. crabcode-0.1.5/packages/desktop/src/events.test.ts +442 -0
  108. crabcode-0.1.5/packages/desktop/src/events.ts +693 -0
  109. crabcode-0.1.5/packages/desktop/src/favorites.test.ts +173 -0
  110. crabcode-0.1.5/packages/desktop/src/favorites.ts +295 -0
  111. crabcode-0.1.5/packages/desktop/src/gateway.ts +772 -0
  112. crabcode-0.1.5/packages/desktop/src/main.tsx +11 -0
  113. crabcode-0.1.5/packages/desktop/src/markdownMath.ts +112 -0
  114. crabcode-0.1.5/packages/desktop/src/native.test.ts +378 -0
  115. crabcode-0.1.5/packages/desktop/src/native.ts +507 -0
  116. crabcode-0.1.5/packages/desktop/src/pathUtils.ts +9 -0
  117. crabcode-0.1.5/packages/desktop/src/styles.css +14891 -0
  118. crabcode-0.1.5/packages/desktop/src/theme.test.ts +102 -0
  119. crabcode-0.1.5/packages/desktop/src/theme.ts +563 -0
  120. crabcode-0.1.5/packages/desktop/src/themePackages.test.ts +128 -0
  121. crabcode-0.1.5/packages/desktop/src/themePackages.ts +321 -0
  122. crabcode-0.1.5/packages/desktop/src/toolPresentation.test.ts +26 -0
  123. crabcode-0.1.5/packages/desktop/src/toolPresentation.ts +432 -0
  124. crabcode-0.1.5/packages/desktop/src/types.ts +724 -0
  125. crabcode-0.1.5/packages/desktop/src/vite-env.d.ts +1 -0
  126. crabcode-0.1.5/packages/desktop/src-tauri/Cargo.lock +5048 -0
  127. crabcode-0.1.5/packages/desktop/src-tauri/Cargo.toml +35 -0
  128. crabcode-0.1.5/packages/desktop/src-tauri/build.rs +3 -0
  129. crabcode-0.1.5/packages/desktop/src-tauri/capabilities/default.json +7 -0
  130. crabcode-0.1.5/packages/desktop/src-tauri/icons/128x128.png +0 -0
  131. crabcode-0.1.5/packages/desktop/src-tauri/icons/128x128@2x.png +0 -0
  132. crabcode-0.1.5/packages/desktop/src-tauri/icons/32x32.png +0 -0
  133. crabcode-0.1.5/packages/desktop/src-tauri/icons/icon.icns +0 -0
  134. crabcode-0.1.5/packages/desktop/src-tauri/icons/icon.ico +0 -0
  135. crabcode-0.1.5/packages/desktop/src-tauri/icons/icon.png +0 -0
  136. crabcode-0.1.5/packages/desktop/src-tauri/resources/dock-icon-light.png +0 -0
  137. crabcode-0.1.5/packages/desktop/src-tauri/src/gateway.rs +663 -0
  138. crabcode-0.1.5/packages/desktop/src-tauri/src/lib.rs +34 -0
  139. crabcode-0.1.5/packages/desktop/src-tauri/src/main.rs +5 -0
  140. crabcode-0.1.5/packages/desktop/src-tauri/src/settings.rs +340 -0
  141. crabcode-0.1.5/packages/desktop/src-tauri/tauri.conf.json +42 -0
  142. crabcode-0.1.5/packages/desktop/tsconfig.json +20 -0
  143. crabcode-0.1.5/packages/desktop/vite.config.ts +13 -0
  144. crabcode-0.1.5/packages/gateway/crabcode_gateway/__init__.py +18 -0
  145. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/acp/agent.py +59 -17
  146. crabcode-0.1.5/packages/gateway/crabcode_gateway/auth.py +139 -0
  147. crabcode-0.1.5/packages/gateway/crabcode_gateway/document_engine.py +636 -0
  148. crabcode-0.1.5/packages/gateway/crabcode_gateway/document_worker.py +301 -0
  149. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/event_bus.py +23 -12
  150. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/grpc/server.py +36 -7
  151. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/middleware.py +78 -17
  152. crabcode-0.1.5/packages/gateway/crabcode_gateway/protocol.py +17 -0
  153. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/routes/agent.py +161 -10
  154. crabcode-0.1.5/packages/gateway/crabcode_gateway/routes/auth.py +150 -0
  155. crabcode-0.1.5/packages/gateway/crabcode_gateway/routes/config.py +1219 -0
  156. crabcode-0.1.5/packages/gateway/crabcode_gateway/routes/document.py +1810 -0
  157. crabcode-0.1.5/packages/gateway/crabcode_gateway/routes/event.py +3553 -0
  158. crabcode-0.1.5/packages/gateway/crabcode_gateway/routes/peer.py +78 -0
  159. crabcode-0.1.5/packages/gateway/crabcode_gateway/routes/schedule.py +300 -0
  160. crabcode-0.1.5/packages/gateway/crabcode_gateway/routes/session.py +1380 -0
  161. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/routes/snapshot.py +74 -32
  162. crabcode-0.1.5/packages/gateway/crabcode_gateway/routes/tasks.py +318 -0
  163. crabcode-0.1.5/packages/gateway/crabcode_gateway/routes/team.py +392 -0
  164. crabcode-0.1.5/packages/gateway/crabcode_gateway/routes/workspace.py +283 -0
  165. crabcode-0.1.5/packages/gateway/crabcode_gateway/safe_file.py +63 -0
  166. crabcode-0.1.5/packages/gateway/crabcode_gateway/schemas.py +1520 -0
  167. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/server.py +136 -4
  168. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/task_registry.py +75 -0
  169. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/pyproject.toml +11 -2
  170. {crabcode-0.1.4 → crabcode-0.1.5}/packages/search/crabcode_search/background.py +6 -9
  171. {crabcode-0.1.4 → crabcode-0.1.5}/packages/search/crabcode_search/indexer.py +10 -7
  172. {crabcode-0.1.4 → crabcode-0.1.5}/packages/search/crabcode_search/store.py +4 -4
  173. {crabcode-0.1.4 → crabcode-0.1.5}/packages/search/crabcode_search/tool.py +5 -1
  174. {crabcode-0.1.4 → crabcode-0.1.5}/packages/search/pyproject.toml +2 -2
  175. crabcode-0.1.5/packages/vscode/.gitignore +1 -0
  176. crabcode-0.1.5/packages/vscode/.nvmrc +1 -0
  177. crabcode-0.1.5/packages/vscode/.vscodeignore +16 -0
  178. crabcode-0.1.5/packages/vscode/CHANGELOG.md +25 -0
  179. crabcode-0.1.5/packages/vscode/LICENSE +21 -0
  180. crabcode-0.1.5/packages/vscode/README.md +156 -0
  181. crabcode-0.1.5/packages/vscode/package-lock.json +4362 -0
  182. {crabcode-0.1.4 → crabcode-0.1.5}/packages/vscode/package.json +31 -4
  183. {crabcode-0.1.4 → crabcode-0.1.5}/packages/vscode/scripts/gen-types.py +56 -10
  184. {crabcode-0.1.4 → crabcode-0.1.5}/packages/vscode/src/chatPanel.ts +4265 -374
  185. {crabcode-0.1.4 → crabcode-0.1.5}/packages/vscode/src/client/protocol.ts +125 -7
  186. crabcode-0.1.5/packages/vscode/src/client/types.ts +1150 -0
  187. {crabcode-0.1.4 → crabcode-0.1.5}/packages/vscode/src/connection.ts +122 -29
  188. {crabcode-0.1.4 → crabcode-0.1.5}/packages/vscode/src/extension.ts +40 -17
  189. crabcode-0.1.5/packages/vscode/src/gatewayManager.ts +907 -0
  190. {crabcode-0.1.4 → crabcode-0.1.5}/packages/vscode/src/pendingEdits.ts +13 -8
  191. crabcode-0.1.5/packages/vscode/tests/contextUsage.test.cjs +28 -0
  192. crabcode-0.1.5/packages/vscode/tests/gatewayManager.test.cjs +71 -0
  193. crabcode-0.1.5/packages/vscode/tests/imageCaptions.test.cjs +89 -0
  194. {crabcode-0.1.4 → crabcode-0.1.5}/pyproject.toml +9 -2
  195. crabcode-0.1.5/scripts/audit_tool_cards.mjs +66 -0
  196. crabcode-0.1.5/scripts/build_document_engine_bundle.py +119 -0
  197. crabcode-0.1.5/tests/test_cli_api_recovery.py +388 -0
  198. crabcode-0.1.5/tests/test_cli_composer.py +215 -0
  199. crabcode-0.1.5/tests/test_cli_model_picker.py +113 -0
  200. crabcode-0.1.5/tests/test_cli_session_picker.py +138 -0
  201. crabcode-0.1.5/tests/test_context_token_accounting.py +326 -0
  202. crabcode-0.1.5/tests/test_image_context.py +231 -0
  203. crabcode-0.1.5/tests/test_image_tool.py +99 -0
  204. crabcode-0.1.5/tests/test_io_isolation.py +388 -0
  205. crabcode-0.1.5/tests/test_model_info.py +122 -0
  206. crabcode-0.1.5/tests/test_windows_audit_regressions.py +382 -0
  207. crabcode-0.1.5/tests/test_windows_compat.py +482 -0
  208. crabcode-0.1.4/packages/core/crabcode_core/schedule/__init__.py +0 -5
  209. crabcode-0.1.4/packages/debugger/crabcode_debugger/runtime.py +0 -23
  210. crabcode-0.1.4/packages/gateway/crabcode_gateway/__init__.py +0 -7
  211. crabcode-0.1.4/packages/gateway/crabcode_gateway/routes/config.py +0 -381
  212. crabcode-0.1.4/packages/gateway/crabcode_gateway/routes/event.py +0 -1537
  213. crabcode-0.1.4/packages/gateway/crabcode_gateway/routes/session.py +0 -781
  214. crabcode-0.1.4/packages/gateway/crabcode_gateway/schemas.py +0 -656
  215. crabcode-0.1.4/packages/vscode/package-lock.json +0 -545
  216. crabcode-0.1.4/packages/vscode/src/client/types.ts +0 -417
  217. crabcode-0.1.4/packages/vscode/src/gatewayManager.ts +0 -466
  218. {crabcode-0.1.4 → crabcode-0.1.5}/.github/workflows/python-publish.yml +0 -0
  219. {crabcode-0.1.4 → crabcode-0.1.5}/packages/cli/crabcode_cli/__init__.py +0 -0
  220. {crabcode-0.1.4 → crabcode-0.1.5}/packages/cli/crabcode_cli/__main__.py +0 -0
  221. {crabcode-0.1.4 → crabcode-0.1.5}/packages/cli/crabcode_cli/pipe.py +0 -0
  222. {crabcode-0.1.4 → crabcode-0.1.5}/packages/cli/crabcode_cli/render/__init__.py +0 -0
  223. {crabcode-0.1.4 → crabcode-0.1.5}/packages/cli/crabcode_cli/render/messages.py +0 -0
  224. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/__init__.py +0 -0
  225. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/api/__init__.py +0 -0
  226. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/api/azure_adapter.py +0 -0
  227. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/api/gemini_adapter.py +0 -0
  228. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/api/ollama_adapter.py +0 -0
  229. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/api/registry.py +0 -0
  230. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/compact/__init__.py +0 -0
  231. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/config/__init__.py +0 -0
  232. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/goal.py +0 -0
  233. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/hooks/__init__.py +0 -0
  234. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/lsp/__init__.py +0 -0
  235. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/mcp/__init__.py +0 -0
  236. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/mcp/client.py +0 -0
  237. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/peer/__init__.py +0 -0
  238. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/permissions/__init__.py +0 -0
  239. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/permissions/ai_reviewer.py +0 -0
  240. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/permissions/manager.py +0 -0
  241. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/plan/__init__.py +0 -0
  242. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/plan/executor.py +0 -0
  243. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/plan/types.py +0 -0
  244. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/prompts/__init__.py +0 -0
  245. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/prompts/profile.py +0 -0
  246. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/query/__init__.py +0 -0
  247. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/schedule/models.py +0 -0
  248. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/session/__init__.py +0 -0
  249. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/session/export.py +0 -0
  250. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/session/title_gen.py +0 -0
  251. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/skills/__init__.py +0 -0
  252. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/skills/loader.py +0 -0
  253. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/skills/matcher.py +0 -0
  254. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/snapshot/__init__.py +0 -0
  255. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/team/__init__.py +0 -0
  256. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/team/bridge.py +0 -0
  257. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/team/manager.py +0 -0
  258. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/team/models.py +0 -0
  259. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/team/recovery.py +0 -0
  260. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/_input_helpers.py +0 -0
  261. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/agent.py +0 -0
  262. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/ask_user.py +0 -0
  263. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/checklist.py +0 -0
  264. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/diff_utils.py +0 -0
  265. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/goal.py +0 -0
  266. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/memory.py +0 -0
  267. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/peer.py +0 -0
  268. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/revert.py +0 -0
  269. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/skill.py +0 -0
  270. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/switch_mode.py +0 -0
  271. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/team.py +0 -0
  272. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/tools/web_search.py +0 -0
  273. {crabcode-0.1.4 → crabcode-0.1.5}/packages/core/crabcode_core/utf8_sanitize.py +0 -0
  274. {crabcode-0.1.4 → crabcode-0.1.5}/packages/debugger/crabcode_debugger/__init__.py +0 -0
  275. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/acp/__init__.py +0 -0
  276. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/acp/session.py +0 -0
  277. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/acp/transport.py +0 -0
  278. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/acp/types.py +0 -0
  279. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/adapter.py +0 -0
  280. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/grpc/__init__.py +0 -0
  281. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/grpc/crabcode_pb2.py +0 -0
  282. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/grpc/crabcode_pb2_grpc.py +0 -0
  283. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/grpc/proto/crabcode.proto +0 -0
  284. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/routes/__init__.py +0 -0
  285. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/routes/health.py +0 -0
  286. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/routes/permission.py +0 -0
  287. {crabcode-0.1.4 → crabcode-0.1.5}/packages/gateway/crabcode_gateway/session_registry.py +0 -0
  288. {crabcode-0.1.4 → crabcode-0.1.5}/packages/search/crabcode_search/__init__.py +0 -0
  289. {crabcode-0.1.4 → crabcode-0.1.5}/packages/search/crabcode_search/chunker.py +0 -0
  290. {crabcode-0.1.4 → crabcode-0.1.5}/packages/search/crabcode_search/embedder.py +0 -0
  291. {crabcode-0.1.4 → crabcode-0.1.5}/packages/vscode/.vscode/launch.json +0 -0
  292. {crabcode-0.1.4 → crabcode-0.1.5}/packages/vscode/.vscode/tasks.json +0 -0
  293. {crabcode-0.1.4 → crabcode-0.1.5}/packages/vscode/esbuild.js +0 -0
  294. {crabcode-0.1.4 → crabcode-0.1.5}/packages/vscode/logo.png +0 -0
  295. {crabcode-0.1.4 → crabcode-0.1.5}/packages/vscode/resources/icon.svg +0 -0
  296. {crabcode-0.1.4 → crabcode-0.1.5}/packages/vscode/tsconfig.json +0 -0
  297. {crabcode-0.1.4 → crabcode-0.1.5}/scripts/sync_version.py +0 -0
@@ -0,0 +1,40 @@
1
+ name: Document engine offline wheels
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ pull_request:
6
+ paths:
7
+ - "pyproject.toml"
8
+ - "packages/gateway/**"
9
+ - "scripts/build_document_engine_bundle.py"
10
+ - ".github/workflows/document-engine-wheels.yml"
11
+
12
+ jobs:
13
+ offline-install:
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ os: [ubuntu-latest, macos-14, windows-latest]
18
+ python: ["3.10", "3.11", "3.12", "3.13"]
19
+ runs-on: ${{ matrix.os }}
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ - uses: actions/setup-python@v5
23
+ with:
24
+ python-version: ${{ matrix.python }}
25
+ - name: Build CrabCode wheel
26
+ run: |
27
+ python -m pip install build
28
+ python -m build --wheel
29
+ - name: Resolve platform wheelhouse
30
+ run: |
31
+ python -m pip download --only-binary=:all: --dest wheelhouse BabelDOC==0.6.4
32
+ python -c "from pathlib import Path; import shutil; shutil.copy2(next(Path('dist').glob('crabcode-*.whl')), 'wheelhouse')"
33
+ - name: Verify fully offline installation
34
+ shell: bash
35
+ run: |
36
+ python -m venv engine-venv
37
+ if [[ "$RUNNER_OS" == "Windows" ]]; then PYTHON=engine-venv/Scripts/python.exe; else PYTHON=engine-venv/bin/python; fi
38
+ "$PYTHON" -m pip install --no-index --find-links wheelhouse BabelDOC==0.6.4
39
+ "$PYTHON" -m pip install --no-index --no-deps --find-links wheelhouse crabcode
40
+ "$PYTHON" -c "import babeldoc; import crabcode_gateway.document_worker"
@@ -0,0 +1,52 @@
1
+ name: Cross-platform compatibility
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [main]
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ python:
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ os: [windows-latest, ubuntu-latest, macos-latest]
17
+ python: ['3.10', '3.12']
18
+ runs-on: ${{ matrix.os }}
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version: ${{ matrix.python }}
24
+ - uses: actions/setup-node@v4
25
+ with:
26
+ node-version: '22'
27
+ - run: python -m pip install -e . fastapi pypdf python-multipart
28
+ - run: python -m unittest discover -s tests -p "test_windows*.py" -v
29
+
30
+ windows-clients:
31
+ runs-on: windows-latest
32
+ steps:
33
+ - uses: actions/checkout@v4
34
+ - uses: actions/setup-node@v4
35
+ with:
36
+ node-version: '22'
37
+ - run: npm ci
38
+ working-directory: packages/desktop
39
+ - run: npm test
40
+ working-directory: packages/desktop
41
+ - run: npx tsc --noEmit
42
+ working-directory: packages/desktop
43
+ - run: npm ci
44
+ working-directory: packages/vscode
45
+ - run: npm test
46
+ working-directory: packages/vscode
47
+ - run: npx tsc --noEmit
48
+ working-directory: packages/vscode
49
+ - run: cargo test --locked
50
+ working-directory: packages/desktop/src-tauri
51
+ - run: cargo test --locked windows_credentials_survive_a_new_entry -- --ignored
52
+ working-directory: packages/desktop/src-tauri
@@ -11,4 +11,7 @@ build/
11
11
  .crabcode/
12
12
  .claude/
13
13
  .DS_Store
14
- node_modules
14
+ theme-samples
15
+ node_modules
16
+ target/
17
+ packages/desktop/src-tauri/gen/schemas/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: crabcode
3
- Version: 0.1.4
3
+ Version: 0.1.5
4
4
  Summary: CrabCode - AI coding assistant in the terminal
5
5
  Requires-Python: >=3.10
6
6
  Requires-Dist: anthropic>=0.40.0
@@ -17,12 +17,17 @@ Provides-Extra: all
17
17
  Requires-Dist: agent-client-protocol>=0.9.0; extra == 'all'
18
18
  Requires-Dist: anthropic[bedrock]>=0.40.0; extra == 'all'
19
19
  Requires-Dist: anthropic[vertex]>=0.40.0; extra == 'all'
20
+ Requires-Dist: babeldoc==0.6.4; extra == 'all'
21
+ Requires-Dist: cryptography>=42.0.0; extra == 'all'
20
22
  Requires-Dist: fastapi>=0.115.0; extra == 'all'
21
23
  Requires-Dist: grpcio-health-checking>=1.65.0; extra == 'all'
22
24
  Requires-Dist: grpcio>=1.65.0; extra == 'all'
23
25
  Requires-Dist: httpx>=0.27.0; extra == 'all'
24
26
  Requires-Dist: modelscope>=1.10.0; extra == 'all'
25
27
  Requires-Dist: playwright>=1.48.0; extra == 'all'
28
+ Requires-Dist: pyjwt>=2.9.0; extra == 'all'
29
+ Requires-Dist: pypdf>=4.0.0; extra == 'all'
30
+ Requires-Dist: python-multipart>=0.0.9; extra == 'all'
26
31
  Requires-Dist: sentence-transformers>=2.0.0; extra == 'all'
27
32
  Requires-Dist: sse-starlette>=2.0.0; extra == 'all'
28
33
  Requires-Dist: tree-sitter-language-pack>=1.0.0; extra == 'all'
@@ -33,12 +38,18 @@ Requires-Dist: anthropic[bedrock]>=0.40.0; extra == 'bedrock'
33
38
  Provides-Extra: browser
34
39
  Requires-Dist: playwright>=1.48.0; extra == 'browser'
35
40
  Provides-Extra: debugger
41
+ Provides-Extra: document-translate
42
+ Requires-Dist: babeldoc==0.6.4; extra == 'document-translate'
36
43
  Provides-Extra: gateway
37
44
  Requires-Dist: agent-client-protocol>=0.9.0; extra == 'gateway'
45
+ Requires-Dist: cryptography>=42.0.0; extra == 'gateway'
38
46
  Requires-Dist: fastapi>=0.115.0; extra == 'gateway'
39
47
  Requires-Dist: grpcio-health-checking>=1.65.0; extra == 'gateway'
40
48
  Requires-Dist: grpcio>=1.65.0; extra == 'gateway'
41
49
  Requires-Dist: httpx>=0.27.0; extra == 'gateway'
50
+ Requires-Dist: pyjwt>=2.9.0; extra == 'gateway'
51
+ Requires-Dist: pypdf>=4.0.0; extra == 'gateway'
52
+ Requires-Dist: python-multipart>=0.0.9; extra == 'gateway'
42
53
  Requires-Dist: sse-starlette>=2.0.0; extra == 'gateway'
43
54
  Requires-Dist: uvicorn[standard]>=0.30.0; extra == 'gateway'
44
55
  Provides-Extra: search
@@ -40,6 +40,10 @@ pip install crabcode[search,bedrock]
40
40
  pip install crabcode[browser,search]
41
41
  ```
42
42
 
43
+ On Windows PowerShell, set environment variables with
44
+ `$env:ANTHROPIC_API_KEY = "YourKey"` (and use the same `$env:NAME` form for
45
+ the provider-specific keys below).
46
+
43
47
  ### Development
44
48
 
45
49
  ```bash
@@ -72,6 +76,11 @@ crabcode --continue # or -c
72
76
  crabcode --resume <id> # or -r <id>
73
77
  ```
74
78
 
79
+ In the interactive CLI, **Enter** sends; **Ctrl+J** or **Alt/Opt+Enter** inserts a
80
+ newline. You can also press **Esc**, then **Enter** to insert a newline. The
81
+ input frame grows with newlines and wrapped text, and scrolls with the cursor
82
+ when it fills the terminal. These keys also work while the agent is running.
83
+
75
84
  ### Persistent Goals
76
85
 
77
86
  Use `/goal` to keep a measurable objective active across turns, compaction, and
@@ -107,6 +116,10 @@ crabcode sessions search "refactor auth"
107
116
  # Export a session to Markdown or JSON
108
117
  crabcode sessions export <id> --format md --output chat.md
109
118
 
119
+ # Fork a session from an assistant reply (full or unique-prefix IDs)
120
+ crabcode sessions fork <session-id> <assistant-message-uuid>
121
+ crabcode sessions fork <session-id> <assistant-message-uuid> --title "Try another approach"
122
+
110
123
  # Archive old sessions (older than 30 days) and clean up
111
124
  crabcode sessions prune --days 30 --delete-files
112
125
 
@@ -115,6 +128,10 @@ crabcode stats
115
128
  crabcode stats --project # current project only
116
129
  ```
117
130
 
131
+ Inside the interactive CLI, use `/fork [assistant-message-uuid]`; omitting the
132
+ UUID forks from the latest completed assistant reply. UUIDs support completion
133
+ and unique prefixes.
134
+
118
135
  ## Multi-API Support
119
136
 
120
137
  ### Gateway Server
@@ -135,41 +152,200 @@ crabcode gateway --port 4096 --grpc-port 50051
135
152
  crabcode gateway --password secret
136
153
  ```
137
154
 
155
+ #### Gateway security modes
156
+
157
+ Gateway authentication is disabled by default. Configure `none`, `password`,
158
+ `publickey`, or `mixed` in the user-level `~/.crabcode/settings.json`. Project
159
+ settings cannot override this process-level security setting.
160
+
161
+ ```json
162
+ {
163
+ "gateway": {
164
+ "security": {
165
+ "mode": "mixed",
166
+ "password": "change-me",
167
+ "authorized_keys": "~/.ssh/authorized_keys",
168
+ "token_ttl_seconds": 900
169
+ }
170
+ }
171
+ }
172
+ ```
173
+
174
+ For deployments, use `CRABCODE_GATEWAY_PASSWORD` instead of a plaintext
175
+ `password`, or configure a `password_hash` in `pbkdf2_sha256$...` format.
176
+ `publickey` and `mixed` read `~/.ssh/authorized_keys` by default and support
177
+ Ed25519, RSA-SHA256, and ECDSA-SHA256. In `mixed` mode either method grants
178
+ access, so the password must still be strong.
179
+
180
+ ```bash
181
+ python -c 'from getpass import getpass; from crabcode_gateway.auth import hash_password; print(hash_password(getpass("Password: ")))'
182
+ ```
183
+
184
+ Password clients submit `{"grant_type":"password","password":"..."}` to
185
+ `POST /auth/token`. Public-key clients first call `GET /auth/challenge`, sign
186
+ the returned UTF-8 `signing_payload` locally, then submit `grant_type=publickey`,
187
+ the authorized-key comment or `SHA256:` fingerprint as `key_id`, the challenge,
188
+ and the Base64 signature to `POST /auth/token`. The private key never leaves the
189
+ client. Both flows return a short-lived JWT used as
190
+ `Authorization: Bearer <token>` for HTTP, WebSocket, and gRPC requests.
191
+ Challenges expire after 60 seconds and are single-use. Five consecutive
192
+ password failures are rate-limited for 60 seconds.
193
+ An explicitly configured `jwt_secret` must be at least 32 bytes; otherwise a
194
+ new secret is generated for each gateway process.
195
+
196
+ The existing `--password` and static Bearer/Basic password behavior remains
197
+ compatible, but new clients should exchange credentials at `/auth/token`.
198
+ Use HTTPS/WSS whenever the gateway is exposed beyond the local machine.
199
+
138
200
  **HTTP API endpoints:**
139
201
 
140
202
  | Endpoint | Method | Description |
141
203
  | ---------- | -------- | ------------- |
142
- | `/health` | GET | Health check |
143
- | `/session/new` | POST | Create a new session |
204
+ | `/health` | GET | Health check with the CrabCode version and gateway protocol compatibility range |
205
+ | `/session/new` | POST | Create a session; accepts `cwd` plus optional `model`, `provider`, `base_url`, `api_format`, and `model_profile` overrides |
144
206
  | `/session/send` | POST | Send a message (starts query loop, events via SSE) |
145
207
  | `/session/interrupt` | POST | Interrupt current turn |
146
208
  | `/session/compact` | POST | Trigger manual compaction |
147
- | `/session/list` | GET | List active sessions |
148
- | `/session/resume` | POST | Resume a session |
209
+ | `/session/clear` | POST | Clear the active context and persist the clear boundary |
210
+ | `/session/messages` | GET | Read the structured active message projection |
211
+ | `/session/fork` | POST | Atomically fork a session through any completed assistant reply; records the source session/message/title |
212
+ | `/session/list` | GET | List persisted sessions for the current project, or for an optional `cwd` |
213
+ | `/session/recent` | GET | List recent sessions across projects |
214
+ | `/session/search` | POST | Search sessions by title or message |
215
+ | `/session/resolve` | GET | Resolve a full ID, unique prefix, or current-project index |
216
+ | `/session/resume` | POST | Resume by full ID, unique prefix, or index, with the same optional API overrides for a cold session |
217
+ | `/session/status` | GET | Read model, mode, effort, and context-window status |
218
+ | `/session/archive` | POST | Archive a loaded or persisted session |
219
+ | `/session/prune` | POST | Archive stale inactive sessions and optionally purge artifacts |
220
+ | `/session/export` | POST | Export Markdown or JSON by ID, prefix, or index |
221
+ | `/session/stats` | GET | Read global, project, and per-model usage statistics |
149
222
  | `/agent/spawn` | POST | Spawn a sub-agent |
150
223
  | `/agent/{id}` | GET | Get agent status |
151
224
  | `/agent/list` | GET | List all agents |
225
+ | `/agent/{id}/transcript` | GET | Read an agent transcript/log tail |
152
226
  | `/agent/{id}/cancel` | POST | Cancel an agent |
153
227
  | `/agent/{id}/input` | POST | Send input to an agent |
154
228
  | `/agent/wait` | POST | Wait for agent(s) to complete |
155
229
  | `/permission/respond` | POST | Respond to a permission request |
156
230
  | `/choice/respond` | POST | Respond to a choice request |
157
231
  | `/config/models` | GET | List available models |
232
+ | `/config/model-settings` | GET/POST | Inspect and mutate raw/effective model settings for a working directory |
233
+ | `/config/runtime-settings` | GET/POST | Inspect and mutate file snapshots and extra-tool settings for a working directory |
158
234
  | `/config/switch-model` | POST | Switch model |
159
235
  | `/config/switch-mode` | POST | Switch agent/plan mode |
236
+ | `/config/reasoning-effort` | POST | Set reasoning effort |
237
+ | `/config/ultra-mode` | POST | Toggle or set ultra mode |
238
+ | `/config/permission-mode` | POST | Set the client tool-permission override |
160
239
  | `/config/goal` | GET/POST | View or manage the session goal |
240
+ | `/config/plan-status` | GET | Read current plan execution status |
161
241
  | `/tools` | GET | List available tools (including MCP) |
242
+ | `/skills` | GET | List available skills |
243
+ | `/skills/expand` | POST | Expand a skill invocation with user input |
162
244
  | `/context` | POST | Push workspace context (active file, selection, cursor) |
245
+ | `/context/{session_id}` | GET | Read the latest client workspace context |
246
+ | `/workspace/info` | GET | Read the startup directory, user home, and allowed browse roots |
247
+ | `/workspace/directories` | GET | List subdirectories within the allowed browse roots |
248
+ | `/workspace/directories/create` | POST | Create one directory within an allowed browse root |
249
+ | `/logs` | GET | List, tail, or clear background logs |
250
+ | `/logs/follow` | GET | Follow a background log as SSE |
251
+ | `/tasks`, `/tasks/{id}` | GET | List background tasks or read one task; `scope=global` lists tasks across loaded sessions |
252
+ | `/tasks/{id}/output` | GET | Read persisted background-task output |
253
+ | `/tasks/stop` | POST | Stop a background task |
254
+ | `/schedule`, `/schedule/{id}` | GET | List scheduled jobs or read one job by ID/unique prefix |
255
+ | `/schedule/{id}/runs` | GET | Read persisted execution history for a scheduled job |
256
+ | `/schedule/create` | POST | Create a cron, interval, or one-shot job; supports enabled state, next-run override, reusable execution session, tags, and extra metadata |
257
+ | `/schedule/pause`, `/schedule/resume` | POST | Pause or resume a scheduled job |
258
+ | `/schedule/trigger`, `/schedule/cancel` | POST | Run a job immediately or permanently delete it |
259
+ | `/peer/list`, `/peer/send` | GET/POST | List messageable sessions or send a peer message |
260
+ | `/team/list`, `/team/{id}/*` | GET | Read teams, status, messages, and task boards |
261
+ | `/team/create`, `/team/spawn`, `/team/shutdown` | POST | Manage the team lifecycle |
262
+ | `/team/message`, `/team/broadcast` | POST | Send teammate messages |
263
+ | `/team/remove`, `/team/messages/read` | POST | Remove a teammate or mark its messages read |
264
+ | `/team/task/*` | POST | Add, claim, complete, or fail team tasks |
265
+ | `/team/bridge`, `/team/{a}/bridge/{b}` | POST/GET | Register or inspect a cross-team bridge policy |
266
+ | `/team/cross-message` | POST | Send a policy-checked cross-team message |
163
267
  | `/snapshot/checkpoint` | POST | Create checkpoint with file snapshot |
164
268
  | `/snapshot/list` | GET | List checkpoints for a session |
165
269
  | `/snapshot/revert` | POST | Revert files + conversation to a checkpoint |
166
270
  | `/snapshot/rollback` | POST | Rollback conversation only (no file restore) |
271
+ | `/snapshot/undo` | POST | Revert the latest checkpoint |
167
272
  | `/event` | GET (SSE) | Real-time event stream with 10s heartbeat |
168
273
  | `/ws` | WebSocket | Bidirectional channel (preferred for VSCode) |
169
274
 
170
- **WebSocket `/ws`** supports incoming commands (`send_message`, `permission_response`, `choice_response`, `push_context`) and outgoing event payloads — a single connection handles all interaction, making it ideal for VSCode extensions.
275
+ `POST /config/model-settings` accepts `action` values `upsert_model`,
276
+ `delete_model`, `upsert_group`, `delete_group`, `set_default_model`, and
277
+ `clear_default_model`. Mutations target `userSettings`, `projectSettings`, or
278
+ `localSettings`; project layers require a `cwd` within the Gateway workspace.
279
+ `POST /config/runtime-settings` accepts `set_snapshot`, `add_extra_tool`, and
280
+ `remove_extra_tool`, using the same configuration layers. Disabling snapshots
281
+ skips only the file-system copy; conversation checkpoints are still persisted.
282
+
283
+ **WebSocket `/ws`** supports the complete interactive command path: session lifecycle (`new_session`, `resume_session`), messages and steering, interrupt, permission/choice responses, workspace context, model/mode/permission changes, and plan actions. `new_session` and `resume_session` accept the same five API override fields as the HTTP lifecycle endpoints. Overrides are rejected for an already-loaded resume target so one client cannot silently replace another client's runtime. A connection remains subscribed to every session it explicitly selects, so background events from an earlier session remain visible after the active UI switches to another one; unrelated sessions are still filtered out. Foreground and plan commands carry an `operation_id`: steering and interrupt should send that ID to avoid targeting a newer turn. Command-validation failures use a typed, non-terminal error envelope, while every admitted operation finishes with exactly one `turn_complete` event. A complete client must also consume structured session history and the session-tagged `agent_state`, `agent_output`, `team_message`, `team_state`, `task_update`, `schedule_run`, `compact`, permission/choice response, file-change, snapshot, and revert events. Schedule CRUD uses the HTTP endpoints above; clients do not need to poll for execution completion.
171
284
 
172
- **gRPC** service is available when `--grpc-port` is set, with streaming `SendMessage` and `SubscribeEvents` RPCs. See `packages/gateway/crabcode_gateway/grpc/proto/crabcode.proto` for the full service definition.
285
+ ### Crab Desktop and Browser UI
286
+
287
+ The React client in `packages/desktop` runs in a browser with `npm run dev`, or
288
+ inside the Tauri shell with `npm run tauri dev`. Both forms support local and
289
+ remote Gateways, projects, concurrent sessions, streaming chat, permissions,
290
+ plans, diffs, and checkpoint recovery. Tauri additionally provides system
291
+ credential storage and automatic local Gateway startup; browser mode connects
292
+ to an already-running Gateway and retains passwords only for the current tab.
293
+
294
+ In Desktop and the VS Code extension, every completed assistant reply can be
295
+ forked into a new session. The new session opens immediately, preserves the
296
+ conversation up to that reply, and shows its source session/title. Running
297
+ turns, pending tools, permission requests, and WebSocket runtime state are not
298
+ copied. In the VS Code chat, copy controls stay hidden until hover or focus;
299
+ they are available for full replies, fenced code, Markdown tables, tool input
300
+ and output, diffs, and error messages.
301
+
302
+ Tauri writes non-secret UI state to `~/.crabcode/settings_desktop.json`.
303
+ Gateway model and tool settings continue to use the normal `settings.json`.
304
+ Desktop's **Settings → Runtime & Tools** section can edit remote file-snapshot
305
+ settings and the `extra_tools` import-path list by configuration layer.
306
+
307
+ Direct `! <cmd>` execution is intentionally a trusted-client feature: the CLI runs it in its local process and the VSCode extension sends it to a local integrated terminal. It is not exposed as a Gateway endpoint because doing so would create a permission-bypassing remote shell.
308
+
309
+ #### High-fidelity PDF engine
310
+
311
+ Layout-preserving PDF translation is provided by an optional, isolated
312
+ BabelDOC 0.6.4 environment. It requires Python 3.10–3.13, uses approximately
313
+ 550 MiB for its models and fonts.
314
+ requests still use the model selected by the active CrabCode session; model
315
+ credentials are never passed to the BabelDOC worker.
316
+
317
+ The Desktop **Document** settings show the install command. For a local Gateway,
318
+ the Tauri app can execute it directly with the **Run install** button. The
319
+ equivalent CLI commands are:
320
+
321
+ ```bash
322
+ # Inspect, install, or remove the managed engine
323
+ crabcode document-engine status
324
+ crabcode document-engine install
325
+ crabcode document-engine remove --yes
326
+ ```
327
+
328
+ The default installer creates a separate virtual environment, installs the
329
+ official BabelDOC package, downloads and verifies BabelDOC's upstream runtime
330
+ assets, then records a local checksum manifest. Document processing is
331
+ network-disabled after installation. Removing the engine does not delete PDFs
332
+ that have already been translated.
333
+
334
+ When the engine is ready, new full-document translations default to the
335
+ high-fidelity path and produce a native translated PDF. The reader can switch
336
+ between the original and translated PDFs. If high-fidelity processing fails,
337
+ the UI offers an explicit **Retry in compatibility mode** action instead of
338
+ silently changing engines mid-job.
339
+
340
+ For a remote Gateway, run `crabcode document-engine install` on the Gateway
341
+ host. CrabCode deliberately does not expose engine installation as a remote
342
+ shell endpoint. Air-gapped installations can use a reviewed offline bundle:
343
+
344
+ ```bash
345
+ crabcode document-engine install --bundle /path/to/crabcode-document-engine.zip
346
+ ```
347
+
348
+ **gRPC** service is available when `--grpc-port` is set, with streaming conversation/event RPCs plus the typed agent, permission, choice, model, and mode RPCs defined in `packages/gateway/crabcode_gateway/grpc/proto/crabcode.proto`.
173
349
 
174
350
  ### ACP (Agent Client Protocol) Support
175
351
 
@@ -288,6 +464,7 @@ Or configure in `~/.crabcode/settings.json`:
288
464
  | `base_url` | Custom API endpoint (for routers or local deployments) | — |
289
465
  | `api_key_env` | **Name** of the env var that holds the API key (not the key itself) | `ANTHROPIC_API_KEY` / `OPENAI_API_KEY` |
290
466
  | `codex_auth_path` | Codex CLI OAuth auth file path. Used only by the `codex` provider when no API key and no `base_url` are configured. | `$CODEX_HOME/auth.json` or `~/.codex/auth.json` |
467
+ | `image_generation_enabled` | Explicitly enable `ImageGenerate` for a compatible Responses endpoint (`provider: "codex"`, or `provider: "router"` with `format: "codex"`). Does not affect automatic image generation availability in official Codex OAuth mode. | `false` |
291
468
  | `http_headers` | Extra HTTP headers to attach to every API request for this config | `{}` |
292
469
  | `anthropic_stream_transport` | Anthropic streaming implementation: `auto` \| `sdk` \| `httpx`. In `auto`, first-party Anthropic uses the SDK and custom `base_url` endpoints use direct SSE for proxies that reject SDK stream helper headers. | `auto` |
293
470
  | `format` | Wire format for router mode: `anthropic` \| `openai` \| `codex` | — |
@@ -317,6 +494,29 @@ For Codex OAuth, set `provider` to `codex` and omit `base_url` and API key setti
317
494
  }
318
495
  ```
319
496
 
497
+ For a third-party Codex/Responses-compatible image generation endpoint, explicitly opt in:
498
+
499
+ ```json
500
+ {
501
+ "models": {
502
+ "compatible-images": {
503
+ "provider": "codex",
504
+ "model": "your-provider-model-id",
505
+ "base_url": "https://your-provider.example/v1",
506
+ "api_key_env": "COMPATIBLE_CODEX_API_KEY",
507
+ "image_generation_enabled": true,
508
+ "timeout": 300
509
+ }
510
+ }
511
+ }
512
+ ```
513
+
514
+ Set `COMPATIBLE_CODEX_API_KEY` in the environment and select `compatible-images`. You can also put these fields under `api` or a shared `groups` entry. Omitted or `false` disables image generation for compatible endpoints; official `auth.json` mode remains automatic. Other wire formats ignore this flag.
515
+
516
+ The endpoint must support `POST <base_url>/responses` with the native `image_generation` tool, `tool_choice`, `stream: true`, and `store: false`, returning a final base64 `image_generation_call.result` in Responses SSE events. An `/images/generations`-only API is not compatible with this option. Requests use the selected model ID, `api_key_env` and `http_headers`; they never load local Codex OAuth credentials for a custom endpoint. `extra_body` passes through provider-specific options, but cannot override the image request's `model`, `instructions`, `input`, `tools`, `tool_choice`, `stream`, or `store`. `prompt_cache_key` (or `http_headers.session_id`) and `prompt_cache_retention` are also forwarded when configured.
517
+
518
+ After restarting with the updated configuration, ask for an image in the conversation. `ImageGenerate` accepts a `prompt` and optional `reference_image_paths` (up to five local images), saves unique files under the workspace's `output/imagegen/`, and returns inline images to Desktop and VS Code. Provider/model support and quotas still apply; enabling this flag does not add upstream image capabilities.
519
+
320
520
  For DeepSeek V4 thinking mode with tool calls, enable reasoning pass-through:
321
521
 
322
522
  ```json
@@ -412,13 +612,13 @@ Example:
412
612
  "pre_tool_call": [
413
613
  {
414
614
  "matcher": "Bash",
415
- "command": "echo '[pre] tool=$CRABCODE_HOOK_TOOL_NAME'"
615
+ "command": "python -c \"import os; print('[pre] tool=' + os.getenv('CRABCODE_HOOK_TOOL_NAME', ''))\""
416
616
  }
417
617
  ],
418
618
  "post_tool_call": [
419
619
  {
420
620
  "matcher": "Bash",
421
- "command": "echo '[post] tool=$CRABCODE_HOOK_TOOL_NAME'"
621
+ "command": "python -c \"import os; print('[post] tool=' + os.getenv('CRABCODE_HOOK_TOOL_NAME', ''))\""
422
622
  }
423
623
  ],
424
624
  "user_prompt_submit": [
@@ -429,7 +629,7 @@ Example:
429
629
  "pre_compact": [
430
630
  {
431
631
  "matcher": "manual",
432
- "command": "echo '[compact] trigger is in $CRABCODE_HOOK_PAYLOAD'"
632
+ "command": "python -c \"import os; print('[compact] trigger is in ' + os.getenv('CRABCODE_HOOK_PAYLOAD', ''))\""
433
633
  }
434
634
  ]
435
635
  }
@@ -476,6 +676,31 @@ Define multiple model profiles in `settings.json` and switch between them at run
476
676
 
477
677
  Each entry under `models` is a full `ApiConfig` and can have its own `provider`, `base_url`, `api_key_env`, `codex_auth_path`, etc.
478
678
 
679
+ For profiles that share a backend, define the common fields once under
680
+ `groups` and reference the group from each model. A model field explicitly set
681
+ under `models` overrides the value inherited from its group:
682
+
683
+ ```json
684
+ {
685
+ "groups": {
686
+ "test_rourter": {
687
+ "provider": "codex",
688
+ "base_url": "https://router.example.com/v1",
689
+ "api_key_env": "TEST_ROUTER_KEY",
690
+ "reasoning_effort": "high",
691
+ "http_headers": {"originator": "codex_vscode"}
692
+ }
693
+ },
694
+ "models": {
695
+ "gpt-5.6": {"group": "test_rourter", "model": "gpt-5.6-sol"},
696
+ "gpt-5.5": {"group": "test_rourter", "model": "gpt-5.5", "reasoning_effort": "low"}
697
+ }
698
+ }
699
+ ```
700
+
701
+ `groups` and `models` accept the same API configuration fields. An unknown
702
+ group leaves the model's own fields unchanged.
703
+
479
704
  **Select a profile at startup:**
480
705
 
481
706
  ```bash
@@ -485,7 +710,7 @@ crabcode --model-profile smart # short: -M smart
485
710
  **Switch inside the REPL:**
486
711
 
487
712
  ```
488
- /model # show active model, list all configured profiles
713
+ /model # open the searchable model picker and switch profiles
489
714
  /model fast # switch to the "fast" (ollama) profile
490
715
  /model smart # switch to the "smart" (anthropic) profile
491
716
  /model code # switch to the "code" (openai) profile
@@ -781,6 +1006,32 @@ CrabCode automatically tracks file-system changes made during a session, allowin
781
1006
  - **Git repos** (preferred): uses `git write-tree` + `git update-ref` under `refs/crabcode/` — lightweight, zero-commit snapshots that don't pollute your git history.
782
1007
  - **Non-git directories**: files are copied to `.crabcode/snapshots/` for tracking.
783
1008
 
1009
+ **Snapshot safety settings:**
1010
+
1011
+ File-system snapshots are enabled by default, with a cumulative workspace-size
1012
+ ceiling of 1024 MiB. Configure them in the project or user `settings.json`:
1013
+
1014
+ ```json
1015
+ {
1016
+ "snapshot": {
1017
+ "enabled": true,
1018
+ "max_size_mb": 1024
1019
+ }
1020
+ }
1021
+ ```
1022
+
1023
+ The scanner always skips the filesystem root and the user home directory. It
1024
+ also skips `.git`, `.crabcode`, dependency and cache directories. If the
1025
+ workspace exceeds `max_size_mb`, or `enabled` is `false`, only the file-system
1026
+ copy is skipped: the conversation checkpoint is still persisted. In that case
1027
+ `/revert` can roll back the conversation but reports that no file snapshot was
1028
+ available.
1029
+
1030
+ Desktop exposes these fields under **Settings → Runtime & Tools**. The same
1031
+ section can add or remove `extra_tools` import paths on the remote Gateway;
1032
+ the package must be installed in that Gateway environment. Changes apply to
1033
+ new sessions or after reconnecting an existing session.
1034
+
784
1035
  **Gateway API:**
785
1036
 
786
1037
  | Endpoint | Method | Description |
@@ -800,7 +1051,7 @@ CrabCode automatically tracks file-system changes made during a session, allowin
800
1051
  | `/logs <name>` | Show tail of a specific log |
801
1052
  | `/logs -f <name>` | Follow a specific log in real time (`Ctrl+C` to stop) |
802
1053
  | `/logs --clear <name>` | Clear a specific log file |
803
- | `/model` | Show active model and all configured named models |
1054
+ | `/model` | Open a searchable model picker organized by group; ↑/↓ select, Enter switches, Esc cancels, Tab and ←/→ filter groups |
804
1055
  | `/model <name>` | Switch to a named model from `settings.models` |
805
1056
  | `/effort` | Show the active reasoning effort |
806
1057
  | `/effort <none\|minimal\|low\|medium\|high\|xhigh\|max>` | Set reasoning effort for subsequent requests in the current runtime session |
@@ -819,16 +1070,29 @@ CrabCode automatically tracks file-system changes made during a session, allowin
819
1070
  | `/wait <id>` | Wait for one agent to finish and print its summary |
820
1071
  | `/cancel-agent <id>` | Cancel a running agent |
821
1072
  | `/team list` | List active agent teams |
1073
+ | `/team create <name> [max]` | Create a team |
822
1074
  | `/team status <team_id>` | Show team status table |
823
1075
  | `/team messages <team_id>` | Show team message history |
1076
+ | `/team tasks <team_id>` | Show the shared task board |
1077
+ | `/team spawn <team_id> [options] <prompt>` | Add a teammate |
1078
+ | `/team message <team_id> <agent_id> <text>` | Send a teammate message |
1079
+ | `/team broadcast <team_id> <text>` | Broadcast to teammates |
1080
+ | `/team task-add <team_id> <description>` | Add a task |
1081
+ | `/team task-claim <team_id> <task_id> [agent_id]` | Claim a task |
1082
+ | `/team task-complete <team_id> <task_id> [result]` | Complete a task |
824
1083
  | `/team shutdown <team_id>` | Shut down a team |
1084
+ | `/schedule list` | List scheduled jobs |
1085
+ | `/schedule show <job_id>` | Show scheduled job details |
1086
+ | `/schedule runs <job_id>` | Show scheduled-job run history |
1087
+ | `/schedule create <name> <type> <schedule> <prompt>` | Create a cron/interval/once job |
1088
+ | `/schedule pause\|resume\|run\|cancel <job_id>` | Manage scheduled-job lifecycle |
825
1089
  | `/new` | Start a fresh session (clear in-memory conversation history) |
826
1090
  | `/compact` | Manually compact conversation history to save context |
827
1091
  | `/clear` | Clear current in-memory conversation messages |
828
1092
  | `/sessions` | List recent saved sessions for current project |
829
1093
  | `/recent` | List recent sessions across all projects |
830
1094
  | `/search <query>` | Search sessions by title or message content |
831
- | `/resume <id>` | Resume a saved session by full/partial id or index (supports cross-project) |
1095
+ | `/resume [id]` | Browse searchable history, or resume by full/partial id or index (supports cross-project) |
832
1096
  | `/archive <id>` | Archive a session (hide from listings) |
833
1097
  | `/export [md\|json] [path]` | Export current session to Markdown or JSON |
834
1098
  | `/stats` | Show usage statistics (tokens, sessions, models) |
@@ -846,7 +1110,7 @@ CrabCode automatically tracks file-system changes made during a session, allowin
846
1110
  - For commands that take `<id>`, you can usually pass the leading prefix shown by `/agents`.
847
1111
  - `/agent-send` live output is controlled by `agent.stream_send_input_output` in `settings.json`.
848
1112
  - `Ctrl+C` interrupts the current operation; pressing `Ctrl+C` again within a few seconds exits.
849
- - `/resume` supports cross-project sessions — if the session ID belongs to another project it will be resolved automatically via the metadata database.
1113
+ - `/resume` opens a keyboard-driven history picker: type to search, ↑/↓ to browse, Enter to resume, Esc/Ctrl+C to return. Tab focuses the project filter (Cwd/All) or sort order (Updated/Created); ←/→ changes the option. `/resume <id>` still supports cross-project sessions via the metadata database.
850
1114
 
851
1115
  ### Plan Mode Workflow
852
1116
 
@@ -993,7 +1257,17 @@ By default, CrabCode does not apply a global timeout to tool calls. Set the top-
993
1257
  }
994
1258
  ```
995
1259
 
996
- Omit `tool_call_timeout` or set it to `null` to let tool calls run indefinitely. Tool-specific timeouts, such as `Bash.timeout` or `agent.timeout`, still apply independently and may be shorter.
1260
+ Omit `tool_call_timeout` or set it to `null` to disable the global limit. Filesystem and tool-specific timeouts, such as `filesystem_timeout`, `Bash.timeout`, or `agent.timeout`, still apply independently and may be shorter.
1261
+
1262
+ The shared filesystem tool timeout defaults to **3600 seconds** for Read, Write, Edit, Glob, Grep, and Bash. Set the top-level `filesystem_timeout` field in `~/.crabcode/settings.json` or the project's `.crabcode/settings.json` to change it:
1263
+
1264
+ ```json
1265
+ {
1266
+ "filesystem_timeout": 3600
1267
+ }
1268
+ ```
1269
+
1270
+ The value must be a finite, positive number of seconds, or `null` to disable the filesystem timeout. Omitting the field keeps the 3600-second default. It applies to both main-session and sub-agent file tools, including file snapshots performed during a tool call. An explicit `Bash.timeout` overrides this default for that invocation, even when `filesystem_timeout` is `null`; a configured `tool_call_timeout` still caps the overall execution. Operations can still be cancelled when the timeout is disabled.
997
1271
 
998
1272
  ## CLAUDE.md (project instructions)
999
1273
 
@@ -1253,8 +1527,16 @@ The recovery helper can normalize stale `busy`/`cancelling` teammate states in a
1253
1527
  | Command | Description |
1254
1528
  | --------- | ------------- |
1255
1529
  | `/team list` | List active teams |
1530
+ | `/team create <name> [max]` | Create a team |
1256
1531
  | `/team status <team_id>` | Show team status table |
1257
1532
  | `/team messages <team_id>` | Show team message history |
1533
+ | `/team tasks <team_id>` | Show the shared task board |
1534
+ | `/team spawn <team_id> [options] <prompt>` | Add a teammate |
1535
+ | `/team message <team_id> <agent_id> <text>` | Send a teammate message |
1536
+ | `/team broadcast <team_id> <text>` | Broadcast to teammates |
1537
+ | `/team task-add <team_id> <description>` | Add a task |
1538
+ | `/team task-claim <team_id> <task_id> [agent_id]` | Claim a task |
1539
+ | `/team task-complete <team_id> <task_id> [result]` | Complete a task |
1258
1540
  | `/team shutdown <team_id>` | Shut down a team |
1259
1541
 
1260
1542
  ### Multi-model example
@@ -1538,6 +1820,8 @@ Memory and patch details:
1538
1820
  - `code_patch` writes explicit bytes only, stores the original bytes, can verify
1539
1821
  `expected_hex` before writing, and uses backend protection/cache primitives
1540
1822
  where available.
1823
+ - Patch hex input is validated strictly. Active patch IDs must be unique, and
1824
+ overlapping active patches are rejected so the original bytes remain recoverable.
1541
1825
  - `code_restore` restores saved patches by `patch_id` or `all=true`.
1542
1826
  - Direct memory access is subject to operating-system process rights. Windows
1543
1827
  requires sufficient `OpenProcess` rights and can fail for elevated or protected
@@ -1550,6 +1834,8 @@ Process and debuggee actions default to permission confirmation. The tools retur
1550
1834
  `ASK` for process inspection, memory reads/writes/freezes, attach, dump, trace,
1551
1835
  and code patching. When `permissions.default_mode` is `"run_everything"` or legacy `permissions.run_everything` is enabled, those `ASK`
1552
1836
  permissions are bypassed by the normal CrabCode permission mode.
1837
+ Adapter discovery also asks for confirmation when a configured adapter declares
1838
+ a custom `probe_command`, because discovery will execute that command.
1553
1839
 
1554
1840
  The intended use is local, authorized process debugging, diagnostics, testing,
1555
1841
  and research. `crabcode-debugger` does not provide stealth injection,