/canvas — Canvas coursework
canvas-sync mirrors the user's Canvas courses into ~/Canvas and indexes them under
~/Canvas/_index/. The CLI is ~/CanvasSync/bin/canvas-sync (usually linked as canvas-sync).
You do not read ~/Canvas course files yourself — that is thousands of files. Spawn the
canvas-planner agent (model: sonnet) and relay its answer. The only things you read directly
are ~/Canvas/_index/last_sync.json (freshness) and whatever the CLI prints.
Freshness check (do this first for every mode except setup)
canvas-sync status --json >/dev/null 2>&1 || echo "not set up"
Read ~/Canvas/_index/last_sync.json; if finished_at is more than 60 minutes ago, run:
canvas-sync sync -q
If ~/Canvas/_index/ does not exist at all, go to /canvas setup.
/canvas or /canvas plan
- Freshness check above.
- If Google Calendar MCP tools are available in this session, list today's and tomorrow's
events and format them as plain lines (
09:00-10:15 CS 115 lecture (Babbio 122)). If they are not available, skip this — do not ask the user to connect anything. - Spawn
canvas-plannerwith: today's date and time, the calendar lines from step 2 under a heading "External calendar (fixed)", and "Mode: plan". Tell it to runcanvas-sync plan --dry-runfirst: that prints the token-free context pack (timetable, preferences, events, ASSIGNMENTS.md, recent announcements) it should plan from. - Relay the plan verbatim in the terminal.
- Offer to push it: "Send this to Telegram?" On yes, write the plan to a temp file and run
canvas-sync notify --text-file /tmp/canvas-plan.txt(add--forceif the user wants it during quiet hours, 23:00–07:00).
The unattended equivalent is canvas-sync plan --push, which runs the same prompt headlessly
from ~/CanvasSync/planner/SYSTEM.md. Use the agent path when the user is here, because only
the interactive session can read their Google Calendar.
/canvas due [N]
canvas-sync status --days ${N:-7}
Print the table as-is. No agent needed. Add --json if the user wants to filter it further.
/canvas sync
canvas-sync sync
Show the counts and the change digest it prints. If it reports per-course errors (403/404),
name the affected courses; those scopes are simply not shared with the student. To push the
digest to Telegram: canvas-sync notify --digest.
/canvas ask <question>
Spawn canvas-planner with "Mode: ask" and the question verbatim. Relay the answer with its
file citations. Good for "what did Prof. X post about the midterm", "where are the week 3
slides", "what does HW1 actually ask for".
/canvas setup
First ask whether their school allows personal access tokens (Canvas → Account → Settings → Approved Integrations → "+ New Access Token"). Branch:
Tokens allowed (simplest):
- Token: name it
canvas-sync, no expiry (or a year), copy it once. canvas-sync setup— prompts for base URL (https://sit.instructure.com), the token (hidden), and the output dir; validates and prints "Authenticated as ".
Tokens disabled (Stevens and similar) — use "both": cookie for material + feed for planning:
- Feed URL: Canvas → Account → Settings → "Calendar Feed" → copy the
…/user_<hash>.icsURL. - Cookie: log into Canvas in a browser, DevTools (⌘⌥I) → Application/Storage → Cookies → copy
canvas_session(and_legacy_normandy_session), or Network → any request → copy the wholeCookie:request header. canvas-sync setup --auth-mode cookie --cookie --feed-url "<the .ics URL>"— it prompts for the cookie (hidden), validates via/users/self, and notes the feed fallback. (Feed-only, no cookie:canvas-sync setup --auth-mode feed --feed-url "<url>".)
Then, for either path:
3. canvas-sync sync for the first full pull (a few minutes).
4. Offer scheduling: canvas-sync install-schedule --plan-time 07:30 --sync-hours 3
(launchd: sync every 3 h, plan pushed to Telegram at 07:30). Check with
canvas-sync schedule --status; undo with canvas-sync uninstall-schedule.
5. Optionally have them fill in planner.timetable and planner.preferences in
~/.config/canvas-sync/config.json — the plans are much better with a real class schedule.
/canvas fix-cookie
Only for cookie / "both" users. When sync reports "Canvas cookie expired" (or status looks
stale and the config's auth_mode is cookie), the web session lapsed. Have them re-copy the
Cookie: header (as in setup) and run:
canvas-sync auth-cookie # prompts for the cookie (hidden), validates, saves
Until they do, planning still works from the Calendar Feed (due dates + events), but file downloads and descriptions are paused.
Notes
- The token or session cookie lives in
~/.config/canvas-sync/config.json(0600). Never print it, never paste it into a message, never pass it to an agent. - Course materials never leave the machine; only the plan/digest text goes to the user's own
Telegram bot via
hermes. canvas-sync notifyrespects quiet hours (23:00–07:00 by default);--forceoverrides.