kill-the-standup

$npx mdskill add Varnan-Tech/opendirectory/kill-the-standup

Reads Linear issues and GitHub commits to generate a standup update and posts it to Slack

  • The user asks for a daily standup update by saying 'kill the standup'. The skill fetches relevant data from Linear and GitHub, formats it into a standup summary, and sends it to the configured Slack channel.
  • This skill depends on the LINEAR_API_KEY for authentication with Linear, SLACK_WEBHOOK_URL for posting updates to Slack, and GITHUB_REPO and GITHUB_USERNAME for fetching commit history if provided.
  • The skill decides what to include in the standup by checking yesterday's Linear issues and GitHub commits. It then formats this information into a structured update suitable for a daily standup meeting.
  • Finally, it posts the formatted standup summary to the configured Slack channel using the provided SLACK_WEBHOOK_URL.

SKILL.md

.github/skills/kill-the-standupView on GitHub ↗
---
name: kill-the-standup
description: Reads yesterday's Linear issues and GitHub commits for the authenticated user, formats a standup update (done / doing / blockers), and posts it to Slack. Use when asked to write a standup, generate a standup update, post to the standup channel, summarize yesterday's work, or automate the daily standup. Trigger when a user says "write my standup", "post standup", "generate standup update", "what did I do yesterday", or "kill the standup".
compatibility: [claude-code, gemini-cli, github-copilot]
author: OpenDirectory
version: 1.0.0
---

# Kill the Standup

Read yesterday's Linear issues and GitHub commits. Format a standup update. Post it to Slack.

---

## Step 1: Setup Check

Confirm required env vars are set:

```bash
echo "LINEAR_API_KEY: ${LINEAR_API_KEY:+set}"
echo "SLACK_WEBHOOK_URL: ${SLACK_WEBHOOK_URL:+set}"
echo "GITHUB_REPO: ${GITHUB_REPO:-not set}"
echo "GITHUB_USERNAME: ${GITHUB_USERNAME:-not set}"
```

**If LINEAR_API_KEY is missing:**
Stop. Tell the user: "LINEAR_API_KEY is required. Get it from Linear → Settings → API → Personal API keys. Add it to your .env file."

**If SLACK_WEBHOOK_URL is missing:**
Stop. Tell the user: "SLACK_WEBHOOK_URL is required. Create an Incoming Webhook at api.slack.com/apps → Your App → Incoming Webhooks. Add it to your .env file."

**If GITHUB_REPO is missing:**
Continue. GitHub commits will be skipped. Note this to the user.

---

## Step 2: Fetch Linear Activity

Compute yesterday's date in ISO 8601 format (e.g. `2026-04-09T00:00:00.000Z`).

**Get current user ID:**
```bash
curl -s -X POST https://api.linear.app/graphql \
  -H "Authorization: Bearer $LINEAR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "query { viewer { id name email } }"}'
```

Extract the `id` field from the response. Store as `LINEAR_USER_ID`.

**Fetch issues assigned to me, updated since yesterday:**
```bash
curl -s -X POST https://api.linear.app/graphql \
  -H "Authorization: Bearer $LINEAR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query($since: DateTime!, $userId: ID!) { issues(first: 50, filter: { assignee: { id: { eq: $userId } } updatedAt: { gte: $since } }) { edges { node { identifier title state { name } url completedAt updatedAt createdAt } } } }",
    "variables": {"since": "YESTERDAY_ISO", "userId": "LINEAR_USER_ID"}
  }'
```

**Categorize issues:**
- `completedAt` is non-null → **Done**
- `state.name` is "In Progress", "Started", or "In Review" → **Doing**
- `state.name` is "Cancelled" → skip
- `state.name` is "Todo" or "Backlog" → skip (not worked on)

If zero issues: note "No Linear activity found for yesterday."

---

## Step 3: Fetch GitHub Commits

Skip this step silently if GITHUB_REPO is not set.

If GITHUB_REPO is set:

```bash
gh api "repos/$GITHUB_REPO/commits?author=${GITHUB_USERNAME:-$(gh api user --jq .login)}&since=YESTERDAY_ISO&per_page=30" \
  --jq '[.[] | {message: .commit.message, url: .html_url}]'
```

**Process commits:**
- Extract the first line of each commit message (everything before the first newline)
- Skip merge commits: drop any message starting with "Merge"
- Deduplicate by message text

If GITHUB_REPO is set but returns zero commits: note "No commits found yesterday."

---

## Step 4: Format Standup

Read `references/standup-format.md` in full before writing.

Produce the standup in this exact structure:

```
**Done**
- [ENG-123] Title of completed issue
- fix: commit message here

**Doing**
- [ENG-124] Title of in-progress issue

**Blockers**
No blockers.
```

Rules from standup-format.md:
- No first-person pronouns ("I", "we")
- Past tense for Done items, present continuous for Doing items
- Each Linear item uses the `[IDENTIFIER] Title` format
- Each GitHub commit uses the first line of the commit message
- If no Done items: write "Nothing completed." under Done
- If no Doing items: write "Nothing in progress." under Doing
- If no blockers: write "No blockers."
- Under 200 words total

---

## Step 5: Post to Slack or Output

Present the formatted standup to the user.

Ask: "Post this to Slack, or output only?"

**On confirmation to post:**

```bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*Standup — DATE_HERE*\n\n*Done*\nITEMS\n\n*Doing*\nITEMS\n\n*Blockers*\nITEMS"
        }
      }
    ]
  }'
```

Pass the body via a temp file or heredoc to avoid shell quoting issues with special characters in commit messages or issue titles:

```bash
cat > /tmp/standup-payload.json << 'ENDJSON'
{
  "blocks": [
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "STANDUP_CONTENT_HERE"
      }
    }
  ]
}
ENDJSON
curl -s -X POST "$SLACK_WEBHOOK_URL" -H "Content-Type: application/json" -d @/tmp/standup-payload.json
```

After posting: "Standup posted."

**On "output only":** Print the standup in a code block for copy-paste.


More from Varnan-Tech/opendirectory

SkillDescription
app-store-review-arbitrageFetches low-star App Store and Google Play reviews, clusters them into broken-promise patterns, and generates a ranked copy brief with positioning opportunities.
blog-cover-generatorUse when the user asks to generate a blog cover image, thumbnail, or article header. Automatically uses modern typography, brand logos, and Google Search grounding to create beautiful 16:9 images with Gemini 3.1 Flash Image Preview.
brand-alchemyWorld-class brand strategist and naming expert. Uses an interrogation-led discovery phase to extract your brand's DNA, then applies scientific naming frameworks (Phonosemantics) and automated multi-TLD domain checking.
claude-md-generatorUse when the user asks to generate or update a project's CLAUDE or AGENTS context file from a codebase scan. Writes a focused file under 100 lines containing only the non-obvious build commands, conventions, and gotchas Claude Code needs.
cold-email-verifierUse when the user wants to verify cold emails, enrich a lead list, or autonomously guess email addresses from a CSV using ValidEmail.co or the open-source Reacher engine.
company-radarCompetitive intelligence orchestrator tracking companies across 8+ platforms (GitHub, Twitter, Reddit, HN, PH, YC Jobs) with heat scores and AI briefings.
competitor-pr-finderGive it your product URL or description. It finds your top 5 competitors, runs three-track PR research across all of them (editorial, podcasts, communities), identifies which channels appear most frequently, looks up the journalist or host for each, and returns a tiered outreach list with story angles and ready-to-send cold pitch drafts tailored to your product. Use when asked to find PR opportunities, discover where competitors got featured, build a media outreach list, find which journalists cover my space, or get pitch templates for press coverage.
cook-the-blogGenerate high-converting, deep-dive growth case studies in MDX format. Use this skill when asked to write a case study or blog post about a company's growth, tech stack, or product-led strategy. It handles the full pipeline (researching the company via Tavily, generating a 16:9 cover image, quality checking the draft, uploading assets to cloud storage, and pushing directly to the target repository).
dependency-update-botScans your project for outdated npm, pip, Cargo, Go, or Ruby packages. Runs a CVE security audit. Fetches changelogs, summarizes breaking changes with Gemini, and opens one PR per risk group (patch, minor, major). Includes Diagnosis Mode for install conflicts. Use when asked to update dependencies, check for outdated packages, open dependency PRs, scan for package updates, audit for CVEs, or flag breaking changes in upgrades. Trigger when a user says "check for outdated packages", "update my dependencies", "open PRs for dependency updates", "scan for CVEs", or "which packages need upgrading".
docs-from-codeGenerates and updates README.md and API reference docs by reading your codebase's functions, routes, types, schemas, and architecture. Uses graphify to build a knowledge graph first, then writes accurate docs from it. Use when asked to write docs, generate a README, document an API, update stale docs, create an API reference from code, add an architecture section, or document a project in any language. Trigger when a user says their docs are missing, outdated, or wants to document their codebase without writing it manually.