gobby 0.2.5__py3-none-any.whl → 0.2.7__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 (244) hide show
  1. gobby/__init__.py +1 -1
  2. gobby/adapters/__init__.py +2 -1
  3. gobby/adapters/claude_code.py +13 -4
  4. gobby/adapters/codex_impl/__init__.py +28 -0
  5. gobby/adapters/codex_impl/adapter.py +722 -0
  6. gobby/adapters/codex_impl/client.py +679 -0
  7. gobby/adapters/codex_impl/protocol.py +20 -0
  8. gobby/adapters/codex_impl/types.py +68 -0
  9. gobby/agents/definitions.py +11 -1
  10. gobby/agents/isolation.py +395 -0
  11. gobby/agents/runner.py +8 -0
  12. gobby/agents/sandbox.py +261 -0
  13. gobby/agents/spawn.py +42 -287
  14. gobby/agents/spawn_executor.py +385 -0
  15. gobby/agents/spawners/__init__.py +24 -0
  16. gobby/agents/spawners/command_builder.py +189 -0
  17. gobby/agents/spawners/embedded.py +21 -2
  18. gobby/agents/spawners/headless.py +21 -2
  19. gobby/agents/spawners/prompt_manager.py +125 -0
  20. gobby/cli/__init__.py +6 -0
  21. gobby/cli/clones.py +419 -0
  22. gobby/cli/conductor.py +266 -0
  23. gobby/cli/install.py +4 -4
  24. gobby/cli/installers/antigravity.py +3 -9
  25. gobby/cli/installers/claude.py +15 -9
  26. gobby/cli/installers/codex.py +2 -8
  27. gobby/cli/installers/gemini.py +8 -8
  28. gobby/cli/installers/shared.py +175 -13
  29. gobby/cli/sessions.py +1 -1
  30. gobby/cli/skills.py +858 -0
  31. gobby/cli/tasks/ai.py +0 -440
  32. gobby/cli/tasks/crud.py +44 -6
  33. gobby/cli/tasks/main.py +0 -4
  34. gobby/cli/tui.py +2 -2
  35. gobby/cli/utils.py +12 -5
  36. gobby/clones/__init__.py +13 -0
  37. gobby/clones/git.py +547 -0
  38. gobby/conductor/__init__.py +16 -0
  39. gobby/conductor/alerts.py +135 -0
  40. gobby/conductor/loop.py +164 -0
  41. gobby/conductor/monitors/__init__.py +11 -0
  42. gobby/conductor/monitors/agents.py +116 -0
  43. gobby/conductor/monitors/tasks.py +155 -0
  44. gobby/conductor/pricing.py +234 -0
  45. gobby/conductor/token_tracker.py +160 -0
  46. gobby/config/__init__.py +12 -97
  47. gobby/config/app.py +69 -91
  48. gobby/config/extensions.py +2 -2
  49. gobby/config/features.py +7 -130
  50. gobby/config/search.py +110 -0
  51. gobby/config/servers.py +1 -1
  52. gobby/config/skills.py +43 -0
  53. gobby/config/tasks.py +9 -41
  54. gobby/hooks/__init__.py +0 -13
  55. gobby/hooks/event_handlers.py +188 -2
  56. gobby/hooks/hook_manager.py +50 -4
  57. gobby/hooks/plugins.py +1 -1
  58. gobby/hooks/skill_manager.py +130 -0
  59. gobby/hooks/webhooks.py +1 -1
  60. gobby/install/claude/hooks/hook_dispatcher.py +4 -4
  61. gobby/install/codex/hooks/hook_dispatcher.py +1 -1
  62. gobby/install/gemini/hooks/hook_dispatcher.py +87 -12
  63. gobby/llm/claude.py +22 -34
  64. gobby/llm/claude_executor.py +46 -256
  65. gobby/llm/codex_executor.py +59 -291
  66. gobby/llm/executor.py +21 -0
  67. gobby/llm/gemini.py +134 -110
  68. gobby/llm/litellm_executor.py +143 -6
  69. gobby/llm/resolver.py +98 -35
  70. gobby/mcp_proxy/importer.py +62 -4
  71. gobby/mcp_proxy/instructions.py +56 -0
  72. gobby/mcp_proxy/models.py +15 -0
  73. gobby/mcp_proxy/registries.py +68 -8
  74. gobby/mcp_proxy/server.py +33 -3
  75. gobby/mcp_proxy/services/recommendation.py +43 -11
  76. gobby/mcp_proxy/services/tool_proxy.py +81 -1
  77. gobby/mcp_proxy/stdio.py +2 -1
  78. gobby/mcp_proxy/tools/__init__.py +0 -2
  79. gobby/mcp_proxy/tools/agent_messaging.py +317 -0
  80. gobby/mcp_proxy/tools/agents.py +31 -731
  81. gobby/mcp_proxy/tools/clones.py +518 -0
  82. gobby/mcp_proxy/tools/memory.py +3 -26
  83. gobby/mcp_proxy/tools/metrics.py +65 -1
  84. gobby/mcp_proxy/tools/orchestration/__init__.py +3 -0
  85. gobby/mcp_proxy/tools/orchestration/cleanup.py +151 -0
  86. gobby/mcp_proxy/tools/orchestration/wait.py +467 -0
  87. gobby/mcp_proxy/tools/sessions/__init__.py +14 -0
  88. gobby/mcp_proxy/tools/sessions/_commits.py +232 -0
  89. gobby/mcp_proxy/tools/sessions/_crud.py +253 -0
  90. gobby/mcp_proxy/tools/sessions/_factory.py +63 -0
  91. gobby/mcp_proxy/tools/sessions/_handoff.py +499 -0
  92. gobby/mcp_proxy/tools/sessions/_messages.py +138 -0
  93. gobby/mcp_proxy/tools/skills/__init__.py +616 -0
  94. gobby/mcp_proxy/tools/spawn_agent.py +417 -0
  95. gobby/mcp_proxy/tools/task_orchestration.py +7 -0
  96. gobby/mcp_proxy/tools/task_readiness.py +14 -0
  97. gobby/mcp_proxy/tools/task_sync.py +1 -1
  98. gobby/mcp_proxy/tools/tasks/_context.py +0 -20
  99. gobby/mcp_proxy/tools/tasks/_crud.py +91 -4
  100. gobby/mcp_proxy/tools/tasks/_expansion.py +348 -0
  101. gobby/mcp_proxy/tools/tasks/_factory.py +6 -16
  102. gobby/mcp_proxy/tools/tasks/_lifecycle.py +110 -45
  103. gobby/mcp_proxy/tools/tasks/_lifecycle_validation.py +18 -29
  104. gobby/mcp_proxy/tools/workflows.py +1 -1
  105. gobby/mcp_proxy/tools/worktrees.py +0 -338
  106. gobby/memory/backends/__init__.py +6 -1
  107. gobby/memory/backends/mem0.py +6 -1
  108. gobby/memory/extractor.py +477 -0
  109. gobby/memory/ingestion/__init__.py +5 -0
  110. gobby/memory/ingestion/multimodal.py +221 -0
  111. gobby/memory/manager.py +73 -285
  112. gobby/memory/search/__init__.py +10 -0
  113. gobby/memory/search/coordinator.py +248 -0
  114. gobby/memory/services/__init__.py +5 -0
  115. gobby/memory/services/crossref.py +142 -0
  116. gobby/prompts/loader.py +5 -2
  117. gobby/runner.py +37 -16
  118. gobby/search/__init__.py +48 -6
  119. gobby/search/backends/__init__.py +159 -0
  120. gobby/search/backends/embedding.py +225 -0
  121. gobby/search/embeddings.py +238 -0
  122. gobby/search/models.py +148 -0
  123. gobby/search/unified.py +496 -0
  124. gobby/servers/http.py +24 -12
  125. gobby/servers/routes/admin.py +294 -0
  126. gobby/servers/routes/mcp/endpoints/__init__.py +61 -0
  127. gobby/servers/routes/mcp/endpoints/discovery.py +405 -0
  128. gobby/servers/routes/mcp/endpoints/execution.py +568 -0
  129. gobby/servers/routes/mcp/endpoints/registry.py +378 -0
  130. gobby/servers/routes/mcp/endpoints/server.py +304 -0
  131. gobby/servers/routes/mcp/hooks.py +1 -1
  132. gobby/servers/routes/mcp/tools.py +48 -1317
  133. gobby/servers/websocket.py +2 -2
  134. gobby/sessions/analyzer.py +2 -0
  135. gobby/sessions/lifecycle.py +1 -1
  136. gobby/sessions/processor.py +10 -0
  137. gobby/sessions/transcripts/base.py +2 -0
  138. gobby/sessions/transcripts/claude.py +79 -10
  139. gobby/skills/__init__.py +91 -0
  140. gobby/skills/loader.py +685 -0
  141. gobby/skills/manager.py +384 -0
  142. gobby/skills/parser.py +286 -0
  143. gobby/skills/search.py +463 -0
  144. gobby/skills/sync.py +119 -0
  145. gobby/skills/updater.py +385 -0
  146. gobby/skills/validator.py +368 -0
  147. gobby/storage/clones.py +378 -0
  148. gobby/storage/database.py +1 -1
  149. gobby/storage/memories.py +43 -13
  150. gobby/storage/migrations.py +162 -201
  151. gobby/storage/sessions.py +116 -7
  152. gobby/storage/skills.py +782 -0
  153. gobby/storage/tasks/_crud.py +4 -4
  154. gobby/storage/tasks/_lifecycle.py +57 -7
  155. gobby/storage/tasks/_manager.py +14 -5
  156. gobby/storage/tasks/_models.py +8 -3
  157. gobby/sync/memories.py +40 -5
  158. gobby/sync/tasks.py +83 -6
  159. gobby/tasks/__init__.py +1 -2
  160. gobby/tasks/external_validator.py +1 -1
  161. gobby/tasks/validation.py +46 -35
  162. gobby/tools/summarizer.py +91 -10
  163. gobby/tui/api_client.py +4 -7
  164. gobby/tui/app.py +5 -3
  165. gobby/tui/screens/orchestrator.py +1 -2
  166. gobby/tui/screens/tasks.py +2 -4
  167. gobby/tui/ws_client.py +1 -1
  168. gobby/utils/daemon_client.py +2 -2
  169. gobby/utils/project_context.py +2 -3
  170. gobby/utils/status.py +13 -0
  171. gobby/workflows/actions.py +221 -1135
  172. gobby/workflows/artifact_actions.py +31 -0
  173. gobby/workflows/autonomous_actions.py +11 -0
  174. gobby/workflows/context_actions.py +93 -1
  175. gobby/workflows/detection_helpers.py +115 -31
  176. gobby/workflows/enforcement/__init__.py +47 -0
  177. gobby/workflows/enforcement/blocking.py +269 -0
  178. gobby/workflows/enforcement/commit_policy.py +283 -0
  179. gobby/workflows/enforcement/handlers.py +269 -0
  180. gobby/workflows/{task_enforcement_actions.py → enforcement/task_policy.py} +29 -388
  181. gobby/workflows/engine.py +13 -2
  182. gobby/workflows/git_utils.py +106 -0
  183. gobby/workflows/lifecycle_evaluator.py +29 -1
  184. gobby/workflows/llm_actions.py +30 -0
  185. gobby/workflows/loader.py +19 -6
  186. gobby/workflows/mcp_actions.py +20 -1
  187. gobby/workflows/memory_actions.py +154 -0
  188. gobby/workflows/safe_evaluator.py +183 -0
  189. gobby/workflows/session_actions.py +44 -0
  190. gobby/workflows/state_actions.py +60 -1
  191. gobby/workflows/stop_signal_actions.py +55 -0
  192. gobby/workflows/summary_actions.py +111 -1
  193. gobby/workflows/task_sync_actions.py +347 -0
  194. gobby/workflows/todo_actions.py +34 -1
  195. gobby/workflows/webhook_actions.py +185 -0
  196. {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/METADATA +87 -21
  197. {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/RECORD +201 -172
  198. {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/WHEEL +1 -1
  199. gobby/adapters/codex.py +0 -1292
  200. gobby/install/claude/commands/gobby/bug.md +0 -51
  201. gobby/install/claude/commands/gobby/chore.md +0 -51
  202. gobby/install/claude/commands/gobby/epic.md +0 -52
  203. gobby/install/claude/commands/gobby/eval.md +0 -235
  204. gobby/install/claude/commands/gobby/feat.md +0 -49
  205. gobby/install/claude/commands/gobby/nit.md +0 -52
  206. gobby/install/claude/commands/gobby/ref.md +0 -52
  207. gobby/install/codex/prompts/forget.md +0 -7
  208. gobby/install/codex/prompts/memories.md +0 -7
  209. gobby/install/codex/prompts/recall.md +0 -7
  210. gobby/install/codex/prompts/remember.md +0 -13
  211. gobby/llm/gemini_executor.py +0 -339
  212. gobby/mcp_proxy/tools/session_messages.py +0 -1056
  213. gobby/mcp_proxy/tools/task_expansion.py +0 -591
  214. gobby/prompts/defaults/expansion/system.md +0 -119
  215. gobby/prompts/defaults/expansion/user.md +0 -48
  216. gobby/prompts/defaults/external_validation/agent.md +0 -72
  217. gobby/prompts/defaults/external_validation/external.md +0 -63
  218. gobby/prompts/defaults/external_validation/spawn.md +0 -83
  219. gobby/prompts/defaults/external_validation/system.md +0 -6
  220. gobby/prompts/defaults/features/import_mcp.md +0 -22
  221. gobby/prompts/defaults/features/import_mcp_github.md +0 -17
  222. gobby/prompts/defaults/features/import_mcp_search.md +0 -16
  223. gobby/prompts/defaults/features/recommend_tools.md +0 -32
  224. gobby/prompts/defaults/features/recommend_tools_hybrid.md +0 -35
  225. gobby/prompts/defaults/features/recommend_tools_llm.md +0 -30
  226. gobby/prompts/defaults/features/server_description.md +0 -20
  227. gobby/prompts/defaults/features/server_description_system.md +0 -6
  228. gobby/prompts/defaults/features/task_description.md +0 -31
  229. gobby/prompts/defaults/features/task_description_system.md +0 -6
  230. gobby/prompts/defaults/features/tool_summary.md +0 -17
  231. gobby/prompts/defaults/features/tool_summary_system.md +0 -6
  232. gobby/prompts/defaults/research/step.md +0 -58
  233. gobby/prompts/defaults/validation/criteria.md +0 -47
  234. gobby/prompts/defaults/validation/validate.md +0 -38
  235. gobby/storage/migrations_legacy.py +0 -1359
  236. gobby/tasks/context.py +0 -747
  237. gobby/tasks/criteria.py +0 -342
  238. gobby/tasks/expansion.py +0 -626
  239. gobby/tasks/prompts/expand.py +0 -327
  240. gobby/tasks/research.py +0 -421
  241. gobby/tasks/tdd.py +0 -352
  242. {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/entry_points.txt +0 -0
  243. {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/licenses/LICENSE.md +0 -0
  244. {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/top_level.txt +0 -0
gobby/config/features.py CHANGED
@@ -42,45 +42,22 @@ class ToolSummarizerConfig(BaseModel):
42
42
  default="claude-haiku-4-5",
43
43
  description="Model to use for summarization (fast/cheap recommended)",
44
44
  )
45
- prompt: str = Field(
46
- default="""Summarize this MCP tool description in 180 characters or less.
47
- Keep it to three sentences or less. Be concise and preserve the key functionality.
48
- Do not add quotes, extra formatting, or code examples.
49
45
 
50
- Description: {description}
51
-
52
- Summary:""",
53
- description="DEPRECATED: Use prompt_path instead. Prompt template for tool description summarization",
54
- )
55
46
  prompt_path: str | None = Field(
56
47
  default=None,
57
48
  description="Path to custom tool summary prompt template (e.g., 'features/tool_summary')",
58
49
  )
59
- system_prompt: str = Field(
60
- default="You are a technical summarizer. Create concise tool descriptions.",
61
- description="DEPRECATED: Use system_prompt_path instead. System prompt for tool description summarization",
62
- )
50
+
63
51
  system_prompt_path: str | None = Field(
64
52
  default=None,
65
53
  description="Path to custom tool summary system prompt (e.g., 'features/tool_summary_system')",
66
54
  )
67
- server_description_prompt: str = Field(
68
- default="""Write a single concise sentence describing what the '{server_name}' MCP server does based on its tools.
69
55
 
70
- Tools:
71
- {tools_list}
72
-
73
- Description (1 sentence, try to keep under 100 characters):""",
74
- description="DEPRECATED: Use server_description_prompt_path instead. Prompt template for server description generation",
75
- )
76
56
  server_description_prompt_path: str | None = Field(
77
57
  default=None,
78
58
  description="Path to custom server description prompt (e.g., 'features/server_description')",
79
59
  )
80
- server_description_system_prompt: str = Field(
81
- default="You write concise technical descriptions.",
82
- description="DEPRECATED: Use server_description_system_prompt_path instead. System prompt for server description generation",
83
- )
60
+
84
61
  server_description_system_prompt_path: str | None = Field(
85
62
  default=None,
86
63
  description="Path to custom server description system prompt (e.g., 'features/server_description_system')",
@@ -110,26 +87,12 @@ class TaskDescriptionConfig(BaseModel):
110
87
  default=50,
111
88
  description="Minimum length of structured extraction before LLM fallback triggers",
112
89
  )
113
- prompt: str = Field(
114
- default="""Generate a concise task description for this task from a spec document.
115
-
116
- Task title: {task_title}
117
- Section: {section_title}
118
- Section content: {section_content}
119
- Existing context: {existing_context}
120
90
 
121
- Write a 1-2 sentence description focusing on the goal and deliverable.
122
- Do not add quotes, extra formatting, or implementation details.""",
123
- description="DEPRECATED: Use prompt_path instead. Prompt template for task description generation",
124
- )
125
91
  prompt_path: str | None = Field(
126
92
  default=None,
127
93
  description="Path to custom task description prompt (e.g., 'features/task_description')",
128
94
  )
129
- system_prompt: str = Field(
130
- default="You are a technical writer creating concise task descriptions for developers.",
131
- description="DEPRECATED: Use system_prompt_path instead. System prompt for task description generation",
132
- )
95
+
133
96
  system_prompt_path: str | None = Field(
134
97
  default=None,
135
98
  description="Path to custom task description system prompt (e.g., 'features/task_description_system')",
@@ -159,83 +122,17 @@ class RecommendToolsConfig(BaseModel):
159
122
  default="claude-sonnet-4-5",
160
123
  description="Model to use for tool recommendations",
161
124
  )
162
- prompt: str = Field(
163
- default="""You are a tool recommendation assistant for Claude Code with access to MCP servers.
164
-
165
- CRITICAL PRIORITIZATION RULES:
166
- 1. Analyze the task type (code navigation, docs lookup, database query, planning, data processing, etc.)
167
- 2. Check available MCP server DESCRIPTIONS for capability matches
168
- 3. If ANY MCP server's description matches the task type -> recommend those tools FIRST
169
- 4. Only recommend built-in Claude Code tools (Grep, Read, Bash, WebSearch) if NO suitable MCP server exists
170
-
171
- TASK TYPE MATCHING GUIDELINES:
172
- - Task needs library/framework documentation -> Look for MCP servers describing "documentation", "library docs", "API reference"
173
- - Task needs code navigation/architecture understanding -> Look for MCP servers describing "code analysis", "symbols", "semantic search"
174
- - Task needs database operations -> Look for MCP servers describing "database", "PostgreSQL", "SQL"
175
- - Task needs complex reasoning/planning -> Look for MCP servers describing "problem-solving", "thinking", "reasoning"
176
- - Task needs data processing/large datasets -> Look for MCP servers describing "code execution", "data processing", "token optimization"
177
-
178
- ANTI-PATTERNS (What NOT to recommend):
179
- - Don't recommend WebSearch when an MCP server provides library/framework documentation
180
- - Don't recommend Grep/Read for code architecture questions when an MCP server does semantic code analysis
181
- - Don't recommend Bash for database queries when an MCP server provides database tools
182
- - Don't recommend direct implementation when an MCP server provides structured reasoning
183
-
184
- OUTPUT FORMAT:
185
- Be concise and specific. Recommend 1-3 tools maximum with:
186
- 1. Which MCP server and tools to use (if applicable)
187
- 2. Brief rationale based on server description matching task type
188
- 3. Suggested workflow (e.g., "First call X, then use result with Y")
189
- 4. Only mention built-in tools if no MCP server is suitable""",
190
- description="DEPRECATED: Use prompt_path instead. System prompt for recommend_tools() MCP tool.",
191
- )
125
+
192
126
  prompt_path: str | None = Field(
193
127
  default=None,
194
128
  description="Path to custom recommend tools system prompt (e.g., 'features/recommend_tools')",
195
129
  )
196
- hybrid_rerank_prompt: str = Field(
197
- default="""You are an expert at selecting tools for tasks.
198
- Task: {task_description}
199
-
200
- Candidate tools (ranked by semantic similarity):
201
- {candidate_list}
202
-
203
- Re-rank these tools by relevance to the task and provide reasoning.
204
- Return the top {top_k} most relevant as JSON:
205
- {{
206
- "recommendations": [
207
- {{
208
- "server": "server_name",
209
- "tool": "tool_name",
210
- "reason": "Why this tool is the best choice"
211
- }}
212
- ]
213
- }}""",
214
- description="DEPRECATED: Use hybrid_rerank_prompt_path instead. Prompt template for hybrid mode re-ranking",
215
- )
130
+
216
131
  hybrid_rerank_prompt_path: str | None = Field(
217
132
  default=None,
218
133
  description="Path to custom hybrid re-rank prompt (e.g., 'features/recommend_tools_hybrid')",
219
134
  )
220
- llm_prompt: str = Field(
221
- default="""You are an expert at selecting the right tools for a given task.
222
- Task: {task_description}
223
-
224
- Available Servers: {available_servers}
225
-
226
- Please recommend which tools from these servers would be most useful for this task.
227
- Return a JSON object with this structure:
228
- {{
229
- "recommendations": [
230
- {{
231
- "server": "server_name",
232
- "tool": "tool_name",
233
- "reason": "Why this tool is useful"
234
- }}
235
- ]
236
- }}""",
237
- description="DEPRECATED: Use llm_prompt_path instead. Prompt template for LLM mode recommendations",
238
- )
135
+
239
136
  llm_prompt_path: str | None = Field(
240
137
  default=None,
241
138
  description="Path to custom LLM recommendation prompt (e.g., 'features/recommend_tools_llm')",
@@ -276,37 +173,17 @@ class ImportMCPServerConfig(BaseModel):
276
173
  default="claude-haiku-4-5",
277
174
  description="Model to use for config extraction",
278
175
  )
279
- prompt: str = Field(
280
- default=DEFAULT_IMPORT_MCP_SERVER_PROMPT,
281
- description="DEPRECATED: Use prompt_path instead. System prompt for MCP server config extraction",
282
- )
176
+
283
177
  prompt_path: str | None = Field(
284
178
  default=None,
285
179
  description="Path to custom import MCP system prompt (e.g., 'features/import_mcp')",
286
180
  )
287
- github_fetch_prompt: str = Field(
288
- default="""Fetch the README from this GitHub repository and extract MCP server configuration:
289
-
290
- {github_url}
291
-
292
- If the URL doesn't point directly to a README, try to find and fetch the README.md file.
293
181
 
294
- After reading the documentation, extract the MCP server configuration as a JSON object.""",
295
- description="DEPRECATED: Use github_fetch_prompt_path instead. User prompt template for GitHub import",
296
- )
297
182
  github_fetch_prompt_path: str | None = Field(
298
183
  default=None,
299
184
  description="Path to custom GitHub fetch prompt (e.g., 'features/import_mcp_github')",
300
185
  )
301
- search_fetch_prompt: str = Field(
302
- default="""Search for MCP server: {search_query}
303
-
304
- Find the official documentation or GitHub repository for this MCP server.
305
- Then fetch and read the README or installation docs.
306
186
 
307
- After reading the documentation, extract the MCP server configuration as a JSON object.""",
308
- description="DEPRECATED: Use search_fetch_prompt_path instead. User prompt template for search-based import",
309
- )
310
187
  search_fetch_prompt_path: str | None = Field(
311
188
  default=None,
312
189
  description="Path to custom search fetch prompt (e.g., 'features/import_mcp_search')",
gobby/config/search.py ADDED
@@ -0,0 +1,110 @@
1
+ """Search configuration for Gobby daemon.
2
+
3
+ Provides configuration for the unified search layer with embedding
4
+ support and TF-IDF fallback.
5
+
6
+ Example usage in config.yaml:
7
+ search:
8
+ mode: auto # tfidf, embedding, auto, hybrid
9
+ embedding_model: text-embedding-3-small
10
+ tfidf_weight: 0.4
11
+ embedding_weight: 0.6
12
+ notify_on_fallback: true
13
+
14
+ For Ollama (local embeddings):
15
+ search:
16
+ mode: auto
17
+ embedding_model: openai/nomic-embed-text
18
+ embedding_api_base: http://localhost:11434/v1
19
+ """
20
+
21
+ from pydantic import BaseModel, Field
22
+
23
+ from gobby.search.models import SearchMode
24
+
25
+
26
+ class SearchConfig(BaseModel):
27
+ """Configuration for unified search with fallback.
28
+
29
+ This config controls how UnifiedSearcher behaves, including:
30
+ - Which search mode to use (tfidf, embedding, auto, hybrid)
31
+ - Which embedding model to use (LiteLLM format)
32
+ - Weights for hybrid mode
33
+ - Whether to notify on fallback
34
+
35
+ Supported modes:
36
+ - tfidf: TF-IDF only (always works, no API needed)
37
+ - embedding: Embedding-based search only (fails if unavailable)
38
+ - auto: Try embedding, fallback to TF-IDF if unavailable
39
+ - hybrid: Combine both with weighted scores
40
+
41
+ LiteLLM model format examples:
42
+ - OpenAI: text-embedding-3-small (needs OPENAI_API_KEY)
43
+ - Ollama: openai/nomic-embed-text (with embedding_api_base)
44
+ - Azure: azure/azure-embedding-model
45
+ - Vertex AI: vertex_ai/text-embedding-004
46
+ - Gemini: gemini/text-embedding-004 (needs GEMINI_API_KEY)
47
+ - Mistral: mistral/mistral-embed (needs MISTRAL_API_KEY)
48
+ """
49
+
50
+ mode: str = Field(
51
+ default="auto",
52
+ description="Search mode: tfidf, embedding, auto, hybrid",
53
+ )
54
+ embedding_model: str = Field(
55
+ default="text-embedding-3-small",
56
+ description="LiteLLM model string (e.g., text-embedding-3-small, openai/nomic-embed-text)",
57
+ )
58
+ embedding_api_base: str | None = Field(
59
+ default=None,
60
+ description="API base URL for Ollama/custom endpoints (e.g., http://localhost:11434/v1)",
61
+ )
62
+ embedding_api_key: str | None = Field(
63
+ default=None,
64
+ description="API key for embedding provider (uses env var if not set)",
65
+ )
66
+ tfidf_weight: float = Field(
67
+ default=0.4,
68
+ ge=0.0,
69
+ le=1.0,
70
+ description="Weight for TF-IDF scores in hybrid mode",
71
+ )
72
+ embedding_weight: float = Field(
73
+ default=0.6,
74
+ ge=0.0,
75
+ le=1.0,
76
+ description="Weight for embedding scores in hybrid mode",
77
+ )
78
+ notify_on_fallback: bool = Field(
79
+ default=True,
80
+ description="Log warning when falling back to TF-IDF",
81
+ )
82
+
83
+ def get_normalized_weights(self) -> tuple[float, float]:
84
+ """Get normalized weights that sum to 1.0.
85
+
86
+ Returns:
87
+ Tuple of (tfidf_weight, embedding_weight) normalized to sum to 1.0
88
+ """
89
+ total = self.tfidf_weight + self.embedding_weight
90
+ if total == 0:
91
+ # Default to equal weights if both are 0
92
+ return (0.5, 0.5)
93
+ return (self.tfidf_weight / total, self.embedding_weight / total)
94
+
95
+ def get_mode_enum(self) -> SearchMode:
96
+ """Get the SearchMode enum instance for the configured mode.
97
+
98
+ Returns:
99
+ SearchMode enum corresponding to the mode string value
100
+
101
+ Raises:
102
+ ValueError: If the configured mode is not a valid SearchMode
103
+ """
104
+ try:
105
+ return SearchMode(self.mode)
106
+ except ValueError as e:
107
+ valid_modes = [m.value for m in SearchMode]
108
+ raise ValueError(
109
+ f"Invalid search mode '{self.mode}'. Valid modes are: {', '.join(valid_modes)}"
110
+ ) from e
gobby/config/servers.py CHANGED
@@ -23,7 +23,7 @@ class WebSocketSettings(BaseModel):
23
23
  description="Enable WebSocket server for real-time communication",
24
24
  )
25
25
  port: int = Field(
26
- default=8766,
26
+ default=60888,
27
27
  description="Port for WebSocket server to listen on",
28
28
  )
29
29
  ping_interval: int = Field(
gobby/config/skills.py ADDED
@@ -0,0 +1,43 @@
1
+ """
2
+ Skills configuration for Gobby daemon.
3
+
4
+ Provides configuration for skill injection and discovery.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import Literal
10
+
11
+ from pydantic import BaseModel, Field, field_validator
12
+
13
+
14
+ class SkillsConfig(BaseModel):
15
+ """
16
+ Configuration for skill injection and discovery.
17
+
18
+ Controls whether and how skills are injected into session context.
19
+ """
20
+
21
+ inject_core_skills: bool = Field(
22
+ default=True,
23
+ description="Whether to inject core skills into session context",
24
+ )
25
+
26
+ core_skills_path: str | None = Field(
27
+ default=None,
28
+ description="Override path for core skills (default: install/shared/skills/)",
29
+ )
30
+
31
+ injection_format: Literal["summary", "full", "none"] = Field(
32
+ default="summary",
33
+ description="Format for skill injection: 'summary' (names only), 'full' (with content), 'none' (disabled)",
34
+ )
35
+
36
+ @field_validator("injection_format")
37
+ @classmethod
38
+ def validate_injection_format(cls, v: str) -> str:
39
+ """Validate injection_format is one of the allowed values."""
40
+ allowed = {"summary", "full", "none"}
41
+ if v not in allowed:
42
+ raise ValueError(f"injection_format must be one of {allowed}, got '{v}'")
43
+ return v
gobby/config/tasks.py CHANGED
@@ -38,14 +38,6 @@ class CompactHandoffConfig(BaseModel):
38
38
  default=True,
39
39
  description="Enable compact handoff context extraction and injection",
40
40
  )
41
- # DEPRECATED: prompt field is no longer used.
42
- # Template is now defined in session-handoff.yaml workflow file.
43
- # Kept for backwards compatibility but will be removed in a future version.
44
- prompt: str | None = Field(
45
- default=None,
46
- description="DEPRECATED: Template moved to session-handoff.yaml workflow. "
47
- "This field is ignored.",
48
- )
49
41
 
50
42
 
51
43
  class PatternCriteriaConfig(BaseModel):
@@ -147,10 +139,7 @@ class TaskExpansionConfig(BaseModel):
147
139
  default="claude-opus-4-5",
148
140
  description="Model to use for expansion",
149
141
  )
150
- prompt: str | None = Field(
151
- default=None,
152
- description="DEPRECATED: Use prompt_path instead. Custom prompt template for task expansion",
153
- )
142
+
154
143
  prompt_path: str | None = Field(
155
144
  default=None,
156
145
  description="Path to custom user prompt template (e.g., 'expansion/user')",
@@ -175,22 +164,11 @@ class TaskExpansionConfig(BaseModel):
175
164
  default="You are a senior developer researching a codebase. Use tools to find relevant code.",
176
165
  description="System prompt for the research agent",
177
166
  )
178
- system_prompt: str | None = Field(
179
- default=None,
180
- description="DEPRECATED: Use system_prompt_path instead. Custom system prompt for task expansion",
181
- )
182
- tdd_prompt: str | None = Field(
183
- default=None,
184
- description="DEPRECATED: TDD mode is now integrated into the system prompt template via Jinja2 conditionals",
185
- )
167
+
186
168
  web_research_enabled: bool = Field(
187
169
  default=True,
188
170
  description="Enable web research for task expansion using MCP tools",
189
171
  )
190
- tdd_mode: bool = Field(
191
- default=True,
192
- description="Enable TDD mode: create test->implement task pairs with appropriate blocking for coding tasks",
193
- )
194
172
  max_subtasks: int = Field(
195
173
  default=15,
196
174
  description="Maximum number of subtasks to create per expansion",
@@ -232,10 +210,7 @@ class TaskValidationConfig(BaseModel):
232
210
  default="You are a QA validator. Output ONLY valid JSON. No markdown, no explanation, no code blocks. Just the raw JSON object.",
233
211
  description="System prompt for task validation",
234
212
  )
235
- prompt: str | None = Field(
236
- default=None,
237
- description="DEPRECATED: Use prompt_path instead. Custom prompt template for task validation",
238
- )
213
+
239
214
  prompt_path: str | None = Field(
240
215
  default=None,
241
216
  description="Path to custom validation prompt template (e.g., 'validation/validate')",
@@ -264,10 +239,7 @@ class TaskValidationConfig(BaseModel):
264
239
  default="You are a QA engineer writing acceptance criteria. CRITICAL: Only include requirements explicitly stated in the task. Do NOT invent specific values, thresholds, timeouts, or edge cases that aren't mentioned. Vague tasks get vague criteria. Use markdown checkboxes.",
265
240
  description="System prompt for generating validation criteria",
266
241
  )
267
- criteria_prompt: str | None = Field(
268
- default=None,
269
- description="DEPRECATED: Use criteria_prompt_path instead. Custom prompt template for generating validation criteria",
270
- )
242
+
271
243
  # Validation loop control
272
244
  max_iterations: int = Field(
273
245
  default=10,
@@ -724,10 +696,6 @@ class WorkflowVariablesConfig(BaseModel):
724
696
  default=False,
725
697
  description="Require an active task (in_progress) before allowing file edits",
726
698
  )
727
- tdd_mode: bool = Field(
728
- default=True,
729
- description="Enable TDD mode for task expansion (test-implementation pairs)",
730
- )
731
699
  session_task: str | list[str] | None = Field(
732
700
  default=None,
733
701
  description="Task(s) to complete before stopping. "
@@ -759,13 +727,13 @@ def merge_workflow_variables(
759
727
  ValidationError: If validate=True and merged values fail validation.
760
728
 
761
729
  Example:
762
- >>> yaml_defaults = {"tdd_mode": True, "require_task_before_edit": False}
763
- >>> db_overrides = {"tdd_mode": False}
730
+ >>> yaml_defaults = {"require_task_before_edit": False, "session_task": None}
731
+ >>> db_overrides = {"require_task_before_edit": True}
764
732
  >>> effective = merge_workflow_variables(yaml_defaults, db_overrides)
765
- >>> effective["tdd_mode"]
766
- False
767
733
  >>> effective["require_task_before_edit"]
768
- False
734
+ True
735
+ >>> effective["session_task"]
736
+ None
769
737
  """
770
738
  # Start with defaults
771
739
  effective = dict(yaml_defaults)
gobby/hooks/__init__.py CHANGED
@@ -65,14 +65,6 @@ from gobby.hooks.plugins import (
65
65
  from gobby.hooks.session_coordinator import SessionCoordinator
66
66
  from gobby.hooks.webhooks import WebhookDispatcher
67
67
 
68
- # Legacy imports for backward compatibility
69
- from gobby.sessions.manager import SessionManager
70
- from gobby.sessions.summary import SummaryFileGenerator
71
- from gobby.sessions.transcripts.claude import ClaudeTranscriptParser
72
-
73
- # Backward-compatible alias
74
- TranscriptProcessor = ClaudeTranscriptParser
75
-
76
68
  __all__ = [
77
69
  # Core coordinator
78
70
  "HookManager",
@@ -96,9 +88,4 @@ __all__ = [
96
88
  "RegisteredHandler",
97
89
  "hook_handler",
98
90
  "run_plugin_handlers",
99
- # Legacy exports (backward compatibility)
100
- "SessionManager",
101
- "SummaryFileGenerator",
102
- "TranscriptProcessor",
103
- "ClaudeTranscriptParser",
104
91
  ]