gobby 0.2.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gobby/__init__.py +3 -0
- gobby/adapters/__init__.py +30 -0
- gobby/adapters/base.py +93 -0
- gobby/adapters/claude_code.py +276 -0
- gobby/adapters/codex.py +1292 -0
- gobby/adapters/gemini.py +343 -0
- gobby/agents/__init__.py +37 -0
- gobby/agents/codex_session.py +120 -0
- gobby/agents/constants.py +112 -0
- gobby/agents/context.py +362 -0
- gobby/agents/definitions.py +133 -0
- gobby/agents/gemini_session.py +111 -0
- gobby/agents/registry.py +618 -0
- gobby/agents/runner.py +968 -0
- gobby/agents/session.py +259 -0
- gobby/agents/spawn.py +916 -0
- gobby/agents/spawners/__init__.py +77 -0
- gobby/agents/spawners/base.py +142 -0
- gobby/agents/spawners/cross_platform.py +266 -0
- gobby/agents/spawners/embedded.py +225 -0
- gobby/agents/spawners/headless.py +226 -0
- gobby/agents/spawners/linux.py +125 -0
- gobby/agents/spawners/macos.py +277 -0
- gobby/agents/spawners/windows.py +308 -0
- gobby/agents/tty_config.py +319 -0
- gobby/autonomous/__init__.py +32 -0
- gobby/autonomous/progress_tracker.py +447 -0
- gobby/autonomous/stop_registry.py +269 -0
- gobby/autonomous/stuck_detector.py +383 -0
- gobby/cli/__init__.py +67 -0
- gobby/cli/__main__.py +8 -0
- gobby/cli/agents.py +529 -0
- gobby/cli/artifacts.py +266 -0
- gobby/cli/daemon.py +329 -0
- gobby/cli/extensions.py +526 -0
- gobby/cli/github.py +263 -0
- gobby/cli/init.py +53 -0
- gobby/cli/install.py +614 -0
- gobby/cli/installers/__init__.py +37 -0
- gobby/cli/installers/antigravity.py +65 -0
- gobby/cli/installers/claude.py +363 -0
- gobby/cli/installers/codex.py +192 -0
- gobby/cli/installers/gemini.py +294 -0
- gobby/cli/installers/git_hooks.py +377 -0
- gobby/cli/installers/shared.py +737 -0
- gobby/cli/linear.py +250 -0
- gobby/cli/mcp.py +30 -0
- gobby/cli/mcp_proxy.py +698 -0
- gobby/cli/memory.py +304 -0
- gobby/cli/merge.py +384 -0
- gobby/cli/projects.py +79 -0
- gobby/cli/sessions.py +622 -0
- gobby/cli/tasks/__init__.py +30 -0
- gobby/cli/tasks/_utils.py +658 -0
- gobby/cli/tasks/ai.py +1025 -0
- gobby/cli/tasks/commits.py +169 -0
- gobby/cli/tasks/crud.py +685 -0
- gobby/cli/tasks/deps.py +135 -0
- gobby/cli/tasks/labels.py +63 -0
- gobby/cli/tasks/main.py +273 -0
- gobby/cli/tasks/search.py +178 -0
- gobby/cli/tui.py +34 -0
- gobby/cli/utils.py +513 -0
- gobby/cli/workflows.py +927 -0
- gobby/cli/worktrees.py +481 -0
- gobby/config/__init__.py +129 -0
- gobby/config/app.py +551 -0
- gobby/config/extensions.py +167 -0
- gobby/config/features.py +472 -0
- gobby/config/llm_providers.py +98 -0
- gobby/config/logging.py +66 -0
- gobby/config/mcp.py +346 -0
- gobby/config/persistence.py +247 -0
- gobby/config/servers.py +141 -0
- gobby/config/sessions.py +250 -0
- gobby/config/tasks.py +784 -0
- gobby/hooks/__init__.py +104 -0
- gobby/hooks/artifact_capture.py +213 -0
- gobby/hooks/broadcaster.py +243 -0
- gobby/hooks/event_handlers.py +723 -0
- gobby/hooks/events.py +218 -0
- gobby/hooks/git.py +169 -0
- gobby/hooks/health_monitor.py +171 -0
- gobby/hooks/hook_manager.py +856 -0
- gobby/hooks/hook_types.py +575 -0
- gobby/hooks/plugins.py +813 -0
- gobby/hooks/session_coordinator.py +396 -0
- gobby/hooks/verification_runner.py +268 -0
- gobby/hooks/webhooks.py +339 -0
- gobby/install/claude/commands/gobby/bug.md +51 -0
- gobby/install/claude/commands/gobby/chore.md +51 -0
- gobby/install/claude/commands/gobby/epic.md +52 -0
- gobby/install/claude/commands/gobby/eval.md +235 -0
- gobby/install/claude/commands/gobby/feat.md +49 -0
- gobby/install/claude/commands/gobby/nit.md +52 -0
- gobby/install/claude/commands/gobby/ref.md +52 -0
- gobby/install/claude/hooks/HOOK_SCHEMAS.md +632 -0
- gobby/install/claude/hooks/hook_dispatcher.py +364 -0
- gobby/install/claude/hooks/validate_settings.py +102 -0
- gobby/install/claude/hooks-template.json +118 -0
- gobby/install/codex/hooks/hook_dispatcher.py +153 -0
- gobby/install/codex/prompts/forget.md +7 -0
- gobby/install/codex/prompts/memories.md +7 -0
- gobby/install/codex/prompts/recall.md +7 -0
- gobby/install/codex/prompts/remember.md +13 -0
- gobby/install/gemini/hooks/hook_dispatcher.py +268 -0
- gobby/install/gemini/hooks-template.json +138 -0
- gobby/install/shared/plugins/code_guardian.py +456 -0
- gobby/install/shared/plugins/example_notify.py +331 -0
- gobby/integrations/__init__.py +10 -0
- gobby/integrations/github.py +145 -0
- gobby/integrations/linear.py +145 -0
- gobby/llm/__init__.py +40 -0
- gobby/llm/base.py +120 -0
- gobby/llm/claude.py +578 -0
- gobby/llm/claude_executor.py +503 -0
- gobby/llm/codex.py +322 -0
- gobby/llm/codex_executor.py +513 -0
- gobby/llm/executor.py +316 -0
- gobby/llm/factory.py +34 -0
- gobby/llm/gemini.py +258 -0
- gobby/llm/gemini_executor.py +339 -0
- gobby/llm/litellm.py +287 -0
- gobby/llm/litellm_executor.py +303 -0
- gobby/llm/resolver.py +499 -0
- gobby/llm/service.py +236 -0
- gobby/mcp_proxy/__init__.py +29 -0
- gobby/mcp_proxy/actions.py +175 -0
- gobby/mcp_proxy/daemon_control.py +198 -0
- gobby/mcp_proxy/importer.py +436 -0
- gobby/mcp_proxy/lazy.py +325 -0
- gobby/mcp_proxy/manager.py +798 -0
- gobby/mcp_proxy/metrics.py +609 -0
- gobby/mcp_proxy/models.py +139 -0
- gobby/mcp_proxy/registries.py +215 -0
- gobby/mcp_proxy/schema_hash.py +381 -0
- gobby/mcp_proxy/semantic_search.py +706 -0
- gobby/mcp_proxy/server.py +549 -0
- gobby/mcp_proxy/services/__init__.py +0 -0
- gobby/mcp_proxy/services/fallback.py +306 -0
- gobby/mcp_proxy/services/recommendation.py +224 -0
- gobby/mcp_proxy/services/server_mgmt.py +214 -0
- gobby/mcp_proxy/services/system.py +72 -0
- gobby/mcp_proxy/services/tool_filter.py +231 -0
- gobby/mcp_proxy/services/tool_proxy.py +309 -0
- gobby/mcp_proxy/stdio.py +565 -0
- gobby/mcp_proxy/tools/__init__.py +27 -0
- gobby/mcp_proxy/tools/agents.py +1103 -0
- gobby/mcp_proxy/tools/artifacts.py +207 -0
- gobby/mcp_proxy/tools/hub.py +335 -0
- gobby/mcp_proxy/tools/internal.py +337 -0
- gobby/mcp_proxy/tools/memory.py +543 -0
- gobby/mcp_proxy/tools/merge.py +422 -0
- gobby/mcp_proxy/tools/metrics.py +283 -0
- gobby/mcp_proxy/tools/orchestration/__init__.py +23 -0
- gobby/mcp_proxy/tools/orchestration/cleanup.py +619 -0
- gobby/mcp_proxy/tools/orchestration/monitor.py +380 -0
- gobby/mcp_proxy/tools/orchestration/orchestrate.py +746 -0
- gobby/mcp_proxy/tools/orchestration/review.py +736 -0
- gobby/mcp_proxy/tools/orchestration/utils.py +16 -0
- gobby/mcp_proxy/tools/session_messages.py +1056 -0
- gobby/mcp_proxy/tools/task_dependencies.py +219 -0
- gobby/mcp_proxy/tools/task_expansion.py +591 -0
- gobby/mcp_proxy/tools/task_github.py +393 -0
- gobby/mcp_proxy/tools/task_linear.py +379 -0
- gobby/mcp_proxy/tools/task_orchestration.py +77 -0
- gobby/mcp_proxy/tools/task_readiness.py +522 -0
- gobby/mcp_proxy/tools/task_sync.py +351 -0
- gobby/mcp_proxy/tools/task_validation.py +843 -0
- gobby/mcp_proxy/tools/tasks/__init__.py +25 -0
- gobby/mcp_proxy/tools/tasks/_context.py +112 -0
- gobby/mcp_proxy/tools/tasks/_crud.py +516 -0
- gobby/mcp_proxy/tools/tasks/_factory.py +176 -0
- gobby/mcp_proxy/tools/tasks/_helpers.py +129 -0
- gobby/mcp_proxy/tools/tasks/_lifecycle.py +517 -0
- gobby/mcp_proxy/tools/tasks/_lifecycle_validation.py +301 -0
- gobby/mcp_proxy/tools/tasks/_resolution.py +55 -0
- gobby/mcp_proxy/tools/tasks/_search.py +215 -0
- gobby/mcp_proxy/tools/tasks/_session.py +125 -0
- gobby/mcp_proxy/tools/workflows.py +973 -0
- gobby/mcp_proxy/tools/worktrees.py +1264 -0
- gobby/mcp_proxy/transports/__init__.py +0 -0
- gobby/mcp_proxy/transports/base.py +95 -0
- gobby/mcp_proxy/transports/factory.py +44 -0
- gobby/mcp_proxy/transports/http.py +139 -0
- gobby/mcp_proxy/transports/stdio.py +213 -0
- gobby/mcp_proxy/transports/websocket.py +136 -0
- gobby/memory/backends/__init__.py +116 -0
- gobby/memory/backends/mem0.py +408 -0
- gobby/memory/backends/memu.py +485 -0
- gobby/memory/backends/null.py +111 -0
- gobby/memory/backends/openmemory.py +537 -0
- gobby/memory/backends/sqlite.py +304 -0
- gobby/memory/context.py +87 -0
- gobby/memory/manager.py +1001 -0
- gobby/memory/protocol.py +451 -0
- gobby/memory/search/__init__.py +66 -0
- gobby/memory/search/text.py +127 -0
- gobby/memory/viz.py +258 -0
- gobby/prompts/__init__.py +13 -0
- gobby/prompts/defaults/expansion/system.md +119 -0
- gobby/prompts/defaults/expansion/user.md +48 -0
- gobby/prompts/defaults/external_validation/agent.md +72 -0
- gobby/prompts/defaults/external_validation/external.md +63 -0
- gobby/prompts/defaults/external_validation/spawn.md +83 -0
- gobby/prompts/defaults/external_validation/system.md +6 -0
- gobby/prompts/defaults/features/import_mcp.md +22 -0
- gobby/prompts/defaults/features/import_mcp_github.md +17 -0
- gobby/prompts/defaults/features/import_mcp_search.md +16 -0
- gobby/prompts/defaults/features/recommend_tools.md +32 -0
- gobby/prompts/defaults/features/recommend_tools_hybrid.md +35 -0
- gobby/prompts/defaults/features/recommend_tools_llm.md +30 -0
- gobby/prompts/defaults/features/server_description.md +20 -0
- gobby/prompts/defaults/features/server_description_system.md +6 -0
- gobby/prompts/defaults/features/task_description.md +31 -0
- gobby/prompts/defaults/features/task_description_system.md +6 -0
- gobby/prompts/defaults/features/tool_summary.md +17 -0
- gobby/prompts/defaults/features/tool_summary_system.md +6 -0
- gobby/prompts/defaults/research/step.md +58 -0
- gobby/prompts/defaults/validation/criteria.md +47 -0
- gobby/prompts/defaults/validation/validate.md +38 -0
- gobby/prompts/loader.py +346 -0
- gobby/prompts/models.py +113 -0
- gobby/py.typed +0 -0
- gobby/runner.py +488 -0
- gobby/search/__init__.py +23 -0
- gobby/search/protocol.py +104 -0
- gobby/search/tfidf.py +232 -0
- gobby/servers/__init__.py +7 -0
- gobby/servers/http.py +636 -0
- gobby/servers/models.py +31 -0
- gobby/servers/routes/__init__.py +23 -0
- gobby/servers/routes/admin.py +416 -0
- gobby/servers/routes/dependencies.py +118 -0
- gobby/servers/routes/mcp/__init__.py +24 -0
- gobby/servers/routes/mcp/hooks.py +135 -0
- gobby/servers/routes/mcp/plugins.py +121 -0
- gobby/servers/routes/mcp/tools.py +1337 -0
- gobby/servers/routes/mcp/webhooks.py +159 -0
- gobby/servers/routes/sessions.py +582 -0
- gobby/servers/websocket.py +766 -0
- gobby/sessions/__init__.py +13 -0
- gobby/sessions/analyzer.py +322 -0
- gobby/sessions/lifecycle.py +240 -0
- gobby/sessions/manager.py +563 -0
- gobby/sessions/processor.py +225 -0
- gobby/sessions/summary.py +532 -0
- gobby/sessions/transcripts/__init__.py +41 -0
- gobby/sessions/transcripts/base.py +125 -0
- gobby/sessions/transcripts/claude.py +386 -0
- gobby/sessions/transcripts/codex.py +143 -0
- gobby/sessions/transcripts/gemini.py +195 -0
- gobby/storage/__init__.py +21 -0
- gobby/storage/agents.py +409 -0
- gobby/storage/artifact_classifier.py +341 -0
- gobby/storage/artifacts.py +285 -0
- gobby/storage/compaction.py +67 -0
- gobby/storage/database.py +357 -0
- gobby/storage/inter_session_messages.py +194 -0
- gobby/storage/mcp.py +680 -0
- gobby/storage/memories.py +562 -0
- gobby/storage/merge_resolutions.py +550 -0
- gobby/storage/migrations.py +860 -0
- gobby/storage/migrations_legacy.py +1359 -0
- gobby/storage/projects.py +166 -0
- gobby/storage/session_messages.py +251 -0
- gobby/storage/session_tasks.py +97 -0
- gobby/storage/sessions.py +817 -0
- gobby/storage/task_dependencies.py +223 -0
- gobby/storage/tasks/__init__.py +42 -0
- gobby/storage/tasks/_aggregates.py +180 -0
- gobby/storage/tasks/_crud.py +449 -0
- gobby/storage/tasks/_id.py +104 -0
- gobby/storage/tasks/_lifecycle.py +311 -0
- gobby/storage/tasks/_manager.py +889 -0
- gobby/storage/tasks/_models.py +300 -0
- gobby/storage/tasks/_ordering.py +119 -0
- gobby/storage/tasks/_path_cache.py +110 -0
- gobby/storage/tasks/_queries.py +343 -0
- gobby/storage/tasks/_search.py +143 -0
- gobby/storage/workflow_audit.py +393 -0
- gobby/storage/worktrees.py +547 -0
- gobby/sync/__init__.py +29 -0
- gobby/sync/github.py +333 -0
- gobby/sync/linear.py +304 -0
- gobby/sync/memories.py +284 -0
- gobby/sync/tasks.py +641 -0
- gobby/tasks/__init__.py +8 -0
- gobby/tasks/build_verification.py +193 -0
- gobby/tasks/commits.py +633 -0
- gobby/tasks/context.py +747 -0
- gobby/tasks/criteria.py +342 -0
- gobby/tasks/enhanced_validator.py +226 -0
- gobby/tasks/escalation.py +263 -0
- gobby/tasks/expansion.py +626 -0
- gobby/tasks/external_validator.py +764 -0
- gobby/tasks/issue_extraction.py +171 -0
- gobby/tasks/prompts/expand.py +327 -0
- gobby/tasks/research.py +421 -0
- gobby/tasks/tdd.py +352 -0
- gobby/tasks/tree_builder.py +263 -0
- gobby/tasks/validation.py +712 -0
- gobby/tasks/validation_history.py +357 -0
- gobby/tasks/validation_models.py +89 -0
- gobby/tools/__init__.py +0 -0
- gobby/tools/summarizer.py +170 -0
- gobby/tui/__init__.py +5 -0
- gobby/tui/api_client.py +281 -0
- gobby/tui/app.py +327 -0
- gobby/tui/screens/__init__.py +25 -0
- gobby/tui/screens/agents.py +333 -0
- gobby/tui/screens/chat.py +450 -0
- gobby/tui/screens/dashboard.py +377 -0
- gobby/tui/screens/memory.py +305 -0
- gobby/tui/screens/metrics.py +231 -0
- gobby/tui/screens/orchestrator.py +904 -0
- gobby/tui/screens/sessions.py +412 -0
- gobby/tui/screens/tasks.py +442 -0
- gobby/tui/screens/workflows.py +289 -0
- gobby/tui/screens/worktrees.py +174 -0
- gobby/tui/widgets/__init__.py +21 -0
- gobby/tui/widgets/chat.py +210 -0
- gobby/tui/widgets/conductor.py +104 -0
- gobby/tui/widgets/menu.py +132 -0
- gobby/tui/widgets/message_panel.py +160 -0
- gobby/tui/widgets/review_gate.py +224 -0
- gobby/tui/widgets/task_tree.py +99 -0
- gobby/tui/widgets/token_budget.py +166 -0
- gobby/tui/ws_client.py +258 -0
- gobby/utils/__init__.py +3 -0
- gobby/utils/daemon_client.py +235 -0
- gobby/utils/git.py +222 -0
- gobby/utils/id.py +38 -0
- gobby/utils/json_helpers.py +161 -0
- gobby/utils/logging.py +376 -0
- gobby/utils/machine_id.py +135 -0
- gobby/utils/metrics.py +589 -0
- gobby/utils/project_context.py +182 -0
- gobby/utils/project_init.py +263 -0
- gobby/utils/status.py +256 -0
- gobby/utils/validation.py +80 -0
- gobby/utils/version.py +23 -0
- gobby/workflows/__init__.py +4 -0
- gobby/workflows/actions.py +1310 -0
- gobby/workflows/approval_flow.py +138 -0
- gobby/workflows/artifact_actions.py +103 -0
- gobby/workflows/audit_helpers.py +110 -0
- gobby/workflows/autonomous_actions.py +286 -0
- gobby/workflows/context_actions.py +394 -0
- gobby/workflows/definitions.py +130 -0
- gobby/workflows/detection_helpers.py +208 -0
- gobby/workflows/engine.py +485 -0
- gobby/workflows/evaluator.py +669 -0
- gobby/workflows/git_utils.py +96 -0
- gobby/workflows/hooks.py +169 -0
- gobby/workflows/lifecycle_evaluator.py +613 -0
- gobby/workflows/llm_actions.py +70 -0
- gobby/workflows/loader.py +333 -0
- gobby/workflows/mcp_actions.py +60 -0
- gobby/workflows/memory_actions.py +272 -0
- gobby/workflows/premature_stop.py +164 -0
- gobby/workflows/session_actions.py +139 -0
- gobby/workflows/state_actions.py +123 -0
- gobby/workflows/state_manager.py +104 -0
- gobby/workflows/stop_signal_actions.py +163 -0
- gobby/workflows/summary_actions.py +344 -0
- gobby/workflows/task_actions.py +249 -0
- gobby/workflows/task_enforcement_actions.py +901 -0
- gobby/workflows/templates.py +52 -0
- gobby/workflows/todo_actions.py +84 -0
- gobby/workflows/webhook.py +223 -0
- gobby/workflows/webhook_executor.py +399 -0
- gobby/worktrees/__init__.py +5 -0
- gobby/worktrees/git.py +690 -0
- gobby/worktrees/merge/__init__.py +20 -0
- gobby/worktrees/merge/conflict_parser.py +177 -0
- gobby/worktrees/merge/resolver.py +485 -0
- gobby-0.2.5.dist-info/METADATA +351 -0
- gobby-0.2.5.dist-info/RECORD +383 -0
- gobby-0.2.5.dist-info/WHEEL +5 -0
- gobby-0.2.5.dist-info/entry_points.txt +2 -0
- gobby-0.2.5.dist-info/licenses/LICENSE.md +193 -0
- gobby-0.2.5.dist-info/top_level.txt +1 -0
gobby/cli/worktrees.py
ADDED
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Worktree management CLI commands.
|
|
3
|
+
|
|
4
|
+
Commands for managing git worktrees:
|
|
5
|
+
- create: Create a new worktree
|
|
6
|
+
- list: List worktrees
|
|
7
|
+
- show: Show worktree details
|
|
8
|
+
- delete: Delete a worktree
|
|
9
|
+
- spawn: Spawn an agent in a worktree
|
|
10
|
+
- claim: Claim a worktree for a session
|
|
11
|
+
- release: Release a worktree
|
|
12
|
+
- sync: Sync worktree with main branch
|
|
13
|
+
- stale: Detect stale worktrees
|
|
14
|
+
- cleanup: Clean up stale worktrees
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import json
|
|
18
|
+
|
|
19
|
+
import click
|
|
20
|
+
import httpx
|
|
21
|
+
|
|
22
|
+
from gobby.cli.tasks._utils import get_task_manager, resolve_task_id
|
|
23
|
+
from gobby.cli.utils import resolve_project_ref, resolve_session_id
|
|
24
|
+
from gobby.storage.database import LocalDatabase
|
|
25
|
+
from gobby.storage.worktrees import LocalWorktreeManager
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_worktree_manager() -> LocalWorktreeManager:
|
|
29
|
+
"""Get initialized worktree manager."""
|
|
30
|
+
db = LocalDatabase()
|
|
31
|
+
return LocalWorktreeManager(db)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def get_daemon_url() -> str:
|
|
35
|
+
"""Get daemon URL from config."""
|
|
36
|
+
from gobby.config.app import load_config
|
|
37
|
+
|
|
38
|
+
config = load_config()
|
|
39
|
+
return f"http://localhost:{config.daemon_port}"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@click.group()
|
|
43
|
+
def worktrees() -> None:
|
|
44
|
+
"""Manage git worktrees for parallel development."""
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@worktrees.command("create")
|
|
49
|
+
@click.argument("branch_name")
|
|
50
|
+
@click.option("--base", "-b", "base_branch", default="main", help="Base branch to create from")
|
|
51
|
+
@click.option("--task", "-t", "task_id", help="Link worktree to a task")
|
|
52
|
+
@click.option("--json", "json_format", is_flag=True, help="Output as JSON")
|
|
53
|
+
def create_worktree(
|
|
54
|
+
branch_name: str,
|
|
55
|
+
base_branch: str,
|
|
56
|
+
task_id: str | None,
|
|
57
|
+
json_format: bool,
|
|
58
|
+
) -> None:
|
|
59
|
+
"""Create a new worktree for parallel development.
|
|
60
|
+
|
|
61
|
+
Examples:
|
|
62
|
+
|
|
63
|
+
gobby worktrees create feature/my-feature
|
|
64
|
+
|
|
65
|
+
gobby worktrees create bugfix/fix-123 --base develop --task #47
|
|
66
|
+
"""
|
|
67
|
+
import os
|
|
68
|
+
|
|
69
|
+
daemon_url = get_daemon_url()
|
|
70
|
+
|
|
71
|
+
arguments = {
|
|
72
|
+
"branch_name": branch_name,
|
|
73
|
+
"base_branch": base_branch,
|
|
74
|
+
"project_path": os.getcwd(),
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if task_id:
|
|
78
|
+
task_manager = get_task_manager()
|
|
79
|
+
resolved = resolve_task_id(task_manager, task_id)
|
|
80
|
+
if not resolved:
|
|
81
|
+
# resolve_task_id prints error
|
|
82
|
+
return
|
|
83
|
+
arguments["task_id"] = resolved.id
|
|
84
|
+
|
|
85
|
+
try:
|
|
86
|
+
response = httpx.post(
|
|
87
|
+
f"{daemon_url}/mcp/gobby-worktrees/tools/create_worktree",
|
|
88
|
+
json=arguments,
|
|
89
|
+
timeout=60.0,
|
|
90
|
+
)
|
|
91
|
+
response.raise_for_status()
|
|
92
|
+
result = response.json()
|
|
93
|
+
except httpx.ConnectError:
|
|
94
|
+
click.echo("Error: Cannot connect to Gobby daemon. Is it running?", err=True)
|
|
95
|
+
return
|
|
96
|
+
except httpx.HTTPStatusError as e:
|
|
97
|
+
click.echo(f"HTTP Error {e.response.status_code}: {e.response.text}", err=True)
|
|
98
|
+
return
|
|
99
|
+
except Exception as e:
|
|
100
|
+
click.echo(f"Error: {e}", err=True)
|
|
101
|
+
return
|
|
102
|
+
|
|
103
|
+
if json_format:
|
|
104
|
+
click.echo(json.dumps(result, indent=2, default=str))
|
|
105
|
+
return
|
|
106
|
+
|
|
107
|
+
if result.get("success"):
|
|
108
|
+
click.echo(f"Created worktree: {result.get('worktree_id', 'unknown')}")
|
|
109
|
+
click.echo(f" Path: {result.get('worktree_path', 'unknown')}")
|
|
110
|
+
click.echo(f" Branch: {result.get('branch_name', 'unknown')}")
|
|
111
|
+
else:
|
|
112
|
+
click.echo(f"Failed to create worktree: {result.get('error')}", err=True)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@worktrees.command("list")
|
|
116
|
+
@click.option("--status", "-s", help="Filter by status (active, stale, merged, abandoned)")
|
|
117
|
+
@click.option("--project", "-p", "project_ref", help="Filter by project (name or UUID)")
|
|
118
|
+
@click.option("--json", "json_format", is_flag=True, help="Output as JSON")
|
|
119
|
+
def list_worktrees(
|
|
120
|
+
status: str | None,
|
|
121
|
+
project_ref: str | None,
|
|
122
|
+
json_format: bool,
|
|
123
|
+
) -> None:
|
|
124
|
+
"""List worktrees."""
|
|
125
|
+
project_id = resolve_project_ref(project_ref) if project_ref else None
|
|
126
|
+
manager = get_worktree_manager()
|
|
127
|
+
|
|
128
|
+
worktrees_list = manager.list_worktrees(status=status, project_id=project_id)
|
|
129
|
+
|
|
130
|
+
if json_format:
|
|
131
|
+
click.echo(json.dumps([w.to_dict() for w in worktrees_list], indent=2, default=str))
|
|
132
|
+
return
|
|
133
|
+
|
|
134
|
+
if not worktrees_list:
|
|
135
|
+
click.echo("No worktrees found.")
|
|
136
|
+
return
|
|
137
|
+
|
|
138
|
+
click.echo(f"Found {len(worktrees_list)} worktree(s):\n")
|
|
139
|
+
for wt in worktrees_list:
|
|
140
|
+
status_icon = {
|
|
141
|
+
"active": "●",
|
|
142
|
+
"stale": "○",
|
|
143
|
+
"merged": "✓",
|
|
144
|
+
"abandoned": "✗",
|
|
145
|
+
}.get(wt.status, "?")
|
|
146
|
+
|
|
147
|
+
session_info = f" (session: {wt.agent_session_id[:8]})" if wt.agent_session_id else ""
|
|
148
|
+
click.echo(f"{status_icon} {wt.id} {wt.branch_name:<30} {wt.status:<10}{session_info}")
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
@worktrees.command("show")
|
|
152
|
+
@click.argument("worktree_ref")
|
|
153
|
+
@click.option("--json", "json_format", is_flag=True, help="Output as JSON")
|
|
154
|
+
def show_worktree(worktree_ref: str, json_format: bool) -> None:
|
|
155
|
+
"""Show details for a worktree (UUID or prefix)."""
|
|
156
|
+
manager = get_worktree_manager()
|
|
157
|
+
worktree_id = resolve_worktree_id(manager, worktree_ref)
|
|
158
|
+
worktree = manager.get(worktree_id)
|
|
159
|
+
|
|
160
|
+
if not worktree:
|
|
161
|
+
click.echo(f"Worktree not found: {worktree_id}", err=True)
|
|
162
|
+
return
|
|
163
|
+
|
|
164
|
+
if json_format:
|
|
165
|
+
click.echo(json.dumps(worktree.to_dict(), indent=2, default=str))
|
|
166
|
+
return
|
|
167
|
+
|
|
168
|
+
click.echo(f"Worktree: {worktree.id}")
|
|
169
|
+
click.echo(f" Status: {worktree.status}")
|
|
170
|
+
click.echo(f" Branch: {worktree.branch_name}")
|
|
171
|
+
click.echo(f" Path: {worktree.worktree_path}")
|
|
172
|
+
click.echo(f" Base Branch: {worktree.base_branch}")
|
|
173
|
+
if worktree.project_id:
|
|
174
|
+
click.echo(f" Project: {worktree.project_id}")
|
|
175
|
+
if worktree.agent_session_id:
|
|
176
|
+
click.echo(f" Session: {worktree.agent_session_id}")
|
|
177
|
+
click.echo(f" Created: {worktree.created_at}")
|
|
178
|
+
click.echo(f" Updated: {worktree.updated_at}")
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
@worktrees.command("delete")
|
|
182
|
+
@click.argument("worktree_ref")
|
|
183
|
+
@click.option("--force", "-f", is_flag=True, help="Force delete even if active")
|
|
184
|
+
@click.option("--yes", "-y", is_flag=True, help="Skip confirmation prompt")
|
|
185
|
+
def delete_worktree(worktree_ref: str, force: bool, yes: bool) -> None:
|
|
186
|
+
"""Delete a worktree (UUID or prefix)."""
|
|
187
|
+
if not yes:
|
|
188
|
+
click.confirm("Are you sure you want to delete this worktree?", abort=True)
|
|
189
|
+
|
|
190
|
+
manager = get_worktree_manager()
|
|
191
|
+
try:
|
|
192
|
+
worktree_id = resolve_worktree_id(manager, worktree_ref)
|
|
193
|
+
except click.ClickException as e:
|
|
194
|
+
click.echo(str(e), err=True)
|
|
195
|
+
return
|
|
196
|
+
|
|
197
|
+
daemon_url = get_daemon_url()
|
|
198
|
+
|
|
199
|
+
try:
|
|
200
|
+
response = httpx.post(
|
|
201
|
+
f"{daemon_url}/mcp/gobby-worktrees/tools/delete_worktree",
|
|
202
|
+
json={"worktree_id": worktree_id, "force": force},
|
|
203
|
+
timeout=30.0,
|
|
204
|
+
)
|
|
205
|
+
response.raise_for_status()
|
|
206
|
+
result = response.json()
|
|
207
|
+
except httpx.ConnectError:
|
|
208
|
+
click.echo("Error: Cannot connect to Gobby daemon. Is it running?", err=True)
|
|
209
|
+
return
|
|
210
|
+
except httpx.HTTPStatusError as e:
|
|
211
|
+
click.echo(f"HTTP Error {e.response.status_code}: {e.response.text}", err=True)
|
|
212
|
+
return
|
|
213
|
+
except Exception as e:
|
|
214
|
+
click.echo(f"Error: {e}", err=True)
|
|
215
|
+
return
|
|
216
|
+
|
|
217
|
+
if result.get("success"):
|
|
218
|
+
click.echo(f"Deleted worktree: {worktree_id}")
|
|
219
|
+
else:
|
|
220
|
+
click.echo(f"Failed to delete worktree: {result.get('error')}", err=True)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
# ... spawn command is unchanged ...
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
@worktrees.command("claim")
|
|
227
|
+
@click.argument("worktree_ref")
|
|
228
|
+
@click.argument("session_id")
|
|
229
|
+
def claim_worktree(worktree_ref: str, session_id: str) -> None:
|
|
230
|
+
"""Claim a worktree for a session (UUID or prefix)."""
|
|
231
|
+
try:
|
|
232
|
+
session_id = resolve_session_id(session_id)
|
|
233
|
+
except click.ClickException as e:
|
|
234
|
+
e.show()
|
|
235
|
+
raise SystemExit(1) from e
|
|
236
|
+
|
|
237
|
+
manager = get_worktree_manager()
|
|
238
|
+
try:
|
|
239
|
+
worktree_id = resolve_worktree_id(manager, worktree_ref)
|
|
240
|
+
except click.ClickException as e:
|
|
241
|
+
raise SystemExit(1) from e
|
|
242
|
+
|
|
243
|
+
result = manager.claim(worktree_id, session_id)
|
|
244
|
+
if result:
|
|
245
|
+
click.echo(f"Claimed worktree {worktree_id} for session {session_id}")
|
|
246
|
+
else:
|
|
247
|
+
click.echo(f"Failed to claim worktree {worktree_id}", err=True)
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
@worktrees.command("release")
|
|
251
|
+
@click.argument("worktree_ref")
|
|
252
|
+
def release_worktree(worktree_ref: str) -> None:
|
|
253
|
+
"""Release a worktree (UUID or prefix)."""
|
|
254
|
+
manager = get_worktree_manager()
|
|
255
|
+
try:
|
|
256
|
+
worktree_id = resolve_worktree_id(manager, worktree_ref)
|
|
257
|
+
except click.ClickException as e:
|
|
258
|
+
raise SystemExit(1) from e
|
|
259
|
+
|
|
260
|
+
result = manager.release(worktree_id)
|
|
261
|
+
if result:
|
|
262
|
+
click.echo(f"Released worktree {worktree_id}")
|
|
263
|
+
else:
|
|
264
|
+
click.echo(f"Failed to release worktree {worktree_id}", err=True)
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
@worktrees.command("sync")
|
|
268
|
+
@click.argument("worktree_ref")
|
|
269
|
+
@click.option(
|
|
270
|
+
"--source", "-s", "source_branch", help="Source branch to sync from (default: base branch)"
|
|
271
|
+
)
|
|
272
|
+
@click.option("--json", "json_format", is_flag=True, help="Output as JSON")
|
|
273
|
+
def sync_worktree(worktree_ref: str, source_branch: str | None, json_format: bool) -> None:
|
|
274
|
+
"""Sync worktree with its base branch (UUID or prefix)."""
|
|
275
|
+
manager = get_worktree_manager()
|
|
276
|
+
try:
|
|
277
|
+
worktree_id = resolve_worktree_id(manager, worktree_ref)
|
|
278
|
+
except click.ClickException as e:
|
|
279
|
+
click.echo(str(e), err=True)
|
|
280
|
+
return
|
|
281
|
+
|
|
282
|
+
daemon_url = get_daemon_url()
|
|
283
|
+
|
|
284
|
+
arguments = {"worktree_id": worktree_id}
|
|
285
|
+
if source_branch:
|
|
286
|
+
arguments["source_branch"] = source_branch
|
|
287
|
+
|
|
288
|
+
try:
|
|
289
|
+
response = httpx.post(
|
|
290
|
+
f"{daemon_url}/mcp/gobby-worktrees/tools/sync_worktree",
|
|
291
|
+
json=arguments,
|
|
292
|
+
timeout=60.0,
|
|
293
|
+
)
|
|
294
|
+
response.raise_for_status()
|
|
295
|
+
result = response.json()
|
|
296
|
+
except httpx.ConnectError:
|
|
297
|
+
click.echo("Error: Cannot connect to Gobby daemon. Is it running?", err=True)
|
|
298
|
+
return
|
|
299
|
+
except httpx.HTTPStatusError as e:
|
|
300
|
+
click.echo(f"HTTP Error {e.response.status_code}: {e.response.text}", err=True)
|
|
301
|
+
return
|
|
302
|
+
except Exception as e:
|
|
303
|
+
click.echo(f"Error: {e}", err=True)
|
|
304
|
+
return
|
|
305
|
+
|
|
306
|
+
if json_format:
|
|
307
|
+
click.echo(json.dumps(result, indent=2, default=str))
|
|
308
|
+
return
|
|
309
|
+
|
|
310
|
+
if result.get("success"):
|
|
311
|
+
click.echo(f"Synced worktree {worktree_id}")
|
|
312
|
+
if result.get("commits_behind"):
|
|
313
|
+
click.echo(f" Commits merged: {result['commits_behind']}")
|
|
314
|
+
else:
|
|
315
|
+
click.echo(f"Failed to sync worktree: {result.get('error')}", err=True)
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
# ... stale/cleanup/stats commands ...
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def resolve_worktree_id(manager: LocalWorktreeManager, worktree_ref: str) -> str:
|
|
322
|
+
"""Resolve worktree reference (UUID or prefix) to full ID."""
|
|
323
|
+
# Optimization: check 36 chars?
|
|
324
|
+
if len(worktree_ref) == 36 and manager.get(worktree_ref):
|
|
325
|
+
return worktree_ref
|
|
326
|
+
|
|
327
|
+
# Use list listing since local manager doesn't expose prefix search easily
|
|
328
|
+
all_worktrees = manager.list_worktrees()
|
|
329
|
+
matches = [w for w in all_worktrees if w.id.startswith(worktree_ref)]
|
|
330
|
+
|
|
331
|
+
if not matches:
|
|
332
|
+
raise click.ClickException(f"Worktree not found: {worktree_ref}")
|
|
333
|
+
|
|
334
|
+
if len(matches) > 1:
|
|
335
|
+
click.echo(f"Ambiguous worktree reference '{worktree_ref}' matches:", err=True)
|
|
336
|
+
for w in matches:
|
|
337
|
+
click.echo(f" {w.id[:8]} ({w.branch_name})", err=True)
|
|
338
|
+
raise click.ClickException(f"Ambiguous worktree reference: {worktree_ref}")
|
|
339
|
+
|
|
340
|
+
return matches[0].id
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
@worktrees.command("stale")
|
|
344
|
+
@click.option("--days", "-d", default=7, help="Days of inactivity to consider stale")
|
|
345
|
+
@click.option("--json", "json_format", is_flag=True, help="Output as JSON")
|
|
346
|
+
def detect_stale(days: int, json_format: bool) -> None:
|
|
347
|
+
"""Detect stale worktrees."""
|
|
348
|
+
daemon_url = get_daemon_url()
|
|
349
|
+
# Convert days to hours for MCP tool
|
|
350
|
+
hours = days * 24
|
|
351
|
+
|
|
352
|
+
try:
|
|
353
|
+
response = httpx.post(
|
|
354
|
+
f"{daemon_url}/mcp/gobby-worktrees/tools/detect_stale_worktrees",
|
|
355
|
+
json={"hours": hours},
|
|
356
|
+
timeout=30.0,
|
|
357
|
+
)
|
|
358
|
+
response.raise_for_status()
|
|
359
|
+
result = response.json()
|
|
360
|
+
except httpx.ConnectError:
|
|
361
|
+
click.echo("Error: Cannot connect to Gobby daemon. Is it running?", err=True)
|
|
362
|
+
return
|
|
363
|
+
except httpx.HTTPStatusError as e:
|
|
364
|
+
click.echo(f"HTTP Error {e.response.status_code}: {e.response.text}", err=True)
|
|
365
|
+
return
|
|
366
|
+
except Exception as e:
|
|
367
|
+
click.echo(f"Error: {e}", err=True)
|
|
368
|
+
return
|
|
369
|
+
|
|
370
|
+
if json_format:
|
|
371
|
+
click.echo(json.dumps(result, indent=2, default=str))
|
|
372
|
+
return
|
|
373
|
+
|
|
374
|
+
stale = result.get("stale_worktrees", [])
|
|
375
|
+
if not stale:
|
|
376
|
+
click.echo(f"No stale worktrees found (inactive > {days} days)")
|
|
377
|
+
return
|
|
378
|
+
|
|
379
|
+
click.echo(f"Found {len(stale)} stale worktree(s) (inactive > {days} days):\n")
|
|
380
|
+
for wt in stale:
|
|
381
|
+
click.echo(
|
|
382
|
+
f" {wt['id']}: {wt['branch_name']} (last updated: {wt.get('updated_at', 'unknown')})"
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
@worktrees.command("cleanup")
|
|
387
|
+
@click.option("--days", "-d", default=7, help="Days of inactivity to consider stale")
|
|
388
|
+
@click.option("--dry-run", is_flag=True, help="Show what would be cleaned up")
|
|
389
|
+
@click.option("--yes", "-y", is_flag=True, help="Skip confirmation prompt")
|
|
390
|
+
def cleanup_worktrees(days: int, dry_run: bool, yes: bool) -> None:
|
|
391
|
+
"""Clean up stale worktrees."""
|
|
392
|
+
daemon_url = get_daemon_url()
|
|
393
|
+
# Convert days to hours for MCP tool
|
|
394
|
+
hours = days * 24
|
|
395
|
+
|
|
396
|
+
if dry_run:
|
|
397
|
+
# Just detect stale - no confirmation needed
|
|
398
|
+
try:
|
|
399
|
+
response = httpx.post(
|
|
400
|
+
f"{daemon_url}/mcp/gobby-worktrees/tools/detect_stale_worktrees",
|
|
401
|
+
json={"hours": hours},
|
|
402
|
+
timeout=30.0,
|
|
403
|
+
)
|
|
404
|
+
response.raise_for_status()
|
|
405
|
+
result = response.json()
|
|
406
|
+
stale = result.get("stale_worktrees", [])
|
|
407
|
+
click.echo(f"Would cleanup {len(stale)} stale worktree(s)")
|
|
408
|
+
for wt in stale:
|
|
409
|
+
click.echo(f" {wt['id']}: {wt['branch_name']}")
|
|
410
|
+
except Exception as e:
|
|
411
|
+
click.echo(f"Error: {e}", err=True)
|
|
412
|
+
return
|
|
413
|
+
|
|
414
|
+
# Confirm before actual cleanup unless --yes is provided
|
|
415
|
+
if not yes:
|
|
416
|
+
click.confirm("Are you sure you want to cleanup stale worktrees?", abort=True)
|
|
417
|
+
|
|
418
|
+
try:
|
|
419
|
+
response = httpx.post(
|
|
420
|
+
f"{daemon_url}/mcp/gobby-worktrees/tools/cleanup_stale_worktrees",
|
|
421
|
+
json={"hours": hours, "dry_run": False},
|
|
422
|
+
timeout=120.0,
|
|
423
|
+
)
|
|
424
|
+
response.raise_for_status()
|
|
425
|
+
result = response.json()
|
|
426
|
+
except httpx.ConnectError:
|
|
427
|
+
click.echo("Error: Cannot connect to Gobby daemon. Is it running?", err=True)
|
|
428
|
+
return
|
|
429
|
+
except httpx.HTTPStatusError as e:
|
|
430
|
+
click.echo(f"HTTP Error {e.response.status_code}: {e.response.text}", err=True)
|
|
431
|
+
return
|
|
432
|
+
except Exception as e:
|
|
433
|
+
click.echo(f"Error: {e}", err=True)
|
|
434
|
+
return
|
|
435
|
+
|
|
436
|
+
if result.get("success"):
|
|
437
|
+
cleaned = result.get("count", 0)
|
|
438
|
+
click.echo(f"Cleaned up {cleaned} stale worktree(s)")
|
|
439
|
+
else:
|
|
440
|
+
click.echo(f"Failed to cleanup worktrees: {result.get('error')}", err=True)
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
@worktrees.command("stats")
|
|
444
|
+
@click.option("--json", "json_format", is_flag=True, help="Output as JSON")
|
|
445
|
+
def worktree_stats(json_format: bool) -> None:
|
|
446
|
+
"""Show worktree statistics."""
|
|
447
|
+
import os
|
|
448
|
+
|
|
449
|
+
daemon_url = get_daemon_url()
|
|
450
|
+
|
|
451
|
+
try:
|
|
452
|
+
response = httpx.post(
|
|
453
|
+
f"{daemon_url}/mcp/gobby-worktrees/tools/get_worktree_stats",
|
|
454
|
+
json={"project_path": os.getcwd()},
|
|
455
|
+
timeout=10.0,
|
|
456
|
+
)
|
|
457
|
+
response.raise_for_status()
|
|
458
|
+
result = response.json()
|
|
459
|
+
except httpx.ConnectError:
|
|
460
|
+
click.echo("Error: Cannot connect to Gobby daemon. Is it running?", err=True)
|
|
461
|
+
return
|
|
462
|
+
except httpx.HTTPStatusError as e:
|
|
463
|
+
click.echo(f"HTTP Error {e.response.status_code}: {e.response.text}", err=True)
|
|
464
|
+
return
|
|
465
|
+
except Exception as e:
|
|
466
|
+
click.echo(f"Error: {e}", err=True)
|
|
467
|
+
return
|
|
468
|
+
|
|
469
|
+
if json_format:
|
|
470
|
+
click.echo(json.dumps(result, indent=2, default=str))
|
|
471
|
+
return
|
|
472
|
+
|
|
473
|
+
counts = result.get("counts", {})
|
|
474
|
+
total = result.get("total", 0)
|
|
475
|
+
click.echo("Worktree Statistics:")
|
|
476
|
+
click.echo(f" Total: {total}")
|
|
477
|
+
click.echo(f" Active: {counts.get('active', 0)}")
|
|
478
|
+
click.echo(f" Stale: {counts.get('stale', 0)}")
|
|
479
|
+
click.echo(f" Merged: {counts.get('merged', 0)}")
|
|
480
|
+
click.echo(f" Abandoned: {counts.get('abandoned', 0)}")
|
|
481
|
+
click.echo(f" With Sessions: {counts.get('with_sessions', 0)}")
|
gobby/config/__init__.py
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configuration package for Gobby daemon.
|
|
3
|
+
|
|
4
|
+
This package provides Pydantic config models for all daemon settings.
|
|
5
|
+
Configuration classes are organized into submodules by functionality:
|
|
6
|
+
|
|
7
|
+
Module structure:
|
|
8
|
+
- app.py: Main DaemonConfig aggregator and utility functions
|
|
9
|
+
- logging.py: LoggingSettings
|
|
10
|
+
- servers.py: WebSocket and MCP proxy configs
|
|
11
|
+
- llm_providers.py: LLM provider configurations
|
|
12
|
+
- persistence.py: Memory storage configs
|
|
13
|
+
- tasks.py: Task expansion, validation, and workflow configs
|
|
14
|
+
- extensions.py: Hook extension configs (webhooks, plugins)
|
|
15
|
+
- sessions.py: Session lifecycle and tracking configs
|
|
16
|
+
- features.py: MCP proxy feature configs (code execution, tool recommendation)
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
# Core configuration and utilities from app.py
|
|
20
|
+
from gobby.config.app import (
|
|
21
|
+
DaemonConfig,
|
|
22
|
+
expand_env_vars,
|
|
23
|
+
load_config,
|
|
24
|
+
save_config,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# Extension configs
|
|
28
|
+
from gobby.config.extensions import (
|
|
29
|
+
HookExtensionsConfig,
|
|
30
|
+
PluginItemConfig,
|
|
31
|
+
PluginsConfig,
|
|
32
|
+
WebhookEndpointConfig,
|
|
33
|
+
WebhooksConfig,
|
|
34
|
+
WebSocketBroadcastConfig,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# Feature configs
|
|
38
|
+
from gobby.config.features import (
|
|
39
|
+
ImportMCPServerConfig,
|
|
40
|
+
MetricsConfig,
|
|
41
|
+
ProjectVerificationConfig,
|
|
42
|
+
RecommendToolsConfig,
|
|
43
|
+
ToolSummarizerConfig,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
# LLM provider configs
|
|
47
|
+
from gobby.config.llm_providers import (
|
|
48
|
+
LLMProviderConfig,
|
|
49
|
+
LLMProvidersConfig,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# Logging configs
|
|
53
|
+
from gobby.config.logging import LoggingSettings
|
|
54
|
+
|
|
55
|
+
# Persistence configs
|
|
56
|
+
from gobby.config.persistence import (
|
|
57
|
+
MemoryConfig,
|
|
58
|
+
MemorySyncConfig,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
# Server configs
|
|
62
|
+
from gobby.config.servers import (
|
|
63
|
+
MCPClientProxyConfig,
|
|
64
|
+
WebSocketSettings,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# Session configs
|
|
68
|
+
from gobby.config.sessions import (
|
|
69
|
+
ContextInjectionConfig,
|
|
70
|
+
MessageTrackingConfig,
|
|
71
|
+
SessionLifecycleConfig,
|
|
72
|
+
SessionSummaryConfig,
|
|
73
|
+
TitleSynthesisConfig,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# Task configs
|
|
77
|
+
from gobby.config.tasks import (
|
|
78
|
+
CompactHandoffConfig,
|
|
79
|
+
GobbyTasksConfig,
|
|
80
|
+
PatternCriteriaConfig,
|
|
81
|
+
TaskExpansionConfig,
|
|
82
|
+
TaskValidationConfig,
|
|
83
|
+
WorkflowConfig,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
__all__ = [
|
|
87
|
+
# Core
|
|
88
|
+
"DaemonConfig",
|
|
89
|
+
"expand_env_vars",
|
|
90
|
+
"load_config",
|
|
91
|
+
"save_config",
|
|
92
|
+
# Extension configs
|
|
93
|
+
"HookExtensionsConfig",
|
|
94
|
+
"PluginItemConfig",
|
|
95
|
+
"PluginsConfig",
|
|
96
|
+
"WebhookEndpointConfig",
|
|
97
|
+
"WebhooksConfig",
|
|
98
|
+
"WebSocketBroadcastConfig",
|
|
99
|
+
# Feature configs
|
|
100
|
+
"ImportMCPServerConfig",
|
|
101
|
+
"MetricsConfig",
|
|
102
|
+
"ProjectVerificationConfig",
|
|
103
|
+
"RecommendToolsConfig",
|
|
104
|
+
"ToolSummarizerConfig",
|
|
105
|
+
# LLM provider configs
|
|
106
|
+
"LLMProviderConfig",
|
|
107
|
+
"LLMProvidersConfig",
|
|
108
|
+
# Logging configs
|
|
109
|
+
"LoggingSettings",
|
|
110
|
+
# Persistence configs
|
|
111
|
+
"MemoryConfig",
|
|
112
|
+
"MemorySyncConfig",
|
|
113
|
+
# Server configs
|
|
114
|
+
"MCPClientProxyConfig",
|
|
115
|
+
"WebSocketSettings",
|
|
116
|
+
# Session configs
|
|
117
|
+
"ContextInjectionConfig",
|
|
118
|
+
"MessageTrackingConfig",
|
|
119
|
+
"SessionLifecycleConfig",
|
|
120
|
+
"SessionSummaryConfig",
|
|
121
|
+
"TitleSynthesisConfig",
|
|
122
|
+
# Task configs
|
|
123
|
+
"CompactHandoffConfig",
|
|
124
|
+
"GobbyTasksConfig",
|
|
125
|
+
"PatternCriteriaConfig",
|
|
126
|
+
"TaskExpansionConfig",
|
|
127
|
+
"TaskValidationConfig",
|
|
128
|
+
"WorkflowConfig",
|
|
129
|
+
]
|