@wilm-ai/wilma-cli 1.1.0 → 1.2.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.
Files changed (4) hide show
  1. package/README.md +13 -1
  2. package/dist/index.js +97 -5
  3. package/package.json +11 -10
  4. package/LICENSE +0 -21
package/README.md CHANGED
@@ -26,7 +26,19 @@ Combines today's and tomorrow's schedule, upcoming exams, recent homework, news,
26
26
 
27
27
  ### Schedule
28
28
  ```bash
29
- wilma schedule list [--when today|tomorrow|week] [--student <id|name>] [--all-students] [--json]
29
+ wilma schedule list [--when today|tomorrow|week] [--date YYYY-MM-DD] [--weekday mon|tue|wed|thu|fri|sat|sun] [--student <id|name>] [--all-students] [--json]
30
+ ```
31
+
32
+ Examples:
33
+ ```bash
34
+ # Specific day by date
35
+ wilma schedule list --date 2026-02-25 --student "Stella" --json
36
+
37
+ # Next Thursday (also accepts Finnish short forms like to/ke/pe)
38
+ wilma schedule list --weekday thu --student "Stella" --json
39
+
40
+ # Tomorrow
41
+ wilma schedule list --when tomorrow --student "Stella" --json
30
42
  ```
31
43
 
32
44
  ### Homework
package/dist/index.js CHANGED
@@ -518,6 +518,8 @@ async function handleCommand(args, config) {
518
518
  });
519
519
  await outputSchedule(perStudentClient, {
520
520
  when: flags.when ?? "week",
521
+ date: flags.date,
522
+ weekday: flags.weekday,
521
523
  json: flags.json,
522
524
  label: studentInfo?.name ?? undefined,
523
525
  });
@@ -591,7 +593,7 @@ async function handleCommand(args, config) {
591
593
  function printUsage() {
592
594
  console.log("Usage:");
593
595
  console.log(" wilma summary [--days 7] [--student <id|name>] [--all-students] [--json]");
594
- console.log(" wilma schedule list [--when today|tomorrow|week] [--student <id|name>] [--all-students] [--json]");
596
+ console.log(" wilma schedule list [--when today|tomorrow|week] [--date YYYY-MM-DD] [--weekday mon|tue|wed|thu|fri|sat|sun] [--student <id|name>] [--all-students] [--json]");
595
597
  console.log(" wilma homework list [--limit 10] [--student <id|name>] [--all-students] [--json]");
596
598
  console.log(" wilma exams list [--limit 20] [--student <id|name>] [--all-students] [--json]");
597
599
  console.log(" wilma grades list [--limit 20] [--student <id|name>] [--all-students] [--json]");
@@ -683,6 +685,16 @@ function parseArgs(args) {
683
685
  i += 2;
684
686
  continue;
685
687
  }
688
+ if (arg === "--date") {
689
+ flags.date = rest[i + 1];
690
+ i += 2;
691
+ continue;
692
+ }
693
+ if (arg === "--weekday") {
694
+ flags.weekday = rest[i + 1];
695
+ i += 2;
696
+ continue;
697
+ }
686
698
  if (!flags.id && !arg.startsWith("--")) {
687
699
  flags.id = arg;
688
700
  i += 1;
@@ -704,6 +716,71 @@ function parseReadId(raw, entity) {
704
716
  }
705
717
  return id;
706
718
  }
719
+ function parseIsoDateOrExit(raw) {
720
+ const value = (raw ?? "").trim();
721
+ // Accept YYYY-MM-DD only.
722
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) {
723
+ console.error(`Invalid date "${raw}". Expected YYYY-MM-DD.`);
724
+ process.exit(1);
725
+ }
726
+ // Validate date is real.
727
+ const d = new Date(value + "T12:00:00Z");
728
+ if (Number.isNaN(d.getTime())) {
729
+ console.error(`Invalid date "${raw}". Expected a real calendar date.`);
730
+ process.exit(1);
731
+ }
732
+ const iso = d.toISOString().slice(0, 10);
733
+ if (iso !== value) {
734
+ console.error(`Invalid date "${raw}". Expected a real calendar date.`);
735
+ process.exit(1);
736
+ }
737
+ return value;
738
+ }
739
+ function normalizeWeekdayOrExit(raw) {
740
+ const v = (raw ?? "").trim().toLowerCase();
741
+ const map = {
742
+ sun: 0,
743
+ su: 0,
744
+ sunday: 0,
745
+ mon: 1,
746
+ ma: 1,
747
+ monday: 1,
748
+ tue: 2,
749
+ ti: 2,
750
+ tuesday: 2,
751
+ wed: 3,
752
+ ke: 3,
753
+ wednesday: 3,
754
+ thu: 4,
755
+ to: 4,
756
+ thursday: 4,
757
+ fri: 5,
758
+ pe: 5,
759
+ friday: 5,
760
+ sat: 6,
761
+ la: 6,
762
+ saturday: 6,
763
+ };
764
+ const day = map[v];
765
+ if (day === undefined) {
766
+ console.error(`Invalid weekday "${raw}". Use mon|tue|wed|thu|fri|sat|sun (also accepts fi: ma|ti|ke|to|pe|la|su).`);
767
+ process.exit(1);
768
+ }
769
+ return day;
770
+ }
771
+ function nextDateForWeekday(rawWeekday) {
772
+ const target = normalizeWeekdayOrExit(rawWeekday);
773
+ const now = new Date();
774
+ // Use local time.
775
+ const today = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 12, 0, 0);
776
+ const current = today.getDay();
777
+ let delta = (target - current + 7) % 7;
778
+ // If you ask for e.g. "thu" on a Saturday, you'll get next Thursday.
779
+ // If you ask for today's weekday, you'll get today.
780
+ const d = new Date(today);
781
+ d.setDate(d.getDate() + delta);
782
+ return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
783
+ }
707
784
  async function readPackageVersion() {
708
785
  const pkgPath = resolve(dirname(new URL(import.meta.url).pathname), "..", "package.json");
709
786
  const raw = await readFile(pkgPath, "utf-8");
@@ -894,7 +971,19 @@ async function outputSchedule(client, opts) {
894
971
  const when = opts.when || "week";
895
972
  let startDate;
896
973
  let endDate;
897
- if (when === "today") {
974
+ if (opts.date && opts.weekday) {
975
+ console.error("Use either --date or --weekday, not both.");
976
+ process.exit(1);
977
+ }
978
+ if (opts.date) {
979
+ const parsed = parseIsoDateOrExit(opts.date);
980
+ startDate = endDate = parsed;
981
+ }
982
+ else if (opts.weekday) {
983
+ const parsed = nextDateForWeekday(opts.weekday);
984
+ startDate = endDate = parsed;
985
+ }
986
+ else if (when === "today") {
898
987
  startDate = endDate = todayString();
899
988
  }
900
989
  else if (when === "tomorrow") {
@@ -905,14 +994,17 @@ async function outputSchedule(client, opts) {
905
994
  }
906
995
  const lessons = overview.schedule.filter((l) => l.date >= startDate && l.date <= endDate);
907
996
  if (opts.json) {
908
- const result = when === "week"
997
+ const result = !opts.date && !opts.weekday && when === "week"
909
998
  ? { when, weekStart: startDate, weekEnd: endDate, lessons }
910
- : { when, date: startDate, lessons };
999
+ : { when: opts.date ? "date" : (opts.weekday ? "weekday" : when), date: startDate, lessons };
911
1000
  console.log(JSON.stringify(result, null, 2));
912
1001
  return;
913
1002
  }
914
1003
  const prefix = opts.label ? `[${opts.label}] ` : "";
915
- if (when === "today") {
1004
+ if (opts.date || opts.weekday) {
1005
+ console.log(`\n${prefix}Schedule for ${startDate}`);
1006
+ }
1007
+ else if (when === "today") {
916
1008
  console.log(`\n${prefix}Schedule for today (${startDate})`);
917
1009
  }
918
1010
  else if (when === "tomorrow") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wilm-ai/wilma-cli",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -8,9 +8,17 @@
8
8
  "wilmai": "dist/index.js",
9
9
  "wilma": "dist/index.js"
10
10
  },
11
+ "scripts": {
12
+ "build": "tsc -p tsconfig.json",
13
+ "lint": "echo 'add lint'",
14
+ "test": "echo 'add tests'",
15
+ "start": "node dist/index.js",
16
+ "prepack": "pnpm --filter @wilm-ai/wilma-client build && pnpm --filter @wilm-ai/wilma-cli build",
17
+ "test:live": "tsc -p tsconfig.json && node test/live.spec.mjs"
18
+ },
11
19
  "dependencies": {
12
20
  "@inquirer/prompts": "^5.3.8",
13
- "@wilm-ai/wilma-client": "^1.1.0"
21
+ "@wilm-ai/wilma-client": "workspace:^"
14
22
  },
15
23
  "devDependencies": {
16
24
  "typescript": "^5.6.3"
@@ -21,12 +29,5 @@
21
29
  ],
22
30
  "publishConfig": {
23
31
  "access": "public"
24
- },
25
- "scripts": {
26
- "build": "tsc -p tsconfig.json",
27
- "lint": "echo 'add lint'",
28
- "test": "echo 'add tests'",
29
- "start": "node dist/index.js",
30
- "test:live": "tsc -p tsconfig.json && node test/live.spec.mjs"
31
32
  }
32
- }
33
+ }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Wilm.ai
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.