gobby 0.2.5__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 (383) hide show
  1. gobby/__init__.py +3 -0
  2. gobby/adapters/__init__.py +30 -0
  3. gobby/adapters/base.py +93 -0
  4. gobby/adapters/claude_code.py +276 -0
  5. gobby/adapters/codex.py +1292 -0
  6. gobby/adapters/gemini.py +343 -0
  7. gobby/agents/__init__.py +37 -0
  8. gobby/agents/codex_session.py +120 -0
  9. gobby/agents/constants.py +112 -0
  10. gobby/agents/context.py +362 -0
  11. gobby/agents/definitions.py +133 -0
  12. gobby/agents/gemini_session.py +111 -0
  13. gobby/agents/registry.py +618 -0
  14. gobby/agents/runner.py +968 -0
  15. gobby/agents/session.py +259 -0
  16. gobby/agents/spawn.py +916 -0
  17. gobby/agents/spawners/__init__.py +77 -0
  18. gobby/agents/spawners/base.py +142 -0
  19. gobby/agents/spawners/cross_platform.py +266 -0
  20. gobby/agents/spawners/embedded.py +225 -0
  21. gobby/agents/spawners/headless.py +226 -0
  22. gobby/agents/spawners/linux.py +125 -0
  23. gobby/agents/spawners/macos.py +277 -0
  24. gobby/agents/spawners/windows.py +308 -0
  25. gobby/agents/tty_config.py +319 -0
  26. gobby/autonomous/__init__.py +32 -0
  27. gobby/autonomous/progress_tracker.py +447 -0
  28. gobby/autonomous/stop_registry.py +269 -0
  29. gobby/autonomous/stuck_detector.py +383 -0
  30. gobby/cli/__init__.py +67 -0
  31. gobby/cli/__main__.py +8 -0
  32. gobby/cli/agents.py +529 -0
  33. gobby/cli/artifacts.py +266 -0
  34. gobby/cli/daemon.py +329 -0
  35. gobby/cli/extensions.py +526 -0
  36. gobby/cli/github.py +263 -0
  37. gobby/cli/init.py +53 -0
  38. gobby/cli/install.py +614 -0
  39. gobby/cli/installers/__init__.py +37 -0
  40. gobby/cli/installers/antigravity.py +65 -0
  41. gobby/cli/installers/claude.py +363 -0
  42. gobby/cli/installers/codex.py +192 -0
  43. gobby/cli/installers/gemini.py +294 -0
  44. gobby/cli/installers/git_hooks.py +377 -0
  45. gobby/cli/installers/shared.py +737 -0
  46. gobby/cli/linear.py +250 -0
  47. gobby/cli/mcp.py +30 -0
  48. gobby/cli/mcp_proxy.py +698 -0
  49. gobby/cli/memory.py +304 -0
  50. gobby/cli/merge.py +384 -0
  51. gobby/cli/projects.py +79 -0
  52. gobby/cli/sessions.py +622 -0
  53. gobby/cli/tasks/__init__.py +30 -0
  54. gobby/cli/tasks/_utils.py +658 -0
  55. gobby/cli/tasks/ai.py +1025 -0
  56. gobby/cli/tasks/commits.py +169 -0
  57. gobby/cli/tasks/crud.py +685 -0
  58. gobby/cli/tasks/deps.py +135 -0
  59. gobby/cli/tasks/labels.py +63 -0
  60. gobby/cli/tasks/main.py +273 -0
  61. gobby/cli/tasks/search.py +178 -0
  62. gobby/cli/tui.py +34 -0
  63. gobby/cli/utils.py +513 -0
  64. gobby/cli/workflows.py +927 -0
  65. gobby/cli/worktrees.py +481 -0
  66. gobby/config/__init__.py +129 -0
  67. gobby/config/app.py +551 -0
  68. gobby/config/extensions.py +167 -0
  69. gobby/config/features.py +472 -0
  70. gobby/config/llm_providers.py +98 -0
  71. gobby/config/logging.py +66 -0
  72. gobby/config/mcp.py +346 -0
  73. gobby/config/persistence.py +247 -0
  74. gobby/config/servers.py +141 -0
  75. gobby/config/sessions.py +250 -0
  76. gobby/config/tasks.py +784 -0
  77. gobby/hooks/__init__.py +104 -0
  78. gobby/hooks/artifact_capture.py +213 -0
  79. gobby/hooks/broadcaster.py +243 -0
  80. gobby/hooks/event_handlers.py +723 -0
  81. gobby/hooks/events.py +218 -0
  82. gobby/hooks/git.py +169 -0
  83. gobby/hooks/health_monitor.py +171 -0
  84. gobby/hooks/hook_manager.py +856 -0
  85. gobby/hooks/hook_types.py +575 -0
  86. gobby/hooks/plugins.py +813 -0
  87. gobby/hooks/session_coordinator.py +396 -0
  88. gobby/hooks/verification_runner.py +268 -0
  89. gobby/hooks/webhooks.py +339 -0
  90. gobby/install/claude/commands/gobby/bug.md +51 -0
  91. gobby/install/claude/commands/gobby/chore.md +51 -0
  92. gobby/install/claude/commands/gobby/epic.md +52 -0
  93. gobby/install/claude/commands/gobby/eval.md +235 -0
  94. gobby/install/claude/commands/gobby/feat.md +49 -0
  95. gobby/install/claude/commands/gobby/nit.md +52 -0
  96. gobby/install/claude/commands/gobby/ref.md +52 -0
  97. gobby/install/claude/hooks/HOOK_SCHEMAS.md +632 -0
  98. gobby/install/claude/hooks/hook_dispatcher.py +364 -0
  99. gobby/install/claude/hooks/validate_settings.py +102 -0
  100. gobby/install/claude/hooks-template.json +118 -0
  101. gobby/install/codex/hooks/hook_dispatcher.py +153 -0
  102. gobby/install/codex/prompts/forget.md +7 -0
  103. gobby/install/codex/prompts/memories.md +7 -0
  104. gobby/install/codex/prompts/recall.md +7 -0
  105. gobby/install/codex/prompts/remember.md +13 -0
  106. gobby/install/gemini/hooks/hook_dispatcher.py +268 -0
  107. gobby/install/gemini/hooks-template.json +138 -0
  108. gobby/install/shared/plugins/code_guardian.py +456 -0
  109. gobby/install/shared/plugins/example_notify.py +331 -0
  110. gobby/integrations/__init__.py +10 -0
  111. gobby/integrations/github.py +145 -0
  112. gobby/integrations/linear.py +145 -0
  113. gobby/llm/__init__.py +40 -0
  114. gobby/llm/base.py +120 -0
  115. gobby/llm/claude.py +578 -0
  116. gobby/llm/claude_executor.py +503 -0
  117. gobby/llm/codex.py +322 -0
  118. gobby/llm/codex_executor.py +513 -0
  119. gobby/llm/executor.py +316 -0
  120. gobby/llm/factory.py +34 -0
  121. gobby/llm/gemini.py +258 -0
  122. gobby/llm/gemini_executor.py +339 -0
  123. gobby/llm/litellm.py +287 -0
  124. gobby/llm/litellm_executor.py +303 -0
  125. gobby/llm/resolver.py +499 -0
  126. gobby/llm/service.py +236 -0
  127. gobby/mcp_proxy/__init__.py +29 -0
  128. gobby/mcp_proxy/actions.py +175 -0
  129. gobby/mcp_proxy/daemon_control.py +198 -0
  130. gobby/mcp_proxy/importer.py +436 -0
  131. gobby/mcp_proxy/lazy.py +325 -0
  132. gobby/mcp_proxy/manager.py +798 -0
  133. gobby/mcp_proxy/metrics.py +609 -0
  134. gobby/mcp_proxy/models.py +139 -0
  135. gobby/mcp_proxy/registries.py +215 -0
  136. gobby/mcp_proxy/schema_hash.py +381 -0
  137. gobby/mcp_proxy/semantic_search.py +706 -0
  138. gobby/mcp_proxy/server.py +549 -0
  139. gobby/mcp_proxy/services/__init__.py +0 -0
  140. gobby/mcp_proxy/services/fallback.py +306 -0
  141. gobby/mcp_proxy/services/recommendation.py +224 -0
  142. gobby/mcp_proxy/services/server_mgmt.py +214 -0
  143. gobby/mcp_proxy/services/system.py +72 -0
  144. gobby/mcp_proxy/services/tool_filter.py +231 -0
  145. gobby/mcp_proxy/services/tool_proxy.py +309 -0
  146. gobby/mcp_proxy/stdio.py +565 -0
  147. gobby/mcp_proxy/tools/__init__.py +27 -0
  148. gobby/mcp_proxy/tools/agents.py +1103 -0
  149. gobby/mcp_proxy/tools/artifacts.py +207 -0
  150. gobby/mcp_proxy/tools/hub.py +335 -0
  151. gobby/mcp_proxy/tools/internal.py +337 -0
  152. gobby/mcp_proxy/tools/memory.py +543 -0
  153. gobby/mcp_proxy/tools/merge.py +422 -0
  154. gobby/mcp_proxy/tools/metrics.py +283 -0
  155. gobby/mcp_proxy/tools/orchestration/__init__.py +23 -0
  156. gobby/mcp_proxy/tools/orchestration/cleanup.py +619 -0
  157. gobby/mcp_proxy/tools/orchestration/monitor.py +380 -0
  158. gobby/mcp_proxy/tools/orchestration/orchestrate.py +746 -0
  159. gobby/mcp_proxy/tools/orchestration/review.py +736 -0
  160. gobby/mcp_proxy/tools/orchestration/utils.py +16 -0
  161. gobby/mcp_proxy/tools/session_messages.py +1056 -0
  162. gobby/mcp_proxy/tools/task_dependencies.py +219 -0
  163. gobby/mcp_proxy/tools/task_expansion.py +591 -0
  164. gobby/mcp_proxy/tools/task_github.py +393 -0
  165. gobby/mcp_proxy/tools/task_linear.py +379 -0
  166. gobby/mcp_proxy/tools/task_orchestration.py +77 -0
  167. gobby/mcp_proxy/tools/task_readiness.py +522 -0
  168. gobby/mcp_proxy/tools/task_sync.py +351 -0
  169. gobby/mcp_proxy/tools/task_validation.py +843 -0
  170. gobby/mcp_proxy/tools/tasks/__init__.py +25 -0
  171. gobby/mcp_proxy/tools/tasks/_context.py +112 -0
  172. gobby/mcp_proxy/tools/tasks/_crud.py +516 -0
  173. gobby/mcp_proxy/tools/tasks/_factory.py +176 -0
  174. gobby/mcp_proxy/tools/tasks/_helpers.py +129 -0
  175. gobby/mcp_proxy/tools/tasks/_lifecycle.py +517 -0
  176. gobby/mcp_proxy/tools/tasks/_lifecycle_validation.py +301 -0
  177. gobby/mcp_proxy/tools/tasks/_resolution.py +55 -0
  178. gobby/mcp_proxy/tools/tasks/_search.py +215 -0
  179. gobby/mcp_proxy/tools/tasks/_session.py +125 -0
  180. gobby/mcp_proxy/tools/workflows.py +973 -0
  181. gobby/mcp_proxy/tools/worktrees.py +1264 -0
  182. gobby/mcp_proxy/transports/__init__.py +0 -0
  183. gobby/mcp_proxy/transports/base.py +95 -0
  184. gobby/mcp_proxy/transports/factory.py +44 -0
  185. gobby/mcp_proxy/transports/http.py +139 -0
  186. gobby/mcp_proxy/transports/stdio.py +213 -0
  187. gobby/mcp_proxy/transports/websocket.py +136 -0
  188. gobby/memory/backends/__init__.py +116 -0
  189. gobby/memory/backends/mem0.py +408 -0
  190. gobby/memory/backends/memu.py +485 -0
  191. gobby/memory/backends/null.py +111 -0
  192. gobby/memory/backends/openmemory.py +537 -0
  193. gobby/memory/backends/sqlite.py +304 -0
  194. gobby/memory/context.py +87 -0
  195. gobby/memory/manager.py +1001 -0
  196. gobby/memory/protocol.py +451 -0
  197. gobby/memory/search/__init__.py +66 -0
  198. gobby/memory/search/text.py +127 -0
  199. gobby/memory/viz.py +258 -0
  200. gobby/prompts/__init__.py +13 -0
  201. gobby/prompts/defaults/expansion/system.md +119 -0
  202. gobby/prompts/defaults/expansion/user.md +48 -0
  203. gobby/prompts/defaults/external_validation/agent.md +72 -0
  204. gobby/prompts/defaults/external_validation/external.md +63 -0
  205. gobby/prompts/defaults/external_validation/spawn.md +83 -0
  206. gobby/prompts/defaults/external_validation/system.md +6 -0
  207. gobby/prompts/defaults/features/import_mcp.md +22 -0
  208. gobby/prompts/defaults/features/import_mcp_github.md +17 -0
  209. gobby/prompts/defaults/features/import_mcp_search.md +16 -0
  210. gobby/prompts/defaults/features/recommend_tools.md +32 -0
  211. gobby/prompts/defaults/features/recommend_tools_hybrid.md +35 -0
  212. gobby/prompts/defaults/features/recommend_tools_llm.md +30 -0
  213. gobby/prompts/defaults/features/server_description.md +20 -0
  214. gobby/prompts/defaults/features/server_description_system.md +6 -0
  215. gobby/prompts/defaults/features/task_description.md +31 -0
  216. gobby/prompts/defaults/features/task_description_system.md +6 -0
  217. gobby/prompts/defaults/features/tool_summary.md +17 -0
  218. gobby/prompts/defaults/features/tool_summary_system.md +6 -0
  219. gobby/prompts/defaults/research/step.md +58 -0
  220. gobby/prompts/defaults/validation/criteria.md +47 -0
  221. gobby/prompts/defaults/validation/validate.md +38 -0
  222. gobby/prompts/loader.py +346 -0
  223. gobby/prompts/models.py +113 -0
  224. gobby/py.typed +0 -0
  225. gobby/runner.py +488 -0
  226. gobby/search/__init__.py +23 -0
  227. gobby/search/protocol.py +104 -0
  228. gobby/search/tfidf.py +232 -0
  229. gobby/servers/__init__.py +7 -0
  230. gobby/servers/http.py +636 -0
  231. gobby/servers/models.py +31 -0
  232. gobby/servers/routes/__init__.py +23 -0
  233. gobby/servers/routes/admin.py +416 -0
  234. gobby/servers/routes/dependencies.py +118 -0
  235. gobby/servers/routes/mcp/__init__.py +24 -0
  236. gobby/servers/routes/mcp/hooks.py +135 -0
  237. gobby/servers/routes/mcp/plugins.py +121 -0
  238. gobby/servers/routes/mcp/tools.py +1337 -0
  239. gobby/servers/routes/mcp/webhooks.py +159 -0
  240. gobby/servers/routes/sessions.py +582 -0
  241. gobby/servers/websocket.py +766 -0
  242. gobby/sessions/__init__.py +13 -0
  243. gobby/sessions/analyzer.py +322 -0
  244. gobby/sessions/lifecycle.py +240 -0
  245. gobby/sessions/manager.py +563 -0
  246. gobby/sessions/processor.py +225 -0
  247. gobby/sessions/summary.py +532 -0
  248. gobby/sessions/transcripts/__init__.py +41 -0
  249. gobby/sessions/transcripts/base.py +125 -0
  250. gobby/sessions/transcripts/claude.py +386 -0
  251. gobby/sessions/transcripts/codex.py +143 -0
  252. gobby/sessions/transcripts/gemini.py +195 -0
  253. gobby/storage/__init__.py +21 -0
  254. gobby/storage/agents.py +409 -0
  255. gobby/storage/artifact_classifier.py +341 -0
  256. gobby/storage/artifacts.py +285 -0
  257. gobby/storage/compaction.py +67 -0
  258. gobby/storage/database.py +357 -0
  259. gobby/storage/inter_session_messages.py +194 -0
  260. gobby/storage/mcp.py +680 -0
  261. gobby/storage/memories.py +562 -0
  262. gobby/storage/merge_resolutions.py +550 -0
  263. gobby/storage/migrations.py +860 -0
  264. gobby/storage/migrations_legacy.py +1359 -0
  265. gobby/storage/projects.py +166 -0
  266. gobby/storage/session_messages.py +251 -0
  267. gobby/storage/session_tasks.py +97 -0
  268. gobby/storage/sessions.py +817 -0
  269. gobby/storage/task_dependencies.py +223 -0
  270. gobby/storage/tasks/__init__.py +42 -0
  271. gobby/storage/tasks/_aggregates.py +180 -0
  272. gobby/storage/tasks/_crud.py +449 -0
  273. gobby/storage/tasks/_id.py +104 -0
  274. gobby/storage/tasks/_lifecycle.py +311 -0
  275. gobby/storage/tasks/_manager.py +889 -0
  276. gobby/storage/tasks/_models.py +300 -0
  277. gobby/storage/tasks/_ordering.py +119 -0
  278. gobby/storage/tasks/_path_cache.py +110 -0
  279. gobby/storage/tasks/_queries.py +343 -0
  280. gobby/storage/tasks/_search.py +143 -0
  281. gobby/storage/workflow_audit.py +393 -0
  282. gobby/storage/worktrees.py +547 -0
  283. gobby/sync/__init__.py +29 -0
  284. gobby/sync/github.py +333 -0
  285. gobby/sync/linear.py +304 -0
  286. gobby/sync/memories.py +284 -0
  287. gobby/sync/tasks.py +641 -0
  288. gobby/tasks/__init__.py +8 -0
  289. gobby/tasks/build_verification.py +193 -0
  290. gobby/tasks/commits.py +633 -0
  291. gobby/tasks/context.py +747 -0
  292. gobby/tasks/criteria.py +342 -0
  293. gobby/tasks/enhanced_validator.py +226 -0
  294. gobby/tasks/escalation.py +263 -0
  295. gobby/tasks/expansion.py +626 -0
  296. gobby/tasks/external_validator.py +764 -0
  297. gobby/tasks/issue_extraction.py +171 -0
  298. gobby/tasks/prompts/expand.py +327 -0
  299. gobby/tasks/research.py +421 -0
  300. gobby/tasks/tdd.py +352 -0
  301. gobby/tasks/tree_builder.py +263 -0
  302. gobby/tasks/validation.py +712 -0
  303. gobby/tasks/validation_history.py +357 -0
  304. gobby/tasks/validation_models.py +89 -0
  305. gobby/tools/__init__.py +0 -0
  306. gobby/tools/summarizer.py +170 -0
  307. gobby/tui/__init__.py +5 -0
  308. gobby/tui/api_client.py +281 -0
  309. gobby/tui/app.py +327 -0
  310. gobby/tui/screens/__init__.py +25 -0
  311. gobby/tui/screens/agents.py +333 -0
  312. gobby/tui/screens/chat.py +450 -0
  313. gobby/tui/screens/dashboard.py +377 -0
  314. gobby/tui/screens/memory.py +305 -0
  315. gobby/tui/screens/metrics.py +231 -0
  316. gobby/tui/screens/orchestrator.py +904 -0
  317. gobby/tui/screens/sessions.py +412 -0
  318. gobby/tui/screens/tasks.py +442 -0
  319. gobby/tui/screens/workflows.py +289 -0
  320. gobby/tui/screens/worktrees.py +174 -0
  321. gobby/tui/widgets/__init__.py +21 -0
  322. gobby/tui/widgets/chat.py +210 -0
  323. gobby/tui/widgets/conductor.py +104 -0
  324. gobby/tui/widgets/menu.py +132 -0
  325. gobby/tui/widgets/message_panel.py +160 -0
  326. gobby/tui/widgets/review_gate.py +224 -0
  327. gobby/tui/widgets/task_tree.py +99 -0
  328. gobby/tui/widgets/token_budget.py +166 -0
  329. gobby/tui/ws_client.py +258 -0
  330. gobby/utils/__init__.py +3 -0
  331. gobby/utils/daemon_client.py +235 -0
  332. gobby/utils/git.py +222 -0
  333. gobby/utils/id.py +38 -0
  334. gobby/utils/json_helpers.py +161 -0
  335. gobby/utils/logging.py +376 -0
  336. gobby/utils/machine_id.py +135 -0
  337. gobby/utils/metrics.py +589 -0
  338. gobby/utils/project_context.py +182 -0
  339. gobby/utils/project_init.py +263 -0
  340. gobby/utils/status.py +256 -0
  341. gobby/utils/validation.py +80 -0
  342. gobby/utils/version.py +23 -0
  343. gobby/workflows/__init__.py +4 -0
  344. gobby/workflows/actions.py +1310 -0
  345. gobby/workflows/approval_flow.py +138 -0
  346. gobby/workflows/artifact_actions.py +103 -0
  347. gobby/workflows/audit_helpers.py +110 -0
  348. gobby/workflows/autonomous_actions.py +286 -0
  349. gobby/workflows/context_actions.py +394 -0
  350. gobby/workflows/definitions.py +130 -0
  351. gobby/workflows/detection_helpers.py +208 -0
  352. gobby/workflows/engine.py +485 -0
  353. gobby/workflows/evaluator.py +669 -0
  354. gobby/workflows/git_utils.py +96 -0
  355. gobby/workflows/hooks.py +169 -0
  356. gobby/workflows/lifecycle_evaluator.py +613 -0
  357. gobby/workflows/llm_actions.py +70 -0
  358. gobby/workflows/loader.py +333 -0
  359. gobby/workflows/mcp_actions.py +60 -0
  360. gobby/workflows/memory_actions.py +272 -0
  361. gobby/workflows/premature_stop.py +164 -0
  362. gobby/workflows/session_actions.py +139 -0
  363. gobby/workflows/state_actions.py +123 -0
  364. gobby/workflows/state_manager.py +104 -0
  365. gobby/workflows/stop_signal_actions.py +163 -0
  366. gobby/workflows/summary_actions.py +344 -0
  367. gobby/workflows/task_actions.py +249 -0
  368. gobby/workflows/task_enforcement_actions.py +901 -0
  369. gobby/workflows/templates.py +52 -0
  370. gobby/workflows/todo_actions.py +84 -0
  371. gobby/workflows/webhook.py +223 -0
  372. gobby/workflows/webhook_executor.py +399 -0
  373. gobby/worktrees/__init__.py +5 -0
  374. gobby/worktrees/git.py +690 -0
  375. gobby/worktrees/merge/__init__.py +20 -0
  376. gobby/worktrees/merge/conflict_parser.py +177 -0
  377. gobby/worktrees/merge/resolver.py +485 -0
  378. gobby-0.2.5.dist-info/METADATA +351 -0
  379. gobby-0.2.5.dist-info/RECORD +383 -0
  380. gobby-0.2.5.dist-info/WHEEL +5 -0
  381. gobby-0.2.5.dist-info/entry_points.txt +2 -0
  382. gobby-0.2.5.dist-info/licenses/LICENSE.md +193 -0
  383. gobby-0.2.5.dist-info/top_level.txt +1 -0
@@ -0,0 +1,139 @@
1
+ """
2
+ MCP Proxy data models and configuration classes.
3
+ """
4
+
5
+ from dataclasses import dataclass
6
+ from datetime import UTC, datetime
7
+ from enum import Enum
8
+
9
+
10
+ class ConnectionState(str, Enum):
11
+ """MCP connection state."""
12
+
13
+ DISCONNECTED = "disconnected"
14
+ CONNECTING = "connecting"
15
+ CONNECTED = "connected"
16
+ FAILED = "failed"
17
+
18
+
19
+ class MCPError(Exception):
20
+ """Base exception for MCP client errors."""
21
+
22
+ def __init__(self, message: str, code: int | None = None):
23
+ """
24
+ Initialize MCP error.
25
+
26
+ Args:
27
+ message: Error message
28
+ code: JSON-RPC error code (if applicable)
29
+ """
30
+ super().__init__(message)
31
+ self.code = code
32
+
33
+
34
+ class HealthState(str, Enum):
35
+ """Connection health state for monitoring."""
36
+
37
+ HEALTHY = "healthy"
38
+ DEGRADED = "degraded"
39
+ UNHEALTHY = "unhealthy"
40
+
41
+
42
+ @dataclass
43
+ class MCPConnectionHealth:
44
+ """
45
+ Health tracking for individual MCP connection.
46
+
47
+ Tracks connection state, consecutive failures, and last health check
48
+ to enable health monitoring and automatic recovery.
49
+ """
50
+
51
+ name: str
52
+ state: ConnectionState
53
+ health: HealthState = HealthState.HEALTHY
54
+ last_health_check: datetime | None = None
55
+ consecutive_failures: int = 0
56
+ last_error: str | None = None
57
+ response_time_ms: float | None = None
58
+
59
+ def record_success(self, response_time_ms: float | None = None) -> None:
60
+ """
61
+ Record successful operation.
62
+
63
+ Args:
64
+ response_time_ms: Response time in milliseconds (optional)
65
+ """
66
+ self.consecutive_failures = 0
67
+ self.last_error = None
68
+ self.health = HealthState.HEALTHY
69
+ self.response_time_ms = response_time_ms
70
+ self.last_health_check = datetime.now(UTC)
71
+
72
+ def record_failure(self, error: str) -> None:
73
+ """
74
+ Record failed operation and update health state.
75
+
76
+ Args:
77
+ error: Error message from failure
78
+ """
79
+ self.consecutive_failures += 1
80
+ self.last_error = error
81
+ self.last_health_check = datetime.now(UTC)
82
+
83
+ # Update health state based on failure count
84
+ if self.consecutive_failures >= 5:
85
+ self.health = HealthState.UNHEALTHY
86
+ elif self.consecutive_failures >= 3:
87
+ self.health = HealthState.DEGRADED
88
+
89
+
90
+ @dataclass
91
+ class MCPServerConfig:
92
+ """Configuration for a single MCP server with transport support."""
93
+
94
+ # Required fields (no defaults) - must come first
95
+ name: str
96
+ project_id: str # UUID string for the project this server belongs to
97
+
98
+ # Optional fields with defaults
99
+ enabled: bool = True
100
+
101
+ # Transport configuration
102
+ transport: str = "http" # "http", "stdio", "websocket", "sse"
103
+
104
+ # HTTP/WebSocket/SSE transport
105
+ url: str | None = None
106
+ headers: dict[str, str] | None = None # Custom headers (e.g., API keys)
107
+
108
+ # Stdio transport
109
+ command: str | None = None
110
+ args: list[str] | None = None
111
+ env: dict[str, str] | None = None
112
+
113
+ # OAuth/Auth (for HTTP/WebSocket)
114
+ requires_oauth: bool = False
115
+ oauth_provider: str | None = None # e.g., "google", "github"
116
+
117
+ # Tool metadata (cached summaries)
118
+ tools: list[dict[str, str]] | None = None # [{"name": "tool_name", "description": "..."}]
119
+
120
+ # Server description (what it does, when to use it)
121
+ description: str | None = None
122
+
123
+ # Connection timeout (seconds) for establishing connections
124
+ connect_timeout: float = 30.0
125
+
126
+ def validate(self) -> None:
127
+ """Validate configuration based on transport type."""
128
+ if self.transport in ("http", "websocket", "sse"):
129
+ if not self.url:
130
+ raise ValueError(f"{self.transport} transport requires 'url' parameter")
131
+ elif self.transport == "stdio":
132
+ if not self.command:
133
+ raise ValueError("stdio transport requires 'command' parameter")
134
+ else:
135
+ raise ValueError(f"Unsupported transport: {self.transport}")
136
+
137
+ # Validate connect_timeout is positive
138
+ if self.connect_timeout <= 0:
139
+ raise ValueError("connect_timeout must be a positive number")
@@ -0,0 +1,215 @@
1
+ """Internal registry initialization."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ from collections.abc import Callable
7
+ from typing import TYPE_CHECKING
8
+
9
+ from gobby.mcp_proxy.tools.internal import InternalRegistryManager
10
+
11
+ if TYPE_CHECKING:
12
+ from gobby.agents.runner import AgentRunner
13
+ from gobby.config.app import DaemonConfig
14
+ from gobby.llm.service import LLMService
15
+ from gobby.mcp_proxy.metrics import ToolMetricsManager
16
+ from gobby.mcp_proxy.services.tool_proxy import ToolProxyService
17
+ from gobby.memory.manager import MemoryManager
18
+ from gobby.sessions.manager import SessionManager
19
+ from gobby.storage.merge_resolutions import MergeResolutionManager
20
+ from gobby.storage.session_messages import LocalSessionMessageManager
21
+ from gobby.storage.sessions import LocalSessionManager
22
+ from gobby.storage.tasks import LocalTaskManager
23
+ from gobby.storage.worktrees import LocalWorktreeManager
24
+ from gobby.sync.tasks import TaskSyncManager
25
+ from gobby.tasks.expansion import TaskExpander
26
+ from gobby.tasks.validation import TaskValidator
27
+ from gobby.worktrees.git import WorktreeGitManager
28
+ from gobby.worktrees.merge import MergeResolver
29
+
30
+ logger = logging.getLogger("gobby.mcp.registries")
31
+
32
+
33
+ def setup_internal_registries(
34
+ _config: DaemonConfig | None,
35
+ _session_manager: SessionManager | None = None,
36
+ memory_manager: MemoryManager | None = None,
37
+ task_manager: LocalTaskManager | None = None,
38
+ sync_manager: TaskSyncManager | None = None,
39
+ task_expander: TaskExpander | None = None,
40
+ task_validator: TaskValidator | None = None,
41
+ message_manager: LocalSessionMessageManager | None = None,
42
+ local_session_manager: LocalSessionManager | None = None,
43
+ metrics_manager: ToolMetricsManager | None = None,
44
+ llm_service: LLMService | None = None,
45
+ agent_runner: AgentRunner | None = None,
46
+ worktree_storage: LocalWorktreeManager | None = None,
47
+ git_manager: WorktreeGitManager | None = None,
48
+ merge_storage: MergeResolutionManager | None = None,
49
+ merge_resolver: MergeResolver | None = None,
50
+ project_id: str | None = None,
51
+ tool_proxy_getter: Callable[[], ToolProxyService | None] | None = None,
52
+ ) -> InternalRegistryManager:
53
+ """
54
+ Setup internal MCP registries (tasks, messages, memory, metrics, agents, worktrees).
55
+
56
+ Args:
57
+ _config: Daemon configuration (reserved for future use)
58
+ _session_manager: Session manager (reserved for future use)
59
+ memory_manager: Memory manager for memory operations
60
+ task_manager: Task storage manager
61
+ sync_manager: Task sync manager for git sync
62
+ task_expander: Task expander for AI expansion
63
+ task_validator: Task validator for validation
64
+ message_manager: Message storage manager
65
+ local_session_manager: Local session manager for session CRUD
66
+ metrics_manager: Tool metrics manager for metrics operations
67
+ llm_service: LLM service for AI-powered operations
68
+ agent_runner: Agent runner for spawning subagents
69
+ worktree_storage: Worktree storage manager for worktree operations
70
+ git_manager: Git manager for git worktree operations
71
+ merge_storage: Merge storage manager for conflict resolution
72
+ merge_resolver: Merge resolver for AI resolution
73
+ project_id: Default project ID for worktree operations
74
+ tool_proxy_getter: Callable that returns ToolProxyService for routing
75
+ tool calls in in-process agents. Called lazily during agent execution.
76
+
77
+ Returns:
78
+ InternalRegistryManager containing all registries
79
+ """
80
+ manager = InternalRegistryManager()
81
+
82
+ # Initialize tasks registry if enabled and task_manager is available
83
+ if _config is None:
84
+ gobby_tasks_enabled = False
85
+ logger.warning("Tasks registry not initialized: config is None")
86
+ else:
87
+ gobby_tasks_enabled = _config.get_gobby_tasks_config().enabled
88
+ if not gobby_tasks_enabled:
89
+ logger.debug("Tasks registry disabled by config")
90
+
91
+ if gobby_tasks_enabled:
92
+ if task_manager is None:
93
+ logger.warning("Tasks registry not initialized: task_manager is None")
94
+ elif sync_manager is None:
95
+ logger.warning("Tasks registry not initialized: sync_manager is None")
96
+ else:
97
+ from gobby.mcp_proxy.tools.tasks import create_task_registry
98
+
99
+ tasks_registry = create_task_registry(
100
+ task_manager=task_manager,
101
+ sync_manager=sync_manager,
102
+ task_expander=task_expander,
103
+ task_validator=task_validator,
104
+ config=_config,
105
+ agent_runner=agent_runner,
106
+ worktree_storage=worktree_storage,
107
+ git_manager=git_manager,
108
+ project_id=project_id,
109
+ )
110
+ manager.add_registry(tasks_registry)
111
+ logger.debug("Tasks registry initialized")
112
+
113
+ # Initialize sessions registry (messages + session CRUD)
114
+ # Register if either message_manager or local_session_manager is available
115
+ if message_manager is not None or local_session_manager is not None:
116
+ from gobby.mcp_proxy.tools.session_messages import create_session_messages_registry
117
+
118
+ session_messages_registry = create_session_messages_registry(
119
+ message_manager=message_manager,
120
+ session_manager=local_session_manager,
121
+ )
122
+ manager.add_registry(session_messages_registry)
123
+ logger.debug("Sessions registry initialized")
124
+
125
+ # Initialize memory registry if memory_manager is available
126
+ if memory_manager is not None:
127
+ from gobby.mcp_proxy.tools.memory import create_memory_registry
128
+
129
+ # Set llm_service on memory_manager for remember_with_image support
130
+ if llm_service is not None:
131
+ memory_manager.llm_service = llm_service
132
+
133
+ memory_registry = create_memory_registry(
134
+ memory_manager=memory_manager,
135
+ llm_service=llm_service,
136
+ )
137
+ manager.add_registry(memory_registry)
138
+ logger.debug("Memory registry initialized")
139
+
140
+ # Initialize workflows registry (always available)
141
+ from gobby.mcp_proxy.tools.workflows import create_workflows_registry
142
+
143
+ workflows_registry = create_workflows_registry(
144
+ session_manager=local_session_manager,
145
+ )
146
+ manager.add_registry(workflows_registry)
147
+ logger.debug("Workflows registry initialized")
148
+
149
+ # Initialize metrics registry if metrics_manager is available
150
+ if metrics_manager is not None:
151
+ from gobby.mcp_proxy.tools.metrics import create_metrics_registry
152
+
153
+ metrics_registry = create_metrics_registry(
154
+ metrics_manager=metrics_manager,
155
+ )
156
+ manager.add_registry(metrics_registry)
157
+ logger.debug("Metrics registry initialized")
158
+
159
+ # Initialize agents registry if agent_runner is available
160
+ if agent_runner is not None:
161
+ from gobby.mcp_proxy.tools.agents import create_agents_registry
162
+
163
+ agents_registry = create_agents_registry(
164
+ runner=agent_runner,
165
+ tool_proxy_getter=tool_proxy_getter,
166
+ )
167
+ manager.add_registry(agents_registry)
168
+ logger.debug("Agents registry initialized")
169
+
170
+ # Initialize worktrees registry if worktree_storage is available
171
+ if worktree_storage is not None:
172
+ from gobby.mcp_proxy.tools.worktrees import create_worktrees_registry
173
+
174
+ worktrees_registry = create_worktrees_registry(
175
+ worktree_storage=worktree_storage,
176
+ git_manager=git_manager,
177
+ project_id=project_id,
178
+ agent_runner=agent_runner,
179
+ )
180
+ manager.add_registry(worktrees_registry)
181
+ logger.debug("Worktrees registry initialized")
182
+
183
+ # Initialize merge resolution registry if merge components are available
184
+ if merge_storage is not None and merge_resolver is not None:
185
+ from gobby.mcp_proxy.tools.merge import create_merge_registry
186
+
187
+ merge_registry = create_merge_registry(
188
+ merge_storage=merge_storage,
189
+ merge_resolver=merge_resolver,
190
+ git_manager=git_manager,
191
+ worktree_manager=worktree_storage,
192
+ )
193
+ manager.add_registry(merge_registry)
194
+ logger.debug("Merge registry initialized")
195
+
196
+ # Initialize hub registry (cross-project queries) if config has database_path
197
+ if _config is not None and hasattr(_config, "database_path"):
198
+ from pathlib import Path
199
+
200
+ from gobby.mcp_proxy.tools.hub import create_hub_registry
201
+
202
+ hub_db_path = Path(_config.database_path).expanduser()
203
+ hub_registry = create_hub_registry(hub_db_path=hub_db_path)
204
+ manager.add_registry(hub_registry)
205
+ logger.debug("Hub registry initialized")
206
+
207
+ logger.info(f"Internal registries initialized: {len(manager)} registries")
208
+ return manager
209
+
210
+
211
+ # Re-export for convenience
212
+ __all__ = [
213
+ "setup_internal_registries",
214
+ "InternalRegistryManager",
215
+ ]