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,985 @@
1
+ Metadata-Version: 2.4
2
+ Name: galangal-orchestrate
3
+ Version: 0.13.0
4
+ Summary: AI-driven development workflow orchestrator
5
+ Project-URL: Homepage, https://github.com/Galangal-Media/galangal-orchestrate
6
+ Project-URL: Repository, https://github.com/Galangal-Media/galangal-orchestrate
7
+ Project-URL: Issues, https://github.com/Galangal-Media/galangal-orchestrate/issues
8
+ Author: Galangal Media
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: ai,claude,development,orchestrator,workflow
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Software Development
22
+ Classifier: Topic :: Software Development :: Quality Assurance
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: pydantic>=2.0.0
25
+ Requires-Dist: pyyaml>=6.0
26
+ Requires-Dist: rich>=13.0.0
27
+ Requires-Dist: structlog>=24.0.0
28
+ Requires-Dist: textual>=0.40.0
29
+ Provides-Extra: dev
30
+ Requires-Dist: mypy>=1.0.0; extra == 'dev'
31
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
32
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
33
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
34
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
35
+ Description-Content-Type: text/markdown
36
+
37
+ # Galangal Orchestrate
38
+
39
+ **Turn AI coding assistants into structured development workflows.**
40
+
41
+ Galangal Orchestrate wraps [Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI to execute a deterministic, multi-stage development pipeline. Instead of open-ended AI coding sessions, you get a structured workflow with approval gates, validation, and automatic rollback.
42
+
43
+ ## Why Use This?
44
+
45
+ When you ask an AI to "add user authentication", you get whatever the AI decides to build. With Galangal:
46
+
47
+ 1. **PM Stage** - AI writes requirements, you approve before any code is written
48
+ 2. **Design Stage** - AI proposes architecture, you approve the approach
49
+ 3. **Dev Stage** - AI implements according to approved specs
50
+ 4. **Test Stage** - AI writes tests, validation ensures they pass
51
+ 5. **QA Stage** - AI verifies requirements are met
52
+ 6. **Review Stage** - AI reviews its own code for issues
53
+ 7. **Docs Stage** - AI updates documentation
54
+
55
+ If anything fails, the workflow automatically rolls back to the appropriate fix point with context about what went wrong.
56
+
57
+ ## Requirements
58
+
59
+ - Python 3.10+
60
+ - [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code) installed (`claude` command available)
61
+ - Claude Pro or Max subscription
62
+ - Git
63
+
64
+ ## Installation
65
+
66
+ ```bash
67
+ # With pip
68
+ pip install galangal-orchestrate
69
+
70
+ # With pipx (recommended for CLI tools)
71
+ pipx install galangal-orchestrate
72
+ ```
73
+
74
+ ## Quick Start
75
+
76
+ ```bash
77
+ # Initialize in your project
78
+ cd your-project
79
+ galangal init
80
+
81
+ # Start a task
82
+ galangal start "Add user authentication with JWT tokens"
83
+
84
+ # Resume after a break
85
+ galangal resume
86
+
87
+ # Check current status
88
+ galangal status
89
+ ```
90
+
91
+ ## Workflow Stages
92
+
93
+ | Stage | Purpose | Output |
94
+ |-------|---------|--------|
95
+ | **PM** | Requirements & planning | SPEC.md, PLAN.md, STAGE_PLAN.md |
96
+ | **DESIGN** | Architecture design | DESIGN.md |
97
+ | **PREFLIGHT** | Environment validation | PREFLIGHT_REPORT.md |
98
+ | **DEV** | Implementation | Code changes |
99
+ | **MIGRATION*** | Database migration checks | MIGRATION_REPORT.md |
100
+ | **TEST** | Test implementation | TEST_PLAN.md, TEST_SUMMARY.md |
101
+ | **TEST_GATE*** | Verify configured test suites pass | TEST_GATE_RESULTS.md |
102
+ | **CONTRACT*** | API contract validation | CONTRACT_REPORT.md |
103
+ | **QA** | Quality assurance | QA_REPORT.md |
104
+ | **BENCHMARK*** | Performance validation | BENCHMARK_REPORT.md |
105
+ | **SECURITY** | Security review | SECURITY_CHECKLIST.md |
106
+ | **REVIEW** | Code review | REVIEW_NOTES.md |
107
+ | **DOCS** | Documentation | DOCS_REPORT.md |
108
+
109
+ *Conditional stages - skipped automatically if not relevant
110
+
111
+ ### Validation Artifacts
112
+
113
+ When validation commands run (tests, linters, etc.), Galangal creates debugging artifacts:
114
+
115
+ - **VALIDATION_REPORT.md** - Full output from all validation commands, useful for debugging failures
116
+ - **TEST_SUMMARY.md** - Concise test results (pass/fail counts, failed test names, coverage) included in downstream stage prompts
117
+
118
+ These artifacts help you understand what failed without digging through logs, and give downstream stages (QA, REVIEW) context about test results without bloating prompts with verbose output.
119
+
120
+ ### Test Gate
121
+
122
+ The **TEST_GATE** stage is an optional quality gate that runs configured test suites mechanically (no AI). It runs after the TEST stage and before QA. All configured tests must pass for the workflow to proceed.
123
+
124
+ **Why use Test Gate?**
125
+ - Ensures specific test suites always pass before QA
126
+ - Separates "writing tests" (TEST stage) from "verifying tests pass" (TEST_GATE)
127
+ - QA can skip running automated tests and focus on exploratory testing
128
+ - Provides a clear, repeatable verification step
129
+
130
+ **Configuration:**
131
+
132
+ ```yaml
133
+ # .galangal/config.yaml
134
+ test_gate:
135
+ enabled: true
136
+ fail_fast: true # Stop on first failure (default: true)
137
+ tests:
138
+ - name: "unit tests"
139
+ command: "npm test"
140
+ timeout: 300 # Optional, defaults to 5 minutes
141
+ - name: "integration tests"
142
+ command: "pytest tests/integration -v"
143
+ - name: "e2e tests"
144
+ command: "cd frontend && npm run e2e"
145
+ timeout: 600 # 10 minutes for slower tests
146
+ ```
147
+
148
+ **Behavior:**
149
+ - Runs each test command in sequence
150
+ - Creates `TEST_GATE_RESULTS.md` with detailed output
151
+ - On success: proceeds to CONTRACT/QA stages
152
+ - On failure: rolls back to DEV with context about which tests failed
153
+ - QA prompt is automatically updated to skip re-running these tests
154
+
155
+ **Skip conditions:**
156
+ - `test_gate.enabled: false` (default)
157
+ - No tests configured in `test_gate.tests`
158
+ - DOCS task type (no code changes)
159
+ - Manual skip artifact (`TEST_GATE_SKIP.md`)
160
+
161
+ ## Task Types
162
+
163
+ Choose the right workflow for your task:
164
+
165
+ | Type | Stages | When to Use |
166
+ |------|--------|-------------|
167
+ | **Feature** | All stages | New functionality |
168
+ | **Bug Fix** | PM → PREFLIGHT → DEV → TEST → QA | Fixing bugs |
169
+ | **Refactor** | PM → DESIGN → PREFLIGHT → DEV → TEST | Code restructuring |
170
+ | **Chore** | PM → PREFLIGHT → DEV → TEST | Config, dependencies |
171
+ | **Docs** | PM → DOCS | Documentation only |
172
+ | **Hotfix** | PM → DEV → TEST | Critical fixes |
173
+
174
+ The PM stage can further customize which stages run based on task analysis.
175
+
176
+ ## Interactive Controls
177
+
178
+ During workflow execution:
179
+
180
+ | Key | Action | Description |
181
+ |-----|--------|-------------|
182
+ | `^Q` | Quit | Pause and exit (resume later with `galangal resume`) |
183
+ | `^I` | Interrupt | Stop current stage, give feedback, rollback to DEV |
184
+ | `^N` | Skip | Skip current stage, advance to next |
185
+ | `^B` | Back | Go back to previous stage |
186
+ | `^E` | Edit | Pause for manual editing, press Enter to resume |
187
+
188
+ ### Interrupt with Feedback (^I)
189
+
190
+ When you see the AI doing something wrong mid-stage:
191
+ 1. Press `^I` to interrupt immediately
192
+ 2. Enter feedback describing what needs to be fixed
193
+ 3. Workflow rolls back to DEV with your feedback as context
194
+ 4. A `ROLLBACK.md` artifact is created for the AI to reference
195
+
196
+ ### Manual Edit Pause (^E)
197
+
198
+ Need to make a quick fix yourself?
199
+ 1. Press `^E` to pause
200
+ 2. Make edits in your editor
201
+ 3. Press Enter to resume the current stage
202
+
203
+ ## PM-driven Stage Planning
204
+
205
+ After analyzing your task, the PM stage outputs a `STAGE_PLAN.md` recommending which optional stages to run or skip:
206
+
207
+ ```markdown
208
+ # Stage Plan
209
+
210
+ ## Recommendations
211
+ | Stage | Action | Reason |
212
+ |-------|--------|--------|
213
+ | MIGRATION | skip | No database changes detected |
214
+ | CONTRACT | skip | Internal refactor, no API changes |
215
+ | SECURITY | run | Handling user authentication input |
216
+ | BENCHMARK | skip | UI-only changes, no performance impact |
217
+ ```
218
+
219
+ The progress bar updates dynamically to show only relevant stages.
220
+
221
+ ### Workflow Preview
222
+
223
+ After PM approval, you'll see a preview showing exactly which stages will run and why others are skipped:
224
+
225
+ ```
226
+ Workflow Preview
227
+
228
+ Stages to run:
229
+ PM → DESIGN → PREFLIGHT → DEV → TEST → QA → REVIEW → DOCS
230
+
231
+ Skipping:
232
+ MIGRATION (no files match: **/migrations/*)
233
+ CONTRACT (no files match: **/api/*, **/openapi.*)
234
+ BENCHMARK (task type: bug_fix)
235
+ SECURITY (PM: simple UI change, no security impact)
236
+
237
+ Controls during execution:
238
+ ^N Skip stage ^B Back ^E Pause for edit ^I Interrupt
239
+ ```
240
+
241
+ Skip reasons include:
242
+ - **Task type** - Based on the workflow template (e.g., bug fixes skip DESIGN)
243
+ - **Config** - Stages listed in `stages.skip` configuration
244
+ - **PM recommendation** - From STAGE_PLAN.md analysis
245
+ - **skip_if condition** - No changed files match the glob pattern
246
+
247
+ ## Commands
248
+
249
+ | Command | Description |
250
+ |---------|-------------|
251
+ | `galangal init` | Initialize in current project |
252
+ | `galangal start "desc"` | Start new task |
253
+ | `galangal list` | List all tasks |
254
+ | `galangal switch <name>` | Switch active task |
255
+ | `galangal status` | Show task status |
256
+ | `galangal resume` | Continue active task |
257
+ | `galangal pause` | Pause for break |
258
+ | `galangal approve` | Approve plan |
259
+ | `galangal approve-design` | Approve design |
260
+ | `galangal skip-design` | Skip design stage |
261
+ | `galangal skip-to <stage>` | Jump to stage |
262
+ | `galangal complete` | Finalize & create PR |
263
+ | `galangal reset` | Delete active task |
264
+ | `galangal github setup` | Set up GitHub integration |
265
+ | `galangal github issues` | List galangal-labeled issues |
266
+ | `galangal github run` | Process issues automatically |
267
+
268
+ ## GitHub Integration
269
+
270
+ Galangal can create tasks directly from GitHub issues, automatically downloading screenshots and inferring task types from labels.
271
+
272
+ ### Quick Setup
273
+
274
+ ```bash
275
+ # 1. Install GitHub CLI (if not already installed)
276
+ # macOS:
277
+ brew install gh
278
+
279
+ # Windows:
280
+ winget install GitHub.cli
281
+
282
+ # Linux: See https://cli.github.com
283
+
284
+ # 2. Authenticate
285
+ gh auth login
286
+
287
+ # 3. Set up GitHub integration (creates labels)
288
+ galangal github setup
289
+ ```
290
+
291
+ ### How It Works
292
+
293
+ 1. Add the `galangal` label to any GitHub issue you want to work on
294
+ 2. Run `galangal start` and select "GitHub issue" as the task source
295
+ 3. Galangal will:
296
+ - Download any screenshots from the issue body
297
+ - Infer the task type from issue labels
298
+ - Create a task linked to the issue
299
+ - Mark the issue as "in-progress"
300
+
301
+ When you complete the task with `galangal complete`, a PR is created that automatically closes the linked issue.
302
+
303
+ ### Batch Processing
304
+
305
+ Process all galangal-labeled issues automatically:
306
+
307
+ ```bash
308
+ # List issues that would be processed
309
+ galangal github run --dry-run
310
+
311
+ # Process all issues headlessly
312
+ galangal github run
313
+ ```
314
+
315
+ ### Issue Screenshots
316
+
317
+ Screenshots embedded in GitHub issues (using `![](url)` syntax) are automatically:
318
+ - Downloaded to `galangal-tasks/<task>/screenshots/`
319
+ - Passed to the AI during PM, Design, and Dev stages
320
+ - Available for the AI to view using Claude's Read tool
321
+
322
+ This is especially useful for bug reports with screenshots or design mockups.
323
+
324
+ ### Label Configuration
325
+
326
+ Galangal maps GitHub labels to task types. The defaults are:
327
+
328
+ | Task Type | Labels |
329
+ |-----------|--------|
330
+ | bug_fix | `bug`, `bugfix` |
331
+ | feature | `enhancement`, `feature` |
332
+ | docs | `documentation`, `docs` |
333
+ | refactor | `refactor` |
334
+ | chore | `chore`, `maintenance` |
335
+ | hotfix | `hotfix`, `critical` |
336
+
337
+ Customize in `.galangal/config.yaml`:
338
+
339
+ ```yaml
340
+ github:
341
+ # Label that triggers galangal to pick up issues
342
+ pickup_label: galangal
343
+
344
+ # Label added when work starts
345
+ in_progress_label: in-progress
346
+
347
+ # Custom label colors (hex without #)
348
+ label_colors:
349
+ galangal: "7C3AED"
350
+ in-progress: "FCD34D"
351
+
352
+ # Map your labels to task types
353
+ label_mapping:
354
+ bug:
355
+ - bug
356
+ - bugfix
357
+ - defect # Add your custom labels
358
+ feature:
359
+ - enhancement
360
+ - feature
361
+ - new-feature
362
+ docs:
363
+ - documentation
364
+ - docs
365
+ refactor:
366
+ - refactor
367
+ - tech-debt
368
+ chore:
369
+ - chore
370
+ - maintenance
371
+ - dependencies
372
+ hotfix:
373
+ - hotfix
374
+ - critical
375
+ - urgent
376
+ ```
377
+
378
+ ### GitHub Commands
379
+
380
+ | Command | Description |
381
+ |---------|-------------|
382
+ | `galangal github setup` | Create required labels, show setup instructions |
383
+ | `galangal github setup --help-install` | Show detailed gh CLI installation instructions |
384
+ | `galangal github check` | Verify gh CLI installation and authentication |
385
+ | `galangal github issues` | List issues with galangal label |
386
+ | `galangal github issues --label <name>` | List issues with custom label |
387
+ | `galangal github run` | Process all labeled issues headlessly |
388
+ | `galangal github run --dry-run` | Preview without processing |
389
+
390
+ ## Configuration
391
+
392
+ After `galangal init`, customize `.galangal/config.yaml`. Here's a complete reference:
393
+
394
+ ```yaml
395
+ # =============================================================================
396
+ # PROJECT CONFIGURATION
397
+ # =============================================================================
398
+ project:
399
+ # Project name (displayed in logs and prompts)
400
+ name: "My Project"
401
+
402
+ # Default approver name for plan/design approvals (auto-fills signoff prompts)
403
+ approver_name: "Jane Smith"
404
+
405
+ # Technology stacks in your project
406
+ # Helps AI understand your codebase structure
407
+ stacks:
408
+ - language: python
409
+ framework: fastapi # Optional: framework name
410
+ root: backend/ # Optional: subdirectory for this stack
411
+ - language: typescript
412
+ framework: vite
413
+ root: frontend/
414
+
415
+ # =============================================================================
416
+ # TASK STORAGE
417
+ # =============================================================================
418
+ # Directory where task state and artifacts are stored
419
+ tasks_dir: galangal-tasks
420
+
421
+ # Git branch naming pattern ({task_name} is replaced with sanitized task name)
422
+ branch_pattern: "task/{task_name}"
423
+
424
+ # =============================================================================
425
+ # STAGE CONFIGURATION
426
+ # =============================================================================
427
+ stages:
428
+ # Stages to always skip (regardless of task type or PM recommendations)
429
+ skip:
430
+ - BENCHMARK
431
+ - CONTRACT
432
+
433
+ # Default timeout for each stage in seconds (4 hours default)
434
+ timeout: 14400
435
+
436
+ # Maximum retries per stage before rollback (default: 5)
437
+ max_retries: 5
438
+
439
+ # =============================================================================
440
+ # TEST GATE CONFIGURATION
441
+ # Mechanical test verification stage (no AI) - runs after TEST, before QA
442
+ # =============================================================================
443
+ test_gate:
444
+ # Enable the test gate stage (default: false)
445
+ enabled: true
446
+
447
+ # Stop on first test failure instead of running all tests (default: true)
448
+ fail_fast: true
449
+
450
+ # Test suites to run - all must pass for the stage to succeed
451
+ tests:
452
+ - name: "unit tests"
453
+ command: "npm test"
454
+ timeout: 300 # Timeout in seconds (default: 300)
455
+ - name: "integration tests"
456
+ command: "pytest tests/integration -v"
457
+ - name: "e2e tests"
458
+ command: "cd frontend && npm run e2e"
459
+ timeout: 600 # Longer timeout for e2e tests
460
+
461
+ # =============================================================================
462
+ # VALIDATION CONFIGURATION
463
+ # Each stage can have validation commands, checks, and skip conditions
464
+ # =============================================================================
465
+ validation:
466
+ # Preflight checks run before DEV stage
467
+ preflight:
468
+ timeout: 300 # Timeout for each check in seconds
469
+ checks:
470
+ - name: "Git status clean"
471
+ command: "git status --porcelain"
472
+ expect_empty: true # Pass if output is empty
473
+ warn_only: false # If true, warn but don't fail
474
+ - name: "Node modules exist"
475
+ path_exists: "node_modules" # Check if path exists
476
+ - name: "Dependencies installed"
477
+ command: "npm ls --depth=0"
478
+ warn_only: true
479
+
480
+ # Migration stage validation
481
+ migration:
482
+ # Skip if no migration files changed
483
+ skip_if:
484
+ no_files_match:
485
+ - "migrations/**"
486
+ - "**/migrations/**"
487
+ - "alembic/**"
488
+ timeout: 600
489
+ commands:
490
+ - name: "Run migrations"
491
+ command: "python manage.py migrate --check"
492
+ timeout: 300 # Override timeout for this command
493
+ optional: false # If true, don't fail if command fails
494
+ allow_failure: false # If true, report but don't block
495
+
496
+ # Test stage validation
497
+ test:
498
+ timeout: 600
499
+ commands:
500
+ - name: "Unit tests"
501
+ command: "pytest tests/unit"
502
+ - name: "Integration tests"
503
+ command: "pytest tests/integration"
504
+ optional: true # Don't fail if integration tests missing
505
+ # Use array form for paths with spaces or special characters
506
+ - name: "Task-specific tests"
507
+ command: ["pytest", "{task_dir}/tests"] # {task_dir} is substituted
508
+
509
+ # Contract stage (API compatibility)
510
+ contract:
511
+ skip_if:
512
+ no_files_match: "openapi.yaml"
513
+ timeout: 300
514
+ commands:
515
+ - name: "Validate OpenAPI spec"
516
+ command: "openapi-spec-validator openapi.yaml"
517
+
518
+ # QA stage validation
519
+ qa:
520
+ timeout: 3600
521
+ commands:
522
+ - name: "Lint"
523
+ command: "./scripts/lint.sh"
524
+ timeout: 600
525
+ - name: "Type check"
526
+ command: "mypy src/"
527
+ timeout: 600
528
+ # Marker-based validation (for AI output verification)
529
+ artifact: "QA_REPORT.md"
530
+ pass_marker: "## PASS"
531
+ fail_marker: "## FAIL"
532
+
533
+ # Security stage validation
534
+ security:
535
+ timeout: 1800
536
+ commands:
537
+ - name: "Security scan"
538
+ command: "bandit -r src/"
539
+ allow_failure: true # Report issues but don't block
540
+ artifacts_required:
541
+ - "SECURITY_CHECKLIST.md"
542
+
543
+ # Review stage validation
544
+ review:
545
+ timeout: 1800
546
+ artifact: "REVIEW_NOTES.md"
547
+ pass_marker: "APPROVED"
548
+ fail_marker: "REJECTED"
549
+
550
+ # Docs stage validation
551
+ docs:
552
+ timeout: 900
553
+ artifacts_required:
554
+ - "DOCS_REPORT.md"
555
+
556
+ # =============================================================================
557
+ # AI BACKEND CONFIGURATION
558
+ # =============================================================================
559
+ ai:
560
+ # Default backend to use
561
+ default: claude
562
+
563
+ # Available backends with customizable CLI flags
564
+ backends:
565
+ claude:
566
+ command: claude # CLI command to invoke
567
+ args: # Arguments with {placeholder} substitution
568
+ - "--output-format"
569
+ - "stream-json"
570
+ - "--verbose"
571
+ - "--max-turns"
572
+ - "{max_turns}" # Replaced with max_turns value
573
+ - "--permission-mode"
574
+ - "bypassPermissions"
575
+ max_turns: 200 # Maximum conversation turns per stage
576
+ read_only: false # If true, backend cannot write files
577
+
578
+ codex:
579
+ command: codex
580
+ args:
581
+ - "exec"
582
+ - "--full-auto"
583
+ - "--output-schema"
584
+ - "{schema_file}" # Replaced with schema file path
585
+ - "-o"
586
+ - "{output_file}" # Replaced with output file path
587
+ max_turns: 50
588
+ read_only: true # Codex runs in read-only sandbox
589
+
590
+ # Use different backends for specific stages
591
+ stage_backends:
592
+ REVIEW: codex # Use Codex for code review
593
+ # QA: gemini # Use Gemini for QA (when supported)
594
+
595
+ # =============================================================================
596
+ # DOCUMENTATION CONFIGURATION
597
+ # =============================================================================
598
+ docs:
599
+ # Directory for changelog entries
600
+ changelog_dir: docs/changelog
601
+
602
+ # Directory for security audit reports
603
+ security_audit: docs/security
604
+
605
+ # Directory for general documentation
606
+ general: docs
607
+
608
+ # Toggle documentation updates
609
+ update_changelog: true # Update changelog in DOCS stage
610
+ update_security_audit: true # Create security reports in SECURITY stage
611
+ update_general_docs: true # Update general docs in DOCS stage
612
+
613
+ # =============================================================================
614
+ # PULL REQUEST CONFIGURATION
615
+ # =============================================================================
616
+ pr:
617
+ # Base branch for PRs (e.g., main, develop)
618
+ base_branch: main
619
+
620
+ # Add @codex review to PR body for automated review
621
+ codex_review: false
622
+
623
+ # =============================================================================
624
+ # STRUCTURED LOGGING
625
+ # =============================================================================
626
+ logging:
627
+ # Enable structured logging to file
628
+ enabled: true
629
+
630
+ # Log level: debug, info, warning, error
631
+ level: info
632
+
633
+ # Log file path (JSON Lines format for easy parsing)
634
+ file: logs/galangal.jsonl
635
+
636
+ # Output format: true for JSON, false for pretty console format
637
+ json_format: true
638
+
639
+ # Also output to console (stderr)
640
+ console: false
641
+
642
+ # =============================================================================
643
+ # TASK TYPE SETTINGS
644
+ # Per-task-type overrides
645
+ # =============================================================================
646
+ task_type_settings:
647
+ bugfix:
648
+ skip_discovery: true # Skip the PM discovery Q&A for bugfixes
649
+ hotfix:
650
+ skip_discovery: true
651
+
652
+ # =============================================================================
653
+ # PROMPT CONTEXT
654
+ # Additional context injected into AI prompts
655
+ # =============================================================================
656
+
657
+ # Global context added to ALL stage prompts
658
+ prompt_context: |
659
+ ## Project Conventions
660
+ - Use repository pattern for data access
661
+ - API responses use api_success() / api_error() helpers
662
+ - All errors should be logged with context
663
+
664
+ ## Testing Standards
665
+ - Unit tests go in tests/unit/
666
+ - Integration tests go in tests/integration/
667
+ - Use pytest fixtures for test data
668
+
669
+ # Per-stage context (merged with global context)
670
+ stage_context:
671
+ dev: |
672
+ ## Development Environment
673
+ - Run `npm run dev` for hot reload
674
+ - Database: PostgreSQL on localhost:5432
675
+ - Redis: localhost:6379
676
+
677
+ test: |
678
+ ## Test Setup
679
+ - Use vitest for frontend unit tests
680
+ - Use pytest for backend tests
681
+ - Mock external APIs in tests
682
+
683
+ security: |
684
+ ## Security Requirements
685
+ - All user input must be validated
686
+ - Use parameterized queries (no raw SQL)
687
+ - Secrets must use environment variables
688
+ ```
689
+
690
+ ## AI Backend Customization
691
+
692
+ Galangal invokes AI backends (like Claude Code CLI) using configurable commands and arguments. This allows you to customize CLI flags without modifying code.
693
+
694
+ ### Default Behavior
695
+
696
+ By default, Galangal invokes Claude with:
697
+ ```bash
698
+ cat prompt.txt | claude --output-format stream-json --verbose --max-turns 200 --permission-mode bypassPermissions
699
+ ```
700
+
701
+ ### Customizing CLI Flags
702
+
703
+ Override any flags in `.galangal/config.yaml`:
704
+
705
+ ```yaml
706
+ ai:
707
+ backends:
708
+ claude:
709
+ command: claude
710
+ args:
711
+ - "--output-format"
712
+ - "stream-json"
713
+ - "--verbose"
714
+ - "--max-turns"
715
+ - "{max_turns}"
716
+ - "--permission-mode"
717
+ - "bypassPermissions"
718
+ - "--model" # Add custom flags
719
+ - "opus"
720
+ max_turns: 300 # Increase max turns
721
+ ```
722
+
723
+ ### Placeholder Reference
724
+
725
+ Arguments can include placeholders that are substituted at runtime:
726
+
727
+ | Placeholder | Backend | Description |
728
+ |-------------|---------|-------------|
729
+ | `{max_turns}` | claude | Maximum conversation turns |
730
+ | `{schema_file}` | codex | Path to JSON schema file |
731
+ | `{output_file}` | codex | Path for structured output |
732
+
733
+ ### Common Customizations
734
+
735
+ **Use a specific model:**
736
+ ```yaml
737
+ ai:
738
+ backends:
739
+ claude:
740
+ args:
741
+ - "--output-format"
742
+ - "stream-json"
743
+ - "--model"
744
+ - "sonnet" # Use Sonnet instead of default
745
+ - "--max-turns"
746
+ - "{max_turns}"
747
+ ```
748
+
749
+ **Increase turn limit for complex tasks:**
750
+ ```yaml
751
+ ai:
752
+ backends:
753
+ claude:
754
+ max_turns: 500 # Default is 200
755
+ args:
756
+ - "--output-format"
757
+ - "stream-json"
758
+ - "--max-turns"
759
+ - "{max_turns}" # Will use 500
760
+ ```
761
+
762
+ **Use different backends per stage:**
763
+ ```yaml
764
+ ai:
765
+ default: claude
766
+ stage_backends:
767
+ REVIEW: codex # Use Codex for code review
768
+ ```
769
+
770
+ ### Adding a Custom Backend
771
+
772
+ Define any CLI tool as a backend:
773
+
774
+ ```yaml
775
+ ai:
776
+ backends:
777
+ my-backend:
778
+ command: my-ai-tool
779
+ args:
780
+ - "--prompt-file"
781
+ - "-" # Read from stdin
782
+ - "--json-output"
783
+ max_turns: 100
784
+ read_only: true # Cannot write files directly
785
+ ```
786
+
787
+ Then use it:
788
+ ```yaml
789
+ ai:
790
+ default: my-backend
791
+ # Or per-stage:
792
+ stage_backends:
793
+ QA: my-backend
794
+ ```
795
+
796
+ ## Customizing Prompts
797
+
798
+ Galangal uses a layered prompt system:
799
+
800
+ 1. **Base prompts** - Built-in, language-agnostic prompts
801
+ 2. **Project prompts** - Your customizations in `.galangal/prompts/`
802
+
803
+ ### Supplement Mode (Recommended)
804
+
805
+ Add project-specific content that gets prepended to the base prompt:
806
+
807
+ ```markdown
808
+ <!-- .galangal/prompts/dev.md -->
809
+
810
+ ## Project CLI Scripts
811
+
812
+ - `./scripts/test.sh` - Run all tests
813
+ - `./scripts/lint.sh` - Run linter
814
+
815
+ ## Patterns to Follow
816
+
817
+ - Always use `api_success()` for responses
818
+ - Never use raw SQL queries
819
+
820
+ # BASE
821
+ ```
822
+
823
+ The `# BASE` marker inserts the default prompt at that location.
824
+
825
+ ### Override Mode
826
+
827
+ To completely replace a base prompt, omit the `# BASE` marker:
828
+
829
+ ```markdown
830
+ <!-- .galangal/prompts/preflight.md -->
831
+
832
+ # Custom Preflight
833
+
834
+ This completely replaces the default preflight prompt.
835
+
836
+ [Your custom instructions...]
837
+ ```
838
+
839
+ ### Available Prompt Files
840
+
841
+ Create any of these in `.galangal/prompts/`:
842
+
843
+ | File | Stage |
844
+ |------|-------|
845
+ | `pm.md` | Requirements & planning |
846
+ | `design.md` | Architecture design |
847
+ | `preflight.md` | Environment checks |
848
+ | `dev.md` | Implementation |
849
+ | `test.md` | Test writing |
850
+ | `qa.md` | Quality assurance |
851
+ | `security.md` | Security review |
852
+ | `review.md` | Code review |
853
+ | `docs.md` | Documentation |
854
+
855
+ ## Troubleshooting
856
+
857
+ ### Debug Mode
858
+
859
+ When something goes wrong and you need to see what happened:
860
+
861
+ ```bash
862
+ # Enable debug logging (writes to logs/galangal_debug.log)
863
+ galangal --debug start "task description"
864
+ galangal --debug resume
865
+
866
+ # Alternative: set environment variable
867
+ GALANGAL_DEBUG=1 galangal start "task description"
868
+ ```
869
+
870
+ Debug mode creates two log files:
871
+ - `logs/galangal_debug.log` - Human-readable debug trace with timestamps
872
+ - `logs/galangal.jsonl` - Structured JSON logs for programmatic analysis
873
+
874
+ **Example debug log:**
875
+ ```
876
+ [14:32:15.123] GitHub integration failed: HTTPError: 401 Unauthorized
877
+ [14:32:15.124] Traceback:
878
+ File "/path/to/start.py", line 138, in task_creation_thread
879
+ check = ensure_github_ready()
880
+ ...
881
+ ```
882
+
883
+ ### Structured Logging Configuration
884
+
885
+ Enable structured logging in `.galangal/config.yaml`:
886
+
887
+ ```yaml
888
+ logging:
889
+ enabled: true # Enable logging
890
+ level: debug # debug, info, warning, error
891
+ file: logs/galangal.jsonl
892
+ json_format: true # JSON for parsing, false for console format
893
+ console: false # Also output to stderr
894
+ ```
895
+
896
+ ### Tests Hang at TEST Stage
897
+
898
+ Test frameworks must run non-interactively. Common issues:
899
+
900
+ **Playwright** - HTML reporter blocks by default:
901
+ ```bash
902
+ # Use non-blocking reporter
903
+ npx playwright test --reporter=list
904
+
905
+ # Or set environment variable
906
+ PLAYWRIGHT_HTML_OPEN=never npx playwright test
907
+
908
+ # Or in playwright.config.ts:
909
+ # reporter: [['html', { open: 'never' }]]
910
+ ```
911
+
912
+ **Jest/Vitest** - Watch mode blocks:
913
+ ```bash
914
+ # Wrong (blocks):
915
+ npm test -- --watch
916
+
917
+ # Correct:
918
+ npm test
919
+ ```
920
+
921
+ **Cypress** - Interactive mode blocks:
922
+ ```bash
923
+ # Wrong (blocks):
924
+ cypress open
925
+
926
+ # Correct:
927
+ cypress run
928
+ ```
929
+
930
+ **General rule**: Use CI-friendly commands that exit automatically. Avoid watch mode, interactive mode, or any GUI that waits for user input.
931
+
932
+ ### TEST Stage Loops Indefinitely
933
+
934
+ If the TEST stage keeps retrying instead of rolling back to DEV:
935
+ 1. Ensure your TEST_PLAN.md has a clear `**Status:** PASS` or `**Status:** FAIL` line
936
+ 2. If tests fail due to implementation bugs, the AI should report FAIL (not try to fix the code)
937
+ 3. Check that test commands exit with proper exit codes (0 for success, non-zero for failure)
938
+
939
+ **Note:** As of v0.12.0, when artifact markers are unclear (missing PASS/FAIL), Galangal prompts you to manually approve or reject instead of retrying indefinitely. You'll see the artifact content and can make the decision yourself.
940
+
941
+ ### "Galangal has not been initialized" Error
942
+
943
+ Run `galangal init` in your project root before using other commands.
944
+
945
+ ### Task Exits Without Error Message
946
+
947
+ If a task quits unexpectedly with no visible error:
948
+
949
+ 1. **Enable debug mode** and re-run:
950
+ ```bash
951
+ galangal --debug start "your task"
952
+ ```
953
+
954
+ 2. **Check the debug log** for the actual error:
955
+ ```bash
956
+ tail -50 logs/galangal_debug.log
957
+ ```
958
+
959
+ 3. **Common causes**:
960
+ - GitHub authentication failed (run `gh auth status`)
961
+ - Network timeout fetching issues
962
+ - Missing permissions for the repository
963
+ - Invalid issue number or no issues with `galangal` label
964
+
965
+ ### GitHub Integration Fails Silently
966
+
967
+ If `galangal start` from a GitHub issue exits without creating a task:
968
+
969
+ ```bash
970
+ # Check GitHub CLI is working
971
+ gh auth status
972
+ gh repo view
973
+
974
+ # Try with debug mode
975
+ galangal --debug start --issue 123
976
+ ```
977
+
978
+ Check `logs/galangal_debug.log` for specific errors like:
979
+ - `401 Unauthorized` - Re-authenticate with `gh auth login`
980
+ - `404 Not Found` - Issue doesn't exist or wrong repo
981
+ - `No issues with 'galangal' label` - Add the label to an issue first
982
+
983
+ ## License
984
+
985
+ MIT License - see LICENSE file.