Skip to main content

What you’ll build

A cron job that runs every morning at 9am. For each team member, it reads the last 24 hours across five sources — what they committed, what they moved in Linear, what they said in Slack, which meetings they were in, what Notion pages they touched — and posts a one-paragraph summary to #standup. No one says “yesterday I…” out loud again.

The code

import { AgentRouter } from '@copass/agent-router';
import open from 'open';

const router = new AgentRouter({
  auth: { type: 'api-key', key: process.env.COPASS_API_KEY! },
  sandboxId: process.env.COPASS_SANDBOX_ID!,
});

// One-time: connect the sources the team is already using.
await router.integrations.connect('github',          { onConnectUrl: open, scope: 'org' });
await router.integrations.connect('linear',          { onConnectUrl: open, scope: 'org' });
await router.integrations.connect('slack_v2',        { onConnectUrl: open, scope: 'workspace' });
await router.integrations.connect('google_calendar', { onConnectUrl: open, scope: 'org' });
await router.integrations.connect('notion',          { onConnectUrl: open, scope: 'org' });

const team = ['alice', 'bob', 'carol', 'dave'];

for (const member of team) {
  for await (const event of router.run({
    provider: 'anthropic',
    model: 'claude-sonnet-4-6',
    system: `You are writing one person's async standup for the last 24 hours.
Source everything from the connected integrations:
  • GitHub — commits merged, PRs opened or reviewed.
  • Linear — issues moved, status changes, new sub-tasks.
  • Slack — significant threads they drove or decisions they weighed in on.
  • Google Calendar — non-trivial meetings attended (skip 1:1s and standups).
  • Notion — pages created or meaningfully edited.

Output one short paragraph: what they shipped, what they're unblocking, what they're blocked on.
Post the result to #standup, tagging the person.`,
    message: `Write today's standup for ${member}.`,
    endUserId: member,                                        // per-member memory
  })) {
    if (event.type === 'text') process.stdout.write(event.text);
  }
}
Schedule it: GitHub Actions on cron: '0 13 * * 1-5', or a Vercel cron, or a plain systemd timer. The sandbox connections persist across runs — you don’t re-OAuth every morning.

What’s happening

  • Five activity streams, one narrative — the agent weaves commits + tickets + chat + meetings + docs into a paragraph that reads like something a human wrote.
  • scope: 'org' / 'workspace' — these integrations are shared across the whole team, not per-user, so one connect covers everyone. See Integrations.
  • endUserId: member — gives each person their own Context Window, so tomorrow’s summary knows what was said about them yesterday. Week-over-week trend reporting comes for free.

Make it yours

  • Add Jirarouter.integrations.connect('jira', …) and the agent pulls tickets from both Linear and Jira shops.
  • Escalate blockers — append If anyone is blocked on a shipped dependency for more than 2 days, ping their manager in a DM. Gets Slack write access automatically.
  • Per-team summaries — instead of per-member, run once per team: Write today's standup for the payments team. Agent segments the work by person.