Internal Documentation internal
TalkIDE internal documentation

Get the current status of all AI team members for an entire project. Status is derived from the activities table and scoped to the project across all conversations. Only authenticated users with access to the project can call this endpoint.

  • The endpoint is project-scoped — it returns team status across all conversations in the project.
  • Mara (talkide-pm) is always present in the response, even if no activities have been recorded yet (placeholder, status IDLE).
  • All other members (Iris, Theo, Eli, Nia, Kai) appear in the response only after their first activity of any type within the project.
  • Status WORKING means there is a TASK_STARTED activity for that agent_role within the project that has no subsequent matching TASK_COMPLETED.
  • Status IDLE means all tasks started by the agent have a matching TASK_COMPLETED, or the agent has no activities at all.
  • currentTask = description of the most recent TASK_STARTED without a TASK_COMPLETED for that agent; null if IDLE.
  • lastActiveAt = created_at of the most recent activity row for that agent; null for Mara if she has no activities yet.
  • This endpoint is a snapshot — for live updates the frontend subscribes to the SSE stream (UC-05001) and updates the team status panel incrementally.

Agent Role Mapping

agent_role (technical key)NameLabel
talkide-pmMaraProduct Manager
talkide-analystIrisAnalyst
talkide-backend-devTheoBackend Engineer
talkide-frontend-devEliFrontend Engineer
talkide-reviewerNiaReviewer
talkide-devopsKaiDevOps
sequenceDiagram
    actor User

    User->>+FE: opens workspace view

    FE->>+BE: GET /api/v1/projects/{projectId}/team <br> Authorization: Bearer {accessToken}

    BE->>BE: validate access token
    alt token missing or invalid
        BE-->>FE: 401 Unauthorized <br> ErrorResponse
    end

    BE->>DB: load project by projectId
    alt project not found
        BE-->>FE: 404 Not Found <br> ErrorResponse
    end

    BE->>BE: check project belongs to user's tenant
    alt project does not belong to tenant
        BE-->>FE: 403 Forbidden <br> ErrorResponse
    end

    BE->>DB: query latest TASK_STARTED without TASK_COMPLETED per agent_role <br> and latest activity created_at per agent_role <br> scoped to project_id

    BE->>BE: always include talkide-pm (Mara) even if no activities <br> include other roles only if they have at least one activity

    BE->>-FE: 200 OK <br> TeamStatusResponse

    FE->>-User: render team status panel

GET /api/v1/projects/{projectId}/team

200 OK TeamStatusResponse (project has activity from Mara and Eli; Iris, Theo, Nia, Kai have no activities yet):

{
  "members": [
    {
      "agentRole": "talkide-pm",
      "name": "Mara",
      "label": "Product Manager",
      "status": "WORKING",
      "currentTask": "Plánuje aplikaci",
      "lastActiveAt": "2026-04-30T11:24:30Z"
    },
    {
      "agentRole": "talkide-frontend-dev",
      "name": "Eli",
      "label": "Frontend Engineer",
      "status": "WORKING",
      "currentTask": "Pozadí aplikace",
      "lastActiveAt": "2026-04-30T11:24:00Z"
    }
  ]
}

200 OK TeamStatusResponse (empty project — no activities at all):

{
  "members": [
    {
      "agentRole": "talkide-pm",
      "name": "Mara",
      "label": "Product Manager",
      "status": "IDLE",
      "currentTask": null,
      "lastActiveAt": null
    }
  ]
}

401 Unauthorized (missing or invalid access token) ErrorResponse:

{
  "status": 401,
  "code": "AUTHENTICATION_FAILED",
  "message": "Access token is missing or invalid"
}

403 Forbidden (project does not belong to user’s tenant) ErrorResponse:

{
  "status": 403,
  "code": "FORBIDDEN",
  "message": "You do not have access to this project"
}

404 Not Found (project not found) ErrorResponse:

{
  "status": 404,
  "code": "NOT_FOUND_PROJECT",
  "message": "Project not found"
}

Team Status Rules

ConditionStatuscurrentTasklastActiveAt
Agent has a TASK_STARTED with no matching TASK_COMPLETEDWORKINGdescription of that TASK_STARTEDcreated_at of most recent activity
Agent has activities but all tasks are completedIDLEnullcreated_at of most recent activity
Agent has no activities at all (other than Mara)not included in response
Mara (talkide-pm) has no activitiesIDLEnullnull

UX Guidelines

Context

Team Status Strip je horizontální pruh v horní části levého sloupce workspace (chat column), hned pod TTopBar. V současnosti je hardcoded přes TEAM_BY_ID data z team.ts a zobrazuje 4 členy. Po refactoru bude řízen daty z GET /team + live update přes SSE eventy (UC-05001). Existující komponenta TeamChip.vue se zachovává a rozšíří o currentTask label a animace.


User Flow

  1. Workspace se načte → FE zavolá GET /projects/{projectId}/team.
  2. Strip zobrazí skeleton (jeden placeholder chip).
  3. Po odpovědi se zobrazí Mara (vždy první) + ostatní členové podle pořadí prvního výskytu.
  4. SSE event activity s eventType=TASK_STARTED → FE přidá/aktualizuje chip dotčeného agenta na WORKING.
  5. SSE event activity s eventType=TASK_COMPLETED → FE přepne chip na IDLE a skryje currentTask.
  6. Hover nad chipem → tooltip s detailem (jméno, label, stav, currentTask, lastActiveAt).
  7. (Future enhancement) Klik na chip → filtruje activity feed na daného agenta.

Layout — Team Strip

┌─────────────────────────────────────────────────────────────┐
│  ON IT   [Mara ●]  [Eli ●]  [Iris ●]  [Theo ○]  [Nia ○]  │
└─────────────────────────────────────────────────────────────┘
  • Kontejner: px-5 py-3.5 border-b border-[var(--line-1)] flex items-center gap-3 shrink-0 (stávající)
  • Label “ON IT”: text-[11px] font-mono uppercase text-[var(--fg-3)] s letter-spacing: 0.06em (stávající)
  • Chipy: flex gap-2 flex-1 — základní wrap zakázán; pokud chipů > 5–6, strip má overflow-x: auto (vodorovný scroll) se skrytou scrollbar
  • Mara je vždy na pozici 0 (první zleva)
  • Ostatní členové v pořadí podle lastActiveAt DESC (= pořadí prvního výskytu, nejdříve aktivní = vlevo)

Chip Anatomy

TeamChip.vue — stávající props: member, status: 'leading' | 'working' | 'idle', task?: string

Po refactoru (props se rozšíří, nezmění se):

  • status prop dostane hodnotu 'leading' pro Maru (vždy), 'working' pokud status === 'WORKING', 'idle' pokud status === 'IDLE'
  • task prop = currentTask z API (string nebo null)

Vizuální anatomie chipu (stávající layout zachován):

┌────────────────────────────────────┐
│  ┌───┐                            │
│  │ E │● jméno  · currentTask…     │
│  └───┘                            │
└────────────────────────────────────┘
SlotPopis
AvatarTAvatar 20px, barevná inicializace z agentColor
Status dot8px kruh absolute -right-0.5 -bottom-0.5; WORKING/leading = glow (box-shadow: 0 0 6px <color>); IDLE = var(--fg-4) bez glow
Agent nametext-xs — vždy viditelný
CurrentTasktext-[11px] text-[var(--fg-3)] — prefixed · — zobrazeno jen pokud task prop není null; truncate na ~25 znaků s ellipsis

Status dot colors (konzistentní s TeamChip.vue):

StavBarvaGlow
leading (Mara)amber var(--amber)ano
workingindigo var(--indigo)ano
idlevar(--fg-4)ne

States

WORKING

  • Status dot: barevný + pulsující (CSS animation pulse 2s infinite — stejný pattern jako u pulsujícího dotu v activity feedu)
  • currentTask prop je vyplněný — zobrazí se vedle jména s · oddělovačem
  • Tooltip zobrazí plnou hodnotu currentTask (pokud je text truncated)

IDLE

  • Status dot: šedý var(--fg-4), bez glow, bez animace
  • task prop je null — currentTask label se nezobrazuje
  • Chip je mírně ztlumený: opacity-70 pro IDLE členy (Mara jako leading má vždy 100 %)

Initial / Empty

Zobrazí se jen Mara s status="leading" a bez task. Ostatní chipy se neukážou dokud nemají activity.


Tooltip on Hover

Na hover nad chipem se zobrazí floating tooltip (vlastní nebo knihovní — implementace na devs):

┌─────────────────────────────┐
│  Eli                        │
│  Frontend Engineer          │
│  ─────────────────────────  │
│  Stav: Pracuje              │
│  Úkol: Pozadí aplikace      │
│  Naposledy aktivní: 2 min   │
└─────────────────────────────┘
  • Pozice: nad chipem (nebo pod pokud u horního okraje), centered horizontálně
  • Background: var(--bg-3), border var(--line-1), rounded-lg, shadow-lg
  • Delay: 400 ms hover delay (neotevírá se na přejetí myší)
  • lastActiveAt: relativní čas stejného formátu jako v activity feedu
  • Pokud status === 'IDLE': řádek “Úkol” se nezobrazuje

Animations

Nový člen přibyde (IDLE → první výskyt)

Chip se přidá na konec řady (za poslední stávající chip):

  1. Vloží se s opacity-0 scale-90
  2. Transition na opacity-100 scale-100 — 300 ms ease-out
  3. Sousední chipy se posunou plynule (layout shift, ne transform)

Přechod IDLE → WORKING

  1. Status dot: barva přejde z var(--fg-4) na var(--indigo) — color transition 500 ms
  2. Glow se rozsvítí (box-shadow transition 500 ms)
  3. currentTask label se objeví s opacity-0 → opacity-100 — 300 ms fade-in (po 200 ms délace, aby dot animace proběhla první)
  4. Chip se mírně rozšíří (width transition přes max-width nebo Tailwind transition-all)

Přechod WORKING → IDLE

  1. currentTask label zfaduje opacity-100 → opacity-0 — 200 ms
  2. Status dot: barva přejde na var(--fg-4) — transition 500 ms
  3. Glow zhasne (box-shadow transition 500 ms)
  4. Chip se zúží (width transition)

Všechny transition třídy: transition-all duration-500 ease-in-out na chip kontejneru.


Accessibility

  • Strip jako celek: role="list" aria-label="Team status" (nebo česky dle aktivního locale)
  • Každý chip: role="listitem"
  • Avatar inicializace: aria-label="{agentName}" (text reprezentace)
  • Status dot: aria-hidden="true" (dekorativní)
  • Tooltip: role="tooltip" + chip má aria-describedby="{tooltip-id}"
  • Tab order: chipy jsou focusable (tabindex="0"); Enter/Space = stejná akce jako klik (future: filter)

i18n Keys

KlíčENCS
workspace.team.status.workingWorkingPracuje
workspace.team.status.idleIdleČeká
workspace.team.status.leadingLeadingŘídí
workspace.team.tooltip.currentTaskTaskÚkol
workspace.team.tooltip.lastActiveLast activeNaposledy aktivní
workspace.team.tooltip.noActivityNo activity yetZatím žádná aktivita
workspace.team.stripLabelOn itNa tom
workspace.team.aria.stripTeam statusStav týmu

Poznámka: workspace.team.stripLabel odpovídá stávajícímu hardcoded t('workspace.onIt') — při refactoru stačí přesunout pod nový klíč nebo ponechat stávající klíč.


Frontend

Validations

FieldConstraintsSizePatternNote
projectId(path)Required path segment

Backend

Validations

FieldConstraintsSizePatternNote
projectIdnot_null, positivePath variable; must reference an existing project belonging to user’s tenant

Test Cases

GIVENWHENTHEN
project exists with no activitiesGET /api/v1/projects/{projectId}/team is called200 OK; response contains exactly one member: Mara with status=IDLE, currentTask=null, lastActiveAt=null
Mara delegates task to Eli with description “Pozadí aplikace” (TASK_STARTED inserted for talkide-frontend-dev, no TASK_COMPLETED yet)GET /api/v1/projects/{projectId}/team is called200 OK; Mara WORKING + Eli WORKING with currentTask=“Pozadí aplikace”; Iris/Theo/Nia/Kai absent
Eli’s TASK_STARTED has a matching TASK_COMPLETEDGET /api/v1/projects/{projectId}/team is called200 OK; Eli status=IDLE, currentTask=null, lastActiveAt updated to TASK_COMPLETED created_at
Mara delegates a second task to Eli with description “Tlačítko odeslat” (new TASK_STARTED, no TASK_COMPLETED)GET /api/v1/projects/{projectId}/team is called200 OK; Eli status=WORKING, currentTask=“Tlačítko odeslat” (most recent open task description)
Mara delegates to Iris (TASK_STARTED for talkide-analyst) and Eli (TASK_STARTED for talkide-frontend-dev) simultaneously, neither has TASK_COMPLETEDGET /api/v1/projects/{projectId}/team is called200 OK; Mara + Iris + Eli all WORKING; Theo/Nia/Kai absent
authenticated user, project belongs to a different tenantGET /api/v1/projects/{projectId}/team is called403 FORBIDDEN error response is returned
authenticated user, project does not existGET /api/v1/projects/{projectId}/team is called404 NOT_FOUND_PROJECT error response is returned
no Authorization headerGET /api/v1/projects/{projectId}/team is called401 AUTHENTICATION_FAILED error response is returned

Was this page helpful?

Thanks for the feedback.