---
name: reports-client-status
description: "📊 REPORTS: Generate client-facing status updates — auto-scan Fireflies, Slack, Jira & Gmail to produce a short, precise, ready-to-send project status update for any cadence. Use whenever asked to prepare or generate a status update for any client project. Triggers include: \"prepare the weekly update\", \"bi-weekly update\", \"sprint summary\", \"sprint status update\", \"end of sprint report\", \"monthly status\", \"monthly summary for [client]\", \"status update for [person]\", \"napisz weekly update\", \"napisz sprint summary\", \"co się działo w tym tygodniu\", \"podsumowanie sprintu\", \"miesięczny update\", \"dwutygodniowy update\", or any variation of summarising a period's progress for a client or stakeholder. Auto-scans all live sources and produces a short, precise, client-ready text covering dev progress, design progress, decisions made, and blockers. Output is shown in chat for review and copy — never posted automatically."
---

# Client Status Update Skill

## Purpose
Auto-generate a short, client-ready status update for any project by scanning all live
sources. Output is shown in chat — not posted anywhere — for review before sending.

Tone: Professional, direct, concise. No filler. No internal jargon.
Length: Weekly ≤ 250w · Bi-weekly ≤ 300w · Sprint ≤ 300w · Monthly ≤ 450w. Scannable. No walls of text.

---

## Step 0: Resolve project context and cadence

If not already clear from conversation, determine:
- **Project name** and client name (+ client email domain for Gmail scan)
- **Cadence** — weekly, bi-weekly, sprint, or monthly? (ask if not specified)
- **Jira project key** (or search for it)
- **Slack channels** to scan (or search for them by project name)
- **Audience** — who is this update for? (affects tone and what to include/exclude)

**Sprint only — ask before proceeding:**
> "Which sprint would you like to summarise? Current sprint (default), last sprint, or a specific one?"

---

## Execution Workflow

### Step 1: Determine the scan window

The scan window depends on the chosen cadence:

**Weekly:** today minus **7 days**. No Confluence lookup needed.

**Bi-weekly:** today minus **14 days**. No Confluence lookup needed.

**Monthly:** today minus **30 days**. No Confluence lookup needed.

**Sprint:**
Based on the user's answer from Step 0, fetch sprint details from Jira:

- **Current sprint (default):**
  ```
  JQL: project = <KEY> AND sprint in openSprints()
  ```
  Use the sprint's `startDate` as scan start, today as scan end.

- **Last sprint:**
  ```
  JQL: project = <KEY> AND sprint in closedSprints() ORDER BY endDate DESC LIMIT 1
  ```
  Use the sprint's `startDate` as scan start and `endDate` as scan end.

- **Specific sprint:** ask the user for the sprint name or number, fetch it by name, use its `startDate` and `endDate`.

If sprint dates are unavailable, default to **14 days ago** and tell the user.

The resolved sprint `startDate` / `endDate` become the single window applied to **all sources** (Fireflies, Slack, Gmail) — not just Jira. See Step 2 for how each source uses them.

Convert all dates to both ISO 8601 (for Fireflies/Gmail) and Unix timestamp (for Slack).
Record both the **scan start date** and **scan end date** — both appear in the output header.

---

### Step 2: Scan sources in parallel

Run all of the following simultaneously:

**Fireflies** — find meetings within the scan window:
- Primary: `keyword: "<project_name>"`, `fromDate: <scan_start>`, `toDate: <scan_end>` (sprint only; omit for other cadences), `limit: 10`
- Fallback: search by `participants: [<pm_email>]`, then filter manually to project-relevant meetings
- For each relevant meeting found, call `fireflies_get_summary`
- Extract: what was built/discussed, decisions made, action items, blockers raised

**Slack** — scan project-related channels:

Primary: `slack_read_channel` with `channel_id: "<channel-id>"`, `oldest: <unix_start_timestamp>`, and `limit: 200` for each relevant channel
(main operational channel, UI/design feedback channel, partner-specific channels).
For sprint reports, enforce the end of the window by ignoring any returned messages with `ts` greater than `<unix_end_timestamp>`.

Fallback if a channel ID is unknown: `slack_search_public_and_private` with a keyword query
to locate the channel, then switch to `slack_read_channel` using `channel_id`, `oldest`, and `limit`, then apply the same timestamp filtering.

For messages that appear to contain a decision, client confirmation, or partner update, read the full thread:
```
slack_read_thread(channel_id: "<channel-id>", thread_ts: "<ts>")
```
Client approvals and confirmations are frequently given as replies to questions, not as standalone messages.
Extract: decisions confirmed, client responses, partner updates, blockers raised.

**Gmail** — scan for client emails within the scan window:
```
search_threads(query: "from:<client_domain> OR to:<client_domain> after:<YYYY/MM/DD> before:<YYYY/MM/DD>", maxResults: 20)
```
Omit `before:` for non-sprint cadences (defaults to today).
- Focus on threads containing approvals, decisions, scope changes, or blockers from the client.
- If client email domain is unknown, search by the client name as a keyword.
- Extract: decisions or approvals given by email, client-raised blockers, confirmed scope changes.

**Jira** — fetch project activity within the scan window:

*Weekly / Bi-weekly:*
```
JQL: project = <KEY> AND updated >= "<scan_start_date>" AND issuetype in (Story, Task) ORDER BY updated DESC
fields: summary, status, assignee, issuetype
maxResults: 30
```

*Sprint:*
```
JQL: project = <KEY> AND sprint = "<sprint_name>" AND issuetype in (Story, Task) ORDER BY updated DESC
fields: summary, status, assignee, issuetype
maxResults: 50
```
Use sprint membership (not date range) so tickets belonging to the sprint are captured regardless of when they were last updated.

*Monthly:*
```
JQL: project = <KEY> AND updated >= "<scan_start_date>" AND issuetype in (Story, Task, Epic) ORDER BY updated DESC
fields: summary, status, assignee, issuetype
maxResults: 50
```

Sub-tasks excluded in all cases — their titles carry no meaning without parent context.
Extract: tickets moved to Done (shipped this period), tickets In Progress (active dev),
newly created stories indicating scope added this period.

---

### Step 3: Synthesise and write the update

Cross-reference all sources and produce the output using the format below.
Ruthlessly prioritise: only include things that moved, changed, or matter this period.
Do not pad. If a section has nothing to report, write "Nothing to report."

---

## Output Format

Present in chat, ready to copy. Use plain text with light markdown only.
Replace `[Cadence]` with the actual label: **Weekly Update**, **Bi-weekly Update**, **Sprint Summary**, or **Monthly Summary**.
Header shows the full date range covered by the scan, not a single date.

---

```
📋 [Project Name] — [Cadence] — [DD.MM.YY]–[DD.MM.YY]

**Development**
• [specific thing built or shipped]
• [specific thing built or shipped]

**Design**
• [specific design completed, shared, or feedback received]

**Decisions**
• [Decision] — [who confirmed it, date if known]

**Blockers & Pending**
• [What is blocked] — [what is needed, from whom]
```

---

## Tone Calibration by Audience

Adjust language based on who receives the update. If audience was not specified, ask.

| Audience | Tone | What to include | What to avoid |
|---|---|---|---|
| Technical client (dev team, CTO) | Direct, precise, can use tech terms | Specific component names, API names, infra decisions | Business fluff, over-explaining |
| Non-technical client (CEO, founder, PM) | Plain language, outcome-oriented | What changed for users, business impact | Tech stack, ticket numbers, internal tool names |
| Internal stakeholder (PM, PMO) | Concise, can use project shorthand | Team dynamics, risks, resource signals | Over-polishing — they want signal, not spin |
| External partner / vendor | Formal, scoped to integration points only | Shared milestones, API contracts, joint blockers | Internal team dynamics, unrelated product areas |

When in doubt: write for a smart person who doesn't work on the project day-to-day.
No internal shorthand (ticket IDs, team nicknames, tool names) unless the audience is internal.

---

## Rules for Each Section

**Development** — 2–4 bullets. Name the specific feature or component, not just "frontend work
continued". Source from: Fireflies meeting summaries, Jira tickets Done or In Progress, Slack
mentions of shipped work.
- ✅ Good: "Cart flow implemented — quantity controls, promo code input, empty state"
- ❌ Bad: "Development work progressed this week"
- If multiple small items shipped: group them into one bullet by theme rather than listing each.

**Design** — 2–3 bullets. What was delivered in Figma, shared with client, or approved.
Include any client feedback received and how it was actioned.
- If the project has no dedicated designer or nothing design-related happened: **omit this section entirely** — don't write "Nothing to report."
- If design and dev are tightly coupled (e.g. design handoff and implementation happened together): merge into the Development section.

**Decisions** — confirmed decisions only, not open discussions. Attribute to a person or
confirmed source. If none this period, write: "• No formal decisions this period."
- A decision must be resolved and communicated — "we're still discussing" is not a decision.
- Include decisions made *about* the project even if made by the client alone (e.g. via email).

**Blockers & Pending** — items actively blocking progress or awaiting client input.
Write as a clear ask: what is needed and from whom. Do not list routine pending items that
aren't actually blocking anything right now. Partner items should only appear here if there
was a concrete development this period. If there was no movement, omit rather than placeholder.
- Distinguish: a **blocker** stops work now. A **pending** item will block future work if not resolved.

---



## Quality Checks

Before presenting, verify:
- [ ] Length within limit: Weekly ≤ 250w · Bi-weekly ≤ 300w · Sprint ≤ 300w · Monthly ≤ 450w
- [ ] Header shows a date range (not a single date)
- [ ] Every bullet is specific and evidenced from a source
- [ ] No vague statements ("work continued", "progress was made")
- [ ] Decisions are attributed to a person or source (including email confirmations)
- [ ] Blockers name what is needed and from whom
- [ ] Tone matches the audience — no internal shorthand for external updates
- [ ] Partner/vendor updates scoped to integration points only if audience is external partner
- [ ] Header label matches the actual cadence (Weekly / Bi-weekly / Sprint / Monthly)
- [ ] Design section omitted entirely if not applicable (not written as empty)

Drop any bullet that can't pass these checks. Never invent progress not found in sources.

---

## After Presenting

Ask: *"Anything to add or change before you copy this?"*

**Posting to Slack:** If the user asks to send it to Slack, confirm which channel, then create
a Slack draft using `slack_send_message_draft`. Show the user the draft link and wait for
explicit confirmation ("yes, send it") before doing anything further. Never post directly.

**Saving to Confluence:** If the user wants to save it, ask which space/page to save it under,
then use `createConfluencePage` with the update as the page body. Show a preview and wait for
confirmation before creating.
