Skill: daily-standup-bot
This skill provides tools for managing teams, members, questions, and standup windows. It operates against the SQLite database used by the daily-standup-bot server.
Best use case
Skill: daily-standup-bot is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
This skill provides tools for managing teams, members, questions, and standup windows. It operates against the SQLite database used by the daily-standup-bot server.
Teams using Skill: daily-standup-bot should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/daily-standup-bot/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How Skill: daily-standup-bot Compares
| Feature / Agent | Skill: daily-standup-bot | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
This skill provides tools for managing teams, members, questions, and standup windows. It operates against the SQLite database used by the daily-standup-bot server.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Skill: daily-standup-bot
This skill provides tools for managing teams, members, questions, and standup windows. It operates against the SQLite database used by the daily-standup-bot server.
## Tools
### `create_team`
Create a new standup team.
```typescript
interface CreateTeamInput {
name: string; // Display name, e.g. "Engineering"
slack_channel_id: string; // Slack channel ID where digest is posted, e.g. "C012AB3CD"
slack_channel_name: string; // Human-readable channel name, e.g. "#eng-standup"
schedule_cron: string; // cron expression for window open time, e.g. "0 9 * * 1-5"
window_duration_min: number; // How long the window stays open, in minutes (e.g. 60)
timezone: string; // IANA timezone, e.g. "America/New_York"
questions?: string[]; // Initial question texts; defaults to the 3 standard questions
}
interface CreateTeamOutput {
team_id: number;
name: string;
slack_channel_id: string;
schedule_cron: string;
window_duration_min: number;
timezone: string;
questions_created: number;
created_at: string; // ISO 8601
}
```
**Implementation notes:**
- Insert row into `teams` table.
- Insert question rows into `questions` table in order (position 1, 2, 3...).
- If `questions` is omitted, seed with: "What did you do yesterday?", "What are you working on today?", "Any blockers?".
- The scheduler picks up the new team automatically on its next tick because it watches the `teams` table.
---
### `add_member`
Add a Slack user to a team's standup roster.
```typescript
interface AddMemberInput {
team_id: number;
slack_user_id: string; // Slack user ID, e.g. "U012AB3CD"
display_name?: string; // Optional override; if omitted, bot fetches from Slack users.info
}
interface AddMemberOutput {
member_id: number;
team_id: number;
slack_user_id: string;
display_name: string;
active: boolean; // Always true on add
added_at: string;
}
```
**Implementation notes:**
- Insert into `team_members`. The `(team_id, slack_user_id)` pair has a UNIQUE constraint; re-adding an existing member reactivates them (`active = 1`) rather than throwing an error.
- If `display_name` is not provided, call `client.users.info({ user: slack_user_id })` using the Slack Bolt client.
---
### `remove_member`
Remove (soft-delete) a member from a team. The member's historical submissions are preserved.
```typescript
interface RemoveMemberInput {
team_id: number;
slack_user_id: string;
}
interface RemoveMemberOutput {
member_id: number;
slack_user_id: string;
deactivated: boolean;
}
```
**Implementation notes:**
- Sets `active = 0` on the `team_members` row. Does not hard-delete.
- The member will no longer receive DMs on future standup windows.
---
### `set_questions`
Replace the question list for a team.
```typescript
interface SetQuestionsInput {
team_id: number;
questions: string[]; // Ordered array of question text. Max 10 items.
}
interface SetQuestionsOutput {
team_id: number;
questions: Array<{
question_id: number;
position: number;
text: string;
}>;
}
```
**Implementation notes:**
- Delete all existing questions for the team, then insert the new set with sequential `position` values starting at 1.
- Changes take effect on the next standup window; any in-progress window uses the question set that was active when it was opened (captured in the `submissions` / `answers` tables).
---
### `open_window`
Manually open a standup window for a team outside of the normal schedule.
```typescript
interface OpenWindowInput {
team_id: number;
opens_at?: string; // ISO 8601 datetime; defaults to now
closes_at?: string; // ISO 8601 datetime; defaults to now + team's window_duration_min
send_dms?: boolean; // Whether to send DM prompts to members; default true
note_to_members?: string; // Optional text appended to the DM greeting
}
interface OpenWindowOutput {
window_id: number;
team_id: number;
status: "open";
opens_at: string;
closes_at: string;
dm_sent_count: number;
}
```
**Implementation notes:**
- Insert a row into `standup_windows` with `status = 'open'`.
- If `send_dms` is true, iterate over all active members and call the DM send helper (same code path used by the scheduler).
- The scheduler's close-window job will close this window at `closes_at` and post the digest.
---
### `get_team_status`
Return current status of a team: active window (if any), today's submission counts, and member list with today's submission state.
```typescript
interface GetTeamStatusInput {
team_id: number;
}
interface GetTeamStatusOutput {
team_id: number;
name: string;
current_window: {
window_id: number;
status: "open" | "closed" | "posted";
opens_at: string;
closes_at: string;
submitted: number;
total_members: number;
} | null;
members: Array<{
member_id: number;
slack_user_id: string;
display_name: string;
today_status: "complete" | "incomplete" | "skipped" | "missing" | "no_window";
submission_id: number | null;
}>;
}
```
---
### `get_submission`
Return the full answers for a single submission.
```typescript
interface GetSubmissionInput {
submission_id: number;
}
interface GetSubmissionOutput {
submission_id: number;
window_id: number;
team_id: number;
member: {
member_id: number;
slack_user_id: string;
display_name: string;
};
status: "complete" | "incomplete" | "skipped";
submitted_at: string;
answers: Array<{
question_id: number;
position: number;
question_text: string;
answer_text: string;
}>;
}
```
---
### `list_windows`
List standup windows with optional filters.
```typescript
interface ListWindowsInput {
team_id?: number;
status?: "open" | "closed" | "posted";
date_from?: string; // YYYY-MM-DD
date_to?: string; // YYYY-MM-DD
limit?: number; // Default 20, max 100
offset?: number;
}
interface ListWindowsOutput {
windows: Array<{
window_id: number;
team_id: number;
team_name: string;
status: string;
opens_at: string;
closes_at: string;
submitted: number;
total: number;
rate_pct: number;
}>;
total: number;
}
```
---
### `get_participation_stats`
Return submission rate statistics for a team or all teams over a date range.
```typescript
interface GetParticipationStatsInput {
team_id?: number; // Omit for all teams combined
date_from: string; // YYYY-MM-DD
date_to: string; // YYYY-MM-DD
group_by?: "day" | "week"; // Default "day"
}
interface GetParticipationStatsOutput {
team_id: number | null;
date_from: string;
date_to: string;
overall_rate_pct: number;
total_windows: number;
total_submissions: number;
total_possible: number;
by_period: Array<{
period_start: string; // YYYY-MM-DD
windows: number;
submitted: number;
possible: number;
rate_pct: number;
}>;
by_member: Array<{
member_id: number;
display_name: string;
submitted: number;
possible: number;
rate_pct: number;
}>;
}
```
**Implementation notes:**
- "Possible" means the number of windows for which the member was active (not paused).
- Skipped submissions count as submitted for rate calculation (member was present and responded).
- Missing submissions reduce the rate.Related Skills
Skill: Uptime Monitoring
## Overview
Skill: Status Page
## Overview
Skill: unit-conversion
## Overview
Skill: recipe-scaler
## Overview
reading-list
Operate the reading-list API to save, manage, tag, search, and export articles.
email-digest
Configure, test, and troubleshoot the reading-list daily email digest delivered via nodemailer.
websocket-realtime
Use the WebSocket connection in poll-builder to receive live vote updates. Use when you need to stream real-time poll results, monitor a poll for new votes, or build a live dashboard. Triggers include "live results", "real-time updates", "stream votes", "watch poll", or "WebSocket".
poll-builder
Self-hosted poll creation tool with real-time results. Use when you need to create a poll, check vote counts, close a poll, export results, or get the shareable link for a poll. Triggers include "create poll", "vote", "poll results", "survey", "collect votes", "share poll", or any task involving polling or voting.
Skill: personal-finance
## Overview
Skill: csv-import
## Overview
Skill: Syntax Highlighting
## Purpose
Skill: Pastebin Core
## Purpose