gobby 0.2.6__py3-none-any.whl → 0.2.8__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 +96 -35
- 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/adapters/gemini.py +140 -38
- gobby/agents/definitions.py +11 -1
- gobby/agents/isolation.py +525 -0
- gobby/agents/registry.py +11 -0
- gobby/agents/sandbox.py +261 -0
- gobby/agents/session.py +1 -0
- gobby/agents/spawn.py +42 -287
- gobby/agents/spawn_executor.py +415 -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/macos.py +26 -1
- gobby/agents/spawners/prompt_manager.py +125 -0
- gobby/cli/__init__.py +0 -2
- gobby/cli/install.py +4 -4
- gobby/cli/installers/claude.py +6 -0
- gobby/cli/installers/gemini.py +6 -0
- gobby/cli/installers/shared.py +103 -4
- gobby/cli/memory.py +185 -0
- gobby/cli/sessions.py +1 -1
- gobby/cli/utils.py +9 -2
- gobby/clones/git.py +177 -0
- gobby/config/__init__.py +12 -97
- gobby/config/app.py +10 -94
- gobby/config/extensions.py +2 -2
- gobby/config/features.py +7 -130
- gobby/config/skills.py +31 -0
- gobby/config/tasks.py +4 -28
- gobby/hooks/__init__.py +0 -13
- gobby/hooks/event_handlers.py +150 -8
- gobby/hooks/hook_manager.py +21 -3
- gobby/hooks/plugins.py +1 -1
- gobby/hooks/webhooks.py +1 -1
- gobby/install/gemini/hooks/hook_dispatcher.py +74 -15
- gobby/llm/resolver.py +3 -2
- gobby/mcp_proxy/importer.py +62 -4
- gobby/mcp_proxy/instructions.py +4 -2
- gobby/mcp_proxy/registries.py +22 -8
- gobby/mcp_proxy/services/recommendation.py +43 -11
- gobby/mcp_proxy/tools/agent_messaging.py +93 -44
- gobby/mcp_proxy/tools/agents.py +76 -740
- gobby/mcp_proxy/tools/artifacts.py +43 -9
- gobby/mcp_proxy/tools/clones.py +0 -385
- gobby/mcp_proxy/tools/memory.py +2 -2
- gobby/mcp_proxy/tools/sessions/__init__.py +14 -0
- gobby/mcp_proxy/tools/sessions/_commits.py +239 -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 +503 -0
- gobby/mcp_proxy/tools/sessions/_messages.py +166 -0
- gobby/mcp_proxy/tools/skills/__init__.py +14 -29
- gobby/mcp_proxy/tools/spawn_agent.py +455 -0
- gobby/mcp_proxy/tools/tasks/_context.py +18 -0
- gobby/mcp_proxy/tools/tasks/_crud.py +13 -6
- gobby/mcp_proxy/tools/tasks/_lifecycle.py +79 -30
- gobby/mcp_proxy/tools/tasks/_lifecycle_validation.py +1 -1
- gobby/mcp_proxy/tools/tasks/_session.py +22 -7
- gobby/mcp_proxy/tools/workflows.py +84 -34
- gobby/mcp_proxy/tools/worktrees.py +32 -350
- gobby/memory/extractor.py +15 -1
- gobby/memory/ingestion/__init__.py +5 -0
- gobby/memory/ingestion/multimodal.py +221 -0
- gobby/memory/manager.py +62 -283
- 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 +13 -0
- gobby/servers/http.py +1 -4
- gobby/servers/routes/admin.py +14 -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 +51 -4
- gobby/servers/routes/mcp/tools.py +48 -1506
- gobby/servers/websocket.py +57 -1
- gobby/sessions/analyzer.py +2 -2
- gobby/sessions/lifecycle.py +1 -1
- gobby/sessions/manager.py +9 -0
- gobby/sessions/processor.py +10 -0
- gobby/sessions/transcripts/base.py +1 -0
- gobby/sessions/transcripts/claude.py +15 -5
- gobby/sessions/transcripts/gemini.py +100 -34
- gobby/skills/parser.py +30 -2
- gobby/storage/database.py +9 -2
- gobby/storage/memories.py +32 -21
- gobby/storage/migrations.py +174 -368
- gobby/storage/sessions.py +45 -7
- gobby/storage/skills.py +80 -7
- gobby/storage/tasks/_lifecycle.py +18 -3
- gobby/sync/memories.py +1 -1
- gobby/tasks/external_validator.py +1 -1
- gobby/tasks/validation.py +22 -20
- gobby/tools/summarizer.py +91 -10
- gobby/utils/project_context.py +2 -3
- gobby/utils/status.py +13 -0
- gobby/workflows/actions.py +221 -1217
- gobby/workflows/artifact_actions.py +31 -0
- gobby/workflows/autonomous_actions.py +11 -0
- gobby/workflows/context_actions.py +50 -1
- gobby/workflows/detection_helpers.py +38 -24
- gobby/workflows/enforcement/__init__.py +47 -0
- gobby/workflows/enforcement/blocking.py +281 -0
- gobby/workflows/enforcement/commit_policy.py +283 -0
- gobby/workflows/enforcement/handlers.py +269 -0
- gobby/workflows/enforcement/task_policy.py +542 -0
- gobby/workflows/engine.py +93 -0
- gobby/workflows/evaluator.py +110 -0
- gobby/workflows/git_utils.py +106 -0
- gobby/workflows/hooks.py +41 -0
- gobby/workflows/llm_actions.py +30 -0
- gobby/workflows/mcp_actions.py +20 -1
- gobby/workflows/memory_actions.py +91 -0
- gobby/workflows/safe_evaluator.py +191 -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 +217 -51
- 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.6.dist-info → gobby-0.2.8.dist-info}/METADATA +6 -1
- {gobby-0.2.6.dist-info → gobby-0.2.8.dist-info}/RECORD +139 -163
- {gobby-0.2.6.dist-info → gobby-0.2.8.dist-info}/WHEEL +1 -1
- gobby/adapters/codex.py +0 -1332
- gobby/cli/tui.py +0 -34
- 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/mcp_proxy/tools/session_messages.py +0 -1055
- 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/handoff/compact.md +0 -63
- gobby/prompts/defaults/handoff/session_end.md +0 -57
- gobby/prompts/defaults/memory/extract.md +0 -61
- 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/tui/__init__.py +0 -5
- gobby/tui/api_client.py +0 -278
- gobby/tui/app.py +0 -329
- gobby/tui/screens/__init__.py +0 -25
- gobby/tui/screens/agents.py +0 -333
- gobby/tui/screens/chat.py +0 -450
- gobby/tui/screens/dashboard.py +0 -377
- gobby/tui/screens/memory.py +0 -305
- gobby/tui/screens/metrics.py +0 -231
- gobby/tui/screens/orchestrator.py +0 -903
- gobby/tui/screens/sessions.py +0 -412
- gobby/tui/screens/tasks.py +0 -440
- gobby/tui/screens/workflows.py +0 -289
- gobby/tui/screens/worktrees.py +0 -174
- gobby/tui/widgets/__init__.py +0 -21
- gobby/tui/widgets/chat.py +0 -210
- gobby/tui/widgets/conductor.py +0 -104
- gobby/tui/widgets/menu.py +0 -132
- gobby/tui/widgets/message_panel.py +0 -160
- gobby/tui/widgets/review_gate.py +0 -224
- gobby/tui/widgets/task_tree.py +0 -99
- gobby/tui/widgets/token_budget.py +0 -166
- gobby/tui/ws_client.py +0 -258
- gobby/workflows/task_enforcement_actions.py +0 -1343
- {gobby-0.2.6.dist-info → gobby-0.2.8.dist-info}/entry_points.txt +0 -0
- {gobby-0.2.6.dist-info → gobby-0.2.8.dist-info}/licenses/LICENSE.md +0 -0
- {gobby-0.2.6.dist-info → gobby-0.2.8.dist-info}/top_level.txt +0 -0
gobby/__init__.py
CHANGED
gobby/adapters/__init__.py
CHANGED
|
@@ -17,7 +17,8 @@ Adapters:
|
|
|
17
17
|
|
|
18
18
|
from gobby.adapters.base import BaseAdapter
|
|
19
19
|
from gobby.adapters.claude_code import ClaudeCodeAdapter
|
|
20
|
-
from gobby.adapters.
|
|
20
|
+
from gobby.adapters.codex_impl.adapter import CodexAdapter, CodexNotifyAdapter
|
|
21
|
+
from gobby.adapters.codex_impl.client import CodexAppServerClient
|
|
21
22
|
from gobby.adapters.gemini import GeminiAdapter
|
|
22
23
|
|
|
23
24
|
__all__ = [
|
gobby/adapters/claude_code.py
CHANGED
|
@@ -104,6 +104,10 @@ class ClaudeCodeAdapter(BaseAdapter):
|
|
|
104
104
|
is_failure = hook_type == "post-tool-use-failure"
|
|
105
105
|
metadata = {"is_failure": is_failure} if is_failure else {}
|
|
106
106
|
|
|
107
|
+
# Normalize event data for CLI-agnostic processing
|
|
108
|
+
# This allows downstream code to use consistent field names
|
|
109
|
+
normalized_data = self._normalize_event_data(input_data)
|
|
110
|
+
|
|
107
111
|
return HookEvent(
|
|
108
112
|
event_type=event_type,
|
|
109
113
|
session_id=session_id,
|
|
@@ -111,10 +115,46 @@ class ClaudeCodeAdapter(BaseAdapter):
|
|
|
111
115
|
timestamp=datetime.now(UTC),
|
|
112
116
|
machine_id=input_data.get("machine_id"),
|
|
113
117
|
cwd=input_data.get("cwd"),
|
|
114
|
-
data=
|
|
118
|
+
data=normalized_data,
|
|
115
119
|
metadata=metadata,
|
|
116
120
|
)
|
|
117
121
|
|
|
122
|
+
def _normalize_event_data(self, input_data: dict[str, Any]) -> dict[str, Any]:
|
|
123
|
+
"""Normalize Claude Code event data for CLI-agnostic processing.
|
|
124
|
+
|
|
125
|
+
This method enriches the input_data with normalized fields so downstream
|
|
126
|
+
code doesn't need to handle Claude-specific formats.
|
|
127
|
+
|
|
128
|
+
Normalizations performed:
|
|
129
|
+
1. tool_input.server_name/tool_name → mcp_server/mcp_tool (for MCP calls)
|
|
130
|
+
2. tool_result → tool_output
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
input_data: Raw input data from Claude Code
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
Enriched data dict with normalized fields added
|
|
137
|
+
"""
|
|
138
|
+
# Start with a copy to avoid mutating original
|
|
139
|
+
data = dict(input_data)
|
|
140
|
+
|
|
141
|
+
# Get tool info
|
|
142
|
+
tool_name = data.get("tool_name", "")
|
|
143
|
+
tool_input = data.get("tool_input", {}) or {}
|
|
144
|
+
|
|
145
|
+
# 1. Extract MCP info from nested tool_input for call_tool calls
|
|
146
|
+
if tool_name in ("call_tool", "mcp__gobby__call_tool"):
|
|
147
|
+
if "mcp_server" not in data:
|
|
148
|
+
data["mcp_server"] = tool_input.get("server_name")
|
|
149
|
+
if "mcp_tool" not in data:
|
|
150
|
+
data["mcp_tool"] = tool_input.get("tool_name")
|
|
151
|
+
|
|
152
|
+
# 2. Normalize tool_result → tool_output
|
|
153
|
+
if "tool_result" in data and "tool_output" not in data:
|
|
154
|
+
data["tool_output"] = data["tool_result"]
|
|
155
|
+
|
|
156
|
+
return data
|
|
157
|
+
|
|
118
158
|
# Map Claude Code hook types to hookEventName for hookSpecificOutput
|
|
119
159
|
HOOK_EVENT_NAME_MAP: dict[str, str] = {
|
|
120
160
|
"session-start": "SessionStart",
|
|
@@ -193,44 +233,65 @@ class ClaudeCodeAdapter(BaseAdapter):
|
|
|
193
233
|
# Add session identifiers from metadata
|
|
194
234
|
# Note: "session_id" in metadata is Gobby's internal platform session ID
|
|
195
235
|
# "external_id" in metadata is the CLI's session UUID
|
|
236
|
+
# "session_ref" is the short #N format for easier reference
|
|
237
|
+
# Token optimization: Only inject full metadata on first hook per session
|
|
196
238
|
if response.metadata:
|
|
197
239
|
gobby_session_id = response.metadata.get("session_id")
|
|
240
|
+
session_ref = response.metadata.get("session_ref")
|
|
198
241
|
external_id = response.metadata.get("external_id")
|
|
242
|
+
is_first_hook = response.metadata.get("_first_hook_for_session", False)
|
|
243
|
+
|
|
199
244
|
if gobby_session_id:
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
"
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
"
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
245
|
+
if is_first_hook:
|
|
246
|
+
# First hook: inject full metadata (~60-100 tokens)
|
|
247
|
+
context_lines = []
|
|
248
|
+
if session_ref:
|
|
249
|
+
context_lines.append(
|
|
250
|
+
f"Gobby Session ID: {session_ref} (or {gobby_session_id})"
|
|
251
|
+
)
|
|
252
|
+
else:
|
|
253
|
+
context_lines.append(f"Gobby Session ID: {gobby_session_id}")
|
|
254
|
+
if external_id:
|
|
255
|
+
context_lines.append(
|
|
256
|
+
f"CLI-Specific Session ID (external_id): {external_id}"
|
|
257
|
+
)
|
|
258
|
+
if response.metadata.get("parent_session_id"):
|
|
259
|
+
context_lines.append(
|
|
260
|
+
f"parent_session_id: {response.metadata['parent_session_id']}"
|
|
261
|
+
)
|
|
262
|
+
if response.metadata.get("machine_id"):
|
|
263
|
+
context_lines.append(f"machine_id: {response.metadata['machine_id']}")
|
|
264
|
+
if response.metadata.get("project_id"):
|
|
265
|
+
context_lines.append(f"project_id: {response.metadata['project_id']}")
|
|
266
|
+
# Add terminal context (non-null values only)
|
|
267
|
+
if response.metadata.get("terminal_term_program"):
|
|
268
|
+
context_lines.append(
|
|
269
|
+
f"terminal: {response.metadata['terminal_term_program']}"
|
|
270
|
+
)
|
|
271
|
+
if response.metadata.get("terminal_tty"):
|
|
272
|
+
context_lines.append(f"tty: {response.metadata['terminal_tty']}")
|
|
273
|
+
if response.metadata.get("terminal_parent_pid"):
|
|
274
|
+
context_lines.append(
|
|
275
|
+
f"parent_pid: {response.metadata['terminal_parent_pid']}"
|
|
276
|
+
)
|
|
277
|
+
# Add terminal-specific session IDs (only one will be present)
|
|
278
|
+
for key in [
|
|
279
|
+
"terminal_iterm_session_id",
|
|
280
|
+
"terminal_term_session_id",
|
|
281
|
+
"terminal_kitty_window_id",
|
|
282
|
+
"terminal_tmux_pane",
|
|
283
|
+
"terminal_vscode_terminal_id",
|
|
284
|
+
"terminal_alacritty_socket",
|
|
285
|
+
]:
|
|
286
|
+
if response.metadata.get(key):
|
|
287
|
+
# Use friendlier names in output
|
|
288
|
+
friendly_name = key.replace("terminal_", "").replace("_", " ")
|
|
289
|
+
context_lines.append(f"{friendly_name}: {response.metadata[key]}")
|
|
290
|
+
additional_context_parts.append("\n".join(context_lines))
|
|
291
|
+
else:
|
|
292
|
+
# Subsequent hooks: inject minimal session ref only (~8 tokens)
|
|
293
|
+
if session_ref:
|
|
294
|
+
additional_context_parts.append(f"Gobby Session ID: {session_ref}")
|
|
234
295
|
|
|
235
296
|
# Build hookSpecificOutput if we have any context to inject
|
|
236
297
|
# Only include hookSpecificOutput for hook types that Claude Code's schema accepts
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Codex adapter implementation package.
|
|
3
|
+
|
|
4
|
+
This package contains the decomposed implementation of the Codex adapter,
|
|
5
|
+
extracted from the monolithic codex.py using the Strangler Fig pattern.
|
|
6
|
+
|
|
7
|
+
Modules:
|
|
8
|
+
- types.py: Type definitions and data classes
|
|
9
|
+
- protocol.py: Protocol/interface definitions
|
|
10
|
+
- client.py: CodexAppServerClient implementation
|
|
11
|
+
- adapter.py: CodexAdapter and CodexNotifyAdapter implementations
|
|
12
|
+
|
|
13
|
+
Importer analysis (from codex.py):
|
|
14
|
+
- src/gobby/servers/http.py: imports CodexAdapter
|
|
15
|
+
- src/gobby/servers/routes/mcp/hooks.py: imports CodexNotifyAdapter
|
|
16
|
+
- src/gobby/adapters/__init__.py: imports CodexAdapter, CodexAppServerClient, CodexNotifyAdapter
|
|
17
|
+
- tests/adapters/test_codex.py: imports various items for testing
|
|
18
|
+
|
|
19
|
+
Migration strategy:
|
|
20
|
+
1. Extract types/dataclasses to types.py
|
|
21
|
+
2. Extract protocol definitions to protocol.py
|
|
22
|
+
3. Extract CodexAppServerClient to client.py
|
|
23
|
+
4. Extract adapters to adapter.py
|
|
24
|
+
5. Update codex.py to re-export from submodules
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
# Phase 3: Placeholders - exports will be added as code is migrated
|
|
28
|
+
__all__: list[str] = []
|