feat(dashboard): unified workspace hub — cookie auth, 9-state projects, planning chat
Merges workspace.html + ralph.html into a single unified project hub with: - Cookie-based auth (DASHBOARD_TOKEN, HttpOnly, SameSite=Strict) - 9-state project badge system (running-ralph/manual, planning, approved, pending, blocked, failed, complete, idle) with BUTTONS_FOR_STATE matrix - SSE realtime + polling fallback, version-based optimistic concurrency (If-Match) - Planning chat modal (phase stepper, markdown bubbles, 50s+ wait state, auto-resume) - Propose modal (Variant B: inline Plan-with-Echo checkbox) - 5-type toast taxonomy (success/info/warning/busy/error, 3px colored left-bar) - Inter font self-hosted + shared tokens.css design system + DESIGN.md - src/jsonlock.py (flock helper, sidecar .lock for stable inode) - src/approved_tasks_cli.py (shell-safe wrapper for cron/ralph.sh) - 55 new tests (T#1–T#30) + real jsonlock bug fix caught by T#16/T#28 - No emoji anywhere (enforced by test_dashboard_no_emoji.py) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -139,9 +139,9 @@ class TestStatus:
|
||||
|
||||
class TestLog:
|
||||
def test_log_returns_progress_lines(self, handler, tmp_path):
|
||||
_make_ralph_project(tmp_path, "p1", [], progress="line1\nline2\nline3")
|
||||
handler.path = "/api/ralph/p1/log"
|
||||
handler.handle_ralph_log("p1")
|
||||
_make_ralph_project(tmp_path, "p1a", [], progress="line1\nline2\nline3")
|
||||
handler.path = "/api/ralph/p1a/log"
|
||||
handler.handle_ralph_log("p1a")
|
||||
assert handler.captured_code == 200
|
||||
assert handler.captured["lines"] == ["line1", "line2", "line3"]
|
||||
assert handler.captured["total"] == 3
|
||||
@@ -170,10 +170,10 @@ class TestLog:
|
||||
class TestPrd:
|
||||
def test_prd_returns_full_json(self, handler, tmp_path):
|
||||
stories = [{"id": "US-001", "passes": False, "title": "t", "priority": 10}]
|
||||
_make_ralph_project(tmp_path, "p1", stories)
|
||||
handler.handle_ralph_prd("p1")
|
||||
_make_ralph_project(tmp_path, "p1a", stories)
|
||||
handler.handle_ralph_prd("p1a")
|
||||
assert handler.captured_code == 200
|
||||
assert handler.captured["projectName"] == "p1"
|
||||
assert handler.captured["projectName"] == "p1a"
|
||||
assert len(handler.captured["userStories"]) == 1
|
||||
|
||||
def test_prd_404_when_missing(self, handler, tmp_path):
|
||||
|
||||
Reference in New Issue
Block a user