Skip to content

Docker Helper Scripts

Przegląd

System zawiera zestaw helper scripts dostępnych w środowisku Docker, które automatyzują kluczowe operacje w lifecycle zadania. Helper scripts są montowane do kontenera i dostępne pod /workspace/files/helpers/.


Przegląd Helper Scripts

ScriptFazaOpisExecutor
init_workspace.shSTARTInicjalizacja workspace - klonowanie repozytoriówbash
backup_task_md.shSTARTBackup oryginalnego task.mdbash
move_task_md.shENDPrzeniesienie task_plan.md + restore task.mdbash
persist_git_changes.shENDCommitowanie zmian + diffbash
github_push_mr.shENDPush + utworzenie PR/MRbash
create_subtaskANYDynamiczne tworzenie follow-up subtaskówbash

init_workspace.sh

Cel

Inicjalizuje workspace poprzez klonowanie wszystkich repozytoriów zdefiniowanych w task.json i checkout na odpowiednie branches.

Użycie

W task.json (start_commands):

json
{
  "id": "init_workspace",
  "catalog": "START",
  "executor": "bash",
  "command": "bash /workspace/files/helpers/init_workspace.sh",
  "dependencies": []
}

Workflow

1. Odczyt task.json

2. Dla każdego repository w task.json.repositories[]:

   2.1. Clone repository do workspace/{folder}
        git clone {git_url} workspace/{folder}

   2.2. Checkout target_branch
        git checkout {target_branch}

   2.3. Create lub checkout working_branch
        git checkout -b {working_branch} || git checkout {working_branch}

   2.4. Pull latest changes (jeśli branch już istnieje remote)
        git pull origin {working_branch}

3. Log rezultatu

Przykład task.json

json
{
  "repositories": [
    {
      "folder": "sembot-angular",
      "git_url": "[email protected]:sembot-io/sembot-angular.git",
      "target_branch": "master",
      "working_branch": "feature/DEV-7315"
    },
    {
      "folder": "sembot-backend",
      "git_url": "[email protected]:sembot-io/sembot-backend.git",
      "target_branch": "develop",
      "working_branch": "feature/DEV-7315-backend"
    }
  ]
}

Output

bash
📦 Initializing workspace...
📂 Repository 1/2: sembot-angular

🔽 Cloning repository...
   git clone [email protected]:sembot-io/sembot-angular.git workspace/sembot-angular
 Cloned successfully

🌿 Checking out target branch: master
 On branch: master

🔀 Creating working branch: feature/DEV-7315
 Branch created and checked out

📂 Repository 2/2: sembot-backend
   ...

 Workspace initialized successfully
   Repositories: 2
   Working directory: /workspace

Error Handling

Clone failed:

  • Log error z git output
  • Exit code: 1
  • Task zostaje przeniesiony do failed/

Branch creation failed:

  • Próba checkout istniejącego brancha
  • Jeśli nadal błąd → exit code: 1

SSH key issues:

  • Sprawdzenie czy SSH key jest dostępny w kontenerze
  • Hint w logach o konfiguracji SSH

backup_task_md.sh

Cel

Tworzy backup oryginalnego task.md przed jego modyfikacją przez planning commands. Backup jest używany później do restore w fazie END.

Użycie

W task.json (start_commands):

json
{
  "id": "backup_task",
  "catalog": "START",
  "executor": "bash",
  "command": "bash /workspace/files/helpers/backup_task_md.sh",
  "dependencies": ["init_workspace"]
}

Workflow

1. Sprawdź czy task.md istnieje

2. Skopiuj task.md → task_original.md
   cp /task/task.md /task/task_original.md

3. Log rezultatu

Struktura Plików

Przed backup:

/task/
├── task.json
└── task.md           ← oryginalne wymagania użytkownika

Po backup:

/task/
├── task.json
├── task.md           ← oryginalne wymagania
└── task_original.md  ← backup

Po planning (task.md zostaje nadpisany):

/task/
├── task.json
├── task.md           ← plan wygenerowany przez AI
└── task_original.md  ← oryginalne wymagania (backup)

Output

bash
📋 Backing up task.md...

📂 Source: /task/task.md
📂 Destination: /task/task_original.md

 Backup created successfully

Error Handling

task.md nie istnieje:

bash
 Error: task.md not found at /task/task.md
   Cannot create backup.

Exit code: 1

Brak uprawnień do zapisu:

bash
 Error: Permission denied when creating backup

Exit code: 1


move_task_md.sh

Cel

W fazie END, przenosi plan wygenerowany przez AI (task.md) do task_plan.md oraz przywraca oryginalne wymagania użytkownika (task_original.md → task.md).

Użycie

W task.json (start_commands):

json
{
  "id": "move_task_spec",
  "catalog": "END",
  "executor": "bash",
  "command": "bash /workspace/files/helpers/move_task_md.sh",
  "dependencies": ["plan_task"]
}

Workflow

1. Sprawdź czy task_original.md istnieje

2. Przenieś task.md → task_plan.md
   mv /task/task.md /task/task_plan.md

3. Przywróć task_original.md → task.md
   cp /task/task_original.md /task/task.md

4. Log rezultatu

Struktura Plików

Przed move_task_md.sh:

/task/
├── task.json
├── task.md           ← plan wygenerowany przez AI
└── task_original.md  ← backup oryginalnych wymagań

Po move_task_md.sh:

/task/
├── task.json
├── task.md           ← oryginalne wymagania (przywrócone)
├── task_plan.md      ← plan wygenerowany przez AI (przeniesiony)
└── task_original.md  ← backup (zachowany)

Uzasadnienie

Dlaczego restore task.md?

  • Oryginalny task.md zawiera wymagania użytkownika
  • task_plan.md to tylko plan wykonania (artefakt pośredni)
  • W final verification potrzebujemy oryginalnych wymagań
  • Dla biznesu/review ważne są user requirements, nie plan

Output

bash
📋 Moving task spec files...

📂 Moving task.md task_plan.md
 Plan saved as task_plan.md

📂 Restoring task_original.md task.md
 Original requirements restored

 Task spec files organized successfully

Error Handling

task_original.md nie istnieje:

bash
⚠️  Warning: task_original.md not found
   Skipping restore, keeping current task.md

Exit code: 0 (warning, nie error - może nie było backup)

Brak task.md:

bash
 Error: task.md not found, nothing to move

Exit code: 1


persist_git_changes.sh

Cel

Commituje wszystkie zmiany w repozytoriach i generuje git diff dla dokumentacji.

Użycie

W task.json (start_commands):

json
{
  "id": "persist_git",
  "catalog": "END",
  "executor": "bash",
  "command": "bash /workspace/files/helpers/persist_git_changes.sh",
  "dependencies": ["move_task_spec"]
}

Workflow

1. Dla każdego repository w task.json.repositories[]:

   1.1. Git add wszystkie zmiany
        git add .

   1.2. Sprawdź czy są zmiany do commit
        git diff --cached --quiet

   1.3. Jeśli są zmiany:
        - Wygeneruj commit message (przez AI lub template)
        - Git commit z message
        - Zapisz git diff do /task/artifacts/diffs/{folder}.diff

   1.4. Jeśli brak zmian:
        - Log "No changes"
        - Skip commit

2. Podsumowanie wszystkich repozytoriów

Commit Message

AI-generated (domyślnie):

bash
# Używa AI (Haiku) do wygenerowania commit message
AI_PROVIDER="claude"
AI_MODEL="haiku"

# Prompt dla AI
PROMPT="Generate concise commit message for these changes:
$(git diff --cached --stat)

Format: <type>: <description>
Types: feat, fix, refactor, test, docs"

COMMIT_MSG=$(ai_generate "$PROMPT")

Template (fallback):

bash
# Jeśli AI niedostępne
COMMIT_MSG="feat: Implement changes for ${TASK_ID}

Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <[email protected]>"

Git Diff Export

Struktura:

/task/artifacts/diffs/
├── sembot-angular.diff     # diff dla pierwszego repo
├── sembot-backend.diff     # diff dla drugiego repo
└── summary.md              # podsumowanie wszystkich zmian

Format diff:

diff
diff --git a/src/app/settings/settings.component.ts b/src/app/settings/settings.component.ts
index 1234567..abcdefg 100644
--- a/src/app/settings/settings.component.ts
+++ b/src/app/settings/settings.component.ts
@@ -10,6 +10,10 @@ export class SettingsComponent {

+  toggleDarkMode() {
+    this.isDarkMode = !this.isDarkMode;
+  }
+
   ngOnInit() {
     // ...
   }

Output

bash
📝 Persisting git changes...

📂 Repository 1/2: sembot-angular

   📊 Changes detected:
      5 files changed, 120 insertions(+), 30 deletions(-)

   💬 Generating commit message...
      feat: Add dark mode toggle to settings

 Changes committed
      Commit: a1b2c3d4

   📄 Diff exported: /task/artifacts/diffs/sembot-angular.diff

📂 Repository 2/2: sembot-backend

   ℹ️  No changes detected
      Skipping commit

 Git changes persisted successfully
   Committed repositories: 1/2
   Total changes: 5 files, 120 insertions(+), 30 deletions(-)

Error Handling

Git commit failed:

bash
 Error: Git commit failed for repository: sembot-angular
   Output: [git error message]

Exit code: 1

Diff export failed:

bash
⚠️  Warning: Could not export diff for sembot-angular
   Continuing with commit...

Exit code: 0 (warning)


github_push_mr.sh

Cel

Pushuje zmiany do remote repository i tworzy Pull Request (GitHub) lub Merge Request (GitLab) z automatycznym assignee.

Użycie

W task.json (start_commands):

json
{
  "id": "github_push_mr",
  "catalog": "END",
  "executor": "bash",
  "command": "bash /workspace/files/helpers/github_push_mr.sh",
  "dependencies": ["persist_git"]
}

Workflow

1. Dla każdego repository w task.json.repositories[]:

   1.1. Push do remote branch
        git push -u origin {working_branch}

   1.2. Sprawdź czy istnieje MR/PR
        - Odczyt merge_request_id z task.json
        - Jeśli null → create new
        - Jeśli not null → skip (already exists)

   1.3. Create Pull Request/Merge Request
        - GitHub: gh pr create
        - GitLab: glab mr create

   1.4. Assign PR/MR
        - Assignee z issue.assignee_github_id
        - GitHub: gh pr edit --add-assignee
        - GitLab: glab mr update --assignee

   1.5. Zapisz MR/PR info do task.json
        - merge_request_id
        - merge_request_url

2. Podsumowanie wszystkich repozytoriów

PR/MR Title i Body

Title:

{issue.id}: {title}

Przykład: DEV-7315: Settings UI Unification

Body (template):

markdown
## Summary

[1-3 bullet points z podsumowaniem zmian]

## Changes

- [Lista głównych zmian]
- [Per repository]

## Test Plan

- [ ] Build passes
- [ ] Unit tests pass
- [ ] Visual verification completed
- [ ] Manual testing done

## Related

- Issue: {issue.url}
- Task: {task_id}

---

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Draft PR Support

W task.json:

json
{
  "repositories": [
    {
      "folder": "sembot-angular",
      "merge_request_create_as_draft": true  // ← create as draft
    }
  ]
}

GitHub:

bash
if [ "$CREATE_AS_DRAFT" = true ]; then
  gh pr create --draft --title "$TITLE" --body "$BODY"
else
  gh pr create --title "$TITLE" --body "$BODY"
fi

GitLab:

bash
if [ "$CREATE_AS_DRAFT" = true ]; then
  glab mr create --draft --title "$TITLE" --description "$BODY"
else
  glab mr create --title "$TITLE" --description "$BODY"
fi

Aktualizacja task.json

Przed push:

json
{
  "repositories": [
    {
      "folder": "sembot-angular",
      "working_branch": "feature/DEV-7315",
      "merge_request_id": null,
      "merge_request_url": null
    }
  ]
}

Po push i create PR:

json
{
  "repositories": [
    {
      "folder": "sembot-angular",
      "working_branch": "feature/DEV-7315",
      "merge_request_id": "123",                                    // ← PR number
      "merge_request_url": "https://github.com/org/repo/pull/123"   // ← PR URL
    }
  ]
}

Output

bash
🚀 Pushing changes and creating PR/MR...

📂 Repository 1/2: sembot-angular

📤 Pushing to remote...
   git push -u origin feature/DEV-7315
 Pushed successfully

🔍 Checking for existing PR/MR...
   ℹ️  No existing PR found (merge_request_id: null)

📝 Creating Pull Request...
   Title: DEV-7315: Settings UI Unification
   Base: master feature/DEV-7315

 PR created: https://github.com/sembot-io/sembot-angular/pull/123

👤 Assigning PR...
   Assignee: techleadgithub
 Assigned successfully

💾 Updating task.json...
 MR info saved

📂 Repository 2/2: sembot-backend
   ℹ️  No changes to push (no commits)

 Push and PR creation completed
   PRs created: 1/2
   Total PRs: 1

Error Handling

Push failed (no permissions):

bash
 Error: Push failed for repository: sembot-angular
   Permission denied (publickey)

   Hint: Check SSH key configuration in Docker

Exit code: 1

PR creation failed (already exists):

bash
⚠️  Warning: PR already exists for branch feature/DEV-7315
   URL: https://github.com/sembot-io/sembot-angular/pull/123

   Skipping PR creation, updating task.json with existing PR

Exit code: 0

Assignee not found:

bash
⚠️  Warning: Could not assign PR to: techleadgithub
   User not found or no permissions

   PR created successfully but not assigned

Exit code: 0


create_subtask (Helper)

Cel

Umożliwia dynamiczne tworzenie follow-up subtasków podczas wykonywania innych subtasków. Używane głównie przez review/test/qa role do tworzenia tasków fix.

Użycie

W subtask (np. podczas review):

bash
create_subtask <priority> <role> <title> <description> [dependencies]

Parametry

ParameterRequiredDescriptionExample
priorityYesSTART, P0, P1, P2, P3, ENDP0
roleYesfrontend, backend, test, qa, reviewer, etc.frontend
titleYesKrótki, opisowy tytułFix Login Form Crash
descriptionYesSzczegółowy opis (wielolinijkowy OK)Security vulnerability found...
dependenciesNoOddzielone przecinkami ID taskówfrontend_abc123,backend_def456

Przykłady Użycia

1. Prosty fix (bez dependencies):

bash
create_subtask P0 frontend \
  "Fix Login Form Crash" \
  "Login form crashes when user clicks submit with empty email field.
  Error: Cannot read property 'value' of null.

  Steps to reproduce:
  1. Open login page
  2. Click submit without entering email
  3. App crashes

  Expected: Show validation error
  Actual: App crashes"

2. Fix z dependencies:

bash
create_subtask P1 backend \
  "Fix Password Validation Bug" \
  "Password validation accepts passwords shorter than 8 characters.
  Should enforce minimum 8 characters.

  Found during testing: test_auth_validation_ghi789" \
  "backend_auth_api_def456"

3. Multiple dependencies:

bash
create_subtask P0 frontend \
  "Fix Settings Menu Icons" \
  "Menu icons not visible on mobile viewport.
  Affects: Settings, Profile, Dashboard" \
  "frontend_settings_abc123,ux_design_icons_xyz789"

Workflow

1. Parsowanie parametrów

2. Generowanie unique ID
   {role}_{random_hash}

3. Tworzenie katalog subtask
   /task/subtasks/{priority}/todo/{role}_{id}/

4. Tworzenie task.json
   - Przepisanie ai.provider, ai.model z parent
   - Ustawienie dependencies
   - Metadata (created_at, etc.)

5. Tworzenie task.md
   - Title jako header
   - Description jako content
   - Evidence links (jeśli dostępne)

6. Log creation
   - Orchestration log
   - Webhook notification

7. Return subtask ID

Generowany task.json

json
{
  "task_id": "frontend_fix_login_a1b2c3d4",
  "priority": "P0",
  "title": "Fix Login Form Crash",
  "why": "Created automatically during review - critical bug found",
  "dependencies": ["frontend_login_form_abc123"],
  "ai": {
    "provider": "claude",
    "model": "claude-sonnet-4",
    "start_command": "/frontend /task/subtasks/P0/todo/frontend_fix_login_a1b2c3d4",
    "sessions": {
      "claude": null,
      "codex": null,
      "gemini": null
    }
  },
  "created_at": "2025-12-31T14:30:00Z",
  "created_by": "reviewer_tech_xyz789",
  "updated_at": "2025-12-31T14:30:00Z",
  "started_at": null,
  "completed_at": null
}

Generowany task.md

markdown
# Fix Login Form Crash

## Problem

Login form crashes when user clicks submit with empty email field.

Error: Cannot read property 'value' of null.

## Steps to Reproduce

1. Open login page
2. Click submit without entering email
3. App crashes

## Expected Behavior

Show validation error

## Actual Behavior

App crashes

## Evidence

- Created by: reviewer_tech_xyz789
- Found during: Technical review
- Related task: frontend_login_form_abc123

## Acceptance Criteria

- [ ] Form does not crash with empty email
- [ ] Validation error shown to user
- [ ] Unit test added to prevent regression

Output

bash
📝 Creating follow-up subtask...

🆔 Subtask ID: frontend_fix_login_a1b2c3d4
📊 Priority: P0
👤 Role: frontend
📌 Title: Fix Login Form Crash
🔗 Dependencies: frontend_login_form_abc123

📂 Creating directory: /task/subtasks/P0/todo/frontend_fix_login_a1b2c3d4/

📄 Writing task.json...
 task.json created

📄 Writing task.md...
 task.md created

📝 Logging to orchestration.log...
 Logged

🔔 Sending webhook notification...
   Event: subtask_created
 Webhook sent

 Follow-up subtask created successfully
   ID: frontend_fix_login_a1b2c3d4
   Path: /task/subtasks/P0/todo/frontend_fix_login_a1b2c3d4/

Role Commands z create_subtask

Przykład w /reviewer_product command:

bash
# Krok 9: Jeśli znaleziono problemy

if [ $CRITICAL_ISSUES -gt 0 ] || [ $MAJOR_ISSUES -gt 0 ]; then
  echo "⚠️  Issues found - creating follow-up tasks..."

  # Critical issue
  create_subtask P0 frontend \
    "Fix Critical: Menu Icons Missing" \
    "Menu icons not visible on mobile. Critical UX issue blocking release." \
    "frontend_settings_menu_abc123"

  # Major issue
  create_subtask P1 frontend \
    "Improve Error Messages" \
    "Error messages not user-friendly. Confusing for end users." \
    "frontend_validation_def456"
fi

Best Practices

1. Jeden task = Jeden problem

bash
# ❌ Źle: grupowanie wielu problemów
create_subtask P0 frontend \
  "Fix Multiple Issues" \
  "Fix crash, improve validation, update styles, add tests"

# ✅ Dobrze: osobny task per problem
create_subtask P0 frontend "Fix Crash" "..."
create_subtask P1 frontend "Improve Validation" "..."
create_subtask P2 frontend "Update Styles" "..."

2. Dołącz dowody

bash
# ✅ Link do evidence
create_subtask P0 frontend \
  "Fix Visual Bug" \
  "Menu icons missing on mobile.

  Evidence:
  - Screenshot: /task/verification/screenshots/23-mobile-settings.png
  - Video: /task/verification/video/menu-bug.webm"

3. Oznacz dependencies

bash
# ✅ Jeśli fix zależy od innego taska
create_subtask P0 backend \
  "Fix API Validation" \
  "API accepts invalid data.

  Depends on: backend_api_endpoint_def456 (must be completed first)" \
  "backend_api_endpoint_def456"

4. Priorytet based on impact

PriorityUse CaseExample
P0Crashes, data loss, security, broken core featuresApp crashes, XSS vulnerability
P1Broken features, significant UX/performance issuesFeature doesn't work, slow page load
P2Minor issues, refactoring, coverage gapsMissing error message, code duplication
P3Polish, documentation, nice-to-havesBetter styling, additional docs

Montowanie Helper Scripts do Docker

docker-compose.yml Configuration

Wszystkie workery muszą mieć:

yaml
services:
  worker:
    image: your-worker-image
    volumes:
      - ./helpers:/workspace/files/helpers:ro   # ← helper scripts (read-only)
      - workspace_volume:/workspace              # ← workspace dla repo
      - ./task:/task                             # ← task spec i artifacts

Struktura Katalogów w Docker

/workspace/
├── files/
│   └── helpers/
│       ├── init_workspace.sh
│       ├── backup_task_md.sh
│       ├── move_task_md.sh
│       ├── persist_git_changes.sh
│       ├── github_push_mr.sh
│       └── create_subtask
├── sembot-angular/              # ← repo 1
├── sembot-backend/              # ← repo 2
└── ...

/task/
├── task.json
├── task.md
├── artifacts/
│   ├── logs/
│   └── diffs/
└── subtasks/

Permissions

Helper scripts muszą być executable:

bash
chmod +x helpers/*.sh
chmod +x helpers/create_subtask

W Dockerfile:

dockerfile
# Upewnij się że helper scripts są executable
RUN chmod +x /workspace/files/helpers/*.sh
RUN chmod +x /workspace/files/helpers/create_subtask

Error Handling - Ogólne Zasady

Exit Codes

CodeMeaningAction
0SuccessContinue
1Error (recoverable)Retry (jeśli retry_count < 1)
2Error (permanent)Fail immediately
130User interruptFail immediately

Logging

Wszystkie helper scripts logują do:

/task/artifacts/logs/helpers/{script_name}.log

Format logu:

[2025-12-31 14:30:00] [INFO] init_workspace.sh: Starting workspace initialization
[2025-12-31 14:30:05] [INFO] init_workspace.sh: Cloning repository: sembot-angular
[2025-12-31 14:30:15] [SUCCESS] init_workspace.sh: Workspace initialized successfully

Webhook Notifications

Helper scripts mogą wysyłać webhooks:

bash
# send_webhook.sh helper
send_webhook() {
  local event_type=$1
  local payload=$2

  curl -X POST "$N8N_WEBHOOK_URL" \
    -H "Content-Type: application/json" \
    -d "$payload"
}

# Przykład użycia w github_push_mr.sh
send_webhook "pr_created" '{
  "task_id": "'"$TASK_ID"'",
  "repository": "'"$REPO_FOLDER"'",
  "pr_url": "'"$PR_URL"'",
  "pr_number": "'"$PR_NUMBER"'"
}'

Changelog

v2.0 - Advanced Helpers

  • ✅ AI-generated commit messages (persist_git_changes.sh)
  • ✅ Draft PR support (github_push_mr.sh)
  • ✅ Dynamic subtask creation (create_subtask)
  • ✅ Dependency tracking across helpers
  • ✅ Webhook notifications per helper

v1.0 - Basic Helpers

  • ✅ init_workspace.sh - Repository cloning
  • ✅ backup_task_md.sh - Task backup
  • ✅ move_task_md.sh - Spec organization
  • ✅ persist_git_changes.sh - Git commits
  • ✅ github_push_mr.sh - PR/MR creation