rk-ef-daily-report

star 0

Generate an Everfit daily standup report from Jira worklogs and post it as a reply into a Slack thread you provide. Pulls cards you logged work on the target date (DONE / PROGRESS CHANGED) plus your open-sprint cards (PLAN FOR TODAY), derives progress % from time tracking, then drafts the report for your review before replying into the thread. Triggers on: 'daily report', 'standup', 'daily', 'EOD report', 'báo cáo ngày', 'wrap up'.

tuannguyen-everfit By tuannguyen-everfit schedule Updated 6/5/2026

name: rk:ef-daily-report description: "Generate an Everfit daily standup report from Jira worklogs and post it as a reply into a Slack thread you provide. Pulls cards you logged work on the target date (DONE / PROGRESS CHANGED) plus your open-sprint cards (PLAN FOR TODAY), derives progress % from time tracking, then drafts the report for your review before replying into the thread. Triggers on: 'daily report', 'standup', 'daily', 'EOD report', 'báo cáo ngày', 'wrap up'." argument-hint: "[] [--date=YYYY-MM-DD] [--thread=] [--no-slack] [--platform=Backend|Web|...] [--blocker=...] [--at-risk=...] [--question=...] [--dry-run]" metadata: author: rock288 version: "2.1.1"

Daily Report

Build the team's daily standup report from Jira and reply it into a Slack thread you provide (the report is a comment in that thread, not a new channel message). Variant B flow: fetch → derive → show the full draft in chat → user edits → then post. Never post without confirmation (unless --no-slack/--dry-run).

IMPORTANT: Do not implement code or modify Jira. This skill only reads Jira, formats a report, and posts to Slack.

Flags

Flag Default Effect
<slack-thread-url> (positional) or --thread=<url> The Slack message/thread URL to reply into. Channel + thread_ts are parsed from the URL. Required to post (omit only with --no-slack/--dry-run).
--date=<YYYY-MM-DD> yesterday The day to pull worklogs for (the "yesterday" anchor).
--no-slack off Print the report, do not post to Slack.
--platform=<...> config Override the Platform line (Backend / Web / Android / iOS / QA / BA).
--blocker=<text> None Fill the Blocker field without prompting.
--at-risk=<text> None Fill the At-risk field without prompting.
--question=<text> None Fill the Question field without prompting.
--dry-run off Derive + print only; no Slack post, no config writes.

Report format (authoritative)

Emit GitHub-flavored markdown- for the task bullet, a 2-space-indented - for each sub-field, **bold** for headers, and a blank line between product-item groups. This is the exact shape (the template below is what the model OUTPUTS, not a code block to paste):

**DAILY REPORT — [DD Mon YYYY]**   ← TODAY (posting day, Asia/Saigon), NOT --date
**Name:** [name]
**Platform:** [Backend / Web / Android / iOS / QA / BA]
——————————————————
**DONE YESTERDAY**

[Product Item Name]
- [Task name] ([UP-XXXXX](https://everfit.atlassian.net/browse/UP-XXXXX))
  - Progress: 100%
- [Task name — not yet done] ([UP-XXXXX](https://everfit.atlassian.net/browse/UP-XXXXX))
  - Progress: X%
  - Remaining: [what is left]

**PROGRESS CHANGED**

[Product Item Name]
- [Task name] ([UP-XXXXX](https://everfit.atlassian.net/browse/UP-XXXXX))
  - Progress: X% → Y%
  - Reason: [cause]

**PLAN FOR TODAY**

[Product Item Name]
- [Task name] ([UP-XXXXX](https://everfit.atlassian.net/browse/UP-XXXXX))
  - Progress: X% by EOD | Full task done: [date / EOD / DD Mon]
  - AI: None OR [how Claude will be used]

**Blocker:** None OR [...]
**At-risk:** None OR [...]
**Question:** None OR [...]

⚠️ Bullets MUST be markdown, never the glyphs / . Slack renders markdown lists (- + indent) into real bullets; the literal / characters do NOT produce list formatting and collapse into one paragraph when pasted. This applies to BOTH the chat draft (step 4) and the Slack post (step 5). The **bold** headers convert to Slack *bold* via the content_type: text/markdown backend, and degrade gracefully on manual paste.

Header date = today (posting day, Asia/Saigon). --date only selects which day's worklogs feed DONE / PROGRESS CHANGED — it does NOT change the header.

Empty section → print None. If a PROGRESS CHANGED card logged time but the % didn't move, use a 2-space-indented - Progress: Still X% with a mandatory - Reason: (blocker/slowdown).

Card links: append each task's card ID as a Jira link — [Task name] ([UP-XXXXX](https://everfit.atlassian.net/browse/UP-XXXXX)). Use standard markdown link syntax (renders as a clickable link in both Slack backends and the chat draft).

Workflow

1. Load config

Load per-repo config from memory/daily_report.md (this skill's folder). Fields:

  • name — report header name.
  • platform — default Platform line.
  • jira_account — usually omit (use currentUser()); set an accountId only to report for someone else.

The Slack channel is not stored — it's parsed from the thread URL each run.

First run / missing fields (skip writes under --dry-run): ask once via AskUserQuestion for name + platform, write the file, continue. Subsequent runs load silently.

2. Derive from Jira

Follow references/derivation.md exactly:

  • Only cards assigned to me — both queries require assignee = currentUser(). A card I logged work on (or created) but that is assigned to someone else is excluded.
  • --date is a Vietnam (Asia/Saigon) calendar day. JQL worklogDate runs in the Jira account tz (LA, ~14h behind), so query a widened window (worklogDate >= date-1 AND < date+2) as a coarse pre-filter, then bucket each worklog started converted to VN and keep only entries whose VN date == --date. loggedTarget = Σ of those.
  • getJiraIssue per card → progress % = timeSpent / (timeSpent + remaining); reconstruct the before% → now% delta from loggedTarget (no state file).
  • Worklog comments are optional — the delta comes from logged time alone. Reason = logged <time>, <status>; only append a comment if one exists.
  • Map Epic/parent → Product Item, summary → Task name.

3. Assemble the report

Fill the format above. Set the header date to today (posting day, Asia/Saigon). Manual fields (Blocker / At-risk / Question) default to Nonenever prompt for them; only fill from --blocker/--at-risk/--question if passed. --platform overrides the config platform.

4. Draft → confirm (Variant B)

Print the full report in chat as RENDERED markdown — never wrapped in a fenced code block (no ). The user copies the report straight from the rendered chat preview and pastes it into Slack; a code block pastes raw -/** source that Slack does NOT convert to bullets, and the literal / glyphs collapse into one paragraph. Rendered markdown (- bullets + [text](url) links) is the ONLY form whose copy keeps the bullet list + clickable links in Slack. Invite the user to edit (they reply with corrections; apply them). Do not proceed to Slack until the user confirms. --dry-run / --no-slack stop here.

5. Reply into the Slack thread

Parse the thread URL (positional arg or --thread=). Accepted forms:

  • https://<workspace>.slack.com/archives/<CHANNEL_ID>/p<DIGITS>channel_id = <CHANNEL_ID>; message ts = insert a dot 6 digits from the end of <DIGITS> (drop the leading p), e.g. p17278901234567891727890123.456789.
  • If the URL has a query ?thread_ts=<ts>&cid=<CHANNEL_ID> (a link to a reply inside a thread), prefer thread_ts from the query and cid for the channel.
  • The parsed message ts becomes thread_ts so the report posts as a reply in that thread.

Post — mirror ef-ship §10 backend selection, always passing thread_ts:

  • Preferred (if registered): mcp__slack-mcp__conversations_add_message with channel_id, thread_ts, text = the report, content_type = text/markdown.
  • Fallback (default bundled): mcp__claude_ai_Slack__slack_send_message with channel_id, thread_ts, message = the report.
  • Capture the returned reply ts. On failure, surface the error but don't crash — print the report so the user can paste it into the thread manually.

Notes

  • currentUser() keys all queries off the authenticated Atlassian account — no account lookup needed for self-reporting.
  • No channel is stored — every post targets the thread URL given that run.
  • Keep the report concise; sacrifice grammar for brevity (team convention).
Install via CLI
npx skills add https://github.com/tuannguyen-everfit/rock288_claude_plugin --skill rk-ef-daily-report
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator
tuannguyen-everfit
tuannguyen-everfit Explore all skills →