gobby 0.2.5__py3-none-any.whl → 0.2.6__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/adapters/claude_code.py +13 -4
- gobby/adapters/codex.py +43 -3
- gobby/agents/runner.py +8 -0
- gobby/cli/__init__.py +6 -0
- gobby/cli/clones.py +419 -0
- gobby/cli/conductor.py +266 -0
- gobby/cli/installers/antigravity.py +3 -9
- gobby/cli/installers/claude.py +9 -9
- gobby/cli/installers/codex.py +2 -8
- gobby/cli/installers/gemini.py +2 -8
- gobby/cli/installers/shared.py +71 -8
- 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 +3 -3
- 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/app.py +63 -1
- gobby/config/search.py +110 -0
- gobby/config/servers.py +1 -1
- gobby/config/skills.py +43 -0
- gobby/config/tasks.py +6 -14
- gobby/hooks/event_handlers.py +145 -2
- gobby/hooks/hook_manager.py +48 -2
- gobby/hooks/skill_manager.py +130 -0
- 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 +95 -33
- gobby/mcp_proxy/instructions.py +54 -0
- gobby/mcp_proxy/models.py +15 -0
- gobby/mcp_proxy/registries.py +68 -5
- gobby/mcp_proxy/server.py +33 -3
- 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/clones.py +903 -0
- gobby/mcp_proxy/tools/memory.py +1 -24
- 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/session_messages.py +1 -2
- gobby/mcp_proxy/tools/skills/__init__.py +631 -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 +60 -29
- gobby/mcp_proxy/tools/tasks/_lifecycle_validation.py +18 -29
- gobby/mcp_proxy/tools/workflows.py +1 -1
- gobby/mcp_proxy/tools/worktrees.py +5 -0
- gobby/memory/backends/__init__.py +6 -1
- gobby/memory/backends/mem0.py +6 -1
- gobby/memory/extractor.py +477 -0
- gobby/memory/manager.py +11 -2
- gobby/prompts/defaults/handoff/compact.md +63 -0
- gobby/prompts/defaults/handoff/session_end.md +57 -0
- gobby/prompts/defaults/memory/extract.md +61 -0
- 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 +23 -8
- gobby/servers/routes/admin.py +280 -0
- gobby/servers/routes/mcp/tools.py +241 -52
- gobby/servers/websocket.py +2 -2
- gobby/sessions/analyzer.py +2 -0
- gobby/sessions/transcripts/base.py +1 -0
- gobby/sessions/transcripts/claude.py +64 -5
- gobby/skills/__init__.py +91 -0
- gobby/skills/loader.py +685 -0
- gobby/skills/manager.py +384 -0
- gobby/skills/parser.py +258 -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 +180 -6
- gobby/storage/sessions.py +73 -0
- gobby/storage/skills.py +749 -0
- gobby/storage/tasks/_crud.py +4 -4
- gobby/storage/tasks/_lifecycle.py +41 -6
- gobby/storage/tasks/_manager.py +14 -5
- gobby/storage/tasks/_models.py +8 -3
- gobby/sync/memories.py +39 -4
- gobby/sync/tasks.py +83 -6
- gobby/tasks/__init__.py +1 -2
- gobby/tasks/validation.py +24 -15
- 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/workflows/actions.py +84 -2
- gobby/workflows/context_actions.py +43 -0
- gobby/workflows/detection_helpers.py +115 -31
- gobby/workflows/engine.py +13 -2
- gobby/workflows/lifecycle_evaluator.py +29 -1
- gobby/workflows/loader.py +19 -6
- gobby/workflows/memory_actions.py +74 -0
- gobby/workflows/summary_actions.py +17 -0
- gobby/workflows/task_enforcement_actions.py +448 -6
- {gobby-0.2.5.dist-info → gobby-0.2.6.dist-info}/METADATA +82 -21
- {gobby-0.2.5.dist-info → gobby-0.2.6.dist-info}/RECORD +136 -107
- 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/task_expansion.py +0 -591
- 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.6.dist-info}/WHEEL +0 -0
- {gobby-0.2.5.dist-info → gobby-0.2.6.dist-info}/entry_points.txt +0 -0
- {gobby-0.2.5.dist-info → gobby-0.2.6.dist-info}/licenses/LICENSE.md +0 -0
- {gobby-0.2.5.dist-info → gobby-0.2.6.dist-info}/top_level.txt +0 -0
gobby/tasks/criteria.py
DELETED
|
@@ -1,342 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Criteria generation for task expansion.
|
|
3
|
-
|
|
4
|
-
This module provides:
|
|
5
|
-
- PatternCriteriaInjector: Detects patterns from labels/descriptions and injects criteria
|
|
6
|
-
- CriteriaGenerator: Shared criteria generator for both structured and LLM expansion
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
from __future__ import annotations
|
|
10
|
-
|
|
11
|
-
import logging
|
|
12
|
-
import re
|
|
13
|
-
from typing import TYPE_CHECKING
|
|
14
|
-
|
|
15
|
-
if TYPE_CHECKING:
|
|
16
|
-
from gobby.config.app import PatternCriteriaConfig, ProjectVerificationConfig
|
|
17
|
-
from gobby.storage.tasks import Task
|
|
18
|
-
from gobby.tasks.context import ExpansionContext
|
|
19
|
-
|
|
20
|
-
logger = logging.getLogger(__name__)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class PatternCriteriaInjector:
|
|
24
|
-
"""Injects pattern-specific validation criteria into task expansion.
|
|
25
|
-
|
|
26
|
-
Detects patterns from:
|
|
27
|
-
- Task labels (e.g., 'strangler-fig', 'tdd')
|
|
28
|
-
- Description keywords (e.g., 'using strangler fig pattern')
|
|
29
|
-
|
|
30
|
-
Then injects appropriate criteria templates with placeholders replaced
|
|
31
|
-
by actual verification commands from project config.
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
def __init__(
|
|
35
|
-
self,
|
|
36
|
-
pattern_config: PatternCriteriaConfig,
|
|
37
|
-
verification_config: ProjectVerificationConfig | None = None,
|
|
38
|
-
):
|
|
39
|
-
"""Initialize the injector.
|
|
40
|
-
|
|
41
|
-
Args:
|
|
42
|
-
pattern_config: Pattern criteria configuration with templates
|
|
43
|
-
verification_config: Project verification commands for placeholder substitution
|
|
44
|
-
"""
|
|
45
|
-
self.pattern_config = pattern_config
|
|
46
|
-
self.verification_config = verification_config
|
|
47
|
-
|
|
48
|
-
def detect_patterns(
|
|
49
|
-
self,
|
|
50
|
-
task: Task,
|
|
51
|
-
labels: list[str] | None = None,
|
|
52
|
-
) -> list[str]:
|
|
53
|
-
"""Detect which patterns apply to a task.
|
|
54
|
-
|
|
55
|
-
Args:
|
|
56
|
-
task: The task to analyze
|
|
57
|
-
labels: Optional explicit labels (overrides task.labels)
|
|
58
|
-
|
|
59
|
-
Returns:
|
|
60
|
-
List of detected pattern names
|
|
61
|
-
"""
|
|
62
|
-
detected: list[str] = []
|
|
63
|
-
task_labels = labels if labels is not None else (task.labels or [])
|
|
64
|
-
|
|
65
|
-
# Normalize labels to lowercase for matching
|
|
66
|
-
normalized_labels = [label.lower() for label in task_labels]
|
|
67
|
-
|
|
68
|
-
# Check labels first (direct match)
|
|
69
|
-
for pattern_name in self.pattern_config.patterns.keys():
|
|
70
|
-
if pattern_name.lower() in normalized_labels:
|
|
71
|
-
if pattern_name not in detected:
|
|
72
|
-
detected.append(pattern_name)
|
|
73
|
-
logger.debug(f"Detected pattern '{pattern_name}' from task labels")
|
|
74
|
-
|
|
75
|
-
# Check description keywords
|
|
76
|
-
description = (task.description or "").lower()
|
|
77
|
-
title = (task.title or "").lower()
|
|
78
|
-
text_to_search = f"{title} {description}"
|
|
79
|
-
|
|
80
|
-
for pattern_name, keywords in self.pattern_config.detection_keywords.items():
|
|
81
|
-
if pattern_name in detected:
|
|
82
|
-
continue # Already detected from labels
|
|
83
|
-
|
|
84
|
-
for keyword in keywords:
|
|
85
|
-
if keyword.lower() in text_to_search:
|
|
86
|
-
detected.append(pattern_name)
|
|
87
|
-
logger.debug(
|
|
88
|
-
f"Detected pattern '{pattern_name}' from keyword '{keyword}' in description"
|
|
89
|
-
)
|
|
90
|
-
break
|
|
91
|
-
|
|
92
|
-
return detected
|
|
93
|
-
|
|
94
|
-
def _get_placeholder_values(self) -> dict[str, str]:
|
|
95
|
-
"""Get placeholder values from verification config.
|
|
96
|
-
|
|
97
|
-
Returns:
|
|
98
|
-
Dict mapping placeholder names to their values
|
|
99
|
-
"""
|
|
100
|
-
values: dict[str, str] = {}
|
|
101
|
-
|
|
102
|
-
if self.verification_config:
|
|
103
|
-
if self.verification_config.unit_tests:
|
|
104
|
-
values["unit_tests"] = self.verification_config.unit_tests
|
|
105
|
-
if self.verification_config.type_check:
|
|
106
|
-
values["type_check"] = self.verification_config.type_check
|
|
107
|
-
if self.verification_config.lint:
|
|
108
|
-
values["lint"] = self.verification_config.lint
|
|
109
|
-
if self.verification_config.integration:
|
|
110
|
-
values["integration"] = self.verification_config.integration
|
|
111
|
-
|
|
112
|
-
# Add any custom verification commands
|
|
113
|
-
for name, cmd in self.verification_config.custom.items():
|
|
114
|
-
values[name] = cmd
|
|
115
|
-
|
|
116
|
-
return values
|
|
117
|
-
|
|
118
|
-
def _substitute_placeholders(
|
|
119
|
-
self,
|
|
120
|
-
template: str,
|
|
121
|
-
extra_values: dict[str, str] | None = None,
|
|
122
|
-
) -> str:
|
|
123
|
-
"""Substitute placeholders in a template string.
|
|
124
|
-
|
|
125
|
-
Args:
|
|
126
|
-
template: Template string with {placeholder} syntax
|
|
127
|
-
extra_values: Additional values to substitute
|
|
128
|
-
|
|
129
|
-
Returns:
|
|
130
|
-
String with placeholders replaced
|
|
131
|
-
"""
|
|
132
|
-
values = self._get_placeholder_values()
|
|
133
|
-
if extra_values:
|
|
134
|
-
values.update(extra_values)
|
|
135
|
-
|
|
136
|
-
# Use a regex to find placeholders and replace only those we have values for
|
|
137
|
-
def replace_placeholder(match: re.Match[str]) -> str:
|
|
138
|
-
key = match.group(1)
|
|
139
|
-
return values.get(key, match.group(0)) # Keep original if no value
|
|
140
|
-
|
|
141
|
-
return re.sub(r"\{(\w+)\}", replace_placeholder, template)
|
|
142
|
-
|
|
143
|
-
def inject(
|
|
144
|
-
self,
|
|
145
|
-
task: Task,
|
|
146
|
-
context: ExpansionContext | None = None,
|
|
147
|
-
labels: list[str] | None = None,
|
|
148
|
-
extra_placeholders: dict[str, str] | None = None,
|
|
149
|
-
) -> str:
|
|
150
|
-
"""Generate pattern-specific criteria markdown for a task.
|
|
151
|
-
|
|
152
|
-
Args:
|
|
153
|
-
task: The task to generate criteria for
|
|
154
|
-
context: Optional expansion context (unused currently, for future extensibility)
|
|
155
|
-
labels: Optional explicit labels (overrides task.labels)
|
|
156
|
-
extra_placeholders: Additional placeholder values for substitution
|
|
157
|
-
|
|
158
|
-
Returns:
|
|
159
|
-
Markdown-formatted criteria string, empty if no patterns detected
|
|
160
|
-
"""
|
|
161
|
-
detected_patterns = self.detect_patterns(task, labels)
|
|
162
|
-
|
|
163
|
-
if not detected_patterns:
|
|
164
|
-
return ""
|
|
165
|
-
|
|
166
|
-
sections: list[str] = []
|
|
167
|
-
|
|
168
|
-
for pattern_name in detected_patterns:
|
|
169
|
-
templates = self.pattern_config.patterns.get(pattern_name, [])
|
|
170
|
-
if not templates:
|
|
171
|
-
continue
|
|
172
|
-
|
|
173
|
-
criteria_lines: list[str] = []
|
|
174
|
-
for template in templates:
|
|
175
|
-
substituted = self._substitute_placeholders(template, extra_placeholders)
|
|
176
|
-
criteria_lines.append(f"- [ ] {substituted}")
|
|
177
|
-
|
|
178
|
-
if criteria_lines:
|
|
179
|
-
# Format pattern name nicely (e.g., "strangler-fig" -> "Strangler-Fig Pattern")
|
|
180
|
-
pattern_title = pattern_name.replace("-", " ").title()
|
|
181
|
-
section = f"## {pattern_title} Pattern Criteria\n\n" + "\n".join(criteria_lines)
|
|
182
|
-
sections.append(section)
|
|
183
|
-
|
|
184
|
-
return "\n\n".join(sections)
|
|
185
|
-
|
|
186
|
-
def inject_for_labels(
|
|
187
|
-
self,
|
|
188
|
-
labels: list[str],
|
|
189
|
-
task: Task | None = None,
|
|
190
|
-
extra_placeholders: dict[str, str] | None = None,
|
|
191
|
-
) -> str:
|
|
192
|
-
"""Generate criteria based on explicit labels without a full task.
|
|
193
|
-
|
|
194
|
-
This is a convenience method when you only have labels and optionally a task.
|
|
195
|
-
|
|
196
|
-
Args:
|
|
197
|
-
labels: List of pattern labels
|
|
198
|
-
task: Optional task for additional context
|
|
199
|
-
extra_placeholders: Additional placeholder values
|
|
200
|
-
|
|
201
|
-
Returns:
|
|
202
|
-
Markdown-formatted criteria string
|
|
203
|
-
"""
|
|
204
|
-
if task:
|
|
205
|
-
return self.inject(task, labels=labels, extra_placeholders=extra_placeholders)
|
|
206
|
-
|
|
207
|
-
# Create minimal criteria from labels only
|
|
208
|
-
sections: list[str] = []
|
|
209
|
-
normalized_labels = [label.lower() for label in labels]
|
|
210
|
-
|
|
211
|
-
for pattern_name in self.pattern_config.patterns.keys():
|
|
212
|
-
if pattern_name.lower() not in normalized_labels:
|
|
213
|
-
continue
|
|
214
|
-
|
|
215
|
-
templates = self.pattern_config.patterns.get(pattern_name, [])
|
|
216
|
-
if not templates:
|
|
217
|
-
continue
|
|
218
|
-
|
|
219
|
-
criteria_lines: list[str] = []
|
|
220
|
-
for template in templates:
|
|
221
|
-
substituted = self._substitute_placeholders(template, extra_placeholders)
|
|
222
|
-
criteria_lines.append(f"- [ ] {substituted}")
|
|
223
|
-
|
|
224
|
-
if criteria_lines:
|
|
225
|
-
pattern_title = pattern_name.replace("-", " ").title()
|
|
226
|
-
section = f"## {pattern_title} Pattern Criteria\n\n" + "\n".join(criteria_lines)
|
|
227
|
-
sections.append(section)
|
|
228
|
-
|
|
229
|
-
return "\n\n".join(sections)
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
class CriteriaGenerator:
|
|
233
|
-
"""Shared criteria generator for both structured and LLM expansion.
|
|
234
|
-
|
|
235
|
-
Generates validation criteria by combining:
|
|
236
|
-
- Pattern-specific criteria (from labels/description)
|
|
237
|
-
- Verification command criteria (from project config)
|
|
238
|
-
- File-specific criteria (when relevant files provided)
|
|
239
|
-
|
|
240
|
-
Can be used by:
|
|
241
|
-
- TaskExpander (LLM expansion)
|
|
242
|
-
- TaskHierarchyBuilder (structured expansion)
|
|
243
|
-
"""
|
|
244
|
-
|
|
245
|
-
def __init__(
|
|
246
|
-
self,
|
|
247
|
-
pattern_config: PatternCriteriaConfig,
|
|
248
|
-
verification_config: ProjectVerificationConfig | None = None,
|
|
249
|
-
):
|
|
250
|
-
"""Initialize the generator.
|
|
251
|
-
|
|
252
|
-
Args:
|
|
253
|
-
pattern_config: Pattern criteria configuration with templates
|
|
254
|
-
verification_config: Project verification commands configuration
|
|
255
|
-
"""
|
|
256
|
-
self.pattern_injector = PatternCriteriaInjector(
|
|
257
|
-
pattern_config=pattern_config,
|
|
258
|
-
verification_config=verification_config,
|
|
259
|
-
)
|
|
260
|
-
self.verification_config = verification_config
|
|
261
|
-
|
|
262
|
-
def generate(
|
|
263
|
-
self,
|
|
264
|
-
title: str,
|
|
265
|
-
description: str | None = None,
|
|
266
|
-
labels: list[str] | None = None,
|
|
267
|
-
relevant_files: list[str] | None = None,
|
|
268
|
-
verification_commands: dict[str, str] | None = None,
|
|
269
|
-
) -> str:
|
|
270
|
-
"""Generate validation criteria markdown.
|
|
271
|
-
|
|
272
|
-
Args:
|
|
273
|
-
title: Task title
|
|
274
|
-
description: Task description
|
|
275
|
-
labels: Optional labels for pattern detection
|
|
276
|
-
relevant_files: Optional list of relevant file paths
|
|
277
|
-
verification_commands: Optional verification commands override
|
|
278
|
-
|
|
279
|
-
Returns:
|
|
280
|
-
Markdown-formatted validation criteria string
|
|
281
|
-
"""
|
|
282
|
-
criteria_parts: list[str] = []
|
|
283
|
-
|
|
284
|
-
# 1. Pattern-specific criteria from labels
|
|
285
|
-
if labels:
|
|
286
|
-
pattern_criteria = self.pattern_injector.inject_for_labels(
|
|
287
|
-
labels=labels,
|
|
288
|
-
extra_placeholders=verification_commands,
|
|
289
|
-
)
|
|
290
|
-
if pattern_criteria:
|
|
291
|
-
criteria_parts.append(pattern_criteria)
|
|
292
|
-
|
|
293
|
-
# 2. File-specific criteria
|
|
294
|
-
if relevant_files and description:
|
|
295
|
-
text_to_check = (title + " " + (description or "")).lower()
|
|
296
|
-
matching_files = [f for f in relevant_files if f.lower() in text_to_check]
|
|
297
|
-
if matching_files:
|
|
298
|
-
file_criteria = ["## File Requirements", ""]
|
|
299
|
-
for f in matching_files:
|
|
300
|
-
file_criteria.append(f"- [ ] `{f}` is correctly modified/created")
|
|
301
|
-
criteria_parts.append("\n".join(file_criteria))
|
|
302
|
-
|
|
303
|
-
# 3. Verification command criteria
|
|
304
|
-
verification = self._get_verification_commands(verification_commands)
|
|
305
|
-
if verification:
|
|
306
|
-
verification_criteria = ["## Verification", ""]
|
|
307
|
-
for name, cmd in verification.items():
|
|
308
|
-
if name in ["unit_tests", "type_check", "lint"]:
|
|
309
|
-
verification_criteria.append(f"- [ ] `{cmd}` passes")
|
|
310
|
-
if len(verification_criteria) > 2: # Has items beyond header
|
|
311
|
-
criteria_parts.append("\n".join(verification_criteria))
|
|
312
|
-
|
|
313
|
-
return "\n\n".join(criteria_parts) if criteria_parts else ""
|
|
314
|
-
|
|
315
|
-
def _get_verification_commands(
|
|
316
|
-
self,
|
|
317
|
-
override: dict[str, str] | None = None,
|
|
318
|
-
) -> dict[str, str]:
|
|
319
|
-
"""Get verification commands from config or override.
|
|
320
|
-
|
|
321
|
-
Args:
|
|
322
|
-
override: Optional override commands
|
|
323
|
-
|
|
324
|
-
Returns:
|
|
325
|
-
Dict of verification command name -> command
|
|
326
|
-
"""
|
|
327
|
-
if override:
|
|
328
|
-
return override
|
|
329
|
-
|
|
330
|
-
commands: dict[str, str] = {}
|
|
331
|
-
if self.verification_config:
|
|
332
|
-
if self.verification_config.unit_tests:
|
|
333
|
-
commands["unit_tests"] = self.verification_config.unit_tests
|
|
334
|
-
if self.verification_config.type_check:
|
|
335
|
-
commands["type_check"] = self.verification_config.type_check
|
|
336
|
-
if self.verification_config.lint:
|
|
337
|
-
commands["lint"] = self.verification_config.lint
|
|
338
|
-
if self.verification_config.integration:
|
|
339
|
-
commands["integration"] = self.verification_config.integration
|
|
340
|
-
for name, cmd in self.verification_config.custom.items():
|
|
341
|
-
commands[name] = cmd
|
|
342
|
-
return commands
|