husamql3/eod-skill/eod

Claude Code and agent skill by husamql3/eod-skill

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Generate a Slack-ready end-of-day work summary from the current git repo. Trigger this skill whenever the user types /eod, asks for an EOD report, wants a daily standup summary, wants to summarize today's work or this week's work, wants to post work updates to Slack, or mentions "end of day", "EOD", or "what did I work on". Accepts time periods like "today", "week", "yesterday", "last 3 days", or "since Monday". Also accepts one or more repo URLs or "owner/repo" names as arguments, each resolved to its local checkout automatically.

Install

npx vskill@latest install husamql3/eod-skill/eod

SKILL.md

EOD Skill

Create a short, clean end-of-day message the user can post to Slack, based on their git commits.

Defaults

  • Default shift window: 6:00 PM to 2:00 AM in the local timezone.
  • If the user does not specify a period, use the current or most recently

completed shift window.

  • When no repo arguments are given, use the current git repo. If the current

directory is not inside a repo, ask the user to run the request from inside their project.

  • When one or more repo URLs or owner/repo names are passed as arguments,

resolve each to its local checkout automatically (see Step 2) and report on all of them. Do not ask the user where a repo lives — search for it.

  • Use EOD_AUTHOR_EMAILS when it is set. It should be a git author regex, for

example husamahmud@gmail.com|husam.yildirim@firstimpactmed.com|husam.yildirim@synergexmed.com.

  • If EOD_AUTHOR_EMAILS is not set, default to

husamahmud@gmail.com|husam.yildirim@firstimpactmed.com|husam.yildirim@synergexmed.com.

  • If that default is removed, use git config user.email. If that is

unavailable, use git config user.name.

Steps

1. Figure out the time period

If the user gives a period, honor it:

  • today: use the relevant 6:00 PM to 2:00 AM shift window.
  • week: from the most recent Monday at 6:00 PM until now.
  • yesterday: yesterday at 6:00 PM to today at 2:00 AM.
  • last N days: from N days ago until now.
  • since Monday or another weekday: from that day at 6:00 PM until now.

If they do not specify a period, use the shift that contains the current local time, based on the live system clock:

  • Before 2:00 AM: use the active overnight shift, yesterday 6:00 PM to today

2:00 AM.

  • From 2:00 AM through 5:59 PM: use the most recently completed shift,

yesterday 6:00 PM to today 2:00 AM.

  • At or after 6:00 PM: use the active overnight shift, today 6:00 PM to

tomorrow 2:00 AM.

Always derive today from the actual local time returned by date, not from a stale prompt timestamp or any other contextual date string. If the prompt date and the system clock disagree, trust the system clock and mention the exact dates used in the final answer when relevant.

Use exact timestamps for SINCE and UNTIL, formatted for git log, such as 2026-07-10 18:00.

2. Find the repo(s)

Build a list of local repo paths to report on. There are two cases.

Case A — no repo arguments. Use the current git repo:

bash
REPO="$(git -C "$(pwd)" rev-parse --show-toplevel 2>/dev/null)"

If there is no repo, stop with:

text
I can't find a git repo here. Try running this from inside your project folder.

Case B — one or more repo URLs or `owner/repo` names were passed as arguments. Resolve each argument to its local checkout automatically. Never ask the user where a repo lives — search the filesystem for it.

For each argument, normalize it and every local repo's origin remote to a comparable host/owner/repo form (lowercased, .git and trailing slashes stripped, git@host: and credentials removed), then match:

bash
# Normalize a git URL or "owner/repo" arg to lowercase "host/owner/repo".
normalize_repo() {
printf '%s' "$1" \
| sed -E 's#^git@([^:]+):#\1/#; s#^[a-z]+://##; s#^[^@/]*@##; s#\.git$##; s#/+$##' \
| tr 'A-Z' 'a-z'
}
# Where to look for local checkouts. Override with EOD_SEARCH_ROOTS if needed.
EOD_SEARCH_ROOTS="${EOD_SEARCH_ROOTS:-$HOME/Code}"
# One line per local repo: "<normalized-remote>\t<absolute-path>".
LOCAL_REPOS="$(
find $EOD_SEARCH_ROOTS -maxdepth 4 -name .git -type d 2>/dev/null \
| while read -r g; do
repo="$(dirname "$g")"
url="$(git -C "$repo" config --get remote.origin.url 2>/dev/null)"
[ -n "$url" ] && printf '%s\t%s\n' "$(normalize_repo "$url")" "$repo"
done
)"
# Resolve a single argument (URL or owner/repo) to a local path.
resolve_repo() {
target="$(normalize_repo "$1")"
# Exact host/owner/repo match first, then fall back to a trailing owner/repo match.
match="$(printf '%s\n' "$LOCAL_REPOS" | awk -F'\t' -v t="$target" '$1==t{print $2; exit}')"
if [ -z "$match" ]; then
owner_repo="$(printf '%s' "$target" | sed -E 's#^.*/([^/]+/[^/]+)$#\1#')"
match="$(printf '%s\n' "$LOCAL_REPOS" | awk -F'\t' -v t="$owner_repo" '$1 ~ ("/" t "$"){print $2; exit}')"
fi
printf '%s' "$match"
}

Run resolve_repo "<arg>" once per argument to build the REPO list. Then, for each resolved repo, optionally refresh remote-tracking refs so the window is complete:

bash
git -C "$REPO" fetch --all --quiet 2>/dev/null

If an argument resolves to nothing, note it in the final answer (do not silently drop it) and continue with the repos that did resolve:

text
Couldn't find a local checkout of <arg> under $EOD_SEARCH_ROOTS. Skipping it.

Run the remaining steps (3–5) once per resolved repo, then group the results by repo in Step 6.

3. Set the author filter
bash
AUTHOR_FILTER="${EOD_AUTHOR_EMAILS:-husamahmud@gmail.com|husam.yildirim@firstimpactmed.com|husam.yildirim@synergexmed.com}"
if [ "$AUTHOR_FILTER" = "husamahmud@gmail.com|husam.yildirim@firstimpactmed.com|husam.yildirim@synergexmed.com" ]; then
GIT_USER_EMAIL="$(git -C "$REPO" config --get user.email)"
if [ -n "$GIT_USER_EMAIL" ]; then
AUTHOR_FILTER="$AUTHOR_FILTER|$GIT_USER_EMAIL"
fi
fi
if [ -z "$AUTHOR_FILTER" ]; then
AUTHOR_FILTER="$(git -C "$REPO" config --get user.email)"
fi
if [ -z "$AUTHOR_FILTER" ]; then
AUTHOR_FILTER="$(git -C "$REPO" config --get user.name)"
fi

If AUTHOR_FILTER is empty, ask the user which git author email or name to use.

4. Get commits across all branches

Scan every local and remote-tracking branch/ref, not only the checked-out branch. This matters when the user worked on multiple PR branches during the same period.

bash
git -C "$REPO" log \
--all \
--author="$AUTHOR_FILTER" \
--since="$SINCE" \
--until="$UNTIL" \
--pretty=format:"COMMIT_START%n%h|%s|%b|COMMIT_END" \
--no-merges

Parse each commit as hash | subject | body. The body may be empty.

Cut off any single commit message, including its subject and body, at 300 characters before using it as context.

If no commits are found with a regex-style AUTHOR_FILTER, do not stop yet. Split the filter on |, trim empties, and rerun the same git log --all query once per concrete author value. Use the union of those results.

Only after both checks are empty:

  • the original git log --all --author="$AUTHOR_FILTER" query
  • the per-author fallback queries for each concrete email or name

then say:

text
No commits found for [period] under [author filter] across all branches. Are you in the right repo?
5. Get branch names

Fetch branch names touched during the period for project context. These branch names are used to infer a readable project name; do not show raw branch names in the final message.

bash
git -C "$REPO" log \
--all \
--author="$AUTHOR_FILTER" \
--since="$SINCE" \
--until="$UNTIL" \
--no-merges \
--pretty=format:"%D" \
| tr ',' '\n' \
| sed 's/^ *//' \
| awk '
/^HEAD -> / { sub(/^HEAD -> /, ""); print; next }
/^origin\// { sub(/^origin\//, ""); print; next }
' \
| sed 's/ .*//' \
| grep -v '^HEAD$' \
| sort -u

If this command returns no branches, continue without branch context.

If the regex-style author filter returns no branches, repeat the same fallback process used for commits: query once per concrete author and take the union.

6. Generate the Slack message

Use the current agent/model to turn the commits and branch names into a clean Slack-formatted summary.

Rules:

  • Use Slack mrkdwn formatting only: *bold*, _italic_, and simple bullets.
  • Use hyphen bullets, not numbered lists.
  • Use past tense.
  • Do not write "I".
  • Describe what was done in plain English, not git actions. For example, write

"redesigned the hero section", not "updated hero component".

  • Extract distinct tasks from both commit subjects and commit bodies. Split

compound commits into separate bullets when useful.

  • Group all work under a single bold project header inferred from branch names

or commit content.

  • Format the project header as *Project Name* on its own line.
  • When reporting on more than one repo, emit one *Project Name* section per

repo (in the order the arguments were given), each with its own bullets. Infer each section's name from that repo's branch names or commit content.

  • Do not write "EOD", "Today's work", or a closing line.

Use this context shape:

text
Here are my git commits for [period]:
[commits]
Branch names active during this period:
[branches]
7. Show the final message and copy it to the clipboard

Display only the generated project header and bullet points in a code block:

text
*Project Name*
- thing done
- another thing done
- one more thing

Then automatically copy the exact same message to the macOS clipboard so the user can paste it straight into Slack. Pipe the final text (everything shown in the code block) to pbcopy:

bash
pbcopy <<'EOD_CLIP'
*Project Name*
- thing done
- another thing done
- one more thing
EOD_CLIP

Use a quoted heredoc delimiter ('EOD_CLIP') so nothing in the message is expanded by the shell, and pick a delimiter that does not collide with the message body. After copying, confirm with a short line such as Copied to clipboard.

If pbcopy is unavailable (not macOS), skip the copy silently and just show the message.

8. Handle follow-up edits

If the user asks to add meetings, append this section after the work bullets:

text
*Meetings*
- Standup
- Design review

If the user asks to add, remove, or reword tasks, apply the edit, re-show the full updated message in a code block, and re-copy the updated message to the clipboard with pbcopy as in Step 7.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
0

Refreshed 7 Oct 2026, a month ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/husamql3/eod-skill/eod/badge)](https://verified-skill.com/skills/husamql3/eod-skill/eod)

Something wrong with this skill or its page? Tell us.