Local-first · Your data stays on your machine

Your Jira backlog,
auto-blocked on Outlook.

ToDo pulls every ticket assigned to you in Selected for Development and drops time blocks into the open slots on your Outlook calendar — sized to each ticket's estimate, never on top of your meetings, and rescheduled automatically when life happens.

What it does

One dashboard, three jobs: pull the right tickets, fit them into the gaps in your day, and keep things tidy when meetings move.

Greedy slot fitting

Reads your busy calendar via Microsoft Graph, subtracts a buffer, and fits each ticket into the first opening big enough — sorted by priority, then created date.

Free by default

Blocks are marked showAs: free so teammates can still book over you. Flip any ticket to Busy with one click before confirming.

Auto-reschedule

A weekday cron sweeps past blocks: tickets that are Done stay put, anything else slides to the next free slot with a "Rescheduled from…" note.

Inline status changes

Move a ticket to Done, In Progress, or Blocked from the dashboard. Marking Done removes its future calendar block automatically.

Sized to your estimate

Block length comes from each ticket's Original Estimate, rounded up to 30 minutes. Missing? Falls back to your default estimate (60 min by default).

Stays out of your way

Local-only Express + SQLite. No accounts, no telemetry — your tokens live on your machine and only talk to Atlassian and Microsoft Graph.

How it works

From the moment you sign in, ToDo turns Jira and Outlook into a single pane of glass.

Sign in with Microsoft

Delegated MSAL flow with Calendars.ReadWrite. Tokens cached locally; nothing leaves your machine.

Pick your projects

Refresh from Jira, tick the project keys you want scheduled. The query is assignee = currentUser().

Preview & confirm

Review the day-grouped block list, toggle Free/Busy per ticket, then confirm to push to Graph.

Forget about it

Cron runs at 07:00 each weekday. Past blocks get tidied; in-flight tickets follow you forward.

Quickstart

Clone, set a few env vars, and run two npm scripts. Full setup with Azure AD and Jira tokens is in the README.

# clone & install
git clone https://github.com/l0lsec/todo.git
cd todo
npm install

# wire up Microsoft + Jira
cp .env.example .env
# fill in MS_TENANT_ID, MS_CLIENT_ID, JIRA_BASE_URL, JIRA_EMAIL, JIRA_TOKEN

# run server (:4000) + UI (:5173)
npm run dev
# open http://localhost:5173

Need help with the Azure AD app registration or Jira API token? The Configure section of the README walks through both in about five minutes each.

FAQ

A few things people usually want to know before they install.

Does this run in the cloud?

No. It's intentionally local-first. The server runs on localhost:4000, the UI on localhost:5173, and SQLite stores token cache + state in a gitignored data/ folder. This page on GitHub Pages is just a marketing landing — there's nothing to host.

Will it move meetings I don't own?

Never. ToDo only writes to your primary calendar, only events it created (tagged with the Jira category and a JiraKey property), and never invites anyone else.

What happens if a meeting moves on top of one of my Jira blocks?

The 07:00 cron sweep — or a manual Run reschedule sweep — patches the existing Graph event to the next free slot, preserves your Free/Busy choice, and notes the original time in the body.

Can I scope it to specific Jira projects?

Yes. Open Settings → Refresh from Jira, then tick the project keys you want scheduled. Everything else is ignored.

What about ticket statuses Jira doesn't let me transition without extra fields?

The dashboard surfaces the verbatim Jira error in a toast so you can fix the workflow on the Atlassian side. ToDo never silently skips a transition.