# Client Dashboard

> Aggregate view of all client context.md files into a single status board. Shows who's onboarding, who's live, who's blocked, and what's overdue. Use when the user says "client dashboard", "status board", "show dashboard", "who's blocked?", "who needs attention?", or "what's my portfolio look like?"

- Skill: `ivangit-avoca/client-dashboard` (Agent Skill)
- Install (CLI): `npx skillmds@latest add ivangit-avoca/client-dashboard`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ivangit-avoca/client-dashboard/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: ivangit-avoca (https://skillmd.com/u/ivangit-avoca)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/ivangit-avoca/client-dashboard

---


# Client Dashboard

## When this applies

- User says **"client dashboard"**, **"status board"**, **"show dashboard"**
- User asks **"who's blocked?"**, **"who needs attention?"**, **"what's my portfolio look like?"**
- Any request for an aggregate view across all clients

## Prerequisites

- `clients/` directory exists with one or more `{Name}-{ID}/context.md` files

## Workflow

### Step 1 — Discover all clients

Glob for `clients/*/context.md`. Read **every** matching file in parallel (batch all reads in one tool-call round).

### Step 2 — Parse each context.md

For each file, extract the fields below. Parsing must tolerate missing sections and naming variations.

| Field | How to extract |
|-------|---------------|
| **Client name** | From the `# {Name} — {ID}` heading. Name is everything before ` — `. |
| **ID** | After ` — ` in the heading. May be a number or `TBD`. |
| **Folder** | The parent directory name (e.g. `Sykes Services-2285`). |
| **Status phase** | From the `## Status:` line. Strip the emoji. Keep the full text after the emoji (e.g. `Live (4/10)`, `In Progress — Testing phase, go-live target week of Apr 14–16`). |
| **Products** | From `**Products**:` under Quick facts. May be blank. |
| **CRM** | From `**CRM**:` under Quick facts. May be blank. |
| **Progress checkboxes** | All `- [x]` and `- [ ]` lines under the section named `## Manual progress` OR `## Onboarding progress`. Count checked vs total. Also capture the text of each unchecked item. |
| **Key dates** | From the `## Key dates` markdown table. Extract rows for Kickoff, Testing, Go-live. Dates may be blank, `TBD`, or in various formats (e.g. `4/6`, `Mar 30`, `2026-03-31`, `End of April`). Parse what you can into comparable dates; leave fuzzy ones as-is. |
| **System health** | Count `[x]` vs `[ ]` lines under `## System health`. Also note critical failures: lines containing `[ ]` with keywords `VAPI assistant`, `phone numbers`, `Responder webhook`, `ST API credentials`. |
| **Last synced** | From `<!-- last_synced: ... -->` near the bottom. Parse as a date. If missing, treat as never synced. |
| **Health checked** | From `<!-- health_checked: ... -->` inside System health. Parse as a date. |
| **Open action items** | Any `- [ ]` lines that are NOT inside `## System health` and NOT inside `## Manual progress` / `## Onboarding progress`. These are ad-hoc action items (e.g. under Notes, or in standalone action-item sections). Capture the text of each. |

### Step 3 — Classify into status buckets

Assign each client to exactly one bucket, evaluated in this order (first match wins):

| Priority | Bucket | Condition |
|----------|--------|-----------|
| 1 | **Live** | Status text contains "live" (case-insensitive) |
| 2 | **Paused** | Status text contains "paused" or "on hold" |
| 3 | **Go-Live Ready** | `Testing call completed` is `[x]` AND `Go-live call completed` is `[ ]` AND status does NOT contain "live" |
| 4 | **Testing** | Status contains "testing" OR `Testing call scheduled` or `Testing call completed` is `[x]` |
| 5 | **Building** | Status contains "building", "in progress", "phase 2", or "creds" |
| 6 | **Kickoff** | Status contains "kickoff" OR none of the above matched |

### Step 4 — Detect flags

For each client, check for these flags. A client can have multiple.

**Blocked:**
- Kickoff date is > 7 days ago AND `Kickoff call completed` is still unchecked
- Has open action items assigned to the client contact (pattern: `- [ ] {Name}:` where Name is NOT "Ivan") — these are waiting on the client
- System health has critical failures for their current phase:
  - Building or later: no VAPI assistant, no phone numbers, no Responder webhook
  - Testing or later: no employee contacts, no transfer destinations

**Overdue:**
- A Key dates row (Testing or Go-live) has a parseable date **before today** AND the corresponding progress checkbox (`Testing call completed` or `Go-live call completed`) is still unchecked
- Go-live target date mentioned in the status line is before today

**Stale data:**
- `last_synced` is missing or more than 3 days before today

**Action items:**
- Has any open action items (the ad-hoc ones from Step 2) — note count

### Step 5 — Render the dashboard

Print the dashboard directly to the user as markdown. Use this structure:

```
# Client Dashboard — {today's date, e.g. Apr 11, 2026}

**Portfolio:** {total} clients | {live count} live | {in-progress count} in progress | {kickoff count} in kickoff
```

Then render each non-empty bucket as a section, in this order: Live, Go-Live Ready, Testing, Building / In Progress, Kickoff, Paused.

**For Live clients:**

```
## Live ({count})

| Client | ID | Products | Go-live date | Status |
|--------|-----|----------|-------------|--------|
| Sykes Services | 2285 | Responder | 4/10 | Handoff pending |
```

Status column: note if handed off, or any open items remaining.

**For Go-Live Ready clients:**

```
## Go-Live Ready ({count})

| Client | ID | Products | Go-live target | Progress | Flags |
|--------|-----|----------|---------------|----------|-------|
| Quality Pro | 2343 | Responder | Apr 14–16 | 4/7 | 4 action items |
```

**For Testing clients:**

```
## Testing ({count})

| Client | ID | Products | Testing date | Progress | Flags |
|--------|-----|----------|-------------|----------|-------|
```

**For Building / In Progress clients:**

```
## Building ({count})

| Client | ID | Products | Next milestone | Progress | Flags |
|--------|-----|----------|---------------|----------|-------|
```

Progress column: `{checked}/{total}` from progress checkboxes.
Next milestone: the first unchecked progress item.
Flags: comma-separated list of flags from Step 4 (e.g. `stale, blocked on client`).

**For Kickoff clients:**

```
## Kickoff ({count})

| Client | ID | Products | Kickoff date | Progress | Flags |
|--------|-----|----------|-------------|----------|-------|
```

**For Paused clients:**

```
## Paused ({count})

| Client | ID | Reason |
|--------|-----|--------|
```

**Skip empty buckets** — don't render a section if no clients fall into it.

After the bucket tables, render an attention summary:

```
---

### Needs attention

List clients that have ANY flag (blocked, overdue, action items, or stale), one bullet per client:

- **{Client}-{ID}**: {comma-separated reasons}
```

If no clients need attention, print: `All clients on track.`

Then:

```
### Stale data (not synced in 3+ days)

- {Client}-{ID}: last synced {date}
```

If none are stale, omit this section.

### Step 6 — Offer follow-up actions

After rendering the dashboard, offer:

1. **Sync stale clients** — "Want me to sync the stale clients?" (runs `sync {client}` for each)
2. **Drill into a client** — "Want details on any specific client?"
3. **Prep for next call** — "Want me to prep you for your next upcoming call?"

## Important rules

- **Read-only.** Never modify any `context.md` file.
- **Show the full board.** Don't summarize or truncate — the user wants the complete picture.
- **Be concise in flag descriptions.** Use short phrases like `stale`, `blocked on client`, `overdue: testing`, `4 action items`.
- **Sort within buckets** by urgency: clients with flags first, then alphabetically.
- **Handle edge cases gracefully:**
  - If a client has no System health section (e.g. pre-team clients with TBD ID), skip health-based flags for them.
  - If Key dates are blank or `TBD`, skip overdue detection for those milestones.
  - If Products or CRM are blank, show `—` in the table cell.
  - If a date format is ambiguous or unparseable, show it as-is and skip date comparisons for it.
- **No auto-sync.** Don't trigger the client-auto-sync rule while reading files for the dashboard. Just read and aggregate. (The auto-sync rule normally fires when reading a single client's context.md during focused work — the dashboard is a bulk read for aggregation purposes.)

