Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .bun-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.4.3
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- uses: actions/checkout@v7
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
bun-version-file: .bun-version
- run: bun install --frozen-lockfile
- run: bun run typecheck
- run: bun run test:coverage
Expand Down Expand Up @@ -45,7 +45,7 @@ jobs:
- uses: actions/checkout@v7
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
bun-version-file: .bun-version
- run: bun install --frozen-lockfile
- run: bun test
env:
Expand All @@ -63,7 +63,7 @@ jobs:
- uses: actions/checkout@v7
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
bun-version-file: .bun-version
- run: bun install --frozen-lockfile
- run: SITE_BASE=/ bun run site:build
- run: test -f site-dist/index.html && test -f site-dist/docs/index.html && test -f site-dist/logo-256.png
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- if: steps.key.outputs.present == 'true'
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
bun-version-file: .bun-version
- if: steps.key.outputs.present == 'true'
run: bun install --frozen-lockfile
- if: steps.key.outputs.present == 'true'
Expand Down
4 changes: 2 additions & 2 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions docs/guide/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,16 @@ Requests to edit answers after the deadline are decided by anyone holding `stand
| `GET` | `/edit-requests` | Pending requests the caller can decide, newest first: `standupId`, `standupName`, `date`, `userName`, `displayName`, `reason`, `askedAt`, `answeredAt` and `until` (midnight in the standup's timezone, as `23:59 Europe/London`) |
| `POST` | `/edit-requests/:id/approve` · `/edit-requests/:id/decline` | `{ note? }` on decline goes to the person; `404` for an unknown request, `403` without `standups.configure` on its standup, `409 refused` once decided or lapsed, or for the caller's own request |

Polls with questions are sent and closed by anyone holding `standups.configure` on the standup:

| Method | Path | Notes |
| --- | --- | --- |
| `GET` | `/standups/:id/question-polls` | Newest first: `title`, `from`, `closesAt` and `closesLabel` (the close time in the standup's timezone), `closedAt`, `open`, `anonymous`, `results` (`everyone` or `managers`), `asked`, `answered` |
| `POST` | `/standups/:id/question-polls` | `{ title, intro?, questions: [{ text, type, required?, options? }], closesAt: "2026-10-24T17:00", remindMinutes?: 15 \| 60 \| 1440 \| null, anonymous?, results? }`. `type` is `short`, `long`, `dropdown`, `single` or `multiple`; up to 10 questions and 20 options. `closesAt` is local to the standup, from 15 minutes to 14 days ahead. Answers `201` with the poll, or `400 invalid` naming the `field` |
| `GET` | `/question-polls/:id` | The poll and its `questions`. `outcome` (who hasn't answered, counts per option with names, text answers) is set for the standup's managers, and for the people asked once a poll with `results: everyone` closes; otherwise `null`. Names are `null` on an anonymous poll |
| `POST` | `/question-polls/:id/close` | Close it now; `409 closed` if it already has |
| `GET` | `/question-polls/:id/export.csv` | One row per answer: `person,question,answer,answered_at`, without `person` on an anonymous poll. Managers only |

Moods are withheld per person when the standup keeps them anonymous; only the team average is returned. A run includes `moodComments` only for callers holding `moods.comments` on the standup: each with `person`, `mood` and `comment`, or with `person: null`, sorted by mood then text, when moods are anonymous.

### Blockers
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Quick team decisions without a meeting — a card in the space, one tap to vote:
| Command | Effect |
| --- | --- |
| `poll Question? \| Option A \| Option B` | Post a poll card (2–6 options). Votes update the card live; voting again changes your vote |
| `polls` | List open polls with vote counts |
| `polls` | List open polls with vote counts, and open polls with questions with how many have answered |
| `poll <id> results` | Current tallies with voter names |
| `poll <id> close` | Close it and post final results (creator or admin) |

Expand Down
1 change: 1 addition & 0 deletions docs/guide/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ Zapier/n8n, or your own service:
| `wrap_up` | The run closes | `standup`, `date`, `summary` (the posted wrap-up's numbers, plus `teamMood` on anonymous standups) |
| `schedule_change` | Someone's days on the standup, or their days off, change | person, summary, who, channel — see [Personal schedules](./schedules#integrations) |
| `time_off_request` | A request needs approval | person, dates, working, reason, request ids |
| `poll_closed` | A poll with questions closes | `poll`: `id`, `title`, `anonymous`, `asked`, `answered` and each question's counts per option, with `names` only on a named poll |
| `test` | **Send test** in the standup's settings | `standup` |

Deliveries time out after 5 s and failures are only logged — a dead webhook
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/mcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Pick only the scopes the assistant needs:

| Scope | Tools |
| --- | --- |
| `read` | `get_me`, `list_standups`, `get_standup`, `get_my_standups`, `list_runs`, `get_run`, `list_blockers`, `get_team`, `get_insights`, `get_schedule`, `list_time_off_requests` |
| `read` | `get_me`, `list_standups`, `get_standup`, `get_my_standups`, `list_runs`, `get_run`, `list_blockers`, `get_team`, `get_insights`, `get_schedule`, `list_time_off_requests`, `list_question_polls`, `get_question_poll_results` (results only where the owner may see them) |
| `blockers:write` | `acknowledge_blocker`, `update_blocker`, `resolve_blocker` |
| `submit` | `submit_answers` (every answer required, and the mood when the standup asks for one; `moodComment` is optional), `skip_today` (takes a one-line `reason`, posted in the day's thread) |
| `schedule` | `update_my_settings` (timezone, vacation), `set_working_days` (with `standupId`), `set_days_off`, `cancel_day_off`, `decide_time_off_request` |
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/roles.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Built-in roles can't be changed. Copy one to start a custom role.
| `reports.view` | See run history and insights | ✓ | ✓ | ✓ | ✓ |
| `people.view` | See the Team directory | ✓ | ✓ | ✓ | |
| `export` | Download answers as CSV | ✓ | ✓ | ✓ | |
| `standups.configure` | Change the schedule, questions, mood, escalation and webhook; run now, nudge, close polls | ✓ | ✓ | | |
| `standups.configure` | Change the schedule, questions, mood, escalation and webhook; run now, nudge, close polls; send polls with questions and read their results | ✓ | ✓ | | |
| `standups.archive` | Archive a standup and bring it back | ✓ | ✓ | | |
| `people.manage` | Add and remove people, mark them required, make managers, grant roles on the standup | ✓ | ✓ | | |
| `schedules.manage` | Change people's days and days off on the standup, decide time-off requests | ✓ | ✓ | | |
Expand Down
20 changes: 20 additions & 0 deletions docs/guide/user-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,23 @@ bot, or straight away when your admins have set up the

Anyone can start one in a space: `@AsyncUp poll Ship Friday? | Yes | No`. Tap an
option to vote; tap another to change your vote.

### Polls with questions

A standup's managers can also send a poll with several questions from the
web app (the standup's **Polls** tab). Everyone on the standup, except people
on vacation, gets a DM card with **Respond**:

- The form asks each question in turn: short or long text, a dropdown, one
choice (radio buttons) or several (checkboxes). Questions marked
*required* must be answered to submit.
- After you answer, **Change answers** reopens the form with your answers
filled in, until the poll closes.
- One reminder comes before the close if you haven't answered yet.
- The close time is shown in the standup's timezone. After it, nothing is
accepted, and the cards say *Closed*.
- An anonymous poll never shows who answered what, to anyone. A named poll
shows the managers who answered what.
- The space gets a card with how many have answered. When the poll closes,
the results post in its thread, or, if the managers keep them, a line
saying so. Text answers stay in the web app.
3 changes: 2 additions & 1 deletion docs/guide/web-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ detects a working Chat connection and skips straight to the standup step.
recent runs, open blockers, schedule), **History** (every run with full
answers, CSV export, and mood comments for people allowed to read them),
**Insights** (participation by person, mood and blocker
charts) and **Settings** (schedule with time pickers, questions, mood, the
charts), **Polls** (polls with questions: open and closed, **New poll** for
managers, and each poll's results, CSV export and **Close now**) and **Settings** (schedule with time pickers, questions, mood, the
People grid and roster group, escalation, webhook with a signed test, digest,
and a Danger zone to archive, unarchive or delete).
- **Blockers** — every open, acknowledged or resolved blocker across the
Expand Down
2 changes: 1 addition & 1 deletion site/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ <h2>Everything a standup bot should do. Nothing it shouldn’t.</h2>
<article class="card"><h3>Away-aware</h3><p>Skip today with a one-line reason the team can see, vacation mode and Google Calendar OOO sync. Away people are neither nagged nor counted.</p></article>
<article class="card"><h3>Blockers that follow up</h3><p>Tag teammates, acknowledge, post updates, resolve. Daily nudges until acknowledged; escalation when stale.</p></article>
<article class="card"><h3>People and schedules</h3><p>Prompts at 09:30 in each person’s own zone, personal weeks and days off, and rosters that follow a Google Group or drop people who leave the Chat space. Leave shows as a Chat status and a Calendar out-of-office.</p></article>
<article class="card"><h3>Insights built in</h3><p>Participation, mood and blocker trends. Weekly digest, CSV export, signed webhooks.</p></article>
<article class="card"><h3>Insights built in</h3><p>Participation, mood and blocker trends. Polls with a few questions and a close time. Weekly digest, CSV export, signed webhooks.</p></article>
<article class="card"><h3>Enterprise SSO, no tax</h3><p>Google sign-in, SAML 2.0 and SCIM provisioning — all in the MIT core.</p></article>
<article class="card"><h3>MCP server</h3><p>Claude Code and other assistants can read standups, answer or skip, work blockers and nudge the team, with scoped tokens. No model runs inside AsyncUp.</p></article>
</div>
Expand Down
Loading
Loading