galangal-orchestrate 0.13.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. galangal/__init__.py +36 -0
  2. galangal/__main__.py +6 -0
  3. galangal/ai/__init__.py +167 -0
  4. galangal/ai/base.py +159 -0
  5. galangal/ai/claude.py +352 -0
  6. galangal/ai/codex.py +370 -0
  7. galangal/ai/gemini.py +43 -0
  8. galangal/ai/subprocess.py +254 -0
  9. galangal/cli.py +371 -0
  10. galangal/commands/__init__.py +27 -0
  11. galangal/commands/complete.py +367 -0
  12. galangal/commands/github.py +355 -0
  13. galangal/commands/init.py +177 -0
  14. galangal/commands/init_wizard.py +762 -0
  15. galangal/commands/list.py +20 -0
  16. galangal/commands/pause.py +34 -0
  17. galangal/commands/prompts.py +89 -0
  18. galangal/commands/reset.py +41 -0
  19. galangal/commands/resume.py +30 -0
  20. galangal/commands/skip.py +62 -0
  21. galangal/commands/start.py +530 -0
  22. galangal/commands/status.py +44 -0
  23. galangal/commands/switch.py +28 -0
  24. galangal/config/__init__.py +15 -0
  25. galangal/config/defaults.py +183 -0
  26. galangal/config/loader.py +163 -0
  27. galangal/config/schema.py +330 -0
  28. galangal/core/__init__.py +33 -0
  29. galangal/core/artifacts.py +136 -0
  30. galangal/core/state.py +1097 -0
  31. galangal/core/tasks.py +454 -0
  32. galangal/core/utils.py +116 -0
  33. galangal/core/workflow/__init__.py +68 -0
  34. galangal/core/workflow/core.py +789 -0
  35. galangal/core/workflow/engine.py +781 -0
  36. galangal/core/workflow/pause.py +35 -0
  37. galangal/core/workflow/tui_runner.py +1322 -0
  38. galangal/exceptions.py +36 -0
  39. galangal/github/__init__.py +31 -0
  40. galangal/github/client.py +427 -0
  41. galangal/github/images.py +324 -0
  42. galangal/github/issues.py +298 -0
  43. galangal/logging.py +364 -0
  44. galangal/prompts/__init__.py +5 -0
  45. galangal/prompts/builder.py +527 -0
  46. galangal/prompts/defaults/benchmark.md +34 -0
  47. galangal/prompts/defaults/contract.md +35 -0
  48. galangal/prompts/defaults/design.md +54 -0
  49. galangal/prompts/defaults/dev.md +89 -0
  50. galangal/prompts/defaults/docs.md +104 -0
  51. galangal/prompts/defaults/migration.md +59 -0
  52. galangal/prompts/defaults/pm.md +110 -0
  53. galangal/prompts/defaults/pm_questions.md +53 -0
  54. galangal/prompts/defaults/preflight.md +32 -0
  55. galangal/prompts/defaults/qa.md +65 -0
  56. galangal/prompts/defaults/review.md +90 -0
  57. galangal/prompts/defaults/review_codex.md +99 -0
  58. galangal/prompts/defaults/security.md +84 -0
  59. galangal/prompts/defaults/test.md +91 -0
  60. galangal/results.py +176 -0
  61. galangal/ui/__init__.py +5 -0
  62. galangal/ui/console.py +126 -0
  63. galangal/ui/tui/__init__.py +56 -0
  64. galangal/ui/tui/adapters.py +168 -0
  65. galangal/ui/tui/app.py +902 -0
  66. galangal/ui/tui/entry.py +24 -0
  67. galangal/ui/tui/mixins.py +196 -0
  68. galangal/ui/tui/modals.py +339 -0
  69. galangal/ui/tui/styles/app.tcss +86 -0
  70. galangal/ui/tui/styles/modals.tcss +197 -0
  71. galangal/ui/tui/types.py +107 -0
  72. galangal/ui/tui/widgets.py +263 -0
  73. galangal/validation/__init__.py +5 -0
  74. galangal/validation/runner.py +1072 -0
  75. galangal_orchestrate-0.13.0.dist-info/METADATA +985 -0
  76. galangal_orchestrate-0.13.0.dist-info/RECORD +79 -0
  77. galangal_orchestrate-0.13.0.dist-info/WHEEL +4 -0
  78. galangal_orchestrate-0.13.0.dist-info/entry_points.txt +2 -0
  79. galangal_orchestrate-0.13.0.dist-info/licenses/LICENSE +674 -0
@@ -0,0 +1,168 @@
1
+ """
2
+ UI adapters and interfaces for stage execution.
3
+
4
+ This module provides:
5
+ - PromptType: Enum for different prompt contexts
6
+ - PROMPT_OPTIONS: Registry mapping PromptType to available options
7
+ - StageUI: Interface for stage execution UI updates
8
+ - TUIAdapter: Adapter connecting ClaudeBackend to WorkflowTUIApp
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from enum import Enum
14
+ from typing import TYPE_CHECKING
15
+
16
+ from galangal.ui.tui.modals import PromptOption
17
+
18
+ if TYPE_CHECKING:
19
+ from galangal.ui.tui.app import WorkflowTUIApp
20
+
21
+
22
+ class PromptType(Enum):
23
+ """Types of prompts the TUI can show."""
24
+
25
+ NONE = "none"
26
+ PLAN_APPROVAL = "plan_approval"
27
+ DESIGN_APPROVAL = "design_approval"
28
+ STAGE_PREVIEW = "stage_preview"
29
+ COMPLETION = "completion"
30
+ TEXT_INPUT = "text_input"
31
+ PREFLIGHT_RETRY = "preflight_retry"
32
+ STAGE_FAILURE = "stage_failure"
33
+ POST_COMPLETION = "post_completion"
34
+ TASK_TYPE = "task_type"
35
+ YES_NO = "yes_no" # Simple yes/no prompt for discovery Q&A
36
+ USER_DECISION = "user_decision" # User must approve/reject when decision file missing
37
+ TASK_SOURCE = "task_source" # Choose between manual task or GitHub issue
38
+
39
+
40
+ # Default options for prompts without specific configuration
41
+ DEFAULT_PROMPT_OPTIONS: list[PromptOption] = [
42
+ PromptOption("1", "Yes", "yes", "#b8bb26"),
43
+ PromptOption("2", "No", "no", "#fb4934"),
44
+ PromptOption("3", "Quit", "quit", "#fabd2f"),
45
+ ]
46
+
47
+ # Registry mapping PromptType to available options
48
+ # This centralizes prompt configuration and makes it easy to add new prompt types
49
+ PROMPT_OPTIONS: dict[PromptType, list[PromptOption]] = {
50
+ PromptType.PLAN_APPROVAL: [
51
+ PromptOption("1", "Approve", "yes", "#b8bb26"),
52
+ PromptOption("2", "Reject", "no", "#fb4934"),
53
+ PromptOption("3", "Quit", "quit", "#fabd2f"),
54
+ ],
55
+ PromptType.DESIGN_APPROVAL: [
56
+ PromptOption("1", "Approve", "yes", "#b8bb26"),
57
+ PromptOption("2", "Reject", "no", "#fb4934"),
58
+ PromptOption("3", "Quit", "quit", "#fabd2f"),
59
+ ],
60
+ PromptType.COMPLETION: [
61
+ PromptOption("1", "Create PR", "yes", "#b8bb26"),
62
+ PromptOption("2", "Back to DEV", "no", "#fb4934"),
63
+ PromptOption("3", "Quit", "quit", "#fabd2f"),
64
+ ],
65
+ PromptType.PREFLIGHT_RETRY: [
66
+ PromptOption("1", "Retry", "retry", "#b8bb26"),
67
+ PromptOption("2", "Quit", "quit", "#fb4934"),
68
+ ],
69
+ PromptType.STAGE_FAILURE: [
70
+ PromptOption("1", "Retry", "retry", "#b8bb26"),
71
+ PromptOption("2", "Fix in DEV", "fix_in_dev", "#fabd2f"),
72
+ PromptOption("3", "Quit", "quit", "#fb4934"),
73
+ ],
74
+ PromptType.POST_COMPLETION: [
75
+ PromptOption("1", "New Task", "new_task", "#b8bb26"),
76
+ PromptOption("2", "Quit", "quit", "#fabd2f"),
77
+ ],
78
+ PromptType.TASK_TYPE: [
79
+ PromptOption("1", "Feature - New functionality", "feature", "#b8bb26"),
80
+ PromptOption("2", "Bug Fix - Fix broken behavior", "bugfix", "#fb4934"),
81
+ PromptOption("3", "Refactor - Restructure code", "refactor", "#83a598"),
82
+ PromptOption("4", "Chore - Dependencies, config", "chore", "#fabd2f"),
83
+ PromptOption("5", "Docs - Documentation only", "docs", "#d3869b"),
84
+ PromptOption("6", "Hotfix - Critical fix", "hotfix", "#fe8019"),
85
+ ],
86
+ PromptType.YES_NO: [
87
+ PromptOption("1", "Yes", "yes", "#b8bb26"),
88
+ PromptOption("2", "No", "no", "#fb4934"),
89
+ ],
90
+ PromptType.STAGE_PREVIEW: [
91
+ PromptOption("1", "Continue", "continue", "#b8bb26"),
92
+ PromptOption("2", "Quit", "quit", "#fb4934"),
93
+ ],
94
+ PromptType.USER_DECISION: [
95
+ PromptOption("1", "Approve", "approve", "#b8bb26"),
96
+ PromptOption("2", "Reject (rollback to DEV)", "reject", "#fb4934"),
97
+ PromptOption("3", "View full report", "view", "#83a598"),
98
+ PromptOption("4", "Quit", "quit", "#fabd2f"),
99
+ ],
100
+ PromptType.TASK_SOURCE: [
101
+ PromptOption("1", "Create manually", "manual", "#b8bb26"),
102
+ PromptOption("2", "From GitHub issue", "github", "#83a598"),
103
+ ],
104
+ }
105
+
106
+
107
+ def get_prompt_options(prompt_type: PromptType) -> list[PromptOption]:
108
+ """
109
+ Get the options for a given prompt type.
110
+
111
+ Args:
112
+ prompt_type: The type of prompt to get options for.
113
+
114
+ Returns:
115
+ List of PromptOption objects for the prompt type.
116
+ Falls back to DEFAULT_PROMPT_OPTIONS if type not in registry.
117
+ """
118
+ return PROMPT_OPTIONS.get(prompt_type, DEFAULT_PROMPT_OPTIONS)
119
+
120
+
121
+ class StageUI:
122
+ """Interface for stage execution UI updates."""
123
+
124
+ def set_status(self, status: str, detail: str = "") -> None:
125
+ pass
126
+
127
+ def add_activity(self, activity: str, icon: str = "•") -> None:
128
+ pass
129
+
130
+ def add_raw_line(self, line: str) -> None:
131
+ pass
132
+
133
+ def set_turns(self, turns: int) -> None:
134
+ pass
135
+
136
+ def finish(self, success: bool) -> None:
137
+ pass
138
+
139
+
140
+ class TUIAdapter(StageUI):
141
+ """Adapter to connect ClaudeBackend to TUI."""
142
+
143
+ def __init__(self, app: WorkflowTUIApp):
144
+ self.app = app
145
+
146
+ def set_status(self, status: str, detail: str = "") -> None:
147
+ self.app.set_status(status, detail)
148
+
149
+ def add_activity(self, activity: str, icon: str = "•") -> None:
150
+ self.app.add_activity(activity, icon)
151
+
152
+ # Track file operations
153
+ if "Read:" in activity or "📖" in activity:
154
+ path = activity.split(":")[-1].strip() if ":" in activity else activity
155
+ self.app.add_file("read", path)
156
+ elif "Edit:" in activity or "Write:" in activity or "✏️" in activity:
157
+ path = activity.split(":")[-1].strip() if ":" in activity else activity
158
+ self.app.add_file("write", path)
159
+
160
+ def add_raw_line(self, line: str) -> None:
161
+ """Pass raw line to app for storage and display."""
162
+ self.app.add_raw_line(line)
163
+
164
+ def set_turns(self, turns: int) -> None:
165
+ self.app.set_turns(turns)
166
+
167
+ def finish(self, success: bool) -> None:
168
+ pass