Files
Software Orchestrator f6691b74f6 feat: add ui_design_specialist (Phase 3 UI Design) v0.2.0
- New specialist: ui_design_specialist with iterative mockup dialog
- New Phase 3 (UI Design) between Architecture and Implementation
- Relay model: orchestrator passes responses verbatim in Phase 3
- Cost-control exception for UI Design phase (unlimited subagent calls)
- Webspace mockup workflow with cache-buster and obscure dirs
- UX states coverage (loading, empty, error, partial)
- WCAG 2.1 AA accessibility guidelines
- Design tokens (CSS custom properties) in design system
- Component states (hover, focus, active, disabled, loading, error)
- Sitemap/wireframe before mockups for complex UIs
- Real content strategy (no Lorem Ipsum)
- Form validation UX in mockups
- Dark mode and i18n support (optional)
- Design handoff support (specialist available during implementation)
- Skip mechanism for non-UI projects
- Mockup state file for context compression recovery
- Multi-page mockup strategy with index.html
- task_graph.json mockup references
- Plugin version: 0.1.14 -> 0.2.0
- 47 files changed across 7 implementation blocks
- 3 review rounds with 41 corrections integrated
2026-06-19 21:33:21 +02:00

15 KiB
Raw Permalink Blame History

Diff-Highlights: Plan v3 Patch vs. Original

Volldiff: /a0/usr/plugins/a0_software_orchestrator/docs/diff-v3-vs-original.patch (1680 Zeilen, 20 Patches)

Patch-Statistik (Top 12 nach +Lines)

Datei + - Total Bemerkung
docs/diff-v3-vs-original.patch 347 0 360
utils/migrate_legacy_project_names.py 155 0 161 NEU
docs/bugfix-auto-registration.md 120 72 333
helpers/db_state_store.py 69 37 187
tools/plan_mode_guard.py 59 42 207
utils/migrate_a0_to_db.py 17 3 47
helpers/compact_protocol.py 11 7 56
helpers/artifact_rules.py 7 2 26
helpers/briefing_file.py 7 3 32
tools/quality_gate.py 6 4 28
helpers/resume_state.py 5 3 27
tools/block_compactor.py 5 3 25

Diff-Snippets (erste 50 Zeilen pro ausgewählter Datei)

helpers/db_state_store.py (+69 -37)

diff -ruN /a0/usr/plugins/a0_software_orchestrator.backup-20260616T095813Z/orig/a0_software_orchestrator/helpers/db_state_store.py /a0/usr/plugins/a0_software_orchestrator/helpers/db_state_store.py
--- /a0/usr/plugins/a0_software_orchestrator.backup-20260616T095813Z/orig/a0_software_orchestrator/helpers/db_state_store.py	2026-06-15 14:24:02.000000000 +0000
+++ /a0/usr/plugins/a0_software_orchestrator/helpers/db_state_store.py	2026-06-16 10:08:25.622937781 +0000
@@ -5,17 +5,25 @@
 
 Verwendung:
     from usr.plugins.a0_software_orchestrator.helpers.db_state_store import (
-        resolve_project, get_kv, set_kv, append_worklog,
-        set_status, add_next_step, add_todo, set_block_compact,
-        create_snapshot, append_briefing, add_score,
+        register_project, get_project_id, resolve_project,
+        get_kv, set_kv, append_worklog, set_status, add_next_step,
+        add_todo, set_block_compact, create_snapshot,
+        append_briefing, add_score,
     )
 
-    pid = resolve_project("crm-system")
+    # Neues Projekt anlegen (explizit, mit Plausiprüfung):
+    pid = register_project("crm-system", git_url="https://...")
     set_kv(pid, "phase", "implementation")
     append_worklog(pid, phase="implementation", work_block="T012",
                    agent="implementation_engineer", summary="Auth-Endpoint fertig")
     add_next_step(pid, "T013: Test schreiben")
     set_status(pid, "12/30 tasks done, Auth läuft")
+
+    # Existierendes Projekt nachschlagen (nur lesen):
+    existing_pid = get_project_id("crm-system")  # gibt None wenn unbekannt
+
+    # In create-on-missing-Aufrufern (z.B. Migration):
+    pid = resolve_project("crm-system")  # wirft LookupError wenn fehlt
 """
 from __future__ import annotations
 
@@ -30,6 +38,37 @@
 
 
 # ---------------------------------------------------------------------------
+# Project-Name Validation (Pattern + Blacklist)
+# ---------------------------------------------------------------------------
+
+import re
+
+PROJECT_NAME_PATTERN = re.compile(r"^[a-z][a-z0-9-]{1,40}$")
+FORBIDDEN_PROJECT_NAMES = frozenset({
+    "a0", "a0-development", "workdir", "dev-projects",
+    "usr", "tmp", "home", "root", "skills", "plugins",
+    "opt", "lib", "etc", "var", "data", "venv",
+})
+
+def _validate_project_name(name: str) -> str:
... (137 weitere Zeilen im Volldiff)

tools/plan_mode_guard.py (+59 -42)

diff -ruN /a0/usr/plugins/a0_software_orchestrator.backup-20260616T095813Z/orig/a0_software_orchestrator/tools/plan_mode_guard.py /a0/usr/plugins/a0_software_orchestrator/tools/plan_mode_guard.py
--- /a0/usr/plugins/a0_software_orchestrator.backup-20260616T095813Z/orig/a0_software_orchestrator/tools/plan_mode_guard.py	2026-06-15 21:03:27.000000000 +0000
+++ /a0/usr/plugins/a0_software_orchestrator/tools/plan_mode_guard.py	2026-06-16 10:14:34.924136247 +0000
@@ -1,21 +1,13 @@
-"""Tool: enforce Plan Mode by checking current mode (DB-backed)."""
+"""Tool: enforce Plan Mode by checking current mode (DB-backed, global)."""
 from __future__ import annotations
 
 import json
-import os
 from typing import Any, Dict
 
 from helpers.tool import Tool, Response
-from usr.plugins.a0_software_orchestrator.helpers.db_state_store import resolve_project, get_kv, set_kv
-from usr.plugins.a0_software_orchestrator.helpers.exceptions import PluginDBError
-
-
-def _resolve_name(project_name: str = "", project_root: str = "") -> str:
-    if project_name:
-        return project_name.strip()
-    if project_root:
-        return os.path.basename(project_root.rstrip("/"))
-    return os.path.basename(os.getcwd())
+from usr.plugins.a0_software_orchestrator.helpers.db_state_store import (
+    _db_error_handler, _db,
+)
 
 
 _DEFAULT_MODE = {
@@ -38,6 +30,11 @@
     "maintenance_allowed": {"allowed_actions": ["code", "test", "commit", "deploy"], "blocked_actions": ["destroy"]},
 }
 
+# Plan-Mode ist plugin-weit (Bug 7 Fix). Der Key lebt in orch_kv mit
+# project_id=0 als globalem Platzhalter, NICHT pro Projekt.
+_PLUGIN_MODE_PROJECT_ID = 0
+_PLUGIN_MODE_KEY = "orchestrator_mode"
+
 
 def _normalize_mode(mode_data: Any) -> Dict[str, Any]:
     """Stellt sicher, dass das gelesene Mode-Dict die erwarteten Keys hat."""
@@ -52,33 +49,57 @@
     return out
 
 
+@_db_error_handler
+def _get_plugin_mode() -> Dict[str, Any]:
+    """Liest den globalen Plan-Mode aus orch_kv (project_id=0).
+
+    Returns _DEFAULT_MODE wenn kein Eintrag existiert.
... (157 weitere Zeilen im Volldiff)

tools/next_step.py (+5 -3)

diff -ruN /a0/usr/plugins/a0_software_orchestrator.backup-20260616T095813Z/orig/a0_software_orchestrator/tools/next_step.py /a0/usr/plugins/a0_software_orchestrator/tools/next_step.py
--- /a0/usr/plugins/a0_software_orchestrator.backup-20260616T095813Z/orig/a0_software_orchestrator/tools/next_step.py	2026-06-15 14:24:02.000000000 +0000
+++ /a0/usr/plugins/a0_software_orchestrator/tools/next_step.py	2026-06-16 10:09:29.231450211 +0000
@@ -5,7 +5,7 @@
 
 from helpers.tool import Tool, Response
 from usr.plugins.a0_software_orchestrator.helpers.db_state_store import (
-    resolve_project,
+    get_project_id,
     add_next_step,
     complete_next_step,
     list_next_steps,
@@ -46,8 +46,10 @@
             return Response(message="ERROR: 'action' required. Supported: add, list, complete", break_loop=False)
         name = _resolve_name(project_name, project_root)
         try:
-            pid = resolve_project(name)
-        except ValueError as e:
+            pid = get_project_id(name)
+            if pid is None:
+                raise LookupError(f"project '{name}' is not registered")
+        except (ValueError, LookupError) as e:
             return Response(message=f"ERROR: {e}", break_loop=False)
         except PluginDBError as e:
             return Response(message=f"Database error: {e}", break_loop=False)

utils/migrate_legacy_project_names.py (+155 -0)

diff -ruN /a0/usr/plugins/a0_software_orchestrator.backup-20260616T095813Z/orig/a0_software_orchestrator/utils/migrate_legacy_project_names.py /a0/usr/plugins/a0_software_orchestrator/utils/migrate_legacy_project_names.py
--- /a0/usr/plugins/a0_software_orchestrator.backup-20260616T095813Z/orig/a0_software_orchestrator/utils/migrate_legacy_project_names.py	1970-01-01 00:00:00.000000000 +0000
+++ /a0/usr/plugins/a0_software_orchestrator/utils/migrate_legacy_project_names.py	2026-06-16 10:15:07.578452765 +0000
@@ -0,0 +1,155 @@
+#!/usr/bin/env python3
+"""migrate_legacy_project_names  archiviert Projekte mit ungültigen Namen.
+
+Bug 1+2 Begleit-Skript (Plan v3 §3.6):
+- Iteriert über alle Projekte in der DB.
+- Prüft jeden Namen gegen PROJECT_NAME_PATTERN + FORBIDDEN_PROJECT_NAMES.
+- Markiert ungültige Namen mit status='archived' in project_state (idempotent).
+- Bestehende 'active'-Projekte mit ungültigem Namen werden zu 'archived'.
+- Bereits archivierte werden NICHT doppelt verändert (idempotent).
+
+Aufruf:
+    python3 utils/migrate_legacy_project_names.py [--dry-run] [--verbose]
+
+Defaults:
+- --dry-run: nur Report, keine DB-Schreibzugriffe.
+- --verbose: zusätzlich pro Projekt-Status ausgeben.
+
+Exit-Code:
+- 0: Erfolg (inkl. 0 archivierte Projekte).
+- 1: DB-Fehler.
+"""
+from __future__ import annotations
+
+import argparse
+import os
+import sys
+from typing import List, Tuple
+
+PLUGIN_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+# Run from /a0 to have usr.plugins.* resolvable.
+from usr.plugins.a0_software_orchestrator.helpers.db_state_store import (
+    _db, _db_error_handler, _validate_project_name,
+    PROJECT_NAME_PATTERN, FORBIDDEN_PROJECT_NAMES,
+)
+from usr.plugins.a0_software_orchestrator.helpers.exceptions import PluginDBError
+
+
+@_db_error_handler
+def list_projects_with_states() -> List[Tuple[int, str, str]]:
+    """Returns Liste von (project_id, project_name, current_status).
+
+    Liest aus projects JOIN project_state. Projekte ohne project_state-Eintrag
+    bekommen den Status '<none>'.
+    """
+    db = _db()
... (111 weitere Zeilen im Volldiff)

api/project_state_get.py (+4 -1)

diff -ruN /a0/usr/plugins/a0_software_orchestrator.backup-20260616T095813Z/orig/a0_software_orchestrator/api/project_state_get.py /a0/usr/plugins/a0_software_orchestrator/api/project_state_get.py
--- /a0/usr/plugins/a0_software_orchestrator.backup-20260616T095813Z/orig/a0_software_orchestrator/api/project_state_get.py	2026-06-15 14:24:02.000000000 +0000
+++ /a0/usr/plugins/a0_software_orchestrator/api/project_state_get.py	2026-06-16 10:14:06.905148563 +0000
@@ -13,7 +13,10 @@
 class ProjectStateGet(ApiHandler):
     async def process(self, input: dict, request: Request) -> dict | Response:
         project_root = input.get("project_root", os.getcwd())
-        project_name = input.get("project_name") or os.path.basename(project_root.rstrip("/"))
+        # Bug 4 Fix: basename-Fallback entfernt. project_name ist Pflicht.
+        project_name = input.get("project_name")
+        if not project_name:
+            return {"ok": False, "error": "project_name is required (basename fallback removed)"}
         try:
             pid = get_project_id(project_name)
             if pid is None:
Binary files /a0/usr/plugins/a0_software_orchestrator.backup-20260616T095813Z/orig/a0_software_orchestrator/api/__pycache__/project_state_get.cpython-313.pyc and /a0/usr/plugins/a0_software_orchestrator/api/__pycache__/project_state_get.cpython-313.pyc differ

helpers/artifact_rules.py (+7 -2)

diff -ruN /a0/usr/plugins/a0_software_orchestrator.backup-20260616T095813Z/orig/a0_software_orchestrator/helpers/artifact_rules.py /a0/usr/plugins/a0_software_orchestrator/helpers/artifact_rules.py
--- /a0/usr/plugins/a0_software_orchestrator.backup-20260616T095813Z/orig/a0_software_orchestrator/helpers/artifact_rules.py	2026-06-15 14:24:02.000000000 +0000
+++ /a0/usr/plugins/a0_software_orchestrator/helpers/artifact_rules.py	2026-06-16 10:11:38.560624907 +0000
@@ -42,7 +42,7 @@
 def _check_db_artifacts(project_name: str) -> Dict[str, bool]:
     """Prüft die 5 DB-backed Artefakte via db_state_store."""
     from .db_state_store import (
-        resolve_project,
+        get_project_id,
         get_kv,
         get_status,
         list_worklog,
@@ -50,7 +50,12 @@
         list_next_steps,
     )
 
-    pid = resolve_project(project_name)
+    pid = get_project_id(project_name)
+    if pid is None:
+        return {
+            "worklog": False, "todo": False, "project_state": False,
+            "current_status": False, "next_steps": False,
+        }
 
     return {
         "worklog":        len(list_worklog(pid, limit=1)) > 0,

v0.2.0: UI Design Specialist (Phase 3 UI Design)

Overview

Added ui_design_specialist as a new specialist subagent and Phase 3 (UI Design) to the phase sequence.

New Phase Sequence (8 phases)

  1. Intake -> 2. Architecture -> 3. UI Design -> 4. Implementation -> 5. Test -> 6. Runtime -> 7. Deployment -> 8. Release

Files Changed (Blocks 3-6)

Block 3: Orchestrator-Prompts (4 files)

  • agents/a0_software_orchestrator/prompts/agent.system.main.solving.md - Phase 3 inserted, all subsequent phases +1, subagent routing updated, plan-mode transitions updated, quality gates + stop gates for UI Design, relay mode + cost control exception + design handoff support documented
  • agents/a0_software_orchestrator/prompts/agent.system.main.specifics.md - ui_design_specialist added to subagents list, quality gates updated, Persona-Modus section with ui_design_specialist + relay mode added
  • agents/a0_software_orchestrator/prompts/agent.system.main.tips.md - Phase references updated, relay mode + cost control + design handoff tips added
  • agents/a0_software_orchestrator/quality_contract.md - UI Design Gate added to quality gates

Block 4: Spezialisten-Prompts (6 files)

  • agents/quality_reviewer/prompts/agent.system.main.specifics.md - UI Design review trigger added
  • agents/quality_reviewer/quality_contract.md - UI Design review checklist section added
  • agents/release_auditor/prompts/agent.system.main.solving.md - UI Design added to phases list
  • agents/solution_architect/prompts/agent.system.main.solving.md - Plan-mode transitions updated: after architecture comes UI Design
  • agents/requirements_analyst/prompts/agent.system.main.solving.md - Flow reference updated: after architecture comes UI Design
  • agents/implementation_engineer/prompts/agent.system.main.solving.md - Hint to read UI design artifacts added

Block 5: Templates (2 new + 17 modified)

  • prompts/project_templates/core/ui_design.md (NEW) - Design system, UX states, accessibility, component states, form validation, design tokens
  • prompts/project_templates/core/component_inventory.md (NEW) - Component list with all states
  • prompts/project_templates/core/phase_gates.md - Gate 3: UI DESIGN -> IMPLEMENTATION added, gates renumbered
  • prompts/project_templates/core/AGENTS.md - Specialists section with ui_design_specialist
  • prompts/project_templates/core/architecture.md - Next-Phase: UI Design
  • prompts/project_templates/core/design.md - Next-Phase: UI Design
  • prompts/project_templates/core/project_state.json - ui_design_done field added
  • prompts/project_templates/core/{resume,worklog,todo,current_status}.md - Phase references updated
  • prompts/project_templates/optional/subagent_policy.yaml - ui_design_specialist profile added
  • prompts/project_templates/optional/quality_gates.md - UI Design Gate added
  • prompts/project_templates/optional/definition_of_done.md - UI Design DoD section added
  • prompts/project_templates/optional/traceability_matrix.md - UI Design Ref column added
  • prompts/project_templates/optional/project_scorecard.md - UI Design category added
  • prompts/project_templates/optional/handoff.md - UI Design section added
  • prompts/project_templates/optional/release_notes.md - UI Design section added

Block 6: Tool-Prompts + Doku + Externe (8 files)

  • prompts/agent.system.tool.quality_gate.md - UI Design uses quality_reviewer note added
  • README.md - Specialist count updated to 9, ui_design_specialist added
  • help/handover/help.md - ui_design_specialist added to known profiles, count updated to 12
  • help/management/tool-governance.md - Available Specialist Profiles section added
  • help/operations/runtime.md - Phase context with 8 phases added
  • help/testing/validation.md - Phase context with 8 phases added
  • docs/diff-highlights.md - This section
  • /a0/usr/workdir/agent.system.main.specifics.promptinclude.md - Persona-Modus: ui_design_specialist added (external file)