@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 +8 -8
- package/dist/main.js +24 -9
- package/package.json +1 -1
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({
|
|
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({
|
|
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({
|
|
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.
|
|
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": {
|