scaffold-dayv0.3.1 · pre-release
Scaffold your day with AI.
A CLI-first, MCP-ready scheduler that places your TODOs into the free slots of your calendar — with AI clients (Claude Code, Cursor, Claude Desktop) as a first-class user. Same surface via CLI flags or MCP tools, so an LLM can plan your day with one tool call instead of piping CLI text.
Install
curl -fsSL https://day.scaffold.at/install.sh | sh
Tier 1: macOS Apple Silicon, Linux x64. v0.2 binaries are unsigned (Apple notarization is post-v0.2). The installer clears the macOS quarantine attribute for you.
Pin a specific version:
curl -fsSL https://day.scaffold.at/install.sh | sh -s -- --version v0.3.1
Update
Re-run the installer. It always resolves the latest release tag and
replaces the binary in place. Existing data in ~/.scaffold-day/
(todos, events, policy, anchors) is preserved.
curl -fsSL https://day.scaffold.at/install.sh | sh
scaffold-day --version # confirm the new version
scaffold-day doctor # sanity check
record_morning) appear.
Quick start
$ scaffold-day init # ~/.scaffold-day + balanced policy
$ scaffold-day morning # anchor today (relative time t=0)
$ scaffold-day todo add --title "Q2 OKR draft" --duration-min 60
$ scaffold-day place suggest <todo-id> --json
$ scaffold-day today --tz Asia/Seoul
Core concepts
scaffold-day separates intent from commitment. Three object types capture different stages:
| Type | Meaning | Created by |
|---|---|---|
| todo | Work to do; no time picked yet | todo add |
| event | Fixed time block (meeting, appointment) — won't move | event add |
| placement | A todo committed to a slot — moves with override or replan | place do |
So todo add alone does not appear in today — it's
a candidate. Use place suggest + place do to land it
on a slot, and the day's view picks it up.
Morning anchor & the relative time modelv0.2
v0.2 introduces an anchor — the wall-clock instant a user "started today". It's the t=0 reference for three new policy fields, all opt-in. Without them, scaffold-day behaves exactly like v0.1.
Recording the anchor
$ scaffold-day morning # now → explicit
$ scaffold-day morning --at 07:30 # custom time → manual
$ scaffold-day morning --force # override existing
AI clients should call the MCP record_morning tool whenever
the user greets them in the morning. The first non-init command of
each day also records an auto-source anchor as a fallback;
an explicit call upgrades it silently.
Three layered policies (all optional)
| Field | Effect | Default |
|---|---|---|
sleep_budget | Reject slots that push tonight's sleep below min_hours; soft penalty below target_hours | min 6h, target 8h |
cognitive_load | Decay heavy tasks (effort_min ≥ 60) past the capacity window after anchor | 4h window, linear -10/h |
recovery_block | Soft penalty on next-day morning slots when yesterday had a forced-late event (≥ 2h past working hours) | 2h block, -30 penalty |
Activate them
$ scaffold-day policy patch '[
{"op":"add","path":"/context/sleep_budget","value":{"target_hours":8,"min_hours":6,"soft_penalty_per_hour":15}},
{"op":"add","path":"/context/cognitive_load","value":{"decay":"linear","full_capacity_window_hours":4,"heavy_task_threshold_min":60,"linear_penalty_per_hour":10,"exponential_base":2}},
{"op":"add","path":"/context/recovery_block","value":{"late_threshold_minutes_past_working_end":120,"morning_block_hours":2,"soft_penalty":30}}
]'
What you'll see in today
CLI command reference
Every command honors --help with a 6-section template
(WHAT/WHEN/COST/INPUT/RETURN/GOTCHA). 22 commands total; 17 land
real behavior in v0.2, 5 are placeholders for v0.2.x (Phase B).
| Command | What it does |
|---|---|
init | Seed ~/.scaffold-day + balanced policy |
today | Today's events / placements / free slots / anchor / rest hint |
morning | Record today's anchor (or query / override) |
day | Months / overview / get / range / replan |
week | 7-day overview |
todo | add / list / get / update / archive / score |
event | add (update / delete are placeholder) |
place | suggest / do / override |
policy | show / patch / preset apply |
conflict | list / resolve / detect |
explain | Show why a slot was chosen (replay) |
auth | Manage Google OAuth token (mock-mode in v0.2) |
doctor | Health check (env / providers / adapters / anchor) |
migrate | Schema migration (preview default) |
mcp | Run the MCP server over stdio |
docs | Single-shot AI-readable surface dump |
Placeholders (print "implementation pending §S##"):
feedback, self-update, telemetry,
logs, rebuild-index. Real impls land in v0.2.x Phase B.
Global flags
--json— structured output (preferred for AI clients and scripts)--dry-run— preview the disk effects + would-be result; no mutation. Works on every write command.
Common recipes
# Add a TODO and place it on the best slot today
ID=$(scaffold-day todo add --title "OKR draft" --duration-min 60 --json | jq -r .id)
SLOT=$(scaffold-day place suggest $ID --json | jq -r '.candidates[0] | "\(.start)/\(.end)"')
scaffold-day place do $ID --slot $SLOT
# Move a placement to a different slot
scaffold-day place override <placement-id> --new-slot 2026-04-29T15:00:00+09:00
# Replan today (auto-shuffle unlocked placements)
scaffold-day day replan 2026-04-29 --json
# Explain why a placement landed where it did
scaffold-day explain <placement-id> --json
Use it from your AI client
scaffold-day mcp speaks the
Model Context Protocol
over stdio. v0.2 ships 27 tools covering day reads,
todo CRUD, placement, policy, and anchors. Drop one of the snippets
below into your client config, then fully restart the client.
~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"scaffold-day": {
"command": "scaffold-day",
"args": ["mcp"]
}
}
}
If scaffold-day is not on Claude Desktop's PATH, replace
"scaffold-day" with the absolute path printed by
which scaffold-day.
One command (writes / merges ~/.config/claude-code/mcp.json)
claude mcp add scaffold-day -- scaffold-day mcp
Cursor → Settings → MCP → Add
{
"mcpServers": {
"scaffold-day": {
"command": "scaffold-day",
"args": ["mcp"]
}
}
}
Tip: paste AGENTS.md into the system prompt
AGENTS.md carries JTBD recipes ("a meeting moved → replan", "add a TODO and place it") plus the full tool surface. One paste at session start saves the LLM from re-deriving call sequences. Token budget is small (~10k chars); well within any modern context.
v0.2 morning anchor flow via MCP
- User greets the AI ("Good morning!") → AI emits
record_morning - User asks "what's on my plate today?" → AI calls
get_day - User adds tasks ("OKR draft, 1 hour") → AI calls
create_todo+compute_task_importance+suggest_placement+place_todoin sequence - User asks "how am I doing?" → AI calls
get_rest_suggestionfor sleep-debt awareness
Policy reference
~/.scaffold-day/policy/current.yaml is the single source of
truth for scheduling decisions. The YAML codec preserves
comments, so hand-editing is safe.
Modify with JSON Patch (RFC 6902, comments preserved)
# Move lunch protection from 12:00-13:00 to 12:30-13:30
scaffold-day policy patch '[
{"op":"replace","path":"/context/protected_ranges/0/start","value":"12:30"},
{"op":"replace","path":"/context/protected_ranges/0/end","value":"13:30"}
]'
Or just edit the file
Comments survive. scaffold-day today picks up changes
on the next call.
$EDITOR ~/.scaffold-day/policy/current.yaml
Field overview
| Path | Meaning |
|---|---|
context.tz | IANA timezone for all relative-time math |
context.working_hours[] | Per-weekday placement window (outside is blocked) |
context.protected_ranges[] | Always-blocked windows (sleep, lunch) |
context.energy_peaks[] | Soft hint for tag-aware preferences |
context.sleep_budgetv0.2 | Hard reject + soft penalty on tonight's sleep |
context.cognitive_loadv0.2 | Decay heavy tasks past capacity window |
context.recovery_blockv0.2 | Soft block on tomorrow morning after late events |
hard_rules[] | Non-negotiable placement constraints |
soft_preferences[] | Tag/time-aware score nudges |
importance_weights | How urgency/impact/effort/etc combine into score |
Test changes safelyv0.2
Every write command supports --dry-run. Disk is untouched;
stdout shows what would have happened.
$ scaffold-day --dry-run todo add --title "test" --duration-min 30 --json
{
"dry_run": true,
"would": {
"command": "todo add",
"writes": [
{ "path": "todos/active/index.json", "op": "update" },
{ "path": "todos/active/detail/<new-id>.json", "op": "create" }
],
"result": { "title": "test", "status": "open", ... }
}
}
Read commands ignore the flag (no-op). MCP tools intentionally
do not have a dry-run mode — the suggest_placement /
compute_task_importance read tools already serve as the
preview path before place_todo / create_todo.
Where your data lives
~/.scaffold-day/
├── .scaffold-day/schema-version.json # migration tracking
├── .secrets/ # 0700, OAuth tokens go here
├── policy/current.yaml # the single source of truth
├── policy-snapshots/ # per-placement snapshot (replay)
├── todos/active/{index.json, detail/} # 2-tier TODO storage
├── todos/archive/ # archived todos
├── days/YYYY-MM/{manifest.json, *.json} # events + placements per day
├── sync/ # Google Cal sync state (mock in v0.2)
├── conflicts/ # conflict partitions
└── logs/
├── heartbeats.jsonl # morning anchor records (v0.2)
├── placement.jsonl # placement decisions (replay)
└── conflict.jsonl # conflict actions
Override the location with SCAFFOLD_DAY_HOME=/path/to/dir.
Troubleshooting
| Symptom | Fix |
|---|---|
| Claude Desktop doesn't show new MCP tools after upgrade | Cmd+Q, then reopen. Tool catalog is fetched on session start. |
scaffold-day --version still shows the old version |
Check which scaffold-day. The installer writes to ~/.local/bin if /usr/local/bin is not writable; older binaries on PATH may shadow it. |
scaffold-day mcp errors out under bun-darwin-arm64 |
Known: bun stdin needs an explicit resume on macOS. v0.2 already wires this; if you see the issue, file an issue with doctor output. |
| Today's anchor is wrong | Override with scaffold-day morning --at 07:30 --force. Future-you can also pass an ISO datetime if you need a specific instant. |
| Want to dogfood the relative time model risk-free | Pair every command with --dry-run until happy. Or use a sandbox home: SCAFFOLD_DAY_HOME=$(mktemp -d) scaffold-day init. |
Why
Most calendar tools optimise for displaying time.
scaffold-day optimises for placing time:
take a list of TODOs, score their importance, and slot them into
the calendar's actual free space — under a transparent,
replayable policy you can edit by hand.
v0.2's relative time model goes one step further: instead of pinning sleep to fixed clock times, you declare a budget, and the placement engine refuses to push you below it. Heavy tasks decay as the day stretches. Late nights surface a recovery block tomorrow. The math is deterministic and replayable; the policy is one YAML file.
Links
- GitHub repo — source · issues · releases
- Latest release notes
- Full CHANGELOG
- AGENTS.md — paste into your AI client at session start
- README · 한국어
- v0.2 progress tracker · v0.2 design notes
- GitHub Discussions — ideas, Q&A, show & tell