@novedu/cli 0.5.0 → 0.6.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
@@ -14,21 +14,21 @@ the same one the app would accept — no separate, drifting rules.
14
14
 
15
15
  ```bash
16
16
  # Validate a local file (relative fragment_files resolve from the same folder)
17
- npx @novedu/cli validate ./tutors/simple-tutor.yaml
17
+ npx @novedu/cli validate ./activities/tutors/simple-tutor.yaml
18
18
 
19
19
  # Validate a published tutor by URL
20
- npx @novedu/cli validate https://raw.githubusercontent.com/Teaching-HTL-Leonding/novedu-chat-mvp/refs/heads/main/tutors/simple-tutor.yaml
20
+ npx @novedu/cli validate https://raw.githubusercontent.com/Teaching-HTL-Leonding/novedu-chat-mvp/refs/heads/main/activities/tutors/simple-tutor.yaml
21
21
 
22
22
  # Validate a fragment library on its own
23
- npx @novedu/cli validate ./tutors/simple-fragments.yaml --kind fragment
23
+ npx @novedu/cli validate ./activities/tutors/simple-fragments.yaml --kind fragment
24
24
 
25
25
  # Validate a quiz, a writing activity, or a coding activity
26
- npx @novedu/cli validate ./quizzes/sample-quiz.yaml --kind quiz
27
- npx @novedu/cli validate ./writings/human-animal-short-story.yaml --kind writing
28
- npx @novedu/cli validate ./coding/beginner-typescript.yaml --kind coding
26
+ npx @novedu/cli validate ./activities/quizzes/sample-quiz.yaml --kind quiz
27
+ npx @novedu/cli validate ./activities/writings/human-animal-short-story.yaml --kind writing
28
+ npx @novedu/cli validate ./activities/coding/beginner-typescript.yaml --kind coding
29
29
 
30
30
  # Machine-readable output (the raw validation result)
31
- npx @novedu/cli validate ./tutors/simple-tutor.yaml --json
31
+ npx @novedu/cli validate ./activities/tutors/simple-tutor.yaml --json
32
32
  ```
33
33
 
34
34
  `--kind` accepts `tutor` (default), `fragment`, `quiz`, `writing`, or `coding`; it
@@ -42,7 +42,7 @@ as a pre-commit / CI gate.
42
42
  The CLI lives in the app repo as an npm workspace.
43
43
 
44
44
  ```bash
45
- npm run cli -- validate ./tutors/simple-tutor.yaml # run from source via tsx
45
+ npm run cli -- validate ./activities/tutors/simple-tutor.yaml # run from source via tsx
46
46
  npm run cli:build # bundle to cli/dist via tsdown
47
47
  npm run test:cli # build + integration tests (local & live URLs)
48
48
  ```
package/dist/main.js CHANGED
@@ -242,6 +242,7 @@ function validate(value, schema, code, url) {
242
242
  })
243
243
  };
244
244
  }
245
+ const providerSchema = z.enum(["SCCH", "Azure Foundry"]).default("SCCH");
245
246
  //#endregion
246
247
  //#region ../lib/tutors/schemas.ts
247
248
  /**
@@ -329,6 +330,7 @@ const TutorSchema = z.strictObject({
329
330
  anonymous: z.boolean().optional(),
330
331
  llm: z.strictObject({
331
332
  model: z.string(),
333
+ provider: providerSchema,
332
334
  imageInput: z.boolean().optional()
333
335
  }),
334
336
  prompt: z.strictObject({
@@ -446,7 +448,7 @@ function resolveRelativeUrl(ref, baseUrl) {
446
448
  * Resolve a fragment-file reference to an absolute URL. An absolute http(s) ref is used
447
449
  * as-is; anything else is treated as relative to the tutor URL — standard URL resolution
448
450
  * drops the tutor's filename and appends the relative path (so `general-fragments.yaml`
449
- * next to `.../tutors/linked-list-tutor.yaml` becomes `.../tutors/general-fragments.yaml`,
451
+ * next to `.../activities/tutors/linked-list-tutor.yaml` becomes `.../activities/tutors/general-fragments.yaml`,
450
452
  * and `./` / `../` segments work too). Throws if a relative ref is unparseable; the schema
451
453
  * already guarantees the only inputs here are http(s) URLs or relative paths.
452
454
  */
@@ -596,6 +598,7 @@ async function loadAndBuildTutorPrompt(url, fetchImpl, opts = {}) {
596
598
  ok: true,
597
599
  prompt: assembleSystemPrompt(consistency.plan, tutor),
598
600
  model: tutor.llm.model,
601
+ provider: tutor.llm.provider,
599
602
  imageInput: tutor.llm.imageInput ?? true,
600
603
  anonymous: tutor.anonymous ?? true,
601
604
  title: tutor.title,
@@ -633,7 +636,10 @@ const CodingYamlSchema = z.strictObject({
633
636
  id: z.string().min(1),
634
637
  name: z.string().optional(),
635
638
  title: z.string().optional(),
636
- llm: z.strictObject({ model: z.string().min(1) }),
639
+ llm: z.strictObject({
640
+ model: z.string().min(1),
641
+ provider: providerSchema
642
+ }),
637
643
  instructions: z.string().min(1)
638
644
  });
639
645
  //#endregion
@@ -655,6 +661,7 @@ function checkCodingValue(parsed, url) {
655
661
  ok: true,
656
662
  codingId: coding.id,
657
663
  model: coding.llm.model,
664
+ provider: coding.llm.provider,
658
665
  title: coding.title ?? null,
659
666
  warnings: []
660
667
  };
@@ -701,7 +708,10 @@ const QuizYamlSchema = z.strictObject({
701
708
  description: z.string().optional(),
702
709
  anonymous: z.boolean().optional(),
703
710
  shuffle: z.boolean().optional(),
704
- llm: z.strictObject({ model: z.string().min(1) }),
711
+ llm: z.strictObject({
712
+ model: z.string().min(1),
713
+ provider: providerSchema
714
+ }),
705
715
  discussion: z.strictObject({ instructions: z.string().min(1) }).optional(),
706
716
  questions: z.array(QuizQuestionSchema).min(1)
707
717
  });
@@ -745,6 +755,7 @@ function checkQuizValue(parsed, url) {
745
755
  ok: true,
746
756
  quizId: quiz.id,
747
757
  model: quiz.llm.model,
758
+ provider: quiz.llm.provider,
748
759
  questionCount: quiz.questions.length,
749
760
  anonymous: quiz.anonymous ?? DEFAULT_ANONYMOUS$1,
750
761
  title: quiz.title ?? null,
@@ -773,7 +784,10 @@ const WritingYamlSchema = z.strictObject({
773
784
  title: z.string().optional(),
774
785
  description: z.string().optional(),
775
786
  anonymous: z.boolean().optional(),
776
- llm: z.strictObject({ model: z.string().min(1) }),
787
+ llm: z.strictObject({
788
+ model: z.string().min(1),
789
+ provider: providerSchema
790
+ }),
777
791
  instructions: z.string().min(1),
778
792
  placeholder: z.string().optional()
779
793
  });
@@ -798,6 +812,7 @@ function checkWritingValue(parsed, url) {
798
812
  ok: true,
799
813
  writingId: writing.id,
800
814
  model: writing.llm.model,
815
+ provider: writing.llm.provider,
801
816
  anonymous: writing.anonymous ?? DEFAULT_ANONYMOUS,
802
817
  title: writing.title ?? null,
803
818
  warnings: []
@@ -1047,15 +1062,15 @@ function registerValidate(program) {
1047
1062
  program.command("validate").description("Validate a tutor (default), fragment library, quiz, writing or coding YAML by local path or public http(s) URL").argument("<pathOrUrl>", "path to a tutor, fragment, quiz, writing or coding YAML file, or a public http(s) URL").option("--kind <kind>", `what the file is: ${VALIDATE_KINDS.map((k) => `'${k}'`).join(", ")} ('tutor' is the default)`, "tutor").option("--json", "print the raw validation result as JSON").addHelpText("after", `
1048
1063
  Examples:
1049
1064
  # Validate a tutor (also strict-renders every fragment in every referenced library)
1050
- $ novedu-cli validate ./tutors/my-tutor.yaml
1065
+ $ novedu-cli validate ./activities/tutors/my-tutor.yaml
1051
1066
 
1052
1067
  # Validate a fragment library on its own
1053
- $ novedu-cli validate ./tutors/my-fragments.yaml --kind fragment
1068
+ $ novedu-cli validate ./activities/tutors/my-fragments.yaml --kind fragment
1054
1069
 
1055
1070
  # Validate a quiz, a writing activity, or a coding activity
1056
- $ novedu-cli validate ./quizzes/my-quiz.yaml --kind quiz
1057
- $ novedu-cli validate ./writings/my-writing.yaml --kind writing
1058
- $ novedu-cli validate ./coding/my-coding.yaml --kind coding
1071
+ $ novedu-cli validate ./activities/quizzes/my-quiz.yaml --kind quiz
1072
+ $ novedu-cli validate ./activities/writings/my-writing.yaml --kind writing
1073
+ $ novedu-cli validate ./activities/coding/my-coding.yaml --kind coding
1059
1074
 
1060
1075
  # Machine-readable output for CI
1061
1076
  $ novedu-cli validate https://example.com/tutor.yaml --json`).action(async (pathOrUrl, options) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@novedu/cli",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Command-line companion for the Novedu chat app. Validates tutor, fragment, quiz, writing and coding YAML definitions (more commands to follow).",
5
5
  "type": "module",
6
6
  "repository": {