@wilm-ai/wilma-cli 1.4.2 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -64,6 +64,13 @@ wilma messages list [--folder inbox] [--limit 20] [--student <id|name>] [--all-s
64
64
  wilma messages read <id> [--student <id|name>] [--json]
65
65
  ```
66
66
 
67
+ ### Attendance / lesson notes
68
+ ```bash
69
+ wilma attendance list [--date YYYY-MM-DD] [--student <id|name>] [--all-students] [--json]
70
+ ```
71
+
72
+ Shows lesson notes (type labels, subjects, teachers) for a given date. Defaults to today if --date is omitted.
73
+
67
74
  ### Other
68
75
  ```bash
69
76
  wilma kids list [--json]
package/dist/index.js CHANGED
@@ -495,6 +495,27 @@ async function handleCommand(args, config) {
495
495
  });
496
496
  return;
497
497
  }
498
+ if (command === "attendance") {
499
+ if (flags.allStudents) {
500
+ await outputAllAttendance(profile, config, { date: flags.date, json: flags.json }, mfaCallback);
501
+ return;
502
+ }
503
+ const studentInfo = await resolveStudentForFlags(profile, config, flags.student);
504
+ if (!studentInfo && !profile.studentNumber) {
505
+ await printStudentSelectionHelp(profile, config);
506
+ return;
507
+ }
508
+ const perStudentClient = await WilmaClient.login({
509
+ ...profile,
510
+ studentNumber: studentInfo?.studentNumber ?? profile.studentNumber,
511
+ }, mfaCallback);
512
+ await outputAttendance(perStudentClient, {
513
+ date: flags.date,
514
+ json: flags.json,
515
+ label: studentInfo?.name ?? undefined,
516
+ });
517
+ return;
518
+ }
498
519
  if (command === "exams") {
499
520
  if (flags.allStudents) {
500
521
  await outputAllExams(profile, config, flags.limit ?? 20, flags.json, mfaCallback);
@@ -616,6 +637,7 @@ function printUsage() {
616
637
  console.log(" wilma news read <id> [--student <id|name>] [--json]");
617
638
  console.log(" wilma messages list [--folder inbox] [--limit 20] [--student <id|name>] [--all-students] [--json]");
618
639
  console.log(" wilma messages read <id> [--student <id|name>] [--json]");
640
+ console.log(" wilma attendance list [--date YYYY-MM-DD] [--student <id|name>] [--all-students] [--json]");
619
641
  console.log(" wilma update");
620
642
  console.log(" wilma config clear");
621
643
  console.log(" wilma --help | -h");
@@ -1076,6 +1098,27 @@ async function outputUpcomingExams(client, opts) {
1076
1098
  console.log(`- ${exam.date} ${exam.subject}: ${exam.name}${topic}`);
1077
1099
  });
1078
1100
  }
1101
+ async function outputAttendance(client, opts) {
1102
+ const notes = await client.attendance.list({ date: opts.date });
1103
+ if (opts.json) {
1104
+ console.log(JSON.stringify(notes, null, 2));
1105
+ return;
1106
+ }
1107
+ const date = opts.date ?? new Date().toISOString().slice(0, 10);
1108
+ const prefix = opts.label ? `[${opts.label}] ` : "";
1109
+ console.log(`\n${prefix}Lesson notes for ${date} (${notes.length})`);
1110
+ if (!notes.length) {
1111
+ console.log(" No lesson notes found.");
1112
+ return;
1113
+ }
1114
+ notes.forEach((note) => {
1115
+ const time = note.start && note.end ? ` (${note.start}-${note.end})` : "";
1116
+ const type = note.typeLabel ? ` [${note.typeLabel}]` : "";
1117
+ const teacher = note.teacher ? ` ${note.teacher}` : "";
1118
+ const subject = note.subject ? ` [${note.subject}]` : "";
1119
+ console.log(`-${time}${type}${teacher}${subject}`);
1120
+ });
1121
+ }
1079
1122
  async function outputGrades(client, opts) {
1080
1123
  const overview = await client.overview.get();
1081
1124
  const slice = overview.grades.slice(0, opts.limit);
@@ -1569,6 +1612,33 @@ async function outputAllExams(profile, config, limit, json, onMfa) {
1569
1612
  });
1570
1613
  });
1571
1614
  }
1615
+ async function outputAllAttendance(profile, config, opts, onMfa) {
1616
+ const students = await getStudentsForCommand(profile, config);
1617
+ const results = [];
1618
+ for (const student of students) {
1619
+ const client = await WilmaClient.login({ ...profile, studentNumber: student.studentNumber }, onMfa);
1620
+ const notes = await client.attendance.list({ date: opts.date });
1621
+ results.push({ student, notes });
1622
+ }
1623
+ if (opts.json) {
1624
+ console.log(JSON.stringify({ students: results.map((r) => ({ student: r.student, items: r.notes })) }, null, 2));
1625
+ return;
1626
+ }
1627
+ for (const r of results) {
1628
+ if (!r.notes.length) {
1629
+ console.log(`\n[${r.student.name}] No lesson notes found.`);
1630
+ continue;
1631
+ }
1632
+ console.log(`\n[${r.student.name}]`);
1633
+ r.notes.forEach((note) => {
1634
+ const time = note.start && note.end ? ` (${note.start}-${note.end})` : "";
1635
+ const type = note.typeLabel ? ` [${note.typeLabel}]` : "";
1636
+ const teacher = note.teacher ? ` ${note.teacher}` : "";
1637
+ const subject = note.subject ? ` [${note.subject}]` : "";
1638
+ console.log(`-${time}${type}${teacher}${subject}`);
1639
+ });
1640
+ }
1641
+ }
1572
1642
  async function outputAllOverviewCommand(profile, config, command, flags, onMfa) {
1573
1643
  const students = await getStudentsForCommand(profile, config);
1574
1644
  if (command === "summary") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wilm-ai/wilma-cli",
3
- "version": "1.4.2",
3
+ "version": "1.5.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@inquirer/prompts": "^5.3.8",
13
- "@wilm-ai/wilma-client": "^1.3.0"
13
+ "@wilm-ai/wilma-client": "^1.4.0"
14
14
  },
15
15
  "devDependencies": {
16
16
  "typescript": "^5.6.3"