From a3be89c59e1626b8fa6556d1a6818890d24e60b5 Mon Sep 17 00:00:00 2001 From: Henrik Jess Nielsen Date: Sat, 9 May 2026 19:09:51 +0200 Subject: [PATCH] feat: Taskz project-first redesign, worklog sync, FA6 icons, indigo theme - Replace 4-column Kanban with project-grouped sidebar + flat task list - Status badges (colored pills) with click-to-cycle - Full task edit modal: title, description, status, priority, tags, findings - Worklog sync endpoints POST /api/v1/worklog/sync + sync-activity - Worklog empty state with curl command + paste-to-upload modal - Font Awesome 6 throughout, no emojis - Indigo topbar (bg-indigo-950) - Fix Knowledge rendering: r.documents, r.files, r.available_agents/skills - HOWTOs filename fallback, agent/skill detail extraction --- app/mcp_client.py | 8 + app/routers/worklog.py | 30 +- app/templates/dashboard.html | 1246 ++++++++++++++++++++++++---------- 3 files changed, 909 insertions(+), 375 deletions(-) diff --git a/app/mcp_client.py b/app/mcp_client.py index 9ce2c2c..6ac7b02 100644 --- a/app/mcp_client.py +++ b/app/mcp_client.py @@ -173,3 +173,11 @@ async def list_skills(domain: Optional[str] = None) -> Dict[str, Any]: async def get_skill(name: str) -> Dict[str, Any]: return await _call_tool("get_skill", {"name": name}) + + +async def ingest_git_history(content: str) -> Dict[str, Any]: + return await _call_tool("ingest_git_history", {"content": content}) + + +async def ingest_activity_log(content: str) -> Dict[str, Any]: + return await _call_tool("ingest_activity_log", {"content": content}) diff --git a/app/routers/worklog.py b/app/routers/worklog.py index ef1372b..ac53799 100644 --- a/app/routers/worklog.py +++ b/app/routers/worklog.py @@ -4,7 +4,7 @@ from __future__ import annotations from typing import Optional -from fastapi import APIRouter, HTTPException +from fastapi import APIRouter, HTTPException, Request from app import mcp_client @@ -37,3 +37,31 @@ async def api_standup(days: int = 2, context: str = "egmont"): return await mcp_client.get_standup(days=days, context=context) except Exception as exc: raise HTTPException(status_code=502, detail=f"DevOpsMCP error: {exc}") from exc + + +@router.post("/worklog/sync") +async def api_worklog_sync(request: Request): + """Accept raw ~/.githistory content and ingest into DevOpsMCP Redis.""" + body = await request.body() + content = body.decode("utf-8", errors="replace") + if not content.strip(): + raise HTTPException(status_code=400, detail="Empty body — send content of ~/.githistory") + try: + result = await mcp_client.ingest_git_history(content) + return {"message": "Git history synced", "result": result} + except Exception as exc: + raise HTTPException(status_code=502, detail=f"DevOpsMCP error: {exc}") from exc + + +@router.post("/worklog/sync-activity") +async def api_worklog_sync_activity(request: Request): + """Accept raw ~/.activitylog content and ingest into DevOpsMCP Redis.""" + body = await request.body() + content = body.decode("utf-8", errors="replace") + if not content.strip(): + raise HTTPException(status_code=400, detail="Empty body — send content of ~/.activitylog") + try: + result = await mcp_client.ingest_activity_log(content) + return {"message": "Activity log synced", "result": result} + except Exception as exc: + raise HTTPException(status_code=502, detail=f"DevOpsMCP error: {exc}") from exc diff --git a/app/templates/dashboard.html b/app/templates/dashboard.html index bc63cfc..6448872 100644 --- a/app/templates/dashboard.html +++ b/app/templates/dashboard.html @@ -8,277 +8,519 @@ + - -
+ +
- ⚡ DevOpsDash - i80.dk + + DevOpsDash + +