Start Working
A session launcher, not a task picker. When you sit down to work, this skill decides what the session is for, splits the work between you and Claude, fires the Claude half immediately, and closes the loop afterwards so the task manager, the calendar, and the notes stay accurate without manual admin. The point is leverage: you should only ever hold the work that genuinely needs you — decisions, relationships, judgement, your accounts.
Two modes. Session start ("start working", "let's work") runs steps 1–6. Close-out ("done", "wrap up") runs step 7. If a close-out arrives with no logged session in today's log, ask what they worked on and log it anyway.
Customise this
This file ships with {{SLOTS}} you fill in once. Find-and-replace them, or paste
SETUP.md into a Claude session and let it interview you and write the filled copy.
Full options and rationale are in README.md.
| Slot | What it is | Common values |
|---|---|---|
{{TASK_MANAGER}} |
Where your tasks live | Apple Reminders · Todoist · Things · TickTick · Linear · Asana · none — a TODO.md file |
{{CALENDAR}} |
Where your time lives | Apple Calendar · Google Calendar · Outlook · Fantastical · none — ask me my schedule |
{{SECOND_BRAIN}} |
Your notes system, read for context | an Obsidian vault at ~/notes · Notion · Logseq · none |
{{SESSION_LOG}} |
Where close-out writes the session record | today's daily note in {{SECOND_BRAIN}} · ~/work-log.md |
{{TIMEZONES}} |
How to resolve your timezone | Europe/Berlin, always · America/NY in the week, Asia/Tokyo when travelling — infer from the calendar |
Use whatever you already use. Wire this to Apple Reminders, Todoist, Things, a
Notion database, or a plain text file — the ritual is what does the work, not the app.
Nothing is mandatory either: set a slot to none and the skill asks you the question in
chat instead of reading a tool.
Tool names in this file are written as capabilities, not vendor API calls ("the task manager's reschedule operation"). Concrete per-vendor mappings live in Connector notes at the bottom — extend that table for your stack.
Step 1 — Gather (silent, parallel)
Do not narrate this step. Issue ALL reads in one parallel batch — a single round trip. Serial pulls are the main avoidable latency in the whole ritual:
- {{TASK_MANAGER}} — three queries, de-duplicated by task id:
- due today, including overdue (limit 50)
- high priority, excluding subtasks (limit 50)
- undated, excluding subtasks (limit 30) — this third pull exists so undated drift is actually visible to the clean-up sweep. Skipping it hides the rot.
- Clock: read the current time from the shell (
date) in the session timezone; never assume it. - {{CALENDAR}}: today's events. Compute the gap from now until the next busy (non-transparent) event. Resolve the timezone per {{TIMEZONES}}; when genuinely unclear, ask once.
- Local task file (
TASKS.md,TODO.mdor similar, if a folder containing one is connected): open items. Tasks appearing in both sources are shown once and flagged. File-only items get an offer to push to {{TASK_MANAGER}} — the goal is convergence on one source of truth. - {{SECOND_BRAIN}}: read the most recent session log entry to pre-select interview defaults and pick up carried-over tasks.
Cap every pull at the limits above. Never pull more than one day of calendar.
Step 2 — Clean-up sweep ("Needs a call")
Before ranking, check the raw list for rot:
- overdue 3+ days
- undated lowest-priority tasks older than 7 days
- duplicates across {{TASK_MANAGER}} and the local task file
Flagged tasks go in the "Needs a call" strip of the session card as a numbered list, capped at 4 rows — group by project and by age band rather than listing items individually (e.g. "1. Website redesign: 4 undated tasks, 19 days"), oldest first, overflow summarised in one final row. No per-row buttons: you answer in one line in chat ("1 kill, 2 defer Friday, 3 do"), and each call maps to do (enters today's ranking), defer (the reschedule operation — never a generic field update, which destroys recurrence; see Connector notes), or kill (complete-as-abandoned or delete, confirm before deleting). The reason this matters: rankings are only trustworthy when the list contains live tasks, and one typed line beats a dozen clicks.
Step 3 — Micro-interview
Ask via the structured question tool, three questions maximum, one round only:
- Session length — default from the calendar gap, capped at 90 minutes. Offer the default, one shorter, one longer option.
- Mode — deep / shallow / mixed. Map energy language directly: "low energy", "tired", "drained" → shallow; "fresh", "focused", "locked in" → deep. Pre-select the mode chosen last session (from {{SESSION_LOG}}) when available; when the log isn't connected, ask cold without commenting on the missing default.
- Goal — "what does winning this session look like?" Offer a suggested default inferred from the likely top pick; free text via Other. The goal steers ranking, heads the log entry, and is what close-out measures against. Meta-goals are valid: if the goal is about systems, setup, or tomorrow rather than a task in {{TASK_MANAGER}}, build the session around it — a light next-day sketch belongs in the Claude lane, but a full day plan is a different job; say so and offer the handoff.
If the user already stated any answer in their message ("let's work, I've got 45 minutes"), skip that question. Never ask a fourth question — a slow ritual is a dead ritual.
Step 4 — Rank and split
Batch detection first: cluster by the same project (the primary key), then by genuinely shared context within it (e.g. four grant applications = one batch with shared positioning). Don't stretch: tasks that merely share a verb ("apply") across different projects are not a batch. A batch competes in the ranking as a single pick.
Ranking order: stated goal alignment, then deadline proximity, then priority, then fit (estimated duration vs session length), then staleness — older avoided tasks surface rather than sink. Never recommend deep work into a gap under 45 minutes; offer shallow picks instead. Produce a top 3 with one line of reasoning each.
Estimate every task's time. Each item in your lane and each cut-list row carries a minute estimate on the card ("~10m"): use the duration set in {{TASK_MANAGER}} when present, otherwise defaults by type — form or quick message ~10, review ~20, drafting ~30, deep build 60–90 — corrected by recent session logs (planned vs actual). Timeline phases sum from these estimates. Never show a task without a number: the estimates are what make the packing honest, and close-out is what makes them accurate over time.
Split the top pick (auto only when the task is ≥45 min or vaguely worded — small admin tasks are picked and boxed, not decomposed):
- Claude, now — drafting, research, structuring, processing. Anything reachable with connected tools. These start immediately on "go", in parallel with your work.
- Claude, needs approval — queued with a one-line ask ("approve and I'll send").
- Yours only — decisions, relationships, judgement, your accounts. This slice becomes the time-boxed work, so boxes shrink as delegation improves.
Heavy items route to a session pack, not to this chat — so they run in parallel instead of queuing behind each other. This chat is Session 1: it holds the ritual, quick inline drafts, and close-out; everything multi-minute goes to its own tab and starts immediately, running alongside your own work rather than after it. Concretely: a 20-minute research task handed to tab 2 is ready by the time you finish a 15-minute email in here — the wait hides behind work they were doing anyway, instead of adding 20 minutes onto the end. Total time drops from the sum of the tasks to whichever runs longest. When you emit the pack, state that payoff in one line so you know why you're opening tabs, not just that you should. For each heavy item (deep research, code work, long documents), emit a numbered, self-contained handoff prompt in its own fenced code block — full context, inputs, constraints, a "done means" line, and where to save the output — headed by a destination and time estimate:
- Code → a coding-agent terminal (Claude Code, Cursor, or similar). Repo path,
relevant files, current vs target behaviour. If two prompts touch the same repo,
include the
git worktree addcommand so parallel agents don't collide. - Research / long drafts → a fresh chat tab, on a cheaper model when the work doesn't need frontier judgement.
Recommend how many sessions to open (cap 3 — attention and rate limits both) and show the count on the card. You paste, then rotate between tabs instead of waiting on any one of them. Because other sessions can't see this one's context, every prompt must stand alone: "research competitions" is a task list; scope, output format, and destination is a delegation.
Step 5 — Render the session card
Render with the visualization widget tool using the template in
assets/session-card.html. Fill the slots; do not redesign. Emit compactly: the
template's style block carries the design, so keep filled markup minimal (no added
inline styles, no comments, no extra wrappers) — every extra token is visible
streaming time. Default aesthetic: Fraunces
(upright, weight 500) for display headings, Space Grotesk for everything else, flat
surfaces, CSS variables for theme colours — swap these freely in the template, but pick
once and keep it stable so the card is recognisable at a glance. Sections in order:
header (session length, mode, time range, timezone), "Needs a call" strip (omit when
empty), context flag banner (omit when none — a context flag is calendar reality not
reflected in {{TASK_MANAGER}}, like a live event running today; it informs but never
overrides a stated goal — surface it and let you decide), top pick with lanes and
timeline, "didn't make the cut" list, and a single action button.
Interaction model — the card is a briefing, chat is the controls. The card carries
exactly one button: Go (fires the full compound instruction — start the Claude lane
and create the calendar block — via sendPrompt), because that one commit command is
tedious to type. Everything else is a typed reply: clean-up calls by number, "calendar
block only", "full ranking", "swap the pick", "make it 60". Close the card's response
with a one-line hint to that effect. Don't add more buttons — canned clicks constrain
you to pre-imagined actions; free-form chat doesn't. Any reply that isn't "go" is a
plan amendment: adjust the plan in place and re-render only what changed — never
re-run the interview or re-pull data for an amendment.
Late-night guard: for sessions starting after ~23:00, the banner flags the trade-off (tomorrow's obligations vs sleep, sharper when tomorrow is a deadline day). Plan the session anyway — the call is yours.
If widget rendering is unavailable, fall back to the same structure in plain text.
Step 6 — Go
When you confirm (button or message):
- Session pack first, at the top of the go reply — you should be opening tabs and pasting within seconds of tapping go. Nothing renders above it.
- In parallel, secure the calendar block. First check today's events for a
placeholder session slot (title starting
Session) beginning within ~15 minutes of now: if one exists, adopt it — update it to rename itFocus: <pick>and resize to the session length. Only create fresh (titleFocus: <pick>, from now for the session length, correct timezone) when no placeholder is there. One block per session either way, confirmed in one line — you don't need to watch this happen. - End the go reply with your kick-off line: the single first action of your slice ("start with: decide the pricing tier") so they start moving without re-reading the card.
- Then run the inline items directly in this chat: small drafts (~under 500 words), single lookups, messages. No subagent spin-up for these — it costs more than the work itself.
- In-session subagents are a fallback, only when you explicitly ask for heavy work to run here: maximum 2, cheaper model, tightly session-scoped ("top 5, one line each", never "comprehensive"), with a one-line ETA ("~3 min — start your slice, don't wait on me") and background execution where the environment offers it. Watching a spinner is a design failure.
"Calendar block only" means item 2 alone; the pack and drafts wait. Never start drafts before an explicit go — drafting is the token-expensive part and stays opt-in.
Step 7 — Close-out
Triggered by "done" / "wrap up", or when a later message reveals the block has ended. Ask one question: what got finished, against the stated goal (achieved / partial / missed, with specifics). If a session pack went out, the same question also collects what the other tabs produced and where it landed — folded into the log's Claude-lane line. Then, without further prompting:
- {{TASK_MANAGER}}: complete finished items. For carries, record the context as a comment on the task ("carried from session, ") — reschedule operations have no note field. Only reschedule when the carry genuinely needs a new date; a carried task already sitting on its real external deadline stays put.
- {{CALENDAR}}: resolve the block's event id by listing today's events, then update it — rename to what actually happened ("Grant apps — 3/4 submitted") and correct the end time to the actual duration. The calendar becomes a record of reality, not intentions.
- {{SESSION_LOG}}: append under a
## Sessionsheading (create the heading if absent). Entry format below. If the log isn't connected, write the entry to the outputs folder, say so, and ask to connect it.
### <HH:MM>–<HH:MM> · <pick>
- Goal: <stated goal> — <achieved | partial | missed>
- Planned: <items> · Done: <items> · Carried: <items → new date>
- Time: planned <N> min, actual <N> min
- Claude lane: <what was drafted/produced>
The planned-vs-actual line is load-bearing: read recent entries in step 1 to calibrate future time-boxes. If forms keep taking 20 minutes instead of 12, allocate 20.
Model economics
A skill cannot change the model of the session it runs in — the interview, ranking, split, and card always run on the session's model. Route accordingly:
- The protocol is deliberately cheap enough for a mid-tier model, so daily sessions don't need a frontier model; save those for days when the ranking judgement is genuinely contested. Verify this on your own stack before trusting it.
- On "go", delegate the bulk work through the Agent tool with an explicit cheaper model: research, shortlists, summarisation, and first-pass drafts → a mid-tier model; purely mechanical transforms (reformatting, extraction) → the cheapest available.
- Keep in the main session: the ranking and split (the judgement), anything being written in your voice for outbound use, and the card render — relaying template HTML from a subagent costs the same output tokens as writing it, so delegating it saves nothing and adds latency.
- If the Agent tool is unavailable in the environment, do everything in-session; never block on delegation.
Environments
Portable by design — this SKILL.md is readable by Claude Code (VS Code/terminal), Cursor, claude.ai, and other agents supporting the skills standard. Degrade gracefully, never fail on a missing tool:
- Tool names are capabilities, not vendor calls: use whatever server prefix the environment exposes. If a source isn't connected, ask instead ("what's on your plate?" / "how long have you got?") and run the protocol on what's stated.
- Interview: use the structured question tool where it exists; otherwise ask the three questions in one plain-text message.
- Card: the HTML widget exists only in some hosts. Elsewhere use the
plain-text card; when a browser is handy, also save the filled standalone card
(template plus its STANDALONE FALLBACK block) to
./start-working-card.html. - {{SECOND_BRAIN}}: with direct filesystem access (Claude Code), append straight to the log file; ask for the path once and record it in the project's CLAUDE.md.
- Non-Claude models: the protocol doesn't change. Judgement steps (ranking, the split) want the strongest model available; mechanical steps run on anything.
Token guards
Per-session overhead should stay near 10k tokens. Hard caps on pulls (step 1), one interview round, template render only (~3.5k), drafts only on explicit go. "start working quiet" skips the HTML card and uses the plain-text fallback. Never schedule recurring runs from inside this skill.
Latency budget: target under ~30 seconds from trigger to interview (one parallel read batch), and a card render around 1.5–2k tokens using the class-based template. When speed matters more than looks, quiet mode is the answer.
Boundaries
This skill owns exactly one thing: the work session that starts now, and its close-out. Whole-day planning, morning briefings, and any push-notification delivery belong elsewhere — including placing the day's empty session slots; this skill adopts and fills them. If you run companion skills for people/CRM lookups or for filtering outbound drafts through your own voice, route to them here and name them explicitly.
Connector notes
Map the capabilities above to your stack, then delete the columns you don't use.
| Capability | Todoist | Apple Reminders (AppleScript) |
|---|---|---|
| tasks due today + overdue | find-tasks-by-date (startDate today, include-overdue) |
every reminder whose completed is false and due date < <tomorrow> |
| high-priority tasks | find-tasks, filter (p1 | p2) & !subtask |
priority (0 none, 1 high, 5 medium, 9 low — confirm on your macOS version) |
| undated tasks | find-tasks, filter no date & !subtask |
whose due date is missing value |
| complete | complete-tasks |
set completed to true |
| reschedule (safe) | reschedule-tasks — never update-tasks |
set due date — but see the recurrence warning below |
| note on a task | add-comments |
append to body |
| today's events | Calendar list_events |
Calendar.app every event whose start date … |
| create / rename block | create_event / update_event |
make new event / set summary |
Recurrence warnings — the one thing that silently breaks things.
- Todoist:
update-tasksoverwrites the whole due string and destroys the recurrence rule. Usereschedule-tasksfor any date change. - Apple Reminders: the AppleScript dictionary exposes no recurrence property at
all — a repeating reminder's rule is invisible to a script, so writing
due dateonto one has undefined results. Treat repeating reminders as read-only: surface them in the sweep, but tell the user to defer them in the app by hand. - Anything else: before wiring a reschedule, create a test recurring task, move it by script, and check the repeat rule survived. If you can't confirm it does, restrict the sweep's defer action to non-recurring tasks.
For a task manager with no API, the fallback is a plain markdown file — read it, write it, and skip the ticking. The protocol loses nothing except the automatic close-out.