sync | { runAt, scope, termCode, timetableCourses[], matchedCourses[], scannedCandidates, counts: { added, updated, unchanged, failed }, downloaded[], errors[], timetableFromCache, forWeek? } |
schedule | { termCode, fromCache, range, lessons[] } (lesson fields come straight from the timetable API: courseCode, courseName, courseEnName, lessonDate, plus extras) |
courses | { source: 'cache' | 'fresh-sync', termCode, total, courses[] } — course: { courseCode, courseName, moodleUrl, files, lastSynced } |
course | { courseCode, courseName, moodleUrl, assignments[], quizzes[], materials[] } — each entry: { name, url, updated } |
pending | { total, events[] } — event: { name, dueDate, course, courseUrl, eventType, url } |
files (bare or --course) | array of { courseCode, courseName, moodleUrl, filename, uploadDate, path }, sorted by uploadDate ascending |
files --course --date | { fromCache, prevDate, files[] } — file: { filename, uploadDate, path } |
files --recent | array of { courseCode, courseName, filename, uploadDate, firstSeen, path }, sorted by firstSeen descending |
status | { totalCourses, totalFiles, lastSynced, timetable, courses[], wemustRoot } — timetable: { termCode, weeksCached, earliest, latest } | null |
| (any) error | { error: string, partialReport?: object } on stderr, exit code 1 |