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.
- gobby/__init__.py +1 -1
- gobby/adapters/__init__.py +2 -1
- gobby/adapters/claude_code.py +13 -4
- gobby/adapters/codex_impl/__init__.py +28 -0
- gobby/adapters/codex_impl/adapter.py +722 -0
- gobby/adapters/codex_impl/client.py +679 -0
- gobby/adapters/codex_impl/protocol.py +20 -0
- gobby/adapters/codex_impl/types.py +68 -0
- gobby/agents/definitions.py +11 -1
- gobby/agents/isolation.py +395 -0
- gobby/agents/runner.py +8 -0
- gobby/agents/sandbox.py +261 -0
- gobby/agents/spawn.py +42 -287
- gobby/agents/spawn_executor.py +385 -0
- gobby/agents/spawners/__init__.py +24 -0
- gobby/agents/spawners/command_builder.py +189 -0
- gobby/agents/spawners/embedded.py +21 -2
- gobby/agents/spawners/headless.py +21 -2
- gobby/agents/spawners/prompt_manager.py +125 -0
- gobby/cli/__init__.py +6 -0
- gobby/cli/clones.py +419 -0
- gobby/cli/conductor.py +266 -0
- gobby/cli/install.py +4 -4
- gobby/cli/installers/antigravity.py +3 -9
- gobby/cli/installers/claude.py +15 -9
- gobby/cli/installers/codex.py +2 -8
- gobby/cli/installers/gemini.py +8 -8
- gobby/cli/installers/shared.py +175 -13
- gobby/cli/sessions.py +1 -1
- gobby/cli/skills.py +858 -0
- gobby/cli/tasks/ai.py +0 -440
- gobby/cli/tasks/crud.py +44 -6
- gobby/cli/tasks/main.py +0 -4
- gobby/cli/tui.py +2 -2
- gobby/cli/utils.py +12 -5
- gobby/clones/__init__.py +13 -0
- gobby/clones/git.py +547 -0
- gobby/conductor/__init__.py +16 -0
- gobby/conductor/alerts.py +135 -0
- gobby/conductor/loop.py +164 -0
- gobby/conductor/monitors/__init__.py +11 -0
- gobby/conductor/monitors/agents.py +116 -0
- gobby/conductor/monitors/tasks.py +155 -0
- gobby/conductor/pricing.py +234 -0
- gobby/conductor/token_tracker.py +160 -0
- gobby/config/__init__.py +12 -97
- gobby/config/app.py +69 -91
- gobby/config/extensions.py +2 -2
- gobby/config/features.py +7 -130
- gobby/config/search.py +110 -0
- gobby/config/servers.py +1 -1
- gobby/config/skills.py +43 -0
- gobby/config/tasks.py +9 -41
- gobby/hooks/__init__.py +0 -13
- gobby/hooks/event_handlers.py +188 -2
- gobby/hooks/hook_manager.py +50 -4
- gobby/hooks/plugins.py +1 -1
- gobby/hooks/skill_manager.py +130 -0
- gobby/hooks/webhooks.py +1 -1
- gobby/install/claude/hooks/hook_dispatcher.py +4 -4
- gobby/install/codex/hooks/hook_dispatcher.py +1 -1
- gobby/install/gemini/hooks/hook_dispatcher.py +87 -12
- gobby/llm/claude.py +22 -34
- gobby/llm/claude_executor.py +46 -256
- gobby/llm/codex_executor.py +59 -291
- gobby/llm/executor.py +21 -0
- gobby/llm/gemini.py +134 -110
- gobby/llm/litellm_executor.py +143 -6
- gobby/llm/resolver.py +98 -35
- gobby/mcp_proxy/importer.py +62 -4
- gobby/mcp_proxy/instructions.py +56 -0
- gobby/mcp_proxy/models.py +15 -0
- gobby/mcp_proxy/registries.py +68 -8
- gobby/mcp_proxy/server.py +33 -3
- gobby/mcp_proxy/services/recommendation.py +43 -11
- gobby/mcp_proxy/services/tool_proxy.py +81 -1
- gobby/mcp_proxy/stdio.py +2 -1
- gobby/mcp_proxy/tools/__init__.py +0 -2
- gobby/mcp_proxy/tools/agent_messaging.py +317 -0
- gobby/mcp_proxy/tools/agents.py +31 -731
- gobby/mcp_proxy/tools/clones.py +518 -0
- gobby/mcp_proxy/tools/memory.py +3 -26
- gobby/mcp_proxy/tools/metrics.py +65 -1
- gobby/mcp_proxy/tools/orchestration/__init__.py +3 -0
- gobby/mcp_proxy/tools/orchestration/cleanup.py +151 -0
- gobby/mcp_proxy/tools/orchestration/wait.py +467 -0
- gobby/mcp_proxy/tools/sessions/__init__.py +14 -0
- gobby/mcp_proxy/tools/sessions/_commits.py +232 -0
- gobby/mcp_proxy/tools/sessions/_crud.py +253 -0
- gobby/mcp_proxy/tools/sessions/_factory.py +63 -0
- gobby/mcp_proxy/tools/sessions/_handoff.py +499 -0
- gobby/mcp_proxy/tools/sessions/_messages.py +138 -0
- gobby/mcp_proxy/tools/skills/__init__.py +616 -0
- gobby/mcp_proxy/tools/spawn_agent.py +417 -0
- gobby/mcp_proxy/tools/task_orchestration.py +7 -0
- gobby/mcp_proxy/tools/task_readiness.py +14 -0
- gobby/mcp_proxy/tools/task_sync.py +1 -1
- gobby/mcp_proxy/tools/tasks/_context.py +0 -20
- gobby/mcp_proxy/tools/tasks/_crud.py +91 -4
- gobby/mcp_proxy/tools/tasks/_expansion.py +348 -0
- gobby/mcp_proxy/tools/tasks/_factory.py +6 -16
- gobby/mcp_proxy/tools/tasks/_lifecycle.py +110 -45
- gobby/mcp_proxy/tools/tasks/_lifecycle_validation.py +18 -29
- gobby/mcp_proxy/tools/workflows.py +1 -1
- gobby/mcp_proxy/tools/worktrees.py +0 -338
- gobby/memory/backends/__init__.py +6 -1
- gobby/memory/backends/mem0.py +6 -1
- gobby/memory/extractor.py +477 -0
- gobby/memory/ingestion/__init__.py +5 -0
- gobby/memory/ingestion/multimodal.py +221 -0
- gobby/memory/manager.py +73 -285
- gobby/memory/search/__init__.py +10 -0
- gobby/memory/search/coordinator.py +248 -0
- gobby/memory/services/__init__.py +5 -0
- gobby/memory/services/crossref.py +142 -0
- gobby/prompts/loader.py +5 -2
- gobby/runner.py +37 -16
- gobby/search/__init__.py +48 -6
- gobby/search/backends/__init__.py +159 -0
- gobby/search/backends/embedding.py +225 -0
- gobby/search/embeddings.py +238 -0
- gobby/search/models.py +148 -0
- gobby/search/unified.py +496 -0
- gobby/servers/http.py +24 -12
- gobby/servers/routes/admin.py +294 -0
- gobby/servers/routes/mcp/endpoints/__init__.py +61 -0
- gobby/servers/routes/mcp/endpoints/discovery.py +405 -0
- gobby/servers/routes/mcp/endpoints/execution.py +568 -0
- gobby/servers/routes/mcp/endpoints/registry.py +378 -0
- gobby/servers/routes/mcp/endpoints/server.py +304 -0
- gobby/servers/routes/mcp/hooks.py +1 -1
- gobby/servers/routes/mcp/tools.py +48 -1317
- gobby/servers/websocket.py +2 -2
- gobby/sessions/analyzer.py +2 -0
- gobby/sessions/lifecycle.py +1 -1
- gobby/sessions/processor.py +10 -0
- gobby/sessions/transcripts/base.py +2 -0
- gobby/sessions/transcripts/claude.py +79 -10
- gobby/skills/__init__.py +91 -0
- gobby/skills/loader.py +685 -0
- gobby/skills/manager.py +384 -0
- gobby/skills/parser.py +286 -0
- gobby/skills/search.py +463 -0
- gobby/skills/sync.py +119 -0
- gobby/skills/updater.py +385 -0
- gobby/skills/validator.py +368 -0
- gobby/storage/clones.py +378 -0
- gobby/storage/database.py +1 -1
- gobby/storage/memories.py +43 -13
- gobby/storage/migrations.py +162 -201
- gobby/storage/sessions.py +116 -7
- gobby/storage/skills.py +782 -0
- gobby/storage/tasks/_crud.py +4 -4
- gobby/storage/tasks/_lifecycle.py +57 -7
- gobby/storage/tasks/_manager.py +14 -5
- gobby/storage/tasks/_models.py +8 -3
- gobby/sync/memories.py +40 -5
- gobby/sync/tasks.py +83 -6
- gobby/tasks/__init__.py +1 -2
- gobby/tasks/external_validator.py +1 -1
- gobby/tasks/validation.py +46 -35
- gobby/tools/summarizer.py +91 -10
- gobby/tui/api_client.py +4 -7
- gobby/tui/app.py +5 -3
- gobby/tui/screens/orchestrator.py +1 -2
- gobby/tui/screens/tasks.py +2 -4
- gobby/tui/ws_client.py +1 -1
- gobby/utils/daemon_client.py +2 -2
- gobby/utils/project_context.py +2 -3
- gobby/utils/status.py +13 -0
- gobby/workflows/actions.py +221 -1135
- gobby/workflows/artifact_actions.py +31 -0
- gobby/workflows/autonomous_actions.py +11 -0
- gobby/workflows/context_actions.py +93 -1
- gobby/workflows/detection_helpers.py +115 -31
- gobby/workflows/enforcement/__init__.py +47 -0
- gobby/workflows/enforcement/blocking.py +269 -0
- gobby/workflows/enforcement/commit_policy.py +283 -0
- gobby/workflows/enforcement/handlers.py +269 -0
- gobby/workflows/{task_enforcement_actions.py → enforcement/task_policy.py} +29 -388
- gobby/workflows/engine.py +13 -2
- gobby/workflows/git_utils.py +106 -0
- gobby/workflows/lifecycle_evaluator.py +29 -1
- gobby/workflows/llm_actions.py +30 -0
- gobby/workflows/loader.py +19 -6
- gobby/workflows/mcp_actions.py +20 -1
- gobby/workflows/memory_actions.py +154 -0
- gobby/workflows/safe_evaluator.py +183 -0
- gobby/workflows/session_actions.py +44 -0
- gobby/workflows/state_actions.py +60 -1
- gobby/workflows/stop_signal_actions.py +55 -0
- gobby/workflows/summary_actions.py +111 -1
- gobby/workflows/task_sync_actions.py +347 -0
- gobby/workflows/todo_actions.py +34 -1
- gobby/workflows/webhook_actions.py +185 -0
- {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/METADATA +87 -21
- {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/RECORD +201 -172
- {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/WHEEL +1 -1
- gobby/adapters/codex.py +0 -1292
- gobby/install/claude/commands/gobby/bug.md +0 -51
- gobby/install/claude/commands/gobby/chore.md +0 -51
- gobby/install/claude/commands/gobby/epic.md +0 -52
- gobby/install/claude/commands/gobby/eval.md +0 -235
- gobby/install/claude/commands/gobby/feat.md +0 -49
- gobby/install/claude/commands/gobby/nit.md +0 -52
- gobby/install/claude/commands/gobby/ref.md +0 -52
- gobby/install/codex/prompts/forget.md +0 -7
- gobby/install/codex/prompts/memories.md +0 -7
- gobby/install/codex/prompts/recall.md +0 -7
- gobby/install/codex/prompts/remember.md +0 -13
- gobby/llm/gemini_executor.py +0 -339
- gobby/mcp_proxy/tools/session_messages.py +0 -1056
- gobby/mcp_proxy/tools/task_expansion.py +0 -591
- gobby/prompts/defaults/expansion/system.md +0 -119
- gobby/prompts/defaults/expansion/user.md +0 -48
- gobby/prompts/defaults/external_validation/agent.md +0 -72
- gobby/prompts/defaults/external_validation/external.md +0 -63
- gobby/prompts/defaults/external_validation/spawn.md +0 -83
- gobby/prompts/defaults/external_validation/system.md +0 -6
- gobby/prompts/defaults/features/import_mcp.md +0 -22
- gobby/prompts/defaults/features/import_mcp_github.md +0 -17
- gobby/prompts/defaults/features/import_mcp_search.md +0 -16
- gobby/prompts/defaults/features/recommend_tools.md +0 -32
- gobby/prompts/defaults/features/recommend_tools_hybrid.md +0 -35
- gobby/prompts/defaults/features/recommend_tools_llm.md +0 -30
- gobby/prompts/defaults/features/server_description.md +0 -20
- gobby/prompts/defaults/features/server_description_system.md +0 -6
- gobby/prompts/defaults/features/task_description.md +0 -31
- gobby/prompts/defaults/features/task_description_system.md +0 -6
- gobby/prompts/defaults/features/tool_summary.md +0 -17
- gobby/prompts/defaults/features/tool_summary_system.md +0 -6
- gobby/prompts/defaults/research/step.md +0 -58
- gobby/prompts/defaults/validation/criteria.md +0 -47
- gobby/prompts/defaults/validation/validate.md +0 -38
- gobby/storage/migrations_legacy.py +0 -1359
- gobby/tasks/context.py +0 -747
- gobby/tasks/criteria.py +0 -342
- gobby/tasks/expansion.py +0 -626
- gobby/tasks/prompts/expand.py +0 -327
- gobby/tasks/research.py +0 -421
- gobby/tasks/tdd.py +0 -352
- {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/entry_points.txt +0 -0
- {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/licenses/LICENSE.md +0 -0
- {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.
|
|
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
|
-
|
|
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
|
-
#
|
|
156
|
-
|
|
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
|
-
|
|
207
|
+
gobby start
|
|
162
208
|
|
|
163
209
|
# In your project directory
|
|
164
|
-
|
|
165
|
-
|
|
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:**
|
|
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": "
|
|
199
|
-
"args": ["
|
|
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 = "
|
|
210
|
-
args = ["
|
|
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 (:
|
|
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
|