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
@@ -0,0 +1,185 @@
1
+ """Webhook workflow actions.
2
+
3
+ Extracted from actions.py as part of strangler fig decomposition.
4
+ These functions handle webhook HTTP request execution from workflows.
5
+ """
6
+
7
+ import logging
8
+ from typing import TYPE_CHECKING, Any
9
+ from urllib.parse import urlparse, urlunparse
10
+
11
+ if TYPE_CHECKING:
12
+ from gobby.workflows.definitions import WorkflowState
13
+ from gobby.workflows.templates import TemplateEngine
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ async def execute_webhook(
19
+ template_engine: "TemplateEngine",
20
+ state: "WorkflowState",
21
+ config: Any | None,
22
+ url: str | None = None,
23
+ webhook_id: str | None = None,
24
+ method: str = "POST",
25
+ headers: dict[str, str] | None = None,
26
+ payload: dict[str, Any] | str | None = None,
27
+ timeout: int = 30,
28
+ retry: dict[str, Any] | None = None,
29
+ capture_response: dict[str, str] | None = None,
30
+ ) -> dict[str, Any]:
31
+ """Execute a webhook HTTP request.
32
+
33
+ Args:
34
+ template_engine: Template engine for interpolation
35
+ state: WorkflowState for variables/artifacts access
36
+ config: Daemon config for webhook_secrets
37
+ url: Target URL for the request
38
+ webhook_id: ID of a pre-configured webhook (alternative to url)
39
+ method: HTTP method (GET, POST, PUT, PATCH, DELETE)
40
+ headers: Request headers dict
41
+ payload: Request body as dict or string
42
+ timeout: Request timeout in seconds
43
+ retry: Retry configuration dict
44
+ capture_response: Response capture config
45
+
46
+ Returns:
47
+ Dict with success status, status_code, and captured response data.
48
+ """
49
+ from gobby.workflows.webhook import WebhookAction
50
+ from gobby.workflows.webhook_executor import WebhookExecutor
51
+
52
+ # Build kwargs dict for WebhookAction
53
+ webhook_kwargs: dict[str, Any] = {
54
+ "method": method,
55
+ "timeout": timeout,
56
+ }
57
+ if url:
58
+ webhook_kwargs["url"] = url
59
+ if webhook_id:
60
+ webhook_kwargs["webhook_id"] = webhook_id
61
+ if headers:
62
+ webhook_kwargs["headers"] = headers
63
+ if payload:
64
+ webhook_kwargs["payload"] = payload
65
+ if retry:
66
+ webhook_kwargs["retry"] = retry
67
+ if capture_response:
68
+ webhook_kwargs["capture_response"] = capture_response
69
+
70
+ try:
71
+ # Parse WebhookAction from kwargs to validate config
72
+ webhook_action = WebhookAction.from_dict(webhook_kwargs)
73
+ except ValueError as e:
74
+ logger.error(f"Invalid webhook action config: {e}")
75
+ return {"success": False, "error": str(e)}
76
+
77
+ # Build context for variable interpolation
78
+ interpolation_context: dict[str, Any] = {}
79
+ if state.variables:
80
+ interpolation_context["state"] = {"variables": state.variables}
81
+ if state.artifacts:
82
+ interpolation_context["artifacts"] = state.artifacts
83
+
84
+ # Get secrets from config if available
85
+ secrets: dict[str, str] = {}
86
+ if config:
87
+ secrets = getattr(config, "webhook_secrets", {})
88
+
89
+ # Create executor with template engine for payload interpolation
90
+ executor = WebhookExecutor(
91
+ template_engine=template_engine,
92
+ secrets=secrets,
93
+ )
94
+
95
+ # Execute the webhook
96
+ if webhook_action.url:
97
+ result = await executor.execute(
98
+ url=webhook_action.url,
99
+ method=webhook_action.method,
100
+ headers=webhook_action.headers,
101
+ payload=webhook_action.payload,
102
+ timeout=webhook_action.timeout,
103
+ retry_config=webhook_action.retry.to_dict() if webhook_action.retry else None,
104
+ context=interpolation_context,
105
+ )
106
+ elif webhook_action.webhook_id:
107
+ # webhook_id execution requires a registry which would be configured
108
+ # at the daemon level - for now we return an error if no registry
109
+ logger.warning("webhook_id execution not yet supported without registry")
110
+ return {"success": False, "error": "webhook_id requires configured webhook registry"}
111
+ else:
112
+ return {"success": False, "error": "Either url or webhook_id is required"}
113
+
114
+ # Capture response into workflow variables if configured
115
+ if webhook_action.capture_response:
116
+ if not state.variables:
117
+ state.variables = {}
118
+
119
+ capture = webhook_action.capture_response
120
+ if capture.status_var and result.status_code is not None:
121
+ state.variables[capture.status_var] = result.status_code
122
+ if capture.body_var and result.body is not None:
123
+ # Try to parse as JSON, fall back to raw string
124
+ json_body = result.json_body()
125
+ state.variables[capture.body_var] = json_body if json_body else result.body
126
+ if capture.headers_var and result.headers is not None:
127
+ state.variables[capture.headers_var] = result.headers
128
+
129
+ # Sanitize URL for logging (remove query params which may contain secrets)
130
+ def _sanitize_url(url: str | None) -> str:
131
+ if not url:
132
+ return "<no-url>"
133
+ try:
134
+ parsed = urlparse(url)
135
+ # Remove query string for logging
136
+ sanitized = urlunparse((parsed.scheme, parsed.netloc, parsed.path, "", "", ""))
137
+ return sanitized or url
138
+ except Exception:
139
+ return "<invalid-url>"
140
+
141
+ sanitized_url = _sanitize_url(webhook_action.url)
142
+
143
+ # Log outcome
144
+ if result.success:
145
+ logger.info(
146
+ f"Webhook {webhook_action.method} {sanitized_url} succeeded: {result.status_code}"
147
+ )
148
+ else:
149
+ logger.warning(
150
+ f"Webhook {webhook_action.method} {sanitized_url} failed: "
151
+ f"{result.error or result.status_code}"
152
+ )
153
+
154
+ return {
155
+ "success": result.success,
156
+ "status_code": result.status_code,
157
+ "error": result.error,
158
+ "body": result.body if result.success else None,
159
+ }
160
+
161
+
162
+ # --- ActionHandler-compatible wrappers ---
163
+ # These match the ActionHandler protocol: (context: ActionContext, **kwargs) -> dict | None
164
+
165
+
166
+ async def handle_webhook(
167
+ context: Any, config: Any | None = None, **kwargs: Any
168
+ ) -> dict[str, Any] | None:
169
+ """ActionHandler wrapper for execute_webhook.
170
+
171
+ Note: config is passed via closure from register_defaults.
172
+ """
173
+ return await execute_webhook(
174
+ template_engine=context.template_engine,
175
+ state=context.state,
176
+ config=config,
177
+ url=kwargs.get("url"),
178
+ webhook_id=kwargs.get("webhook_id"),
179
+ method=kwargs.get("method", "POST"),
180
+ headers=kwargs.get("headers"),
181
+ payload=kwargs.get("payload"),
182
+ timeout=kwargs.get("timeout", 30),
183
+ retry=kwargs.get("retry"),
184
+ capture_response=kwargs.get("capture_response"),
185
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gobby
3
- Version: 0.2.5
3
+ Version: 0.2.7
4
4
  Summary: A local-first daemon to unify your AI coding tools. Session tracking and handoffs across Claude Code, Gemini CLI, and Codex. An MCP proxy that discovers tools without flooding context. Task management with dependencies, validation, and TDD expansion. Agent spawning and worktree orchestration. Persistent memory, extensible workflows, and hooks.
5
5
  Author-email: Josh Wilhelmi <josh@gobby.ai>
6
6
  License-Expression: MIT
@@ -38,8 +38,10 @@ Requires-Dist: msgspec>=0.20.0
38
38
  Requires-Dist: gitingest>=0.3.1
39
39
  Requires-Dist: scikit-learn>=1.0.0
40
40
  Requires-Dist: textual>=7.3.0
41
- Requires-Dist: mem0ai
42
41
  Requires-Dist: memu-py>=1.0.0
42
+ Requires-Dist: python-multipart>=0.0.22
43
+ Provides-Extra: mem0
44
+ Requires-Dist: mem0ai; extra == "mem0"
43
45
  Dynamic: license-file
44
46
 
45
47
  <!-- markdownlint-disable MD033 MD041 -->
@@ -149,35 +151,92 @@ call_tool("gobby-worktrees", "spawn_agent_in_worktree", {
149
151
  })
150
152
  ```
151
153
 
152
- ## Quick Start
154
+ ### 🔗 Claude Code Task Integration
155
+
156
+ Gobby transparently intercepts Claude Code's built-in task system (TaskCreate, TaskUpdate, etc.) and syncs operations to Gobby's persistent task store. Benefits:
157
+
158
+ - **Tasks persist** across sessions (unlike CC's session-scoped tasks)
159
+ - **Commit linking** — tasks auto-link to git commits
160
+ - **Validation gates** — define criteria for task completion
161
+ - **LLM expansion** — break complex tasks into subtasks
162
+
163
+ No configuration needed — just use Claude Code's native task tools and Gobby handles the rest.
164
+
165
+ ### 📚 Skills System
166
+
167
+ Reusable instructions that teach agents how to perform specific tasks. Compatible with the [Agent Skills specification](https://agentskills.io) and SkillPort.
168
+
169
+ - **Core skills** bundled with Gobby for tasks, sessions, memory, workflows
170
+ - **Project skills** in `.gobby/skills/` for team-specific patterns
171
+ - **Install from anywhere** — GitHub repos, local paths, ZIP archives
172
+ - **Search and discovery** — TF-IDF and semantic search across your skill library
173
+
174
+ ```bash
175
+ # Install a skill from GitHub
176
+ gobby skills install github:user/repo/skills/my-skill
177
+
178
+ # Search for relevant skills
179
+ gobby skills search "testing coverage"
180
+ ```
181
+
182
+ ## Installation
183
+
184
+ ### Try it instantly
185
+ ```bash
186
+ uvx gobby --help
187
+ ```
153
188
 
189
+ ### Install globally
154
190
  ```bash
155
- # Clone and install
156
- git clone https://github.com/GobbyAI/gobby.git
157
- cd gobby
158
- uv sync
191
+ # With uv (recommended)
192
+ uv tool install gobby
159
193
 
194
+ # With pipx
195
+ pipx install gobby
196
+
197
+ # With pip
198
+ pip install gobby
199
+ ```
200
+
201
+ **Requirements:** Python 3.13+
202
+
203
+ ## Quick Start
204
+
205
+ ```bash
160
206
  # Start the daemon
161
- uv run gobby start
207
+ gobby start
162
208
 
163
209
  # In your project directory
164
- uv run gobby init
165
- uv run gobby install # Installs hooks for detected CLIs
166
-
167
- # Optional: install globally
168
- uv pip install -e .
210
+ gobby init
211
+ gobby install # Installs hooks for detected CLIs
169
212
  ```
170
213
 
171
- **Requirements:** Python 3.11+, [uv](https://github.com/astral-sh/uv), at least one AI CLI ([Claude Code](https://claude.ai/code), [Gemini CLI](https://github.com/google-gemini/gemini-cli), or [Codex CLI](https://github.com/openai/codex))
214
+ **Requirements:** At least one AI CLI ([Claude Code](https://claude.ai/code), [Gemini CLI](https://github.com/google-gemini/gemini-cli), or [Codex CLI](https://github.com/openai/codex))
172
215
 
173
216
  Works with your Claude, Gemini, or Codex subscriptions—or bring your own API keys. Local model support coming soon.
174
217
 
175
218
  ## Configure Your AI CLI
176
219
 
177
- Add Gobby as an MCP server:
220
+ Add Gobby as an MCP server. Choose the `command` and `args` that match your installation:
221
+
222
+ - **pip/pipx install**: `"command": "gobby"`, `"args": ["mcp-server"]`
223
+ - **uv tool install**: `"command": "uv"`, `"args": ["run", "gobby", "mcp-server"]`
178
224
 
179
225
  **Claude Code** (`.mcp.json` or `~/.claude.json`):
180
226
 
227
+ ```json
228
+ {
229
+ "mcpServers": {
230
+ "gobby": {
231
+ "command": "gobby",
232
+ "args": ["mcp-server"]
233
+ }
234
+ }
235
+ }
236
+ ```
237
+
238
+ Or with uv:
239
+
181
240
  ```json
182
241
  {
183
242
  "mcpServers": {
@@ -195,8 +254,8 @@ Add Gobby as an MCP server:
195
254
  {
196
255
  "mcpServers": {
197
256
  "gobby": {
198
- "command": "uv",
199
- "args": ["run", "gobby", "mcp-server"]
257
+ "command": "gobby",
258
+ "args": ["mcp-server"]
200
259
  }
201
260
  }
202
261
  }
@@ -206,8 +265,8 @@ Add Gobby as an MCP server:
206
265
 
207
266
  ```toml
208
267
  [mcp_servers.gobby]
209
- command = "uv"
210
- args = ["run", "gobby", "mcp-server"]
268
+ command = "gobby"
269
+ args = ["mcp-server"]
211
270
  ```
212
271
 
213
272
  **Gemini Antigravity** (`~/.gemini/antigravity/mcp_config.json`):
@@ -256,7 +315,7 @@ AI CLI (Claude/Gemini/Codex)
256
315
  Hook Dispatcher
257
316
  │ HTTP POST
258
317
 
259
- Gobby Daemon (:8765)
318
+ Gobby Daemon (:60887)
260
319
 
261
320
  ┌────┴────┐
262
321
  ▼ ▼
@@ -298,9 +357,12 @@ Gobby exposes tools via MCP that your AI coding assistant can use:
298
357
  **Worktrees** (`gobby-worktrees`)
299
358
  `create_worktree`, `spawn_agent_in_worktree`, `list_worktrees`
300
359
 
301
- **MCP Proxy**
360
+ **MCP Proxy**
302
361
  `list_mcp_servers`, `add_mcp_server`, `import_mcp_server`, `list_tools`, `get_tool_schema`, `call_tool`, `recommend_tools`
303
362
 
363
+ **Skills** (`gobby-skills`)
364
+ `list_skills`, `get_skill`, `search_skills`, `install_skill`, `remove_skill`, `update_skill`
365
+
304
366
  ## For AI Agents
305
367
 
306
368
  **If you're an AI agent reading this:** Check out [docs/AGENT_INSTRUCTIONS.md](docs/AGENT_INSTRUCTIONS.md) for your operating procedures, and [CLAUDE.md](CLAUDE.md) for Claude Code-specific guidance.
@@ -317,6 +379,10 @@ See [ROADMAP.md](ROADMAP.md) for the full plan, but highlights:
317
379
 
318
380
  **Vision:** Always local first, but Pro cloud features to keep the lights on: Fleet management (manage sessions across multiple machines), Plugin ecosystem, Team workflows, Enterprise hardening
319
381
 
382
+ ## Changelog
383
+
384
+ See [CHANGELOG.md](CHANGELOG.md) for release history and detailed changes.
385
+
320
386
  ## Development
321
387
 
322
388
  ```bash