@novedu/cli 0.11.0 → 0.12.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 (2) hide show
  1. package/dist/main.js +39 -6
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -249,10 +249,10 @@ async function runApiRequest(options) {
249
249
  }
250
250
  //#endregion
251
251
  //#region src/commands/codes.ts
252
- const SERVER_OPTION$1 = ["--server <url>", "Novedu server base URL (defaults to the NOVEDU_SERVER env var, then production)"];
252
+ const SERVER_OPTION$2 = ["--server <url>", "Novedu server base URL (defaults to the NOVEDU_SERVER env var, then production)"];
253
253
  function registerCodes(program) {
254
254
  const codes = program.command("codes").description("Manage activity codes on the Novedu server");
255
- codes.command("create").description("Create a code for an activity YAML (validated server-side before storing)").requiredOption("--module <module>", "activity module: tutor, quiz, writing or coding").requiredOption("--file <url>", "public http(s) URL of the activity YAML").option("--start <iso>", "window start, ISO 8601 with explicit offset (e.g. 2026-07-07T08:00:00Z)").option("--end <iso>", "window end, ISO 8601 with explicit offset").option("--note <text>", "note shown in the codes list").option("--llm-provider <provider>", "LLM override provider (\"SCCH\" or \"Azure Foundry\"; needs --llm-model)").option("--llm-model <model>", "LLM override model id (needs --llm-provider)").option(...SERVER_OPTION$1).action(async (options) => {
255
+ codes.command("create").description("Create a code for an activity YAML (validated server-side before storing)").requiredOption("--module <module>", "activity module: tutor, quiz, writing or coding").requiredOption("--file <url>", "public http(s) URL of the activity YAML").option("--start <iso>", "window start, ISO 8601 with explicit offset (e.g. 2026-07-07T08:00:00Z)").option("--end <iso>", "window end, ISO 8601 with explicit offset").option("--note <text>", "note shown in the codes list").option("--llm-provider <provider>", "LLM override provider (\"SCCH\" or \"Azure Foundry\"; needs --llm-model)").option("--llm-model <model>", "LLM override model id (needs --llm-provider)").option(...SERVER_OPTION$2).action(async (options) => {
256
256
  await runApiRequest({
257
257
  server: options.server,
258
258
  path: "/api/codes",
@@ -270,7 +270,7 @@ function registerCodes(program) {
270
270
  }
271
271
  });
272
272
  });
273
- codes.command("list").description("List codes (defaults to only your own, like the web list)").option("--search <q>", "contains-filter over note/code").option("--module <module>", "only codes for one activity module").option("--all", "include codes created by other teachers").option(...SERVER_OPTION$1).action(async (options) => {
273
+ codes.command("list").description("List codes (defaults to only your own, like the web list)").option("--search <q>", "contains-filter over note/code").option("--module <module>", "only codes for one activity module").option("--all", "include codes created by other teachers").option(...SERVER_OPTION$2).action(async (options) => {
274
274
  const params = new URLSearchParams();
275
275
  if (options.search) params.set("q", options.search);
276
276
  if (options.module) params.set("module", options.module);
@@ -284,7 +284,7 @@ function registerCodes(program) {
284
284
  }
285
285
  //#endregion
286
286
  //#region src/commands/files.ts
287
- const SERVER_OPTION = ["--server <url>", "Novedu server base URL (defaults to the NOVEDU_SERVER env var, then production)"];
287
+ const SERVER_OPTION$1 = ["--server <url>", "Novedu server base URL (defaults to the NOVEDU_SERVER env var, then production)"];
288
288
  async function readStdin() {
289
289
  const chunks = [];
290
290
  for await (const chunk of process.stdin) chunks.push(chunk);
@@ -292,7 +292,7 @@ async function readStdin() {
292
292
  }
293
293
  function registerFiles(program) {
294
294
  const files = program.command("files").description("Manage app-hosted YAML files on the Novedu server");
295
- files.command("upload <name>").description("Create or update an app-hosted YAML file from --file or stdin (validated server-side)").option("--kind <kind>", "file kind (tutor, fragment, quiz, writing, coding) — required when creating").option("--file <path>", "read the YAML from this path instead of stdin").option(...SERVER_OPTION).action(async (name, options) => {
295
+ files.command("upload <name>").description("Create or update an app-hosted YAML file from --file or stdin (validated server-side)").option("--kind <kind>", "file kind (tutor, fragment, quiz, writing, coding) — required when creating").option("--file <path>", "read the YAML from this path instead of stdin").option(...SERVER_OPTION$1).action(async (name, options) => {
296
296
  let content;
297
297
  try {
298
298
  content = options.file === void 0 ? await readStdin() : await readFile(options.file, "utf8");
@@ -310,7 +310,7 @@ function registerFiles(program) {
310
310
  }
311
311
  });
312
312
  });
313
- files.command("list").description("List app-hosted YAML files (defaults to only your own, like the web list)").option("--search <q>", "contains-filter over name/title/description").option("--all", "include files last written by other teachers").option(...SERVER_OPTION).action(async (options) => {
313
+ files.command("list").description("List app-hosted YAML files (defaults to only your own, like the web list)").option("--search <q>", "contains-filter over name/title/description").option("--all", "include files last written by other teachers").option(...SERVER_OPTION$1).action(async (options) => {
314
314
  const params = new URLSearchParams();
315
315
  if (options.search) params.set("q", options.search);
316
316
  if (options.all) params.set("mine", "0");
@@ -358,6 +358,38 @@ Purely local — already-issued access tokens stay valid until they expire
358
358
  });
359
359
  }
360
360
  //#endregion
361
+ //#region src/commands/reports.ts
362
+ const SERVER_OPTION = ["--server <url>", "Novedu server base URL (defaults to the NOVEDU_SERVER env var, then production)"];
363
+ function registerReports(program) {
364
+ const reports = program.command("reports").description("Triage student reports on the Novedu server");
365
+ reports.command("list").description("List reports (defaults to open reports on your own codes, like the web inbox)").option("--status <status>", "open (default), resolved or all").option("--reaction <reaction>", "filter by reaction: good, omg, bad or holysh").option("--search <q>", "contains-filter over description, reporter, code and note").option("--all", "include reports on codes created by other teachers").option(...SERVER_OPTION).action(async (options) => {
366
+ const params = new URLSearchParams();
367
+ if (options.status) params.set("status", options.status);
368
+ if (options.reaction) params.set("reaction", options.reaction);
369
+ if (options.search) params.set("q", options.search);
370
+ if (options.all) params.set("mine", "0");
371
+ const query = params.toString();
372
+ await runApiRequest({
373
+ server: options.server,
374
+ path: `/api/reports${query ? `?${query}` : ""}`
375
+ });
376
+ });
377
+ reports.command("show <id>").description("Show one report; a chat report embeds its conversation transcript").option(...SERVER_OPTION).action(async (id, options) => {
378
+ await runApiRequest({
379
+ server: options.server,
380
+ path: `/api/reports/${encodeURIComponent(id)}`
381
+ });
382
+ });
383
+ reports.command("resolve <id...>").description("Resolve one or more reports by id (bulk, in a single request)").option(...SERVER_OPTION).action(async (ids, options) => {
384
+ await runApiRequest({
385
+ server: options.server,
386
+ path: "/api/reports/resolve",
387
+ method: "POST",
388
+ body: { ids }
389
+ });
390
+ });
391
+ }
392
+ //#endregion
361
393
  //#region ../lib/prompt-fragments/assemble.ts
362
394
  const COMPILE_OPTIONS = {
363
395
  strict: true,
@@ -1705,6 +1737,7 @@ registerLogout(program);
1705
1737
  registerWhoami(program);
1706
1738
  registerCodes(program);
1707
1739
  registerFiles(program);
1740
+ registerReports(program);
1708
1741
  program.parseAsync().catch((err) => {
1709
1742
  console.error(err instanceof Error ? err.message : err);
1710
1743
  process.exitCode = 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@novedu/cli",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "Command-line companion for the Novedu chat app. Validates tutor, fragment, quiz, writing and coding YAML definitions; signs in with Entra ID and manages codes and app-hosted files over the app's API.",
5
5
  "type": "module",
6
6
  "repository": {