@tostudy-ai/cli 0.6.0 → 0.7.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 (3) hide show
  1. package/dist/cli.js +1100 -480
  2. package/dist/cli.js.map +4 -4
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -219,6 +219,47 @@ function getConfigDir(override) {
219
219
  }
220
220
  return path2.join(os2.homedir(), ".tostudy");
221
221
  }
222
+ function getCourseOnboardingPath(configDir) {
223
+ return path2.join(getConfigDir(configDir), "course-onboarding.json");
224
+ }
225
+ function readCourseOnboardingState(configDir) {
226
+ const onboardingPath = getCourseOnboardingPath(configDir);
227
+ if (!fs2.existsSync(onboardingPath)) return {};
228
+ return JSON.parse(fs2.readFileSync(onboardingPath, "utf-8"));
229
+ }
230
+ function writeCourseOnboardingState(state, configDir) {
231
+ const dir = getConfigDir(configDir);
232
+ fs2.mkdirSync(dir, { recursive: true });
233
+ fs2.writeFileSync(getCourseOnboardingPath(configDir), JSON.stringify(state, null, 2), {
234
+ mode: 384
235
+ });
236
+ }
237
+ async function getCourseOnboardingState(courseId, configDir) {
238
+ const state = readCourseOnboardingState(configDir);
239
+ return state[courseId] ?? null;
240
+ }
241
+ async function updateCourseOnboardingState(courseId, patch, configDir) {
242
+ const state = readCourseOnboardingState(configDir);
243
+ state[courseId] = {
244
+ ...state[courseId] ?? {},
245
+ ...patch
246
+ };
247
+ writeCourseOnboardingState(state, configDir);
248
+ }
249
+ async function setCourseWorkspacePath(courseId, workspacePath, configDir) {
250
+ await updateCourseOnboardingState(courseId, { workspacePath }, configDir);
251
+ }
252
+ async function saveCourseLearnerProfile(course, learnerProfile, artifacts, configDir) {
253
+ await updateCourseOnboardingState(
254
+ course.courseId,
255
+ {
256
+ enrollmentId: course.enrollmentId,
257
+ learnerProfile,
258
+ artifacts
259
+ },
260
+ configDir
261
+ );
262
+ }
222
263
  async function saveSession(session, configDir) {
223
264
  const dir = getConfigDir(configDir);
224
265
  fs2.mkdirSync(dir, { recursive: true });
@@ -263,6 +304,8 @@ async function clearSession(configDir) {
263
304
  if (fs2.existsSync(p)) fs2.unlinkSync(p);
264
305
  const ap = path2.join(dir, "active-course.json");
265
306
  if (fs2.existsSync(ap)) fs2.unlinkSync(ap);
307
+ const onboardingPath = getCourseOnboardingPath(configDir);
308
+ if (fs2.existsSync(onboardingPath)) fs2.unlinkSync(onboardingPath);
266
309
  await deleteStoredSessionSecrets(dir);
267
310
  }
268
311
  async function getActiveCourse(configDir) {
@@ -274,7 +317,9 @@ async function getActiveCourse(configDir) {
274
317
  async function setActiveCourse(course, configDir) {
275
318
  const dir = getConfigDir(configDir);
276
319
  fs2.mkdirSync(dir, { recursive: true });
277
- fs2.writeFileSync(path2.join(dir, "active-course.json"), JSON.stringify(course, null, 2), {
320
+ const onboardingState = await getCourseOnboardingState(course.courseId, configDir);
321
+ const persistedCourse = onboardingState?.initCompletedAt && !course.lastInitCourseId ? { ...course, lastInitCourseId: course.courseId } : course;
322
+ fs2.writeFileSync(path2.join(dir, "active-course.json"), JSON.stringify(persistedCourse, null, 2), {
278
323
  mode: 384
279
324
  });
280
325
  }
@@ -332,6 +377,13 @@ async function setLastInitCourseId(courseId, configDir) {
332
377
  const existing = await getActiveCourse(configDir);
333
378
  if (!existing) return;
334
379
  await setActiveCourse({ ...existing, lastInitCourseId: courseId }, configDir);
380
+ await updateCourseOnboardingState(
381
+ courseId,
382
+ {
383
+ initCompletedAt: (/* @__PURE__ */ new Date()).toISOString()
384
+ },
385
+ configDir
386
+ );
335
387
  }
336
388
  async function checkCourseDrift(configDir) {
337
389
  const course = await getActiveCourse(configDir);
@@ -400,9 +452,17 @@ function formatCourseList(courses3) {
400
452
  const lines = ["Seus cursos:", ""];
401
453
  courses3.forEach((course, idx) => {
402
454
  const bar = progressBar(course.progress);
455
+ const enrolledDate = course.enrolledAt ? new Date(course.enrolledAt).toLocaleDateString("pt-BR", {
456
+ year: "numeric",
457
+ month: "short",
458
+ day: "numeric"
459
+ }) : null;
403
460
  lines.push(` ${idx + 1}. ${course.title}`);
404
461
  lines.push(` ${bar}`);
405
462
  lines.push(` Professor: ${course.creatorName}`);
463
+ if (enrolledDate) {
464
+ lines.push(` Inscrito em: ${enrolledDate}`);
465
+ }
406
466
  lines.push("");
407
467
  });
408
468
  lines.push("\u2192 tostudy select <n\xFAmero> para ativar um curso");
@@ -768,6 +828,65 @@ var init_mcp_setup = __esm({
768
828
  }
769
829
  });
770
830
 
831
+ // src/workspace/resolve.ts
832
+ import fs4 from "node:fs/promises";
833
+ import path4 from "node:path";
834
+ import os4 from "node:os";
835
+ function courseSlug(title) {
836
+ return title.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
837
+ }
838
+ async function resolveWorkspace(courseTitle, basePath = DEFAULT_BASE) {
839
+ const slug = courseSlug(courseTitle);
840
+ const candidate = path4.join(basePath, slug);
841
+ try {
842
+ await fs4.access(path4.join(candidate, ".ana-config.json"));
843
+ return { found: true, workspacePath: candidate };
844
+ } catch {
845
+ return { found: false, workspacePath: null };
846
+ }
847
+ }
848
+ var DEFAULT_BASE;
849
+ var init_resolve = __esm({
850
+ "src/workspace/resolve.ts"() {
851
+ "use strict";
852
+ DEFAULT_BASE = path4.join(os4.homedir(), "study");
853
+ }
854
+ });
855
+
856
+ // src/onboarding/status.ts
857
+ import fs5 from "node:fs/promises";
858
+ import path5 from "node:path";
859
+ async function resolveStoredWorkspace(workspacePath) {
860
+ if (!workspacePath) return null;
861
+ try {
862
+ await fs5.access(path5.join(workspacePath, ".ana-config.json"));
863
+ return workspacePath;
864
+ } catch {
865
+ return null;
866
+ }
867
+ }
868
+ async function getCourseOnboardingStatus(activeCourse, configDir) {
869
+ const onboardingState = await getCourseOnboardingState(activeCourse.courseId, configDir);
870
+ const initReady = Boolean(onboardingState?.initCompletedAt);
871
+ let workspacePath = await resolveStoredWorkspace(onboardingState?.workspacePath);
872
+ if (!workspacePath) {
873
+ const resolvedWorkspace = await resolveWorkspace(activeCourse.courseTitle);
874
+ workspacePath = resolvedWorkspace.workspacePath;
875
+ }
876
+ return {
877
+ initReady,
878
+ workspaceReady: Boolean(workspacePath),
879
+ workspacePath
880
+ };
881
+ }
882
+ var init_status = __esm({
883
+ "src/onboarding/status.ts"() {
884
+ "use strict";
885
+ init_session();
886
+ init_resolve();
887
+ }
888
+ });
889
+
771
890
  // src/commands/setup.ts
772
891
  import { Command as Command3 } from "commander";
773
892
  async function runSetup(opts, deps = defaultDeps) {
@@ -821,8 +940,34 @@ async function runSetup(opts, deps = defaultDeps) {
821
940
  await deps.runMcpSetup(session, token2);
822
941
  deps.log(" \u2713 MCP configurado\n");
823
942
  }
943
+ const activeCourse = await deps.getActiveCourse();
944
+ if (!activeCourse) {
945
+ deps.log(" Ambiente validado, mas ainda falta selecionar um curso.");
946
+ deps.log(" Pr\xF3ximos passos obrigat\xF3rios:");
947
+ deps.log(" \u2192 tostudy courses");
948
+ deps.log(" \u2192 tostudy select <n\xFAmero>");
949
+ deps.log(" \u2192 tostudy init");
950
+ deps.log(" \u2192 tostudy workspace setup\n");
951
+ return;
952
+ }
953
+ const onboarding = await deps.getCourseOnboardingStatus(activeCourse);
954
+ if (!onboarding.initReady || !onboarding.workspaceReady) {
955
+ deps.log(
956
+ ` Ambiente validado para ${activeCourse.courseTitle}, mas o onboarding ainda n\xE3o terminou.`
957
+ );
958
+ deps.log(" Checklist obrigat\xF3rio antes do primeiro start:");
959
+ if (!onboarding.initReady) {
960
+ deps.log(" \u2192 tostudy init");
961
+ }
962
+ if (!onboarding.workspaceReady) {
963
+ deps.log(" \u2192 tostudy workspace setup");
964
+ }
965
+ deps.log(" \u2192 tostudy start ficar\xE1 dispon\xEDvel depois desses passos\n");
966
+ return;
967
+ }
824
968
  deps.log(" Setup completo!");
825
- deps.log(" \u2192 tostudy courses (ver cursos matriculados)");
969
+ deps.log(" \u2192 tostudy start (iniciar ou retomar o m\xF3dulo atual)");
970
+ deps.log(" \u2192 tostudy courses (ver cursos matriculados)");
826
971
  deps.log(" \u2192 tostudy doctor (diagn\xF3stico completo)\n");
827
972
  }
828
973
  async function runSetupMcpSubcommand() {
@@ -844,10 +989,13 @@ var init_setup = __esm({
844
989
  init_ide_detector();
845
990
  init_session();
846
991
  init_mcp_setup();
992
+ init_status();
847
993
  defaultDeps = {
848
994
  detectNode,
849
995
  detectIDEs,
850
996
  getSession,
997
+ getActiveCourse,
998
+ getCourseOnboardingStatus,
851
999
  exchangeCliSessionForMcpToken,
852
1000
  runMcpSetup,
853
1001
  log: (message = "") => {
@@ -872,20 +1020,20 @@ __export(update_checker_exports, {
872
1020
  fetchLatestVersion: () => fetchLatestVersion,
873
1021
  isNewerVersion: () => isNewerVersion
874
1022
  });
875
- import fs4 from "node:fs";
876
- import path4 from "node:path";
877
- import os4 from "node:os";
1023
+ import fs6 from "node:fs";
1024
+ import path6 from "node:path";
1025
+ import os5 from "node:os";
878
1026
  function getConfigDir2() {
879
1027
  if (process.platform === "linux" && process.env["XDG_CONFIG_HOME"]) {
880
- return path4.join(process.env["XDG_CONFIG_HOME"], "tostudy");
1028
+ return path6.join(process.env["XDG_CONFIG_HOME"], "tostudy");
881
1029
  }
882
- return path4.join(os4.homedir(), ".tostudy");
1030
+ return path6.join(os5.homedir(), ".tostudy");
883
1031
  }
884
1032
  function readCache() {
885
1033
  try {
886
- const p = path4.join(getConfigDir2(), CACHE_FILE);
887
- if (!fs4.existsSync(p)) return null;
888
- return JSON.parse(fs4.readFileSync(p, "utf-8"));
1034
+ const p = path6.join(getConfigDir2(), CACHE_FILE);
1035
+ if (!fs6.existsSync(p)) return null;
1036
+ return JSON.parse(fs6.readFileSync(p, "utf-8"));
889
1037
  } catch {
890
1038
  return null;
891
1039
  }
@@ -893,8 +1041,8 @@ function readCache() {
893
1041
  function writeCache(cache) {
894
1042
  try {
895
1043
  const dir = getConfigDir2();
896
- fs4.mkdirSync(dir, { recursive: true });
897
- fs4.writeFileSync(path4.join(dir, CACHE_FILE), JSON.stringify(cache));
1044
+ fs6.mkdirSync(dir, { recursive: true });
1045
+ fs6.writeFileSync(path6.join(dir, CACHE_FILE), JSON.stringify(cache));
898
1046
  } catch {
899
1047
  }
900
1048
  }
@@ -1140,7 +1288,7 @@ var init_context = __esm({
1140
1288
  // ../../packages/logger/src/formatters/json.ts
1141
1289
  function formatJson(entry) {
1142
1290
  const { timestamp: timestamp2, level, message, service, environment, context, data, error: error49 } = entry;
1143
- const output2 = {
1291
+ const output3 = {
1144
1292
  timestamp: timestamp2,
1145
1293
  level,
1146
1294
  message,
@@ -1150,9 +1298,9 @@ function formatJson(entry) {
1150
1298
  ...data
1151
1299
  };
1152
1300
  if (error49) {
1153
- output2.error = error49;
1301
+ output3.error = error49;
1154
1302
  }
1155
- return JSON.stringify(output2);
1303
+ return JSON.stringify(output3);
1156
1304
  }
1157
1305
  var init_json = __esm({
1158
1306
  "../../packages/logger/src/formatters/json.ts"() {
@@ -1167,8 +1315,8 @@ var require_picocolors = __commonJS({
1167
1315
  var argv = p.argv || [];
1168
1316
  var env = p.env || {};
1169
1317
  var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
1170
- var formatter = (open, close, replace = open) => (input) => {
1171
- let string4 = "" + input, index2 = string4.indexOf(close, open.length);
1318
+ var formatter = (open, close, replace = open) => (input2) => {
1319
+ let string4 = "" + input2, index2 = string4.indexOf(close, open.length);
1172
1320
  return ~index2 ? open + replaceClose(string4, close, replace, index2) + close : open + string4 + close;
1173
1321
  };
1174
1322
  var replaceClose = (string4, close, replace, index2) => {
@@ -1259,7 +1407,7 @@ function formatPretty(entry) {
1259
1407
  const lvl = formatLevel(level);
1260
1408
  const mod = context.module ? import_picocolors.default.dim(`[${context.module}]`) + " " : "";
1261
1409
  const svc = import_picocolors.default.dim(`[${service}]`) + " ";
1262
- let output2 = `${import_picocolors.default.dim(time4)} ${lvl} ${svc}${mod}${message}`;
1410
+ let output3 = `${import_picocolors.default.dim(time4)} ${lvl} ${svc}${mod}${message}`;
1263
1411
  const traceInfo = {};
1264
1412
  if (context.traceId) traceInfo.traceId = context.traceId;
1265
1413
  if (context.requestId && context.requestId !== context.traceId) {
@@ -1269,22 +1417,22 @@ function formatPretty(entry) {
1269
1417
  if (context.duration !== void 0) traceInfo.duration = `${context.duration}ms`;
1270
1418
  const allData = { ...traceInfo, ...data };
1271
1419
  if (Object.keys(allData).length > 0) {
1272
- output2 += formatData(allData);
1420
+ output3 += formatData(allData);
1273
1421
  }
1274
1422
  if (error49) {
1275
- output2 += "\n" + import_picocolors.default.red(` ${error49.name}: ${error49.message}`);
1423
+ output3 += "\n" + import_picocolors.default.red(` ${error49.name}: ${error49.message}`);
1276
1424
  if (error49.code) {
1277
- output2 += import_picocolors.default.dim(` (${error49.code})`);
1425
+ output3 += import_picocolors.default.dim(` (${error49.code})`);
1278
1426
  }
1279
1427
  if (error49.stack) {
1280
1428
  const stackLines = error49.stack.split("\n").slice(1, 4);
1281
- output2 += "\n" + stackLines.map((l) => import_picocolors.default.dim(` ${l.trim()}`)).join("\n");
1429
+ output3 += "\n" + stackLines.map((l) => import_picocolors.default.dim(` ${l.trim()}`)).join("\n");
1282
1430
  }
1283
1431
  if (error49.cause) {
1284
- output2 += "\n" + import_picocolors.default.dim(` Caused by: ${error49.cause.name}: ${error49.cause.message}`);
1432
+ output3 += "\n" + import_picocolors.default.dim(` Caused by: ${error49.cause.name}: ${error49.cause.message}`);
1285
1433
  }
1286
1434
  }
1287
- return output2;
1435
+ return output3;
1288
1436
  }
1289
1437
  var import_picocolors, LEVEL_COLORS, LEVEL_WIDTH;
1290
1438
  var init_pretty = __esm({
@@ -1372,6 +1520,22 @@ function isSensitiveKey(key) {
1372
1520
  return patterns.some((p) => lowerKey.includes(p));
1373
1521
  });
1374
1522
  }
1523
+ function serializeError(error49) {
1524
+ const serialized = {
1525
+ name: error49.name,
1526
+ message: error49.message
1527
+ };
1528
+ if (error49.stack) {
1529
+ serialized.stack = error49.stack;
1530
+ }
1531
+ if ("code" in error49 && typeof error49.code === "string") {
1532
+ serialized.code = error49.code;
1533
+ }
1534
+ if (error49.cause instanceof Error) {
1535
+ serialized.cause = serializeError(error49.cause);
1536
+ }
1537
+ return serialized;
1538
+ }
1375
1539
  function object(obj, additionalSensitiveKeys) {
1376
1540
  if (!obj || typeof obj !== "object") return obj;
1377
1541
  const sanitized = { ...obj };
@@ -1383,6 +1547,10 @@ function object(obj, additionalSensitiveKeys) {
1383
1547
  sanitized[key] = "[REDACTED]";
1384
1548
  continue;
1385
1549
  }
1550
+ if (value instanceof Error) {
1551
+ sanitized[key] = serializeError(value);
1552
+ continue;
1553
+ }
1386
1554
  if (value && typeof value === "object" && !Array.isArray(value)) {
1387
1555
  sanitized[key] = object(
1388
1556
  value,
@@ -1392,6 +1560,7 @@ function object(obj, additionalSensitiveKeys) {
1392
1560
  }
1393
1561
  if (Array.isArray(value)) {
1394
1562
  sanitized[key] = value.map((item) => {
1563
+ if (item instanceof Error) return serializeError(item);
1395
1564
  if (item && typeof item === "object" && !Array.isArray(item)) {
1396
1565
  return object(item, additionalSensitiveKeys);
1397
1566
  }
@@ -1402,13 +1571,7 @@ function object(obj, additionalSensitiveKeys) {
1402
1571
  return sanitized;
1403
1572
  }
1404
1573
  function headers(hdrs) {
1405
- const sensitiveHeaders = [
1406
- "authorization",
1407
- "x-api-key",
1408
- "x-auth-token",
1409
- "cookie",
1410
- "set-cookie"
1411
- ];
1574
+ const sensitiveHeaders = ["authorization", "x-api-key", "x-auth-token", "cookie", "set-cookie"];
1412
1575
  const sanitized = { ...hdrs };
1413
1576
  for (const key of Object.keys(sanitized)) {
1414
1577
  if (sensitiveHeaders.some((h) => key.toLowerCase() === h)) {
@@ -1986,9 +2149,9 @@ var init_src = __esm({
1986
2149
  });
1987
2150
 
1988
2151
  // ../../packages/tostudy-core/src/courses/list-courses.ts
1989
- async function listCourses(input, deps) {
1990
- deps.logger.info("tostudy-core: listCourses", { userId: input.userId });
1991
- return deps.data.courses.list(input.userId);
2152
+ async function listCourses(input2, deps) {
2153
+ deps.logger.info("tostudy-core: listCourses", { userId: input2.userId });
2154
+ return deps.data.courses.list(input2.userId);
1992
2155
  }
1993
2156
  var init_list_courses = __esm({
1994
2157
  "../../packages/tostudy-core/src/courses/list-courses.ts"() {
@@ -1997,9 +2160,9 @@ var init_list_courses = __esm({
1997
2160
  });
1998
2161
 
1999
2162
  // ../../packages/tostudy-core/src/courses/select-course.ts
2000
- async function selectCourse(input, deps) {
2001
- deps.logger.info("tostudy-core: selectCourse", input);
2002
- return deps.data.courses.select(input.userId, input.courseId);
2163
+ async function selectCourse(input2, deps) {
2164
+ deps.logger.info("tostudy-core: selectCourse", input2);
2165
+ return deps.data.courses.select(input2.userId, input2.courseId);
2003
2166
  }
2004
2167
  var init_select_course = __esm({
2005
2168
  "../../packages/tostudy-core/src/courses/select-course.ts"() {
@@ -2008,9 +2171,9 @@ var init_select_course = __esm({
2008
2171
  });
2009
2172
 
2010
2173
  // ../../packages/tostudy-core/src/courses/get-progress.ts
2011
- async function getProgress(input, deps) {
2012
- deps.logger.info("tostudy-core: getProgress", input);
2013
- return deps.data.courses.getProgress(input.enrollmentId);
2174
+ async function getProgress(input2, deps) {
2175
+ deps.logger.info("tostudy-core: getProgress", input2);
2176
+ return deps.data.courses.getProgress(input2.enrollmentId);
2014
2177
  }
2015
2178
  var init_get_progress = __esm({
2016
2179
  "../../packages/tostudy-core/src/courses/get-progress.ts"() {
@@ -2272,9 +2435,9 @@ var init_progress = __esm({
2272
2435
  });
2273
2436
 
2274
2437
  // ../../packages/tostudy-core/src/lessons/next-lesson.ts
2275
- async function nextLesson(input, deps) {
2276
- deps.logger.info("tostudy-core: nextLesson", { enrollmentId: input.enrollmentId });
2277
- return deps.data.lessons.next(input.enrollmentId, input.userConfirmation);
2438
+ async function nextLesson(input2, deps) {
2439
+ deps.logger.info("tostudy-core: nextLesson", { enrollmentId: input2.enrollmentId });
2440
+ return deps.data.lessons.next(input2.enrollmentId, input2.userConfirmation);
2278
2441
  }
2279
2442
  var init_next_lesson = __esm({
2280
2443
  "../../packages/tostudy-core/src/lessons/next-lesson.ts"() {
@@ -2283,9 +2446,9 @@ var init_next_lesson = __esm({
2283
2446
  });
2284
2447
 
2285
2448
  // ../../packages/tostudy-core/src/lessons/get-content.ts
2286
- async function getContent(input, deps) {
2287
- deps.logger.info("tostudy-core: getContent", { lessonId: input.lessonId });
2288
- return deps.data.lessons.getContent(input.lessonId, input.enrollmentId);
2449
+ async function getContent(input2, deps) {
2450
+ deps.logger.info("tostudy-core: getContent", { lessonId: input2.lessonId });
2451
+ return deps.data.lessons.getContent(input2.lessonId, input2.enrollmentId);
2289
2452
  }
2290
2453
  var init_get_content = __esm({
2291
2454
  "../../packages/tostudy-core/src/lessons/get-content.ts"() {
@@ -2294,9 +2457,9 @@ var init_get_content = __esm({
2294
2457
  });
2295
2458
 
2296
2459
  // ../../packages/tostudy-core/src/lessons/get-hint.ts
2297
- async function getHint(input, deps) {
2298
- deps.logger.info("tostudy-core: getHint", { userId: input.userId });
2299
- return deps.data.lessons.getHint(input.userId, input.enrollmentId);
2460
+ async function getHint(input2, deps) {
2461
+ deps.logger.info("tostudy-core: getHint", { userId: input2.userId });
2462
+ return deps.data.lessons.getHint(input2.userId, input2.enrollmentId);
2300
2463
  }
2301
2464
  var init_get_hint = __esm({
2302
2465
  "../../packages/tostudy-core/src/lessons/get-hint.ts"() {
@@ -2305,9 +2468,9 @@ var init_get_hint = __esm({
2305
2468
  });
2306
2469
 
2307
2470
  // ../../packages/tostudy-core/src/lessons/start-module.ts
2308
- async function startModule(input, deps) {
2309
- deps.logger.info("tostudy-core: startModule", { enrollmentId: input.enrollmentId });
2310
- return deps.data.lessons.startModule(input.enrollmentId);
2471
+ async function startModule(input2, deps) {
2472
+ deps.logger.info("tostudy-core: startModule", { enrollmentId: input2.enrollmentId });
2473
+ return deps.data.lessons.startModule(input2.enrollmentId);
2311
2474
  }
2312
2475
  var init_start_module = __esm({
2313
2476
  "../../packages/tostudy-core/src/lessons/start-module.ts"() {
@@ -2316,9 +2479,9 @@ var init_start_module = __esm({
2316
2479
  });
2317
2480
 
2318
2481
  // ../../packages/tostudy-core/src/lessons/start-next-module.ts
2319
- async function startNextModule(input, deps) {
2320
- deps.logger.info("tostudy-core: startNextModule", { enrollmentId: input.enrollmentId });
2321
- return deps.data.lessons.startNextModule(input.enrollmentId);
2482
+ async function startNextModule(input2, deps) {
2483
+ deps.logger.info("tostudy-core: startNextModule", { enrollmentId: input2.enrollmentId });
2484
+ return deps.data.lessons.startNextModule(input2.enrollmentId);
2322
2485
  }
2323
2486
  var init_start_next_module = __esm({
2324
2487
  "../../packages/tostudy-core/src/lessons/start-next-module.ts"() {
@@ -2955,8 +3118,8 @@ var init_common = __esm({
2955
3118
  function isPgEnum(obj) {
2956
3119
  return !!obj && typeof obj === "function" && isPgEnumSym in obj && obj[isPgEnumSym] === true;
2957
3120
  }
2958
- function pgEnum(enumName, input) {
2959
- return Array.isArray(input) ? pgEnumWithSchema(enumName, [...input], void 0) : pgEnumObjectWithSchema(enumName, input, void 0);
3121
+ function pgEnum(enumName, input2) {
3122
+ return Array.isArray(input2) ? pgEnumWithSchema(enumName, [...input2], void 0) : pgEnumObjectWithSchema(enumName, input2, void 0);
2960
3123
  }
2961
3124
  function pgEnumWithSchema(enumName, values2, schema) {
2962
3125
  const enumInstance = Object.assign(
@@ -3817,7 +3980,7 @@ var init_query_promise = __esm({
3817
3980
  function mapResultRow(columns, row, joinsNotNullableMap) {
3818
3981
  const nullifyMap = {};
3819
3982
  const result = columns.reduce(
3820
- (result2, { path: path14, field }, columnIndex) => {
3983
+ (result2, { path: path15, field }, columnIndex) => {
3821
3984
  let decoder;
3822
3985
  if (is(field, Column)) {
3823
3986
  decoder = field;
@@ -3829,8 +3992,8 @@ function mapResultRow(columns, row, joinsNotNullableMap) {
3829
3992
  decoder = field.sql.decoder;
3830
3993
  }
3831
3994
  let node = result2;
3832
- for (const [pathChunkIndex, pathChunk] of path14.entries()) {
3833
- if (pathChunkIndex < path14.length - 1) {
3995
+ for (const [pathChunkIndex, pathChunk] of path15.entries()) {
3996
+ if (pathChunkIndex < path15.length - 1) {
3834
3997
  if (!(pathChunk in node)) {
3835
3998
  node[pathChunk] = {};
3836
3999
  }
@@ -3838,8 +4001,8 @@ function mapResultRow(columns, row, joinsNotNullableMap) {
3838
4001
  } else {
3839
4002
  const rawValue = row[columnIndex];
3840
4003
  const value = node[pathChunk] = rawValue === null ? null : decoder.mapFromDriverValue(rawValue);
3841
- if (joinsNotNullableMap && is(field, Column) && path14.length === 2) {
3842
- const objectName = path14[0];
4004
+ if (joinsNotNullableMap && is(field, Column) && path15.length === 2) {
4005
+ const objectName = path15[0];
3843
4006
  if (!(objectName in nullifyMap)) {
3844
4007
  nullifyMap[objectName] = value === null ? getTableName(field.table) : false;
3845
4008
  } else if (typeof nullifyMap[objectName] === "string" && nullifyMap[objectName] !== getTableName(field.table)) {
@@ -7786,13 +7949,13 @@ function Subscribe(postgres2, options) {
7786
7949
  }
7787
7950
  }
7788
7951
  function handle(a, b2) {
7789
- const path14 = b2.relation.schema + "." + b2.relation.table;
7952
+ const path15 = b2.relation.schema + "." + b2.relation.table;
7790
7953
  call("*", a, b2);
7791
- call("*:" + path14, a, b2);
7792
- b2.relation.keys.length && call("*:" + path14 + "=" + b2.relation.keys.map((x2) => a[x2.name]), a, b2);
7954
+ call("*:" + path15, a, b2);
7955
+ b2.relation.keys.length && call("*:" + path15 + "=" + b2.relation.keys.map((x2) => a[x2.name]), a, b2);
7793
7956
  call(b2.command, a, b2);
7794
- call(b2.command + ":" + path14, a, b2);
7795
- b2.relation.keys.length && call(b2.command + ":" + path14 + "=" + b2.relation.keys.map((x2) => a[x2.name]), a, b2);
7957
+ call(b2.command + ":" + path15, a, b2);
7958
+ b2.relation.keys.length && call(b2.command + ":" + path15 + "=" + b2.relation.keys.map((x2) => a[x2.name]), a, b2);
7796
7959
  }
7797
7960
  function pong() {
7798
7961
  const x2 = Buffer.alloc(34);
@@ -7905,8 +8068,8 @@ function parseEvent(x) {
7905
8068
  const xs = x.match(/^(\*|insert|update|delete)?:?([^.]+?\.?[^=]+)?=?(.+)?/i) || [];
7906
8069
  if (!xs)
7907
8070
  throw new Error("Malformed subscribe pattern: " + x);
7908
- const [, command, path14, key] = xs;
7909
- return (command || "*") + (path14 ? ":" + (path14.indexOf(".") === -1 ? "public." + path14 : path14) : "") + (key ? "=" + key : "");
8071
+ const [, command, path15, key] = xs;
8072
+ return (command || "*") + (path15 ? ":" + (path15.indexOf(".") === -1 ? "public." + path15 : path15) : "") + (key ? "=" + key : "");
7910
8073
  }
7911
8074
  var noop2;
7912
8075
  var init_subscribe = __esm({
@@ -7987,8 +8150,8 @@ var init_large = __esm({
7987
8150
  });
7988
8151
 
7989
8152
  // ../../node_modules/postgres/src/index.js
7990
- import os5 from "os";
7991
- import fs5 from "fs";
8153
+ import os6 from "os";
8154
+ import fs7 from "fs";
7992
8155
  function Postgres(a, b2) {
7993
8156
  const options = parseOptions(a, b2), subscribe = options.no_subscribe || Subscribe(Postgres, { ...options });
7994
8157
  let ending = false;
@@ -8044,10 +8207,10 @@ function Postgres(a, b2) {
8044
8207
  });
8045
8208
  return query;
8046
8209
  }
8047
- function file2(path14, args = [], options2 = {}) {
8210
+ function file2(path15, args = [], options2 = {}) {
8048
8211
  arguments.length === 2 && !Array.isArray(args) && (options2 = args, args = []);
8049
8212
  const query = new Query([], args, (query2) => {
8050
- fs5.readFile(path14, "utf8", (err, string4) => {
8213
+ fs7.readFile(path15, "utf8", (err, string4) => {
8051
8214
  if (err)
8052
8215
  return query2.reject(err);
8053
8216
  query2.strings = [string4];
@@ -8365,7 +8528,7 @@ function parseUrl(url2) {
8365
8528
  }
8366
8529
  function osUsername() {
8367
8530
  try {
8368
- return os5.userInfo().username;
8531
+ return os6.userInfo().username;
8369
8532
  } catch (_) {
8370
8533
  return process.env.USERNAME || process.env.USER || process.env.LOGNAME;
8371
8534
  }
@@ -8717,19 +8880,19 @@ var init_view_common2 = __esm({
8717
8880
  });
8718
8881
 
8719
8882
  // ../../node_modules/drizzle-orm/casing.js
8720
- function toSnakeCase(input) {
8721
- const words = input.replace(/['\u2019]/g, "").match(/[\da-z]+|[A-Z]+(?![a-z])|[A-Z][\da-z]+/g) ?? [];
8883
+ function toSnakeCase(input2) {
8884
+ const words = input2.replace(/['\u2019]/g, "").match(/[\da-z]+|[A-Z]+(?![a-z])|[A-Z][\da-z]+/g) ?? [];
8722
8885
  return words.map((word) => word.toLowerCase()).join("_");
8723
8886
  }
8724
- function toCamelCase(input) {
8725
- const words = input.replace(/['\u2019]/g, "").match(/[\da-z]+|[A-Z]+(?![a-z])|[A-Z][\da-z]+/g) ?? [];
8887
+ function toCamelCase(input2) {
8888
+ const words = input2.replace(/['\u2019]/g, "").match(/[\da-z]+|[A-Z]+(?![a-z])|[A-Z][\da-z]+/g) ?? [];
8726
8889
  return words.reduce((acc, word, i) => {
8727
8890
  const formattedWord = i === 0 ? word.toLowerCase() : `${word[0].toUpperCase()}${word.slice(1)}`;
8728
8891
  return acc + formattedWord;
8729
8892
  }, "");
8730
8893
  }
8731
- function noopCase(input) {
8732
- return input;
8894
+ function noopCase(input2) {
8895
+ return input2;
8733
8896
  }
8734
8897
  var CasingCache;
8735
8898
  var init_casing = __esm({
@@ -12382,12 +12545,12 @@ var init_schema = __esm({
12382
12545
  materializedView = (name, columns) => {
12383
12546
  return pgMaterializedViewWithSchema(name, columns, this.schemaName);
12384
12547
  };
12385
- enum(enumName, input) {
12386
- return Array.isArray(input) ? pgEnumWithSchema(
12548
+ enum(enumName, input2) {
12549
+ return Array.isArray(input2) ? pgEnumWithSchema(
12387
12550
  enumName,
12388
- [...input],
12551
+ [...input2],
12389
12552
  this.schemaName
12390
- ) : pgEnumObjectWithSchema(enumName, input, this.schemaName);
12553
+ ) : pgEnumObjectWithSchema(enumName, input2, this.schemaName);
12391
12554
  }
12392
12555
  sequence = (name, options) => {
12393
12556
  return pgSequenceWithSchema(name, options, this.schemaName);
@@ -13038,8 +13201,8 @@ function cached(getter) {
13038
13201
  }
13039
13202
  };
13040
13203
  }
13041
- function nullish(input) {
13042
- return input === null || input === void 0;
13204
+ function nullish(input2) {
13205
+ return input2 === null || input2 === void 0;
13043
13206
  }
13044
13207
  function cleanRegex(source) {
13045
13208
  const start = source.startsWith("^") ? 1 : 0;
@@ -13105,10 +13268,10 @@ function mergeDefs(...defs) {
13105
13268
  function cloneDef(schema) {
13106
13269
  return mergeDefs(schema._zod.def);
13107
13270
  }
13108
- function getElementAtPath(obj, path14) {
13109
- if (!path14)
13271
+ function getElementAtPath(obj, path15) {
13272
+ if (!path15)
13110
13273
  return obj;
13111
- return path14.reduce((acc, key) => acc?.[key], obj);
13274
+ return path15.reduce((acc, key) => acc?.[key], obj);
13112
13275
  }
13113
13276
  function promiseAllObject(promisesObj) {
13114
13277
  const keys = Object.keys(promisesObj);
@@ -13132,8 +13295,8 @@ function randomString(length = 10) {
13132
13295
  function esc(str) {
13133
13296
  return JSON.stringify(str);
13134
13297
  }
13135
- function slugify(input) {
13136
- return input.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
13298
+ function slugify(input2) {
13299
+ return input2.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
13137
13300
  }
13138
13301
  function isObject(data) {
13139
13302
  return typeof data === "object" && data !== null && !Array.isArray(data);
@@ -13420,11 +13583,11 @@ function aborted(x, startIndex = 0) {
13420
13583
  }
13421
13584
  return false;
13422
13585
  }
13423
- function prefixIssues(path14, issues) {
13586
+ function prefixIssues(path15, issues) {
13424
13587
  return issues.map((iss) => {
13425
13588
  var _a2;
13426
13589
  (_a2 = iss).path ?? (_a2.path = []);
13427
- iss.path.unshift(path14);
13590
+ iss.path.unshift(path15);
13428
13591
  return iss;
13429
13592
  });
13430
13593
  }
@@ -13444,19 +13607,19 @@ function finalizeIssue(iss, ctx, config2) {
13444
13607
  }
13445
13608
  return full;
13446
13609
  }
13447
- function getSizableOrigin(input) {
13448
- if (input instanceof Set)
13610
+ function getSizableOrigin(input2) {
13611
+ if (input2 instanceof Set)
13449
13612
  return "set";
13450
- if (input instanceof Map)
13613
+ if (input2 instanceof Map)
13451
13614
  return "map";
13452
- if (input instanceof File)
13615
+ if (input2 instanceof File)
13453
13616
  return "file";
13454
13617
  return "unknown";
13455
13618
  }
13456
- function getLengthableOrigin(input) {
13457
- if (Array.isArray(input))
13619
+ function getLengthableOrigin(input2) {
13620
+ if (Array.isArray(input2))
13458
13621
  return "array";
13459
- if (typeof input === "string")
13622
+ if (typeof input2 === "string")
13460
13623
  return "string";
13461
13624
  return "unknown";
13462
13625
  }
@@ -13482,12 +13645,12 @@ function parsedType(data) {
13482
13645
  return t;
13483
13646
  }
13484
13647
  function issue(...args) {
13485
- const [iss, input, inst] = args;
13648
+ const [iss, input2, inst] = args;
13486
13649
  if (typeof iss === "string") {
13487
13650
  return {
13488
13651
  message: iss,
13489
13652
  code: "custom",
13490
- input,
13653
+ input: input2,
13491
13654
  inst
13492
13655
  };
13493
13656
  }
@@ -13666,7 +13829,7 @@ function formatError(error49, mapper = (issue2) => issue2.message) {
13666
13829
  }
13667
13830
  function treeifyError(error49, mapper = (issue2) => issue2.message) {
13668
13831
  const result = { errors: [] };
13669
- const processError = (error50, path14 = []) => {
13832
+ const processError = (error50, path15 = []) => {
13670
13833
  var _a2, _b;
13671
13834
  for (const issue2 of error50.issues) {
13672
13835
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -13676,7 +13839,7 @@ function treeifyError(error49, mapper = (issue2) => issue2.message) {
13676
13839
  } else if (issue2.code === "invalid_element") {
13677
13840
  processError({ issues: issue2.issues }, issue2.path);
13678
13841
  } else {
13679
- const fullpath = [...path14, ...issue2.path];
13842
+ const fullpath = [...path15, ...issue2.path];
13680
13843
  if (fullpath.length === 0) {
13681
13844
  result.errors.push(mapper(issue2));
13682
13845
  continue;
@@ -13708,8 +13871,8 @@ function treeifyError(error49, mapper = (issue2) => issue2.message) {
13708
13871
  }
13709
13872
  function toDotPath(_path) {
13710
13873
  const segs = [];
13711
- const path14 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
13712
- for (const seg of path14) {
13874
+ const path15 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
13875
+ for (const seg of path15) {
13713
13876
  if (typeof seg === "number")
13714
13877
  segs.push(`[${seg}]`);
13715
13878
  else if (typeof seg === "symbol")
@@ -14135,23 +14298,23 @@ var init_checks2 = __esm({
14135
14298
  bag.pattern = integer2;
14136
14299
  });
14137
14300
  inst._zod.check = (payload) => {
14138
- const input = payload.value;
14301
+ const input2 = payload.value;
14139
14302
  if (isInt) {
14140
- if (!Number.isInteger(input)) {
14303
+ if (!Number.isInteger(input2)) {
14141
14304
  payload.issues.push({
14142
14305
  expected: origin,
14143
14306
  format: def.format,
14144
14307
  code: "invalid_type",
14145
14308
  continue: false,
14146
- input,
14309
+ input: input2,
14147
14310
  inst
14148
14311
  });
14149
14312
  return;
14150
14313
  }
14151
- if (!Number.isSafeInteger(input)) {
14152
- if (input > 0) {
14314
+ if (!Number.isSafeInteger(input2)) {
14315
+ if (input2 > 0) {
14153
14316
  payload.issues.push({
14154
- input,
14317
+ input: input2,
14155
14318
  code: "too_big",
14156
14319
  maximum: Number.MAX_SAFE_INTEGER,
14157
14320
  note: "Integers must be within the safe integer range.",
@@ -14162,7 +14325,7 @@ var init_checks2 = __esm({
14162
14325
  });
14163
14326
  } else {
14164
14327
  payload.issues.push({
14165
- input,
14328
+ input: input2,
14166
14329
  code: "too_small",
14167
14330
  minimum: Number.MIN_SAFE_INTEGER,
14168
14331
  note: "Integers must be within the safe integer range.",
@@ -14175,10 +14338,10 @@ var init_checks2 = __esm({
14175
14338
  return;
14176
14339
  }
14177
14340
  }
14178
- if (input < minimum) {
14341
+ if (input2 < minimum) {
14179
14342
  payload.issues.push({
14180
14343
  origin: "number",
14181
- input,
14344
+ input: input2,
14182
14345
  code: "too_small",
14183
14346
  minimum,
14184
14347
  inclusive: true,
@@ -14186,10 +14349,10 @@ var init_checks2 = __esm({
14186
14349
  continue: !def.abort
14187
14350
  });
14188
14351
  }
14189
- if (input > maximum) {
14352
+ if (input2 > maximum) {
14190
14353
  payload.issues.push({
14191
14354
  origin: "number",
14192
- input,
14355
+ input: input2,
14193
14356
  code: "too_big",
14194
14357
  maximum,
14195
14358
  inclusive: true,
@@ -14209,11 +14372,11 @@ var init_checks2 = __esm({
14209
14372
  bag.maximum = maximum;
14210
14373
  });
14211
14374
  inst._zod.check = (payload) => {
14212
- const input = payload.value;
14213
- if (input < minimum) {
14375
+ const input2 = payload.value;
14376
+ if (input2 < minimum) {
14214
14377
  payload.issues.push({
14215
14378
  origin: "bigint",
14216
- input,
14379
+ input: input2,
14217
14380
  code: "too_small",
14218
14381
  minimum,
14219
14382
  inclusive: true,
@@ -14221,10 +14384,10 @@ var init_checks2 = __esm({
14221
14384
  continue: !def.abort
14222
14385
  });
14223
14386
  }
14224
- if (input > maximum) {
14387
+ if (input2 > maximum) {
14225
14388
  payload.issues.push({
14226
14389
  origin: "bigint",
14227
- input,
14390
+ input: input2,
14228
14391
  code: "too_big",
14229
14392
  maximum,
14230
14393
  inclusive: true,
@@ -14247,16 +14410,16 @@ var init_checks2 = __esm({
14247
14410
  inst2._zod.bag.maximum = def.maximum;
14248
14411
  });
14249
14412
  inst._zod.check = (payload) => {
14250
- const input = payload.value;
14251
- const size2 = input.size;
14413
+ const input2 = payload.value;
14414
+ const size2 = input2.size;
14252
14415
  if (size2 <= def.maximum)
14253
14416
  return;
14254
14417
  payload.issues.push({
14255
- origin: getSizableOrigin(input),
14418
+ origin: getSizableOrigin(input2),
14256
14419
  code: "too_big",
14257
14420
  maximum: def.maximum,
14258
14421
  inclusive: true,
14259
- input,
14422
+ input: input2,
14260
14423
  inst,
14261
14424
  continue: !def.abort
14262
14425
  });
@@ -14275,16 +14438,16 @@ var init_checks2 = __esm({
14275
14438
  inst2._zod.bag.minimum = def.minimum;
14276
14439
  });
14277
14440
  inst._zod.check = (payload) => {
14278
- const input = payload.value;
14279
- const size2 = input.size;
14441
+ const input2 = payload.value;
14442
+ const size2 = input2.size;
14280
14443
  if (size2 >= def.minimum)
14281
14444
  return;
14282
14445
  payload.issues.push({
14283
- origin: getSizableOrigin(input),
14446
+ origin: getSizableOrigin(input2),
14284
14447
  code: "too_small",
14285
14448
  minimum: def.minimum,
14286
14449
  inclusive: true,
14287
- input,
14450
+ input: input2,
14288
14451
  inst,
14289
14452
  continue: !def.abort
14290
14453
  });
@@ -14304,13 +14467,13 @@ var init_checks2 = __esm({
14304
14467
  bag.size = def.size;
14305
14468
  });
14306
14469
  inst._zod.check = (payload) => {
14307
- const input = payload.value;
14308
- const size2 = input.size;
14470
+ const input2 = payload.value;
14471
+ const size2 = input2.size;
14309
14472
  if (size2 === def.size)
14310
14473
  return;
14311
14474
  const tooBig = size2 > def.size;
14312
14475
  payload.issues.push({
14313
- origin: getSizableOrigin(input),
14476
+ origin: getSizableOrigin(input2),
14314
14477
  ...tooBig ? { code: "too_big", maximum: def.size } : { code: "too_small", minimum: def.size },
14315
14478
  inclusive: true,
14316
14479
  exact: true,
@@ -14333,17 +14496,17 @@ var init_checks2 = __esm({
14333
14496
  inst2._zod.bag.maximum = def.maximum;
14334
14497
  });
14335
14498
  inst._zod.check = (payload) => {
14336
- const input = payload.value;
14337
- const length = input.length;
14499
+ const input2 = payload.value;
14500
+ const length = input2.length;
14338
14501
  if (length <= def.maximum)
14339
14502
  return;
14340
- const origin = getLengthableOrigin(input);
14503
+ const origin = getLengthableOrigin(input2);
14341
14504
  payload.issues.push({
14342
14505
  origin,
14343
14506
  code: "too_big",
14344
14507
  maximum: def.maximum,
14345
14508
  inclusive: true,
14346
- input,
14509
+ input: input2,
14347
14510
  inst,
14348
14511
  continue: !def.abort
14349
14512
  });
@@ -14362,17 +14525,17 @@ var init_checks2 = __esm({
14362
14525
  inst2._zod.bag.minimum = def.minimum;
14363
14526
  });
14364
14527
  inst._zod.check = (payload) => {
14365
- const input = payload.value;
14366
- const length = input.length;
14528
+ const input2 = payload.value;
14529
+ const length = input2.length;
14367
14530
  if (length >= def.minimum)
14368
14531
  return;
14369
- const origin = getLengthableOrigin(input);
14532
+ const origin = getLengthableOrigin(input2);
14370
14533
  payload.issues.push({
14371
14534
  origin,
14372
14535
  code: "too_small",
14373
14536
  minimum: def.minimum,
14374
14537
  inclusive: true,
14375
- input,
14538
+ input: input2,
14376
14539
  inst,
14377
14540
  continue: !def.abort
14378
14541
  });
@@ -14392,11 +14555,11 @@ var init_checks2 = __esm({
14392
14555
  bag.length = def.length;
14393
14556
  });
14394
14557
  inst._zod.check = (payload) => {
14395
- const input = payload.value;
14396
- const length = input.length;
14558
+ const input2 = payload.value;
14559
+ const length = input2.length;
14397
14560
  if (length === def.length)
14398
14561
  return;
14399
- const origin = getLengthableOrigin(input);
14562
+ const origin = getLengthableOrigin(input2);
14400
14563
  const tooBig = length > def.length;
14401
14564
  payload.issues.push({
14402
14565
  origin,
@@ -14674,15 +14837,15 @@ function handleArrayResult(result, final, index2) {
14674
14837
  }
14675
14838
  final.value[index2] = result.value;
14676
14839
  }
14677
- function handlePropertyResult(result, final, key, input, isOptionalOut) {
14840
+ function handlePropertyResult(result, final, key, input2, isOptionalOut) {
14678
14841
  if (result.issues.length) {
14679
- if (isOptionalOut && !(key in input)) {
14842
+ if (isOptionalOut && !(key in input2)) {
14680
14843
  return;
14681
14844
  }
14682
14845
  final.issues.push(...prefixIssues(key, result.issues));
14683
14846
  }
14684
14847
  if (result.value === void 0) {
14685
- if (key in input) {
14848
+ if (key in input2) {
14686
14849
  final.value[key] = void 0;
14687
14850
  }
14688
14851
  } else {
@@ -14705,31 +14868,31 @@ function normalizeDef(def) {
14705
14868
  optionalKeys: new Set(okeys)
14706
14869
  };
14707
14870
  }
14708
- function handleCatchall(proms, input, payload, ctx, def, inst) {
14871
+ function handleCatchall(proms, input2, payload, ctx, def, inst) {
14709
14872
  const unrecognized = [];
14710
14873
  const keySet = def.keySet;
14711
14874
  const _catchall = def.catchall._zod;
14712
14875
  const t = _catchall.def.type;
14713
14876
  const isOptionalOut = _catchall.optout === "optional";
14714
- for (const key in input) {
14877
+ for (const key in input2) {
14715
14878
  if (keySet.has(key))
14716
14879
  continue;
14717
14880
  if (t === "never") {
14718
14881
  unrecognized.push(key);
14719
14882
  continue;
14720
14883
  }
14721
- const r = _catchall.run({ value: input[key], issues: [] }, ctx);
14884
+ const r = _catchall.run({ value: input2[key], issues: [] }, ctx);
14722
14885
  if (r instanceof Promise) {
14723
- proms.push(r.then((r2) => handlePropertyResult(r2, payload, key, input, isOptionalOut)));
14886
+ proms.push(r.then((r2) => handlePropertyResult(r2, payload, key, input2, isOptionalOut)));
14724
14887
  } else {
14725
- handlePropertyResult(r, payload, key, input, isOptionalOut);
14888
+ handlePropertyResult(r, payload, key, input2, isOptionalOut);
14726
14889
  }
14727
14890
  }
14728
14891
  if (unrecognized.length) {
14729
14892
  payload.issues.push({
14730
14893
  code: "unrecognized_keys",
14731
14894
  keys: unrecognized,
14732
- input,
14895
+ input: input2,
14733
14896
  inst
14734
14897
  });
14735
14898
  }
@@ -14872,7 +15035,7 @@ function handleTupleResult(result, final, index2) {
14872
15035
  }
14873
15036
  final.value[index2] = result.value;
14874
15037
  }
14875
- function handleMapResult(keyResult, valueResult, final, key, input, inst, ctx) {
15038
+ function handleMapResult(keyResult, valueResult, final, key, input2, inst, ctx) {
14876
15039
  if (keyResult.issues.length) {
14877
15040
  if (propertyKeyTypes.has(typeof key)) {
14878
15041
  final.issues.push(...prefixIssues(key, keyResult.issues));
@@ -14880,7 +15043,7 @@ function handleMapResult(keyResult, valueResult, final, key, input, inst, ctx) {
14880
15043
  final.issues.push({
14881
15044
  code: "invalid_key",
14882
15045
  origin: "map",
14883
- input,
15046
+ input: input2,
14884
15047
  inst,
14885
15048
  issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config()))
14886
15049
  });
@@ -14893,7 +15056,7 @@ function handleMapResult(keyResult, valueResult, final, key, input, inst, ctx) {
14893
15056
  final.issues.push({
14894
15057
  origin: "map",
14895
15058
  code: "invalid_element",
14896
- input,
15059
+ input: input2,
14897
15060
  inst,
14898
15061
  key,
14899
15062
  issues: valueResult.issues.map((iss) => finalizeIssue(iss, ctx, config()))
@@ -14908,8 +15071,8 @@ function handleSetResult(result, final) {
14908
15071
  }
14909
15072
  final.value.add(result.value);
14910
15073
  }
14911
- function handleOptionalResult(result, input) {
14912
- if (result.issues.length && input === void 0) {
15074
+ function handleOptionalResult(result, input2) {
15075
+ if (result.issues.length && input2 === void 0) {
14913
15076
  return { issues: [], value: void 0 };
14914
15077
  }
14915
15078
  return result;
@@ -14969,11 +15132,11 @@ function handleReadonlyResult(payload) {
14969
15132
  payload.value = Object.freeze(payload.value);
14970
15133
  return payload;
14971
15134
  }
14972
- function handleRefineResult(result, payload, input, inst) {
15135
+ function handleRefineResult(result, payload, input2, inst) {
14973
15136
  if (!result) {
14974
15137
  const _iss = {
14975
15138
  code: "custom",
14976
- input,
15139
+ input: input2,
14977
15140
  inst,
14978
15141
  // incorporates params.error into issue reporting
14979
15142
  path: [...inst._zod.def.path ?? []],
@@ -15386,15 +15549,15 @@ var init_schemas = __esm({
15386
15549
  payload.value = Number(payload.value);
15387
15550
  } catch (_) {
15388
15551
  }
15389
- const input = payload.value;
15390
- if (typeof input === "number" && !Number.isNaN(input) && Number.isFinite(input)) {
15552
+ const input2 = payload.value;
15553
+ if (typeof input2 === "number" && !Number.isNaN(input2) && Number.isFinite(input2)) {
15391
15554
  return payload;
15392
15555
  }
15393
- const received = typeof input === "number" ? Number.isNaN(input) ? "NaN" : !Number.isFinite(input) ? "Infinity" : void 0 : void 0;
15556
+ const received = typeof input2 === "number" ? Number.isNaN(input2) ? "NaN" : !Number.isFinite(input2) ? "Infinity" : void 0 : void 0;
15394
15557
  payload.issues.push({
15395
15558
  expected: "number",
15396
15559
  code: "invalid_type",
15397
- input,
15560
+ input: input2,
15398
15561
  inst,
15399
15562
  ...received ? { received } : {}
15400
15563
  });
@@ -15414,13 +15577,13 @@ var init_schemas = __esm({
15414
15577
  payload.value = Boolean(payload.value);
15415
15578
  } catch (_) {
15416
15579
  }
15417
- const input = payload.value;
15418
- if (typeof input === "boolean")
15580
+ const input2 = payload.value;
15581
+ if (typeof input2 === "boolean")
15419
15582
  return payload;
15420
15583
  payload.issues.push({
15421
15584
  expected: "boolean",
15422
15585
  code: "invalid_type",
15423
- input,
15586
+ input: input2,
15424
15587
  inst
15425
15588
  });
15426
15589
  return payload;
@@ -15453,13 +15616,13 @@ var init_schemas = __esm({
15453
15616
  $ZodSymbol = /* @__PURE__ */ $constructor("$ZodSymbol", (inst, def) => {
15454
15617
  $ZodType.init(inst, def);
15455
15618
  inst._zod.parse = (payload, _ctx) => {
15456
- const input = payload.value;
15457
- if (typeof input === "symbol")
15619
+ const input2 = payload.value;
15620
+ if (typeof input2 === "symbol")
15458
15621
  return payload;
15459
15622
  payload.issues.push({
15460
15623
  expected: "symbol",
15461
15624
  code: "invalid_type",
15462
- input,
15625
+ input: input2,
15463
15626
  inst
15464
15627
  });
15465
15628
  return payload;
@@ -15472,13 +15635,13 @@ var init_schemas = __esm({
15472
15635
  inst._zod.optin = "optional";
15473
15636
  inst._zod.optout = "optional";
15474
15637
  inst._zod.parse = (payload, _ctx) => {
15475
- const input = payload.value;
15476
- if (typeof input === "undefined")
15638
+ const input2 = payload.value;
15639
+ if (typeof input2 === "undefined")
15477
15640
  return payload;
15478
15641
  payload.issues.push({
15479
15642
  expected: "undefined",
15480
15643
  code: "invalid_type",
15481
- input,
15644
+ input: input2,
15482
15645
  inst
15483
15646
  });
15484
15647
  return payload;
@@ -15489,13 +15652,13 @@ var init_schemas = __esm({
15489
15652
  inst._zod.pattern = _null;
15490
15653
  inst._zod.values = /* @__PURE__ */ new Set([null]);
15491
15654
  inst._zod.parse = (payload, _ctx) => {
15492
- const input = payload.value;
15493
- if (input === null)
15655
+ const input2 = payload.value;
15656
+ if (input2 === null)
15494
15657
  return payload;
15495
15658
  payload.issues.push({
15496
15659
  expected: "null",
15497
15660
  code: "invalid_type",
15498
- input,
15661
+ input: input2,
15499
15662
  inst
15500
15663
  });
15501
15664
  return payload;
@@ -15524,13 +15687,13 @@ var init_schemas = __esm({
15524
15687
  $ZodVoid = /* @__PURE__ */ $constructor("$ZodVoid", (inst, def) => {
15525
15688
  $ZodType.init(inst, def);
15526
15689
  inst._zod.parse = (payload, _ctx) => {
15527
- const input = payload.value;
15528
- if (typeof input === "undefined")
15690
+ const input2 = payload.value;
15691
+ if (typeof input2 === "undefined")
15529
15692
  return payload;
15530
15693
  payload.issues.push({
15531
15694
  expected: "void",
15532
15695
  code: "invalid_type",
15533
- input,
15696
+ input: input2,
15534
15697
  inst
15535
15698
  });
15536
15699
  return payload;
@@ -15545,15 +15708,15 @@ var init_schemas = __esm({
15545
15708
  } catch (_err) {
15546
15709
  }
15547
15710
  }
15548
- const input = payload.value;
15549
- const isDate = input instanceof Date;
15550
- const isValidDate = isDate && !Number.isNaN(input.getTime());
15711
+ const input2 = payload.value;
15712
+ const isDate = input2 instanceof Date;
15713
+ const isValidDate = isDate && !Number.isNaN(input2.getTime());
15551
15714
  if (isValidDate)
15552
15715
  return payload;
15553
15716
  payload.issues.push({
15554
15717
  expected: "date",
15555
15718
  code: "invalid_type",
15556
- input,
15719
+ input: input2,
15557
15720
  ...isDate ? { received: "Invalid Date" } : {},
15558
15721
  inst
15559
15722
  });
@@ -15563,20 +15726,20 @@ var init_schemas = __esm({
15563
15726
  $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
15564
15727
  $ZodType.init(inst, def);
15565
15728
  inst._zod.parse = (payload, ctx) => {
15566
- const input = payload.value;
15567
- if (!Array.isArray(input)) {
15729
+ const input2 = payload.value;
15730
+ if (!Array.isArray(input2)) {
15568
15731
  payload.issues.push({
15569
15732
  expected: "array",
15570
15733
  code: "invalid_type",
15571
- input,
15734
+ input: input2,
15572
15735
  inst
15573
15736
  });
15574
15737
  return payload;
15575
15738
  }
15576
- payload.value = Array(input.length);
15739
+ payload.value = Array(input2.length);
15577
15740
  const proms = [];
15578
- for (let i = 0; i < input.length; i++) {
15579
- const item = input[i];
15741
+ for (let i = 0; i < input2.length; i++) {
15742
+ const item = input2[i];
15580
15743
  const result = def.element._zod.run({
15581
15744
  value: item,
15582
15745
  issues: []
@@ -15627,12 +15790,12 @@ var init_schemas = __esm({
15627
15790
  let value;
15628
15791
  inst._zod.parse = (payload, ctx) => {
15629
15792
  value ?? (value = _normalized.value);
15630
- const input = payload.value;
15631
- if (!isObject2(input)) {
15793
+ const input2 = payload.value;
15794
+ if (!isObject2(input2)) {
15632
15795
  payload.issues.push({
15633
15796
  expected: "object",
15634
15797
  code: "invalid_type",
15635
- input,
15798
+ input: input2,
15636
15799
  inst
15637
15800
  });
15638
15801
  return payload;
@@ -15643,17 +15806,17 @@ var init_schemas = __esm({
15643
15806
  for (const key of value.keys) {
15644
15807
  const el = shape[key];
15645
15808
  const isOptionalOut = el._zod.optout === "optional";
15646
- const r = el._zod.run({ value: input[key], issues: [] }, ctx);
15809
+ const r = el._zod.run({ value: input2[key], issues: [] }, ctx);
15647
15810
  if (r instanceof Promise) {
15648
- proms.push(r.then((r2) => handlePropertyResult(r2, payload, key, input, isOptionalOut)));
15811
+ proms.push(r.then((r2) => handlePropertyResult(r2, payload, key, input2, isOptionalOut)));
15649
15812
  } else {
15650
- handlePropertyResult(r, payload, key, input, isOptionalOut);
15813
+ handlePropertyResult(r, payload, key, input2, isOptionalOut);
15651
15814
  }
15652
15815
  }
15653
15816
  if (!catchall) {
15654
15817
  return proms.length ? Promise.all(proms).then(() => payload) : payload;
15655
15818
  }
15656
- return handleCatchall(proms, input, payload, ctx, _normalized.value, inst);
15819
+ return handleCatchall(proms, input2, payload, ctx, _normalized.value, inst);
15657
15820
  };
15658
15821
  });
15659
15822
  $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) => {
@@ -15734,12 +15897,12 @@ var init_schemas = __esm({
15734
15897
  let value;
15735
15898
  inst._zod.parse = (payload, ctx) => {
15736
15899
  value ?? (value = _normalized.value);
15737
- const input = payload.value;
15738
- if (!isObject2(input)) {
15900
+ const input2 = payload.value;
15901
+ if (!isObject2(input2)) {
15739
15902
  payload.issues.push({
15740
15903
  expected: "object",
15741
15904
  code: "invalid_type",
15742
- input,
15905
+ input: input2,
15743
15906
  inst
15744
15907
  });
15745
15908
  return payload;
@@ -15750,7 +15913,7 @@ var init_schemas = __esm({
15750
15913
  payload = fastpass(payload, ctx);
15751
15914
  if (!catchall)
15752
15915
  return payload;
15753
- return handleCatchall([], input, payload, ctx, value, inst);
15916
+ return handleCatchall([], input2, payload, ctx, value, inst);
15754
15917
  }
15755
15918
  return superParse(payload, ctx);
15756
15919
  };
@@ -15868,17 +16031,17 @@ var init_schemas = __esm({
15868
16031
  return map2;
15869
16032
  });
15870
16033
  inst._zod.parse = (payload, ctx) => {
15871
- const input = payload.value;
15872
- if (!isObject(input)) {
16034
+ const input2 = payload.value;
16035
+ if (!isObject(input2)) {
15873
16036
  payload.issues.push({
15874
16037
  code: "invalid_type",
15875
16038
  expected: "object",
15876
- input,
16039
+ input: input2,
15877
16040
  inst
15878
16041
  });
15879
16042
  return payload;
15880
16043
  }
15881
- const opt = disc.value.get(input?.[def.discriminator]);
16044
+ const opt = disc.value.get(input2?.[def.discriminator]);
15882
16045
  if (opt) {
15883
16046
  return opt._zod.run(payload, ctx);
15884
16047
  }
@@ -15890,7 +16053,7 @@ var init_schemas = __esm({
15890
16053
  errors: [],
15891
16054
  note: "No matching discriminator",
15892
16055
  discriminator: def.discriminator,
15893
- input,
16056
+ input: input2,
15894
16057
  path: [def.discriminator],
15895
16058
  inst
15896
16059
  });
@@ -15900,9 +16063,9 @@ var init_schemas = __esm({
15900
16063
  $ZodIntersection = /* @__PURE__ */ $constructor("$ZodIntersection", (inst, def) => {
15901
16064
  $ZodType.init(inst, def);
15902
16065
  inst._zod.parse = (payload, ctx) => {
15903
- const input = payload.value;
15904
- const left = def.left._zod.run({ value: input, issues: [] }, ctx);
15905
- const right = def.right._zod.run({ value: input, issues: [] }, ctx);
16066
+ const input2 = payload.value;
16067
+ const left = def.left._zod.run({ value: input2, issues: [] }, ctx);
16068
+ const right = def.right._zod.run({ value: input2, issues: [] }, ctx);
15906
16069
  const async = left instanceof Promise || right instanceof Promise;
15907
16070
  if (async) {
15908
16071
  return Promise.all([left, right]).then(([left2, right2]) => {
@@ -15916,10 +16079,10 @@ var init_schemas = __esm({
15916
16079
  $ZodType.init(inst, def);
15917
16080
  const items = def.items;
15918
16081
  inst._zod.parse = (payload, ctx) => {
15919
- const input = payload.value;
15920
- if (!Array.isArray(input)) {
16082
+ const input2 = payload.value;
16083
+ if (!Array.isArray(input2)) {
15921
16084
  payload.issues.push({
15922
- input,
16085
+ input: input2,
15923
16086
  inst,
15924
16087
  expected: "tuple",
15925
16088
  code: "invalid_type"
@@ -15931,12 +16094,12 @@ var init_schemas = __esm({
15931
16094
  const reversedIndex = [...items].reverse().findIndex((item) => item._zod.optin !== "optional");
15932
16095
  const optStart = reversedIndex === -1 ? 0 : items.length - reversedIndex;
15933
16096
  if (!def.rest) {
15934
- const tooBig = input.length > items.length;
15935
- const tooSmall = input.length < optStart - 1;
16097
+ const tooBig = input2.length > items.length;
16098
+ const tooSmall = input2.length < optStart - 1;
15936
16099
  if (tooBig || tooSmall) {
15937
16100
  payload.issues.push({
15938
16101
  ...tooBig ? { code: "too_big", maximum: items.length, inclusive: true } : { code: "too_small", minimum: items.length },
15939
- input,
16102
+ input: input2,
15940
16103
  inst,
15941
16104
  origin: "array"
15942
16105
  });
@@ -15946,12 +16109,12 @@ var init_schemas = __esm({
15946
16109
  let i = -1;
15947
16110
  for (const item of items) {
15948
16111
  i++;
15949
- if (i >= input.length) {
16112
+ if (i >= input2.length) {
15950
16113
  if (i >= optStart)
15951
16114
  continue;
15952
16115
  }
15953
16116
  const result = item._zod.run({
15954
- value: input[i],
16117
+ value: input2[i],
15955
16118
  issues: []
15956
16119
  }, ctx);
15957
16120
  if (result instanceof Promise) {
@@ -15961,7 +16124,7 @@ var init_schemas = __esm({
15961
16124
  }
15962
16125
  }
15963
16126
  if (def.rest) {
15964
- const rest = input.slice(items.length);
16127
+ const rest = input2.slice(items.length);
15965
16128
  for (const el of rest) {
15966
16129
  i++;
15967
16130
  const result = def.rest._zod.run({
@@ -15983,12 +16146,12 @@ var init_schemas = __esm({
15983
16146
  $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
15984
16147
  $ZodType.init(inst, def);
15985
16148
  inst._zod.parse = (payload, ctx) => {
15986
- const input = payload.value;
15987
- if (!isPlainObject(input)) {
16149
+ const input2 = payload.value;
16150
+ if (!isPlainObject(input2)) {
15988
16151
  payload.issues.push({
15989
16152
  expected: "record",
15990
16153
  code: "invalid_type",
15991
- input,
16154
+ input: input2,
15992
16155
  inst
15993
16156
  });
15994
16157
  return payload;
@@ -16001,7 +16164,7 @@ var init_schemas = __esm({
16001
16164
  for (const key of values2) {
16002
16165
  if (typeof key === "string" || typeof key === "number" || typeof key === "symbol") {
16003
16166
  recordKeys.add(typeof key === "number" ? key.toString() : key);
16004
- const result = def.valueType._zod.run({ value: input[key], issues: [] }, ctx);
16167
+ const result = def.valueType._zod.run({ value: input2[key], issues: [] }, ctx);
16005
16168
  if (result instanceof Promise) {
16006
16169
  proms.push(result.then((result2) => {
16007
16170
  if (result2.issues.length) {
@@ -16018,7 +16181,7 @@ var init_schemas = __esm({
16018
16181
  }
16019
16182
  }
16020
16183
  let unrecognized;
16021
- for (const key in input) {
16184
+ for (const key in input2) {
16022
16185
  if (!recordKeys.has(key)) {
16023
16186
  unrecognized = unrecognized ?? [];
16024
16187
  unrecognized.push(key);
@@ -16027,14 +16190,14 @@ var init_schemas = __esm({
16027
16190
  if (unrecognized && unrecognized.length > 0) {
16028
16191
  payload.issues.push({
16029
16192
  code: "unrecognized_keys",
16030
- input,
16193
+ input: input2,
16031
16194
  inst,
16032
16195
  keys: unrecognized
16033
16196
  });
16034
16197
  }
16035
16198
  } else {
16036
16199
  payload.value = {};
16037
- for (const key of Reflect.ownKeys(input)) {
16200
+ for (const key of Reflect.ownKeys(input2)) {
16038
16201
  if (key === "__proto__")
16039
16202
  continue;
16040
16203
  let keyResult = def.keyType._zod.run({ value: key, issues: [] }, ctx);
@@ -16053,7 +16216,7 @@ var init_schemas = __esm({
16053
16216
  }
16054
16217
  if (keyResult.issues.length) {
16055
16218
  if (def.mode === "loose") {
16056
- payload.value[key] = input[key];
16219
+ payload.value[key] = input2[key];
16057
16220
  } else {
16058
16221
  payload.issues.push({
16059
16222
  code: "invalid_key",
@@ -16066,7 +16229,7 @@ var init_schemas = __esm({
16066
16229
  }
16067
16230
  continue;
16068
16231
  }
16069
- const result = def.valueType._zod.run({ value: input[key], issues: [] }, ctx);
16232
+ const result = def.valueType._zod.run({ value: input2[key], issues: [] }, ctx);
16070
16233
  if (result instanceof Promise) {
16071
16234
  proms.push(result.then((result2) => {
16072
16235
  if (result2.issues.length) {
@@ -16091,27 +16254,27 @@ var init_schemas = __esm({
16091
16254
  $ZodMap = /* @__PURE__ */ $constructor("$ZodMap", (inst, def) => {
16092
16255
  $ZodType.init(inst, def);
16093
16256
  inst._zod.parse = (payload, ctx) => {
16094
- const input = payload.value;
16095
- if (!(input instanceof Map)) {
16257
+ const input2 = payload.value;
16258
+ if (!(input2 instanceof Map)) {
16096
16259
  payload.issues.push({
16097
16260
  expected: "map",
16098
16261
  code: "invalid_type",
16099
- input,
16262
+ input: input2,
16100
16263
  inst
16101
16264
  });
16102
16265
  return payload;
16103
16266
  }
16104
16267
  const proms = [];
16105
16268
  payload.value = /* @__PURE__ */ new Map();
16106
- for (const [key, value] of input) {
16269
+ for (const [key, value] of input2) {
16107
16270
  const keyResult = def.keyType._zod.run({ value: key, issues: [] }, ctx);
16108
16271
  const valueResult = def.valueType._zod.run({ value, issues: [] }, ctx);
16109
16272
  if (keyResult instanceof Promise || valueResult instanceof Promise) {
16110
16273
  proms.push(Promise.all([keyResult, valueResult]).then(([keyResult2, valueResult2]) => {
16111
- handleMapResult(keyResult2, valueResult2, payload, key, input, inst, ctx);
16274
+ handleMapResult(keyResult2, valueResult2, payload, key, input2, inst, ctx);
16112
16275
  }));
16113
16276
  } else {
16114
- handleMapResult(keyResult, valueResult, payload, key, input, inst, ctx);
16277
+ handleMapResult(keyResult, valueResult, payload, key, input2, inst, ctx);
16115
16278
  }
16116
16279
  }
16117
16280
  if (proms.length)
@@ -16122,10 +16285,10 @@ var init_schemas = __esm({
16122
16285
  $ZodSet = /* @__PURE__ */ $constructor("$ZodSet", (inst, def) => {
16123
16286
  $ZodType.init(inst, def);
16124
16287
  inst._zod.parse = (payload, ctx) => {
16125
- const input = payload.value;
16126
- if (!(input instanceof Set)) {
16288
+ const input2 = payload.value;
16289
+ if (!(input2 instanceof Set)) {
16127
16290
  payload.issues.push({
16128
- input,
16291
+ input: input2,
16129
16292
  inst,
16130
16293
  expected: "set",
16131
16294
  code: "invalid_type"
@@ -16134,7 +16297,7 @@ var init_schemas = __esm({
16134
16297
  }
16135
16298
  const proms = [];
16136
16299
  payload.value = /* @__PURE__ */ new Set();
16137
- for (const item of input) {
16300
+ for (const item of input2) {
16138
16301
  const result = def.valueType._zod.run({ value: item, issues: [] }, ctx);
16139
16302
  if (result instanceof Promise) {
16140
16303
  proms.push(result.then((result2) => handleSetResult(result2, payload)));
@@ -16153,14 +16316,14 @@ var init_schemas = __esm({
16153
16316
  inst._zod.values = valuesSet;
16154
16317
  inst._zod.pattern = new RegExp(`^(${values2.filter((k) => propertyKeyTypes.has(typeof k)).map((o) => typeof o === "string" ? escapeRegex(o) : o.toString()).join("|")})$`);
16155
16318
  inst._zod.parse = (payload, _ctx) => {
16156
- const input = payload.value;
16157
- if (valuesSet.has(input)) {
16319
+ const input2 = payload.value;
16320
+ if (valuesSet.has(input2)) {
16158
16321
  return payload;
16159
16322
  }
16160
16323
  payload.issues.push({
16161
16324
  code: "invalid_value",
16162
16325
  values: values2,
16163
- input,
16326
+ input: input2,
16164
16327
  inst
16165
16328
  });
16166
16329
  return payload;
@@ -16175,14 +16338,14 @@ var init_schemas = __esm({
16175
16338
  inst._zod.values = values2;
16176
16339
  inst._zod.pattern = new RegExp(`^(${def.values.map((o) => typeof o === "string" ? escapeRegex(o) : o ? escapeRegex(o.toString()) : String(o)).join("|")})$`);
16177
16340
  inst._zod.parse = (payload, _ctx) => {
16178
- const input = payload.value;
16179
- if (values2.has(input)) {
16341
+ const input2 = payload.value;
16342
+ if (values2.has(input2)) {
16180
16343
  return payload;
16181
16344
  }
16182
16345
  payload.issues.push({
16183
16346
  code: "invalid_value",
16184
16347
  values: def.values,
16185
- input,
16348
+ input: input2,
16186
16349
  inst
16187
16350
  });
16188
16351
  return payload;
@@ -16191,13 +16354,13 @@ var init_schemas = __esm({
16191
16354
  $ZodFile = /* @__PURE__ */ $constructor("$ZodFile", (inst, def) => {
16192
16355
  $ZodType.init(inst, def);
16193
16356
  inst._zod.parse = (payload, _ctx) => {
16194
- const input = payload.value;
16195
- if (input instanceof File)
16357
+ const input2 = payload.value;
16358
+ if (input2 instanceof File)
16196
16359
  return payload;
16197
16360
  payload.issues.push({
16198
16361
  expected: "file",
16199
16362
  code: "invalid_type",
16200
- input,
16363
+ input: input2,
16201
16364
  inst
16202
16365
  });
16203
16366
  return payload;
@@ -16211,9 +16374,9 @@ var init_schemas = __esm({
16211
16374
  }
16212
16375
  const _out = def.transform(payload.value, payload);
16213
16376
  if (ctx.async) {
16214
- const output2 = _out instanceof Promise ? _out : Promise.resolve(_out);
16215
- return output2.then((output3) => {
16216
- payload.value = output3;
16377
+ const output3 = _out instanceof Promise ? _out : Promise.resolve(_out);
16378
+ return output3.then((output4) => {
16379
+ payload.value = output4;
16217
16380
  return payload;
16218
16381
  });
16219
16382
  }
@@ -16565,12 +16728,12 @@ var init_schemas = __esm({
16565
16728
  output: inst._def.output
16566
16729
  });
16567
16730
  };
16568
- inst.output = (output2) => {
16731
+ inst.output = (output3) => {
16569
16732
  const F = inst.constructor;
16570
16733
  return new F({
16571
16734
  type: "function",
16572
16735
  input: inst._def.input,
16573
- output: output2
16736
+ output: output3
16574
16737
  });
16575
16738
  };
16576
16739
  return inst;
@@ -16600,12 +16763,12 @@ var init_schemas = __esm({
16600
16763
  return payload;
16601
16764
  };
16602
16765
  inst._zod.check = (payload) => {
16603
- const input = payload.value;
16604
- const r = def.fn(input);
16766
+ const input2 = payload.value;
16767
+ const r = def.fn(input2);
16605
16768
  if (r instanceof Promise) {
16606
- return r.then((r2) => handleRefineResult(r2, payload, input, inst));
16769
+ return r.then((r2) => handleRefineResult(r2, payload, input2, inst));
16607
16770
  }
16608
- handleRefineResult(r, payload, input, inst);
16771
+ handleRefineResult(r, payload, input2, inst);
16609
16772
  return;
16610
16773
  };
16611
16774
  });
@@ -23250,23 +23413,23 @@ function _overwrite(tx) {
23250
23413
  }
23251
23414
  // @__NO_SIDE_EFFECTS__
23252
23415
  function _normalize(form) {
23253
- return /* @__PURE__ */ _overwrite((input) => input.normalize(form));
23416
+ return /* @__PURE__ */ _overwrite((input2) => input2.normalize(form));
23254
23417
  }
23255
23418
  // @__NO_SIDE_EFFECTS__
23256
23419
  function _trim() {
23257
- return /* @__PURE__ */ _overwrite((input) => input.trim());
23420
+ return /* @__PURE__ */ _overwrite((input2) => input2.trim());
23258
23421
  }
23259
23422
  // @__NO_SIDE_EFFECTS__
23260
23423
  function _toLowerCase() {
23261
- return /* @__PURE__ */ _overwrite((input) => input.toLowerCase());
23424
+ return /* @__PURE__ */ _overwrite((input2) => input2.toLowerCase());
23262
23425
  }
23263
23426
  // @__NO_SIDE_EFFECTS__
23264
23427
  function _toUpperCase() {
23265
- return /* @__PURE__ */ _overwrite((input) => input.toUpperCase());
23428
+ return /* @__PURE__ */ _overwrite((input2) => input2.toUpperCase());
23266
23429
  }
23267
23430
  // @__NO_SIDE_EFFECTS__
23268
23431
  function _slugify() {
23269
- return /* @__PURE__ */ _overwrite((input) => slugify(input));
23432
+ return /* @__PURE__ */ _overwrite((input2) => slugify(input2));
23270
23433
  }
23271
23434
  // @__NO_SIDE_EFFECTS__
23272
23435
  function _array(Class2, element, params) {
@@ -23571,8 +23734,8 @@ function _stringbool(Classes, _params) {
23571
23734
  type: "pipe",
23572
23735
  in: stringSchema,
23573
23736
  out: booleanSchema,
23574
- transform: ((input, payload) => {
23575
- let data = input;
23737
+ transform: ((input2, payload) => {
23738
+ let data = input2;
23576
23739
  if (params.case !== "sensitive")
23577
23740
  data = data.toLowerCase();
23578
23741
  if (truthySet.has(data)) {
@@ -23591,8 +23754,8 @@ function _stringbool(Classes, _params) {
23591
23754
  return {};
23592
23755
  }
23593
23756
  }),
23594
- reverseTransform: ((input, _payload) => {
23595
- if (input === true) {
23757
+ reverseTransform: ((input2, _payload) => {
23758
+ if (input2 === true) {
23596
23759
  return truthyArray[0] || "true";
23597
23760
  } else {
23598
23761
  return falsyArray[0] || "false";
@@ -23995,9 +24158,9 @@ var init_to_json_schema = __esm({
23995
24158
  });
23996
24159
 
23997
24160
  // ../../node_modules/zod/v4/core/json-schema-processors.js
23998
- function toJSONSchema(input, params) {
23999
- if ("_idmap" in input) {
24000
- const registry2 = input;
24161
+ function toJSONSchema(input2, params) {
24162
+ if ("_idmap" in input2) {
24163
+ const registry2 = input2;
24001
24164
  const ctx2 = initializeContext({ ...params, processors: allProcessors });
24002
24165
  const defs = {};
24003
24166
  for (const entry of registry2._idmap.entries()) {
@@ -24025,9 +24188,9 @@ function toJSONSchema(input, params) {
24025
24188
  return { schemas };
24026
24189
  }
24027
24190
  const ctx = initializeContext({ ...params, processors: allProcessors });
24028
- process2(input, ctx);
24029
- extractDefs(ctx, input);
24030
- return finalize(ctx, input);
24191
+ process2(input2, ctx);
24192
+ extractDefs(ctx, input2);
24193
+ return finalize(ctx, input2);
24031
24194
  }
24032
24195
  var formatMap, stringProcessor, numberProcessor, booleanProcessor, bigintProcessor, symbolProcessor, nullProcessor, undefinedProcessor, voidProcessor, neverProcessor, anyProcessor, unknownProcessor, dateProcessor, enumProcessor, literalProcessor, nanProcessor, templateLiteralProcessor, fileProcessor, successProcessor, customProcessor, functionProcessor, transformProcessor, mapProcessor, setProcessor, arrayProcessor, objectProcessor, unionProcessor, intersectionProcessor, tupleProcessor, recordProcessor, nullableProcessor, nonoptionalProcessor, defaultProcessor, prefaultProcessor, catchProcessor, pipeProcessor, readonlyProcessor, promiseProcessor, optionalProcessor, lazyProcessor, allProcessors;
24033
24196
  var init_json_schema_processors = __esm({
@@ -26233,14 +26396,14 @@ var init_schemas2 = __esm({
26233
26396
  payload.issues.push(util_exports.issue(_issue));
26234
26397
  }
26235
26398
  };
26236
- const output2 = def.transform(payload.value, payload);
26237
- if (output2 instanceof Promise) {
26238
- return output2.then((output3) => {
26239
- payload.value = output3;
26399
+ const output3 = def.transform(payload.value, payload);
26400
+ if (output3 instanceof Promise) {
26401
+ return output3.then((output4) => {
26402
+ payload.value = output4;
26240
26403
  return payload;
26241
26404
  });
26242
26405
  }
26243
- payload.value = output2;
26406
+ payload.value = output3;
26244
26407
  return payload;
26245
26408
  };
26246
26409
  });
@@ -26403,13 +26566,13 @@ function resolveRef(ref, ctx) {
26403
26566
  if (!ref.startsWith("#")) {
26404
26567
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
26405
26568
  }
26406
- const path14 = ref.slice(1).split("/").filter(Boolean);
26407
- if (path14.length === 0) {
26569
+ const path15 = ref.slice(1).split("/").filter(Boolean);
26570
+ if (path15.length === 0) {
26408
26571
  return ctx.rootSchema;
26409
26572
  }
26410
26573
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
26411
- if (path14[0] === defsKey) {
26412
- const key = path14[1];
26574
+ if (path15[0] === defsKey) {
26575
+ const key = path15[1];
26413
26576
  if (!key || !ctx.defs[key]) {
26414
26577
  throw new Error(`Reference not found: ${ref}`);
26415
26578
  }
@@ -28209,7 +28372,8 @@ var init_enrollments = __esm({
28209
28372
  expiresAt: timestamp("expires_at"),
28210
28373
  // Story 3.5: Preview expiration (enrolledAt + 7 days)
28211
28374
  setupChecklist: jsonb("setup_checklist").$type(),
28212
- updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull()
28375
+ updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull(),
28376
+ metadata: jsonb("metadata").$type().default({})
28213
28377
  },
28214
28378
  (table) => ({
28215
28379
  userIdIdx: index("enrollments_user_id_idx").on(table.userId),
@@ -36053,6 +36217,80 @@ var init_student_course_memory = __esm({
36053
36217
  }
36054
36218
  });
36055
36219
 
36220
+ // ../../packages/database/src/schema/student-feedback.ts
36221
+ var studentFeedbackKindEnum, studentFeedbackSurfaceEnum, studentFeedbackCategoryEnum, studentFeedback;
36222
+ var init_student_feedback = __esm({
36223
+ "../../packages/database/src/schema/student-feedback.ts"() {
36224
+ "use strict";
36225
+ init_drizzle_orm();
36226
+ init_pg_core();
36227
+ init_courses3();
36228
+ init_lessons();
36229
+ init_module_exercises();
36230
+ init_study_module_sessions();
36231
+ init_users();
36232
+ studentFeedbackKindEnum = pgEnum("student_feedback_kind", [
36233
+ "free_text",
36234
+ "lesson_pulse"
36235
+ ]);
36236
+ studentFeedbackSurfaceEnum = pgEnum("student_feedback_surface", [
36237
+ "lesson",
36238
+ "exercise",
36239
+ "chatstudy"
36240
+ ]);
36241
+ studentFeedbackCategoryEnum = pgEnum("student_feedback_category", [
36242
+ "BUG",
36243
+ "UX",
36244
+ "FEAT",
36245
+ "CONTENT",
36246
+ "PERF",
36247
+ "INTEG"
36248
+ ]);
36249
+ studentFeedback = pgTable(
36250
+ "student_feedback",
36251
+ {
36252
+ id: uuid("id").defaultRandom().primaryKey(),
36253
+ studentId: uuid("student_id").references(() => users.id, { onDelete: "cascade" }).notNull(),
36254
+ courseId: uuid("course_id").references(() => courses.id, { onDelete: "cascade" }).notNull(),
36255
+ surface: studentFeedbackSurfaceEnum("surface").notNull(),
36256
+ routeOrSlug: text("route_or_slug").notNull(),
36257
+ kind: studentFeedbackKindEnum("kind").notNull().default("free_text"),
36258
+ category: studentFeedbackCategoryEnum("category"),
36259
+ comment: text("comment"),
36260
+ rating: integer("rating"),
36261
+ lessonId: uuid("lesson_id").references(() => lessons.id, { onDelete: "set null" }),
36262
+ exerciseId: uuid("exercise_id").references(() => moduleExercises.id, { onDelete: "set null" }),
36263
+ // Current fullscreen student flow uses v2 module sessions.
36264
+ chatSessionId: uuid("chat_session_id").references(() => studyModuleSessions.id, {
36265
+ onDelete: "set null"
36266
+ }),
36267
+ capturedAt: timestamp("captured_at", { withTimezone: true }).defaultNow().notNull(),
36268
+ createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
36269
+ updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull()
36270
+ },
36271
+ (table) => ({
36272
+ courseCapturedAtIdx: index("student_feedback_course_captured_at_idx").on(
36273
+ table.courseId,
36274
+ table.capturedAt
36275
+ ),
36276
+ surfaceCapturedAtIdx: index("student_feedback_surface_captured_at_idx").on(
36277
+ table.surface,
36278
+ table.capturedAt
36279
+ ),
36280
+ categoryCapturedAtIdx: index("student_feedback_category_captured_at_idx").on(
36281
+ table.category,
36282
+ table.capturedAt
36283
+ ),
36284
+ studentCapturedAtIdx: index("student_feedback_student_captured_at_idx").on(
36285
+ table.studentId,
36286
+ table.capturedAt
36287
+ ),
36288
+ lessonPulseUniqueIdx: uniqueIndex("student_feedback_lesson_pulse_unique_idx").on(table.studentId, table.lessonId).where(sql`${table.kind} = 'lesson_pulse' AND ${table.lessonId} IS NOT NULL`)
36289
+ })
36290
+ );
36291
+ }
36292
+ });
36293
+
36056
36294
  // ../../packages/database/src/schema/student-module-progress.ts
36057
36295
  var moduleProgressStatusEnum, studentModuleProgress;
36058
36296
  var init_student_module_progress = __esm({
@@ -38230,6 +38468,10 @@ __export(schema_exports, {
38230
38468
  stringifySettingValue: () => stringifySettingValue,
38231
38469
  studentCourseMemory: () => studentCourseMemory,
38232
38470
  studentCourseMemoryRelations: () => studentCourseMemoryRelations,
38471
+ studentFeedback: () => studentFeedback,
38472
+ studentFeedbackCategoryEnum: () => studentFeedbackCategoryEnum,
38473
+ studentFeedbackKindEnum: () => studentFeedbackKindEnum,
38474
+ studentFeedbackSurfaceEnum: () => studentFeedbackSurfaceEnum,
38233
38475
  studentModuleProgress: () => studentModuleProgress,
38234
38476
  studentNotes: () => studentNotes2,
38235
38477
  studentNotesRelations: () => studentNotesRelations2,
@@ -38402,6 +38644,7 @@ var init_schema3 = __esm({
38402
38644
  init_exercise_materials();
38403
38645
  init_course_knowledge_bases();
38404
38646
  init_student_course_memory();
38647
+ init_student_feedback();
38405
38648
  init_student_module_progress();
38406
38649
  init_course_projects();
38407
38650
  init_source_extractions();
@@ -39850,6 +40093,32 @@ var init_exercise_types = __esm({
39850
40093
  }
39851
40094
  });
39852
40095
 
40096
+ // ../../packages/tostudy-core/src/workspace/lesson-exercise-data.ts
40097
+ var init_lesson_exercise_data = __esm({
40098
+ "../../packages/tostudy-core/src/workspace/lesson-exercise-data.ts"() {
40099
+ "use strict";
40100
+ }
40101
+ });
40102
+
40103
+ // ../../packages/tostudy-core/src/learning/sync-enrollment-progress.ts
40104
+ var init_sync_enrollment_progress = __esm({
40105
+ "../../packages/tostudy-core/src/learning/sync-enrollment-progress.ts"() {
40106
+ "use strict";
40107
+ init_src4();
40108
+ init_src();
40109
+ }
40110
+ });
40111
+
40112
+ // ../../packages/tostudy-core/src/learning/study-state-sync.ts
40113
+ var DEFAULT_MAX_SESSION_TIME_SECONDS;
40114
+ var init_study_state_sync = __esm({
40115
+ "../../packages/tostudy-core/src/learning/study-state-sync.ts"() {
40116
+ "use strict";
40117
+ init_src4();
40118
+ DEFAULT_MAX_SESSION_TIME_SECONDS = 2 * 60 * 60;
40119
+ }
40120
+ });
40121
+
39853
40122
  // ../../packages/tostudy-core/src/learning/start-module-full.ts
39854
40123
  var init_start_module_full = __esm({
39855
40124
  "../../packages/tostudy-core/src/learning/start-module-full.ts"() {
@@ -39857,6 +40126,9 @@ var init_start_module_full = __esm({
39857
40126
  init_src4();
39858
40127
  init_parser();
39859
40128
  init_exercise_types();
40129
+ init_lesson_exercise_data();
40130
+ init_sync_enrollment_progress();
40131
+ init_study_state_sync();
39860
40132
  }
39861
40133
  });
39862
40134
 
@@ -39866,6 +40138,9 @@ var init_next_lesson_full = __esm({
39866
40138
  "use strict";
39867
40139
  init_src4();
39868
40140
  init_parser();
40141
+ init_lesson_exercise_data();
40142
+ init_sync_enrollment_progress();
40143
+ init_study_state_sync();
39869
40144
  }
39870
40145
  });
39871
40146
 
@@ -39876,6 +40151,8 @@ var init_validate_solution_full = __esm({
39876
40151
  init_src4();
39877
40152
  init_parser();
39878
40153
  init_exercise_types();
40154
+ init_study_state_sync();
40155
+ init_sync_enrollment_progress();
39879
40156
  }
39880
40157
  });
39881
40158
 
@@ -39935,6 +40212,7 @@ var init_learning = __esm({
39935
40212
  init_get_lesson_content_full();
39936
40213
  init_get_hint_full();
39937
40214
  init_explain_concept();
40215
+ init_sync_enrollment_progress();
39938
40216
  }
39939
40217
  });
39940
40218
 
@@ -39953,7 +40231,50 @@ var init_lessons2 = __esm({
39953
40231
 
39954
40232
  // src/commands/start.ts
39955
40233
  import { Command as Command8 } from "commander";
39956
- var logger5, startCommand;
40234
+ function buildOnboardingBlockerMessage(courseTitle, onboarding) {
40235
+ const lines = [`Onboarding obrigat\xF3rio pendente para "${courseTitle}".`];
40236
+ if (!onboarding.initReady) {
40237
+ lines.push("Execute `tostudy init` primeiro para configurar o tutor deste curso.");
40238
+ }
40239
+ if (!onboarding.workspaceReady) {
40240
+ lines.push("Execute `tostudy workspace setup` para criar o workspace local antes de iniciar.");
40241
+ }
40242
+ return lines.join("\n");
40243
+ }
40244
+ async function runStart(opts, deps = defaultDeps2) {
40245
+ try {
40246
+ const session = await deps.requireSession();
40247
+ const activeCourse = await deps.requireActiveCourse();
40248
+ const onboarding = await deps.getCourseOnboardingStatus(activeCourse);
40249
+ if (!onboarding.initReady || !onboarding.workspaceReady) {
40250
+ throw new StartBlockedError(
40251
+ buildOnboardingBlockerMessage(activeCourse.courseTitle, onboarding)
40252
+ );
40253
+ }
40254
+ const driftWarning = await deps.checkCourseDrift();
40255
+ if (driftWarning) deps.stderrWrite(driftWarning + "\n");
40256
+ const data = deps.createHttpProvider(session.apiUrl, session.token);
40257
+ const moduleData = await deps.startModule(
40258
+ { enrollmentId: activeCourse.enrollmentId },
40259
+ { data, logger: deps.logger }
40260
+ );
40261
+ await deps.setActiveCourse({ ...activeCourse, currentLessonId: moduleData.firstLesson.id });
40262
+ if (opts.json) {
40263
+ deps.output(moduleData, { json: true });
40264
+ } else {
40265
+ deps.output(deps.formatModuleStart(moduleData), { json: false });
40266
+ }
40267
+ } catch (err) {
40268
+ if (err instanceof CliApiError && err.status === 403 && err.message === "CHANNEL_MISMATCH") {
40269
+ process.stderr.write("Este curso n\xE3o est\xE1 dispon\xEDvel via CLI.\n");
40270
+ process.stderr.write("Acesse tostudy.ai para estudar este curso pelo ChatStudy.\n");
40271
+ process.exit(1);
40272
+ }
40273
+ const msg = err instanceof Error ? err.message : String(err);
40274
+ deps.error(msg);
40275
+ }
40276
+ }
40277
+ var logger5, defaultDeps2, StartBlockedError, startCommand;
39957
40278
  var init_start = __esm({
39958
40279
  "src/commands/start.ts"() {
39959
40280
  "use strict";
@@ -39961,32 +40282,27 @@ var init_start = __esm({
39961
40282
  init_lessons2();
39962
40283
  init_http2();
39963
40284
  init_session();
40285
+ init_status();
39964
40286
  init_formatter();
39965
40287
  logger5 = createLogger("cli:start");
40288
+ defaultDeps2 = {
40289
+ requireSession,
40290
+ requireActiveCourse,
40291
+ checkCourseDrift,
40292
+ getCourseOnboardingStatus,
40293
+ createHttpProvider,
40294
+ startModule,
40295
+ setActiveCourse,
40296
+ formatModuleStart,
40297
+ output,
40298
+ error,
40299
+ stderrWrite: (message) => process.stderr.write(message),
40300
+ logger: logger5
40301
+ };
40302
+ StartBlockedError = class extends Error {
40303
+ };
39966
40304
  startCommand = new Command8("start").description("Start (or resume) the current module of the active course").option("--json", "Output structured JSON").action(async (opts) => {
39967
- try {
39968
- const session = await requireSession();
39969
- const activeCourse = await requireActiveCourse();
39970
- const driftWarning = await checkCourseDrift();
39971
- if (driftWarning) process.stderr.write(driftWarning + "\n");
39972
- const data = createHttpProvider(session.apiUrl, session.token);
39973
- const deps = { data, logger: logger5 };
39974
- const moduleData = await startModule({ enrollmentId: activeCourse.enrollmentId }, deps);
39975
- await setActiveCourse({ ...activeCourse, currentLessonId: moduleData.firstLesson.id });
39976
- if (opts.json) {
39977
- output(moduleData, { json: true });
39978
- } else {
39979
- output(formatModuleStart(moduleData), { json: false });
39980
- }
39981
- } catch (err) {
39982
- if (err instanceof CliApiError && err.status === 403 && err.message === "CHANNEL_MISMATCH") {
39983
- process.stderr.write("Este curso n\xE3o est\xE1 dispon\xEDvel via CLI.\n");
39984
- process.stderr.write("Acesse tostudy.ai para estudar este curso pelo ChatStudy.\n");
39985
- process.exit(1);
39986
- }
39987
- const msg = err instanceof Error ? err.message : String(err);
39988
- error(msg);
39989
- }
40305
+ await runStart(opts);
39990
40306
  });
39991
40307
  }
39992
40308
  });
@@ -40091,31 +40407,6 @@ var init_next = __esm({
40091
40407
  }
40092
40408
  });
40093
40409
 
40094
- // src/workspace/resolve.ts
40095
- import fs6 from "node:fs/promises";
40096
- import path5 from "node:path";
40097
- import os6 from "node:os";
40098
- function courseSlug(title) {
40099
- return title.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
40100
- }
40101
- async function resolveWorkspace(courseTitle, basePath = DEFAULT_BASE) {
40102
- const slug = courseSlug(courseTitle);
40103
- const candidate = path5.join(basePath, slug);
40104
- try {
40105
- await fs6.access(path5.join(candidate, ".ana-config.json"));
40106
- return { found: true, workspacePath: candidate };
40107
- } catch {
40108
- return { found: false, workspacePath: null };
40109
- }
40110
- }
40111
- var DEFAULT_BASE;
40112
- var init_resolve = __esm({
40113
- "src/workspace/resolve.ts"() {
40114
- "use strict";
40115
- DEFAULT_BASE = path5.join(os6.homedir(), "study");
40116
- }
40117
- });
40118
-
40119
40410
  // src/commands/lesson.ts
40120
40411
  import { Command as Command11 } from "commander";
40121
40412
  function adjustTimeEstimate(type, baseMinutes) {
@@ -40239,13 +40530,13 @@ var init_hint = __esm({
40239
40530
  });
40240
40531
 
40241
40532
  // ../../packages/tostudy-core/src/exercises/validate-solution.ts
40242
- async function validateSolution(input, deps) {
40243
- deps.logger.info("tostudy-core: validateSolution", { lessonId: input.lessonId });
40533
+ async function validateSolution(input2, deps) {
40534
+ deps.logger.info("tostudy-core: validateSolution", { lessonId: input2.lessonId });
40244
40535
  return deps.data.exercises.validate(
40245
- input.lessonId,
40246
- input.solution,
40247
- input.userId,
40248
- input.enrollmentId
40536
+ input2.lessonId,
40537
+ input2.solution,
40538
+ input2.userId,
40539
+ input2.enrollmentId
40249
40540
  );
40250
40541
  }
40251
40542
  var init_validate_solution = __esm({
@@ -40371,6 +40662,109 @@ function buildInitTemplate(userName, course, progress3) {
40371
40662
  lines.push("- Instru\xE7\xF5es do ToStudy \u2192 fluxo de estudo (navega\xE7\xE3o, exerc\xEDcios, valida\xE7\xE3o)");
40372
40663
  return lines.join("\n");
40373
40664
  }
40665
+ function resolveTutorMode(level) {
40666
+ if (level === "beginner") return "guided";
40667
+ if (level === "advanced") return "direct";
40668
+ return "balanced";
40669
+ }
40670
+ function formatTutorMode(mode) {
40671
+ const map2 = {
40672
+ guided: "Guiado",
40673
+ balanced: "Equilibrado",
40674
+ direct: "Direto"
40675
+ };
40676
+ return map2[mode];
40677
+ }
40678
+ function buildTutorPersonalizationSection(course, learnerProfile) {
40679
+ const mode = resolveTutorMode(course.level);
40680
+ const lines = [];
40681
+ lines.push("## 6. Personaliza\xE7\xE3o do Tutor");
40682
+ lines.push(`- Modo inicial do tutor: ${formatTutorMode(mode)}`);
40683
+ lines.push(
40684
+ "- Na primeira intera\xE7\xE3o, apresente a escolha entre cen\xE1rio fict\xEDcio do curso e adapta\xE7\xE3o ao contexto real do aluno."
40685
+ );
40686
+ lines.push(
40687
+ `- O aluno atual j\xE1 optou por: ${learnerProfile.adaptToRealContext ? "Adaptar para o contexto real" : "Manter o cen\xE1rio fict\xEDcio"}`
40688
+ );
40689
+ lines.push(`- Segmento: ${learnerProfile.segment}`);
40690
+ lines.push(`- Empresa: ${learnerProfile.company}`);
40691
+ lines.push(`- Produtos/servi\xE7os: ${learnerProfile.productsOrServices}`);
40692
+ lines.push(`- Regi\xE3o: ${learnerProfile.region}`);
40693
+ lines.push(`- Equipe: ${learnerProfile.team}`);
40694
+ lines.push(`- Objetivo: ${learnerProfile.goal}`);
40695
+ lines.push(`- N\xEDvel declarado do aluno: ${formatCourseLevel(learnerProfile.learnerLevel)}`);
40696
+ if (learnerProfile.adaptToRealContext) {
40697
+ lines.push(
40698
+ "- Use o contexto do aluno como padr\xE3o para explica\xE7\xF5es, exemplos, exerc\xEDcios e framing."
40699
+ );
40700
+ lines.push(
40701
+ "- Troque nomes, entreg\xE1veis e restri\xE7\xF5es do cen\xE1rio fict\xEDcio por equivalentes reais."
40702
+ );
40703
+ lines.push(
40704
+ "- Preserve objetivos pedag\xF3gicos, crit\xE9rios de valida\xE7\xE3o e progress\xE3o de dificuldade."
40705
+ );
40706
+ } else {
40707
+ lines.push(
40708
+ "- Preserve o cen\xE1rio fict\xEDcio como padr\xE3o e conecte os conceitos ao neg\xF3cio real quando isso ajudar."
40709
+ );
40710
+ lines.push(
40711
+ "- Se o aluno quiser migrar para o contexto real depois, oriente a rodar `tostudy init` novamente."
40712
+ );
40713
+ }
40714
+ if (mode === "guided") {
40715
+ lines.push(
40716
+ "- No modo guiado, explique o porqu\xEA de cada passo, proponha checkpoints curtos e confirme entendimento antes de avan\xE7ar."
40717
+ );
40718
+ } else if (mode === "direct") {
40719
+ lines.push(
40720
+ "- Mesmo no modo mais direto, continue sem dar a resposta pronta e preserve a progress\xE3o pedag\xF3gica."
40721
+ );
40722
+ } else {
40723
+ lines.push(
40724
+ "- No modo equilibrado, combine explica\xE7\xF5es curtas com autonomia entre checkpoints."
40725
+ );
40726
+ }
40727
+ return lines.join("\n");
40728
+ }
40729
+ function buildLearnerBrief(userName, course, learnerProfile) {
40730
+ const lines = [];
40731
+ lines.push("# ToStudy CLI \u2014 Brief do Aluno");
40732
+ lines.push("");
40733
+ lines.push("Este documento resume o contexto real do aluno para orientar exemplos e exercicios.");
40734
+ lines.push("");
40735
+ lines.push("## 1. Identificacao");
40736
+ lines.push(`- Aluno: ${userName}`);
40737
+ lines.push(`- Curso: "${course.title}"`);
40738
+ lines.push(`- Segmento: ${learnerProfile.segment}`);
40739
+ lines.push(`- Empresa: ${learnerProfile.company}`);
40740
+ lines.push(`- Produtos/servicos: ${learnerProfile.productsOrServices}`);
40741
+ lines.push(`- Regiao: ${learnerProfile.region}`);
40742
+ lines.push(`- Equipe: ${learnerProfile.team}`);
40743
+ lines.push("");
40744
+ lines.push("## 2. Objetivo e Contexto");
40745
+ lines.push(`- Objetivo principal: ${learnerProfile.goal}`);
40746
+ lines.push(`- Nivel do aluno: ${formatCourseLevel(learnerProfile.learnerLevel)}`);
40747
+ lines.push(
40748
+ `- Adaptar curso ao contexto real: ${learnerProfile.adaptToRealContext ? "Sim" : "Nao"}`
40749
+ );
40750
+ lines.push("");
40751
+ lines.push("## 3. Como usar este brief");
40752
+ lines.push("- Reutilize este contexto para adaptar exemplos, cenarios e exercicios.");
40753
+ lines.push("- Preserve a proposta pedagogica do curso antes de customizar o contexto.");
40754
+ lines.push(
40755
+ "- Se algo mudar no negocio do aluno, rode `tostudy init` novamente para atualizar o brief."
40756
+ );
40757
+ return lines.join("\n");
40758
+ }
40759
+ function buildInitArtifacts(userName, course, progress3, learnerProfile) {
40760
+ return {
40761
+ tutorInstructions: [
40762
+ buildInitTemplate(userName, course, progress3),
40763
+ buildTutorPersonalizationSection(course, learnerProfile)
40764
+ ].join("\n\n"),
40765
+ learnerBrief: buildLearnerBrief(userName, course, learnerProfile)
40766
+ };
40767
+ }
40374
40768
  var LANGUAGE_TAGS;
40375
40769
  var init_init_template = __esm({
40376
40770
  "src/output/init-template.ts"() {
@@ -40405,8 +40799,8 @@ var init_init_template = __esm({
40405
40799
  });
40406
40800
 
40407
40801
  // src/commands/validate.ts
40408
- import fs7 from "node:fs";
40409
- import path6 from "node:path";
40802
+ import fs8 from "node:fs";
40803
+ import path7 from "node:path";
40410
40804
  import { Command as Command13 } from "commander";
40411
40805
  var logger10, validateCommand;
40412
40806
  var init_validate = __esm({
@@ -40431,17 +40825,17 @@ var init_validate = __esm({
40431
40825
  }
40432
40826
  let solution;
40433
40827
  if (opts.stdin) {
40434
- solution = fs7.readFileSync("/dev/stdin", "utf-8");
40828
+ solution = fs8.readFileSync("/dev/stdin", "utf-8");
40435
40829
  } else if (file2) {
40436
- if (!fs7.existsSync(file2)) {
40830
+ if (!fs8.existsSync(file2)) {
40437
40831
  error(`Arquivo n\xE3o encontrado: ${file2}`);
40438
40832
  }
40439
- solution = fs7.readFileSync(file2, "utf-8");
40833
+ solution = fs8.readFileSync(file2, "utf-8");
40440
40834
  } else {
40441
40835
  error("Forne\xE7a um arquivo ou use --stdin.\n\nExemplo: tostudy validate resposta.md");
40442
40836
  }
40443
40837
  if (file2 && activeCourse.courseTags?.length) {
40444
- const ext = path6.extname(file2).toLowerCase();
40838
+ const ext = path7.extname(file2).toLowerCase();
40445
40839
  const LANG_EXTENSIONS = {
40446
40840
  ".html": ["html", "html5"],
40447
40841
  ".css": ["css"],
@@ -40565,9 +40959,273 @@ var init_menu = __esm({
40565
40959
  }
40566
40960
  });
40567
40961
 
40962
+ // src/onboarding/learner-context.ts
40963
+ import readline from "node:readline/promises";
40964
+ import { stdin as input, stdout as output2 } from "node:process";
40965
+ async function askNonEmpty(question, deps, defaultValue) {
40966
+ while (true) {
40967
+ const answer = (await deps.ask(question)).trim();
40968
+ if (answer.length > 0) return answer;
40969
+ if (defaultValue) return defaultValue;
40970
+ }
40971
+ }
40972
+ async function askChoice(question, choices, deps, defaultChoice) {
40973
+ while (true) {
40974
+ const rawAnswer = (await deps.ask(question)).trim().toLowerCase();
40975
+ if (rawAnswer.length === 0 && defaultChoice) return defaultChoice;
40976
+ const answer = rawAnswer;
40977
+ if (choices.includes(answer)) return answer;
40978
+ }
40979
+ }
40980
+ function createPromptDeps() {
40981
+ const rl = readline.createInterface({ input, output: output2 });
40982
+ return {
40983
+ ask: (question) => rl.question(question),
40984
+ write: (content) => output2.write(content),
40985
+ close: () => rl.close()
40986
+ };
40987
+ }
40988
+ async function collectLearnerContextProfileWithDeps(input2, deps) {
40989
+ const existingProfile = input2.existingProfile;
40990
+ if (existingProfile) {
40991
+ deps.write(
40992
+ [
40993
+ "",
40994
+ `Brief existente encontrado (${input2.existingSource === "web" ? "web" : "CLI"}):`,
40995
+ `- Segmento: ${existingProfile.segment}`,
40996
+ `- Empresa: ${existingProfile.company}`,
40997
+ `- Produtos/servicos: ${existingProfile.productsOrServices}`,
40998
+ `- Regiao: ${existingProfile.region}`,
40999
+ `- Equipe: ${existingProfile.team}`,
41000
+ `- Objetivo: ${existingProfile.goal}`,
41001
+ `- Nivel: ${existingProfile.learnerLevel}`,
41002
+ `- Contexto real: ${existingProfile.adaptToRealContext ? "sim" : "nao"}`,
41003
+ ""
41004
+ ].join("\n")
41005
+ );
41006
+ }
41007
+ const action = existingProfile ? await askChoice(
41008
+ "Manter este brief ou editar? (keep/edit): ",
41009
+ ["keep", "edit"],
41010
+ deps,
41011
+ "keep"
41012
+ ) : "edit";
41013
+ const baseProfile = existingProfile;
41014
+ const segment = action === "keep" && baseProfile ? baseProfile.segment : await askNonEmpty(
41015
+ baseProfile ? `Segmento ou nicho do aluno [${baseProfile.segment}]: ` : "Segmento ou nicho do aluno: ",
41016
+ deps,
41017
+ baseProfile?.segment
41018
+ );
41019
+ const company = action === "keep" && baseProfile ? baseProfile.company : await askNonEmpty(
41020
+ baseProfile ? `Empresa ou tipo de negocio [${baseProfile.company}]: ` : "Empresa ou tipo de negocio: ",
41021
+ deps,
41022
+ baseProfile?.company
41023
+ );
41024
+ const productsOrServices = action === "keep" && baseProfile ? baseProfile.productsOrServices : await askNonEmpty(
41025
+ baseProfile ? `Produtos ou servicos principais [${baseProfile.productsOrServices}]: ` : "Produtos ou servicos principais: ",
41026
+ deps,
41027
+ baseProfile?.productsOrServices
41028
+ );
41029
+ const region = action === "keep" && baseProfile ? baseProfile.region : await askNonEmpty(
41030
+ baseProfile ? `Regiao de atuacao [${baseProfile.region}]: ` : "Regiao de atuacao: ",
41031
+ deps,
41032
+ baseProfile?.region
41033
+ );
41034
+ const team = action === "keep" && baseProfile ? baseProfile.team : await askNonEmpty(
41035
+ baseProfile ? `Equipe envolvida neste contexto [${baseProfile.team}]: ` : "Equipe envolvida neste contexto: ",
41036
+ deps,
41037
+ baseProfile?.team
41038
+ );
41039
+ const goal = action === "keep" && baseProfile ? baseProfile.goal : await askNonEmpty(
41040
+ baseProfile ? `Objetivo principal com este curso [${baseProfile.goal}]: ` : "Objetivo principal com este curso: ",
41041
+ deps,
41042
+ baseProfile?.goal
41043
+ );
41044
+ const learnerLevel = action === "keep" && baseProfile ? baseProfile.learnerLevel : await askChoice(
41045
+ baseProfile ? `Nivel do aluno (beginner/intermediate/advanced) [${baseProfile.learnerLevel}]: ` : "Nivel do aluno (beginner/intermediate/advanced): ",
41046
+ ["beginner", "intermediate", "advanced"],
41047
+ deps,
41048
+ baseProfile?.learnerLevel
41049
+ );
41050
+ const adaptToRealContext = await askChoice(
41051
+ baseProfile ? `Quer que o tutor adapte exemplos ao seu contexto real ou prefere usar os cenarios ficticios do curso? (yes/no) [${baseProfile.adaptToRealContext ? "yes" : "no"}]: ` : "Quer que o tutor adapte exemplos ao seu contexto real ou prefere usar os cenarios ficticios do curso? (yes/no): ",
41052
+ ["yes", "no"],
41053
+ deps,
41054
+ baseProfile ? baseProfile.adaptToRealContext ? "yes" : "no" : void 0
41055
+ ) === "yes";
41056
+ return {
41057
+ segment,
41058
+ company,
41059
+ productsOrServices,
41060
+ region,
41061
+ team,
41062
+ goal,
41063
+ learnerLevel,
41064
+ adaptToRealContext
41065
+ };
41066
+ }
41067
+ async function collectLearnerContextProfile(input2) {
41068
+ const deps = createPromptDeps();
41069
+ try {
41070
+ return await collectLearnerContextProfileWithDeps(input2, deps);
41071
+ } finally {
41072
+ deps.close();
41073
+ }
41074
+ }
41075
+ var init_learner_context = __esm({
41076
+ "src/onboarding/learner-context.ts"() {
41077
+ "use strict";
41078
+ }
41079
+ });
41080
+
41081
+ // src/onboarding/api.ts
41082
+ async function apiFetch2(url2, token2, init) {
41083
+ const response = await fetch(url2, {
41084
+ ...init,
41085
+ headers: {
41086
+ "Content-Type": "application/json",
41087
+ Authorization: `Bearer ${token2}`,
41088
+ ...init?.headers
41089
+ }
41090
+ });
41091
+ const body = await response.json();
41092
+ if (!response.ok) {
41093
+ throw new CliApiError(body.error ?? `API error ${response.status}`, response.status);
41094
+ }
41095
+ return body;
41096
+ }
41097
+ async function getRemoteEnrollmentOnboarding(input2) {
41098
+ const url2 = new URL(`${input2.apiUrl}/api/cli/onboarding`);
41099
+ url2.searchParams.set("enrollmentId", input2.enrollmentId);
41100
+ const response = await apiFetch2(
41101
+ url2.toString(),
41102
+ input2.token
41103
+ );
41104
+ return response.onboarding;
41105
+ }
41106
+ async function saveRemoteEnrollmentOnboarding(input2) {
41107
+ const response = await apiFetch2(
41108
+ `${input2.apiUrl}/api/cli/onboarding`,
41109
+ input2.token,
41110
+ {
41111
+ method: "POST",
41112
+ body: JSON.stringify({
41113
+ enrollmentId: input2.enrollmentId,
41114
+ learnerBrief: input2.learnerBrief,
41115
+ learnerProfile: input2.learnerProfile
41116
+ })
41117
+ }
41118
+ );
41119
+ return response.onboarding;
41120
+ }
41121
+ var init_api2 = __esm({
41122
+ "src/onboarding/api.ts"() {
41123
+ "use strict";
41124
+ init_http2();
41125
+ }
41126
+ });
41127
+
40568
41128
  // src/commands/init.ts
40569
41129
  import { Command as Command15 } from "commander";
40570
- var logger11, initCommand;
41130
+ async function runInit(deps = defaultDeps3) {
41131
+ const session = await deps.getSession();
41132
+ if (!session) {
41133
+ deps.output("Nao autenticado. Rode `tostudy login` para comecar.", { json: false });
41134
+ return;
41135
+ }
41136
+ const data = deps.createHttpProvider(session.apiUrl, session.token);
41137
+ const apiDeps = { data, logger: deps.logger };
41138
+ const activeCourse = await deps.getActiveCourse();
41139
+ if (!activeCourse) {
41140
+ try {
41141
+ const courses3 = await deps.listCourses({ userId: session.userId }, apiDeps);
41142
+ const courseListStr = courses3.length > 0 ? courses3.map((c, i) => ` ${i + 1}. ${c.title} (${c.progress}%)`).join("\n") : " (nenhum curso encontrado)";
41143
+ deps.output(
41144
+ `Nenhum curso ativo.
41145
+
41146
+ Seus cursos:
41147
+ ${courseListStr}
41148
+
41149
+ Rode \`tostudy select <n\xFAmero>\` para ativar um curso.`,
41150
+ { json: false }
41151
+ );
41152
+ } catch {
41153
+ deps.output("Nenhum curso ativo. Rode `tostudy courses` e `tostudy select <n\xFAmero>`.", {
41154
+ json: false
41155
+ });
41156
+ }
41157
+ return;
41158
+ }
41159
+ let matchedCourse = null;
41160
+ try {
41161
+ const courses3 = await deps.listCourses({ userId: session.userId }, apiDeps);
41162
+ matchedCourse = courses3.find((course) => course.courseId === activeCourse.courseId) ?? null;
41163
+ } catch (err) {
41164
+ deps.logger.warn("Failed to fetch course metadata for init", { error: err });
41165
+ }
41166
+ if (!matchedCourse) {
41167
+ matchedCourse = {
41168
+ enrollmentId: activeCourse.enrollmentId,
41169
+ courseId: activeCourse.courseId,
41170
+ title: activeCourse.courseTitle,
41171
+ progress: 0,
41172
+ creatorName: "Desconhecido",
41173
+ teachingApproach: "hybrid",
41174
+ enrolledAt: /* @__PURE__ */ new Date()
41175
+ };
41176
+ }
41177
+ let progressData = null;
41178
+ try {
41179
+ progressData = await deps.getProgress({ enrollmentId: activeCourse.enrollmentId }, apiDeps);
41180
+ } catch (err) {
41181
+ deps.logger.warn("Failed to fetch progress for init", { error: err });
41182
+ }
41183
+ let remoteOnboarding = null;
41184
+ try {
41185
+ remoteOnboarding = await deps.getRemoteEnrollmentOnboarding({
41186
+ apiUrl: session.apiUrl,
41187
+ token: session.token,
41188
+ enrollmentId: activeCourse.enrollmentId
41189
+ });
41190
+ } catch (err) {
41191
+ deps.logger.warn("Failed to fetch remote enrollment onboarding", { error: err });
41192
+ }
41193
+ const onboardingState = await deps.getCourseOnboardingState(activeCourse.courseId);
41194
+ const existingProfile = remoteOnboarding?.learnerProfile ?? onboardingState?.learnerProfile;
41195
+ const existingSource = remoteOnboarding?.source ?? (onboardingState?.learnerProfile ? "cli" : void 0);
41196
+ const learnerProfile = await deps.collectLearnerContextProfile({
41197
+ userName: session.userName,
41198
+ course: matchedCourse,
41199
+ activeCourse,
41200
+ ...existingProfile ? {
41201
+ existingProfile,
41202
+ existingSource
41203
+ } : {}
41204
+ });
41205
+ const artifacts = deps.buildInitArtifacts(
41206
+ session.userName,
41207
+ matchedCourse,
41208
+ progressData,
41209
+ learnerProfile
41210
+ );
41211
+ await deps.saveRemoteEnrollmentOnboarding({
41212
+ apiUrl: session.apiUrl,
41213
+ token: session.token,
41214
+ enrollmentId: activeCourse.enrollmentId,
41215
+ learnerBrief: artifacts.learnerBrief,
41216
+ learnerProfile,
41217
+ source: "cli"
41218
+ });
41219
+ await deps.saveCourseLearnerProfile(activeCourse, learnerProfile, artifacts);
41220
+ try {
41221
+ await deps.setLastInitCourseId(activeCourse.courseId);
41222
+ } catch (err) {
41223
+ deps.logger.warn("Failed to save lastInitCourseId", { error: err });
41224
+ }
41225
+ deps.output(artifacts.tutorInstructions, { json: false });
41226
+ deps.output(artifacts.learnerBrief, { json: false });
41227
+ }
41228
+ var logger11, defaultDeps3, initCommand;
40571
41229
  var init_init = __esm({
40572
41230
  "src/commands/init.ts"() {
40573
41231
  "use strict";
@@ -40577,92 +41235,52 @@ var init_init = __esm({
40577
41235
  init_session();
40578
41236
  init_formatter();
40579
41237
  init_init_template();
41238
+ init_learner_context();
41239
+ init_api2();
40580
41240
  logger11 = createLogger("cli:init");
40581
- initCommand = new Command15("init").description("Generate LLM tutor instructions for the active course").action(async () => {
40582
- const session = await getSession();
40583
- if (!session) {
40584
- output("N\xE3o autenticado. Rode `tostudy login` para come\xE7ar.", { json: false });
40585
- return;
40586
- }
40587
- const data = createHttpProvider(session.apiUrl, session.token);
40588
- const deps = { data, logger: logger11 };
40589
- const activeCourse = await getActiveCourse();
40590
- if (!activeCourse) {
40591
- try {
40592
- const courses3 = await listCourses({ userId: session.userId }, deps);
40593
- const courseListStr = courses3.length > 0 ? courses3.map((c, i) => ` ${i + 1}. ${c.title} (${c.progress}%)`).join("\n") : " (nenhum curso encontrado)";
40594
- output(
40595
- `Nenhum curso ativo.
40596
-
40597
- Seus cursos:
40598
- ${courseListStr}
40599
-
40600
- Rode \`tostudy select <n\xFAmero>\` para ativar um curso.`,
40601
- { json: false }
40602
- );
40603
- } catch {
40604
- output("Nenhum curso ativo. Rode `tostudy courses` e `tostudy select <n\xFAmero>`.", {
40605
- json: false
40606
- });
40607
- }
40608
- return;
40609
- }
40610
- let matchedCourse = null;
40611
- try {
40612
- const courses3 = await listCourses({ userId: session.userId }, deps);
40613
- matchedCourse = courses3.find((c) => c.courseId === activeCourse.courseId) ?? null;
40614
- } catch (err) {
40615
- logger11.warn("Failed to fetch course metadata for init", { error: err });
40616
- }
40617
- if (!matchedCourse) {
40618
- matchedCourse = {
40619
- enrollmentId: activeCourse.enrollmentId,
40620
- courseId: activeCourse.courseId,
40621
- title: activeCourse.courseTitle,
40622
- progress: 0,
40623
- creatorName: "Desconhecido",
40624
- teachingApproach: "hybrid",
40625
- enrolledAt: /* @__PURE__ */ new Date()
40626
- };
40627
- }
40628
- let progressData = null;
40629
- try {
40630
- progressData = await getProgress({ enrollmentId: activeCourse.enrollmentId }, deps);
40631
- } catch (err) {
40632
- logger11.warn("Failed to fetch progress for init", { error: err });
40633
- }
40634
- try {
40635
- await setLastInitCourseId(activeCourse.courseId);
40636
- } catch (err) {
40637
- logger11.warn("Failed to save lastInitCourseId", { error: err });
40638
- }
40639
- const template = buildInitTemplate(session.userName, matchedCourse, progressData);
40640
- output(template, { json: false });
41241
+ defaultDeps3 = {
41242
+ getSession,
41243
+ getActiveCourse,
41244
+ listCourses,
41245
+ getProgress,
41246
+ getRemoteEnrollmentOnboarding,
41247
+ saveRemoteEnrollmentOnboarding,
41248
+ setLastInitCourseId,
41249
+ getCourseOnboardingState,
41250
+ collectLearnerContextProfile,
41251
+ saveCourseLearnerProfile,
41252
+ buildInitArtifacts,
41253
+ output,
41254
+ logger: logger11,
41255
+ createHttpProvider
41256
+ };
41257
+ initCommand = new Command15("init").description("Generate tutor instructions and learner brief for the active course").action(async () => {
41258
+ await runInit();
40641
41259
  });
40642
41260
  }
40643
41261
  });
40644
41262
 
40645
41263
  // ../../packages/tostudy-core/src/workspace/setup-workspace.ts
40646
- import fs8 from "node:fs/promises";
40647
- import path7 from "node:path";
40648
- async function setupWorkspace(input) {
40649
- const workspacePath = path7.join(input.basePath, input.courseSlug);
41264
+ import fs9 from "node:fs/promises";
41265
+ import path8 from "node:path";
41266
+ async function setupWorkspace(input2) {
41267
+ const workspacePath = path8.join(input2.basePath, input2.courseSlug);
40650
41268
  for (const dir of WORKSPACE_DIRS) {
40651
- await fs8.mkdir(path7.join(workspacePath, dir), { recursive: true });
41269
+ await fs9.mkdir(path8.join(workspacePath, dir), { recursive: true });
40652
41270
  }
40653
- const configPath = path7.join(workspacePath, ".ana-config.json");
41271
+ const configPath = path8.join(workspacePath, ".ana-config.json");
40654
41272
  const config2 = {
40655
- courseId: input.courseId,
40656
- courseSlug: input.courseSlug,
40657
- courseName: input.courseName,
41273
+ courseId: input2.courseId,
41274
+ courseSlug: input2.courseSlug,
41275
+ courseName: input2.courseName,
40658
41276
  workspacePath,
40659
- locale: input.locale,
41277
+ locale: input2.locale,
40660
41278
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
40661
41279
  lastAccessedAt: (/* @__PURE__ */ new Date()).toISOString()
40662
41280
  };
40663
- await fs8.writeFile(configPath, JSON.stringify(config2, null, 2), "utf-8");
41281
+ await fs9.writeFile(configPath, JSON.stringify(config2, null, 2), "utf-8");
40664
41282
  const readme = [
40665
- `# ${input.courseName}`,
41283
+ `# ${input2.courseName}`,
40666
41284
  "",
40667
41285
  "Workspace de estudo gerado pelo ToStudy.",
40668
41286
  "",
@@ -40685,7 +41303,7 @@ async function setupWorkspace(input) {
40685
41303
  "tostudy vault sync # Sincronizar progresso",
40686
41304
  "```"
40687
41305
  ].join("\n");
40688
- await fs8.writeFile(path7.join(workspacePath, "README.md"), readme, "utf-8");
41306
+ await fs9.writeFile(path8.join(workspacePath, "README.md"), readme, "utf-8");
40689
41307
  return { workspacePath, directories: WORKSPACE_DIRS, configPath };
40690
41308
  }
40691
41309
  var WORKSPACE_DIRS;
@@ -40786,8 +41404,8 @@ var init_templates = __esm({
40786
41404
  });
40787
41405
 
40788
41406
  // ../../packages/tostudy-core/src/workspace/extract-exercise.ts
40789
- import fs9 from "node:fs/promises";
40790
- import path8 from "node:path";
41407
+ import fs10 from "node:fs/promises";
41408
+ import path9 from "node:path";
40791
41409
  function padOrder(n) {
40792
41410
  return String(n).padStart(2, "0");
40793
41411
  }
@@ -40807,20 +41425,20 @@ function getStarterCode(structuredData) {
40807
41425
  const data = sd.data;
40808
41426
  return data?.starterCode ?? null;
40809
41427
  }
40810
- async function extractExercise(input) {
40811
- const { lessonData, exerciseTier, workspacePath } = input;
41428
+ async function extractExercise(input2) {
41429
+ const { lessonData, exerciseTier, workspacePath } = input2;
40812
41430
  const moduleDir = `${padOrder(lessonData.moduleOrder)}-${lessonData.moduleSlug}`;
40813
41431
  const lessonDir = `${padOrder(lessonData.lessonOrder)}-${lessonData.lessonSlug}`;
40814
- const exercisePath = path8.join(workspacePath, "exercises", moduleDir, lessonDir);
40815
- await fs9.mkdir(exercisePath, { recursive: true });
41432
+ const exercisePath = path9.join(workspacePath, "exercises", moduleDir, lessonDir);
41433
+ await fs10.mkdir(exercisePath, { recursive: true });
40816
41434
  const extractedFiles = [];
40817
41435
  let hasStarterCode = false;
40818
41436
  if (lessonData.sandpackConfig?.files) {
40819
41437
  for (const [filePath, fileData] of Object.entries(lessonData.sandpackConfig.files)) {
40820
41438
  const cleanPath = filePath.startsWith("/") ? filePath.slice(1) : filePath;
40821
- const fullPath = path8.join(exercisePath, cleanPath);
40822
- await fs9.mkdir(path8.dirname(fullPath), { recursive: true });
40823
- await fs9.writeFile(fullPath, fileData.code, "utf-8");
41439
+ const fullPath = path9.join(exercisePath, cleanPath);
41440
+ await fs10.mkdir(path9.dirname(fullPath), { recursive: true });
41441
+ await fs10.writeFile(fullPath, fileData.code, "utf-8");
40824
41442
  extractedFiles.push(cleanPath);
40825
41443
  hasStarterCode = true;
40826
41444
  }
@@ -40828,13 +41446,13 @@ async function extractExercise(input) {
40828
41446
  const tierData = getTierData(lessonData.structuredData, exerciseTier);
40829
41447
  const tierCode = tierData?.code;
40830
41448
  if (tierCode) {
40831
- await fs9.writeFile(path8.join(exercisePath, "exercise.js"), tierCode, "utf-8");
41449
+ await fs10.writeFile(path9.join(exercisePath, "exercise.js"), tierCode, "utf-8");
40832
41450
  extractedFiles.push("exercise.js");
40833
41451
  hasStarterCode = true;
40834
41452
  } else {
40835
41453
  const starter = getStarterCode(lessonData.structuredData);
40836
41454
  if (starter) {
40837
- await fs9.writeFile(path8.join(exercisePath, "exercise.js"), starter, "utf-8");
41455
+ await fs10.writeFile(path9.join(exercisePath, "exercise.js"), starter, "utf-8");
40838
41456
  extractedFiles.push("exercise.js");
40839
41457
  hasStarterCode = true;
40840
41458
  }
@@ -40852,8 +41470,8 @@ async function extractExercise(input) {
40852
41470
  ...exerciseDeps
40853
41471
  }
40854
41472
  };
40855
- await fs9.writeFile(
40856
- path8.join(exercisePath, "package.json"),
41473
+ await fs10.writeFile(
41474
+ path9.join(exercisePath, "package.json"),
40857
41475
  JSON.stringify(pkgJson, null, 2),
40858
41476
  "utf-8"
40859
41477
  );
@@ -40865,20 +41483,20 @@ async function extractExercise(input) {
40865
41483
  );
40866
41484
  for (const [configFile, configContent] of Object.entries(scaffold.configs)) {
40867
41485
  if (!sandpackFileNames.has(configFile)) {
40868
- await fs9.writeFile(path8.join(exercisePath, configFile), configContent, "utf-8");
41486
+ await fs10.writeFile(path9.join(exercisePath, configFile), configContent, "utf-8");
40869
41487
  extractedFiles.push(configFile);
40870
41488
  }
40871
41489
  }
40872
41490
  const setupSh = `#!/bin/sh
40873
41491
  ${scaffold.setupScript}
40874
41492
  `;
40875
- await fs9.writeFile(path8.join(exercisePath, "setup.sh"), setupSh, "utf-8");
41493
+ await fs10.writeFile(path9.join(exercisePath, "setup.sh"), setupSh, "utf-8");
40876
41494
  extractedFiles.push("setup.sh");
40877
41495
  }
40878
41496
  }
40879
41497
  const readme = generateReadme(lessonData, exerciseTier);
40880
- const readmePath = path8.join(exercisePath, "README.md");
40881
- await fs9.writeFile(readmePath, readme, "utf-8");
41498
+ const readmePath = path9.join(exercisePath, "README.md");
41499
+ await fs10.writeFile(readmePath, readme, "utf-8");
40882
41500
  extractedFiles.push("README.md");
40883
41501
  return {
40884
41502
  exercisePath,
@@ -40944,14 +41562,15 @@ var init_workspace = __esm({
40944
41562
  init_extract_exercise();
40945
41563
  init_export_artifact();
40946
41564
  init_templates();
41565
+ init_lesson_exercise_data();
40947
41566
  }
40948
41567
  });
40949
41568
 
40950
41569
  // src/commands/workspace.ts
40951
41570
  import { Command as Command16 } from "commander";
40952
- import path9 from "node:path";
41571
+ import path10 from "node:path";
40953
41572
  import os7 from "node:os";
40954
- import fs10 from "node:fs/promises";
41573
+ import fs11 from "node:fs/promises";
40955
41574
  var logger12, workspaceCommand;
40956
41575
  var init_workspace2 = __esm({
40957
41576
  "src/commands/workspace.ts"() {
@@ -40963,7 +41582,7 @@ var init_workspace2 = __esm({
40963
41582
  workspaceCommand = new Command16("workspace").description(
40964
41583
  "Gerenciar workspace de estudo local"
40965
41584
  );
40966
- workspaceCommand.command("setup").description("Criar estrutura do workspace para o curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace", path9.join(os7.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
41585
+ workspaceCommand.command("setup").description("Criar estrutura do workspace para o curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace", path10.join(os7.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
40967
41586
  try {
40968
41587
  await requireSession();
40969
41588
  const activeCourse = await requireActiveCourse();
@@ -40974,6 +41593,7 @@ var init_workspace2 = __esm({
40974
41593
  basePath: opts.path,
40975
41594
  locale: "pt-BR"
40976
41595
  });
41596
+ await setCourseWorkspacePath(activeCourse.courseId, result.workspacePath);
40977
41597
  if (opts.json) {
40978
41598
  process.stdout.write(JSON.stringify(result, null, 2) + "\n");
40979
41599
  } else {
@@ -40995,14 +41615,14 @@ Pr\xF3ximo passo: tostudy export
40995
41615
  process.exit(1);
40996
41616
  }
40997
41617
  });
40998
- workspaceCommand.command("status").description("Mostrar status do workspace do curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace", path9.join(os7.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
41618
+ workspaceCommand.command("status").description("Mostrar status do workspace do curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace", path10.join(os7.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
40999
41619
  try {
41000
41620
  const activeCourse = await requireActiveCourse();
41001
41621
  const courseSlug2 = activeCourse.courseTitle.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
41002
- const workspacePath = path9.join(opts.path, courseSlug2);
41622
+ const workspacePath = path10.join(opts.path, courseSlug2);
41003
41623
  let configData = null;
41004
41624
  try {
41005
- const raw = await fs10.readFile(path9.join(workspacePath, ".ana-config.json"), "utf-8");
41625
+ const raw = await fs11.readFile(path10.join(workspacePath, ".ana-config.json"), "utf-8");
41006
41626
  configData = JSON.parse(raw);
41007
41627
  } catch {
41008
41628
  process.stderr.write(
@@ -41010,42 +41630,42 @@ Pr\xF3ximo passo: tostudy export
41010
41630
  );
41011
41631
  process.exit(1);
41012
41632
  }
41013
- const exercisesDir = path9.join(workspacePath, "exercises");
41633
+ const exercisesDir = path10.join(workspacePath, "exercises");
41014
41634
  let exerciseCount = 0;
41015
41635
  try {
41016
- const moduleDirs = await fs10.readdir(exercisesDir);
41636
+ const moduleDirs = await fs11.readdir(exercisesDir);
41017
41637
  for (const modDir of moduleDirs) {
41018
- const modPath = path9.join(exercisesDir, modDir);
41019
- const stat = await fs10.stat(modPath);
41638
+ const modPath = path10.join(exercisesDir, modDir);
41639
+ const stat = await fs11.stat(modPath);
41020
41640
  if (stat.isDirectory()) {
41021
- const lessonDirs = await fs10.readdir(modPath);
41641
+ const lessonDirs = await fs11.readdir(modPath);
41022
41642
  for (const lessonDir of lessonDirs) {
41023
- const lessonPath = path9.join(modPath, lessonDir);
41024
- const lstat = await fs10.stat(lessonPath);
41643
+ const lessonPath = path10.join(modPath, lessonDir);
41644
+ const lstat = await fs11.stat(lessonPath);
41025
41645
  if (lstat.isDirectory()) exerciseCount++;
41026
41646
  }
41027
41647
  }
41028
41648
  }
41029
41649
  } catch {
41030
41650
  }
41031
- const generatedDir = path9.join(workspacePath, "generated");
41651
+ const generatedDir = path10.join(workspacePath, "generated");
41032
41652
  let artifactCount = 0;
41033
41653
  try {
41034
- const files = await fs10.readdir(generatedDir);
41654
+ const files = await fs11.readdir(generatedDir);
41035
41655
  artifactCount = files.length;
41036
41656
  } catch {
41037
41657
  }
41038
- const diagramsDir = path9.join(workspacePath, "diagrams");
41658
+ const diagramsDir = path10.join(workspacePath, "diagrams");
41039
41659
  let diagramCount = 0;
41040
41660
  try {
41041
- const files = await fs10.readdir(diagramsDir);
41661
+ const files = await fs11.readdir(diagramsDir);
41042
41662
  diagramCount = files.length;
41043
41663
  } catch {
41044
41664
  }
41045
- const vaultDir = path9.join(workspacePath, "vault");
41665
+ const vaultDir = path10.join(workspacePath, "vault");
41046
41666
  let hasVault = false;
41047
41667
  try {
41048
- await fs10.access(path9.join(vaultDir, ".ana-vault.json"));
41668
+ await fs11.access(path10.join(vaultDir, ".ana-vault.json"));
41049
41669
  hasVault = true;
41050
41670
  } catch {
41051
41671
  }
@@ -41089,7 +41709,7 @@ Pr\xF3ximo passo: tostudy export
41089
41709
 
41090
41710
  // src/commands/export.ts
41091
41711
  import { Command as Command17 } from "commander";
41092
- import path10 from "node:path";
41712
+ import path11 from "node:path";
41093
41713
  import os8 from "node:os";
41094
41714
  var logger13, exportCommand;
41095
41715
  var init_export = __esm({
@@ -41101,7 +41721,7 @@ var init_export = __esm({
41101
41721
  init_session();
41102
41722
  init_resolve();
41103
41723
  logger13 = createLogger("cli:export");
41104
- exportCommand = new Command17("export").description("Extrair exerc\xEDcio atual para o workspace local").option("--tier <tier>", "Tier do exerc\xEDcio: guided, semiGuided, challenging", "guided").option("--path <dir>", "Diret\xF3rio base do workspace", path10.join(os8.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
41724
+ exportCommand = new Command17("export").description("Extrair exerc\xEDcio atual para o workspace local").option("--tier <tier>", "Tier do exerc\xEDcio: guided, semiGuided, challenging", "guided").option("--path <dir>", "Diret\xF3rio base do workspace", path11.join(os8.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
41105
41725
  try {
41106
41726
  const session = await requireSession();
41107
41727
  const activeCourse = await requireActiveCourse();
@@ -41157,14 +41777,14 @@ ${result.files.map((f) => ` \u{1F4C4} ${f}`).join("\n")}
41157
41777
  // src/commands/open.ts
41158
41778
  import { Command as Command18 } from "commander";
41159
41779
  import { execFile as execFile3 } from "node:child_process";
41160
- import fs11 from "node:fs/promises";
41161
- import path11 from "node:path";
41780
+ import fs12 from "node:fs/promises";
41781
+ import path12 from "node:path";
41162
41782
  import os9 from "node:os";
41163
41783
  async function findWorkspacePath(courseTitle, basePath) {
41164
41784
  const slug = courseTitle.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
41165
- const candidate = path11.join(basePath, slug);
41785
+ const candidate = path12.join(basePath, slug);
41166
41786
  try {
41167
- await fs11.access(path11.join(candidate, ".ana-config.json"));
41787
+ await fs12.access(path12.join(candidate, ".ana-config.json"));
41168
41788
  return candidate;
41169
41789
  } catch {
41170
41790
  return null;
@@ -41177,7 +41797,7 @@ var init_open = __esm({
41177
41797
  init_src();
41178
41798
  init_session();
41179
41799
  logger14 = createLogger("cli:open");
41180
- openCommand = new Command18("open").description("Abrir workspace do curso na IDE").option("--path <dir>", "Diret\xF3rio base do workspace", path11.join(os9.homedir(), "study")).action(async (opts) => {
41800
+ openCommand = new Command18("open").description("Abrir workspace do curso na IDE").option("--path <dir>", "Diret\xF3rio base do workspace", path12.join(os9.homedir(), "study")).action(async (opts) => {
41181
41801
  try {
41182
41802
  const activeCourse = await requireActiveCourse();
41183
41803
  const workspacePath = await findWorkspacePath(activeCourse.courseTitle, opts.path);
@@ -41226,24 +41846,24 @@ var init_types3 = __esm({
41226
41846
  });
41227
41847
 
41228
41848
  // ../../packages/tostudy-core/src/vault/write-vault.ts
41229
- import fs12 from "node:fs/promises";
41230
- import path12 from "node:path";
41849
+ import fs13 from "node:fs/promises";
41850
+ import path13 from "node:path";
41231
41851
  async function writeVaultFiles(files, outputPath, courseId, courseSlug2) {
41232
41852
  for (const file2 of files) {
41233
- const fullPath = path12.join(outputPath, file2.relativePath);
41234
- await fs12.mkdir(path12.dirname(fullPath), { recursive: true });
41235
- await fs12.writeFile(fullPath, file2.content, "utf-8");
41853
+ const fullPath = path13.join(outputPath, file2.relativePath);
41854
+ await fs13.mkdir(path13.dirname(fullPath), { recursive: true });
41855
+ await fs13.writeFile(fullPath, file2.content, "utf-8");
41236
41856
  }
41237
- const vaultPath = path12.join(outputPath, courseSlug2);
41857
+ const vaultPath = path13.join(outputPath, courseSlug2);
41238
41858
  const marker = {
41239
41859
  courseId,
41240
41860
  courseSlug: courseSlug2,
41241
41861
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
41242
41862
  version: VAULT_MARKER_VERSION
41243
41863
  };
41244
- await fs12.mkdir(vaultPath, { recursive: true });
41245
- await fs12.writeFile(
41246
- path12.join(vaultPath, VAULT_MARKER_FILENAME),
41864
+ await fs13.mkdir(vaultPath, { recursive: true });
41865
+ await fs13.writeFile(
41866
+ path13.join(vaultPath, VAULT_MARKER_FILENAME),
41247
41867
  JSON.stringify(marker, null, 2),
41248
41868
  "utf-8"
41249
41869
  );
@@ -41268,9 +41888,9 @@ var init_vault = __esm({
41268
41888
 
41269
41889
  // src/commands/vault.ts
41270
41890
  import { Command as Command19 } from "commander";
41271
- import path13 from "node:path";
41891
+ import path14 from "node:path";
41272
41892
  import os10 from "node:os";
41273
- import fs13 from "node:fs/promises";
41893
+ import fs14 from "node:fs/promises";
41274
41894
  var logger15, vaultCommand;
41275
41895
  var init_vault2 = __esm({
41276
41896
  "src/commands/vault.ts"() {
@@ -41282,15 +41902,15 @@ var init_vault2 = __esm({
41282
41902
  init_session();
41283
41903
  logger15 = createLogger("cli:vault");
41284
41904
  vaultCommand = new Command19("vault").description("Gerenciar vault Obsidian do curso");
41285
- vaultCommand.command("init").description("Gerar vault Obsidian para o curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace", path13.join(os10.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
41905
+ vaultCommand.command("init").description("Gerar vault Obsidian para o curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace", path14.join(os10.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
41286
41906
  try {
41287
41907
  const session = await requireSession();
41288
41908
  const activeCourse = await requireActiveCourse();
41289
41909
  const driftWarning = await checkCourseDrift();
41290
41910
  if (driftWarning) process.stderr.write(driftWarning + "\n");
41291
41911
  const courseSlug2 = activeCourse.courseTitle.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
41292
- const workspacePath = path13.join(opts.path, courseSlug2);
41293
- const vaultOutputPath = path13.join(workspacePath, "vault");
41912
+ const workspacePath = path14.join(opts.path, courseSlug2);
41913
+ const vaultOutputPath = path14.join(workspacePath, "vault");
41294
41914
  const res = await fetch(`${session.apiUrl}/api/cli/vault/init`, {
41295
41915
  method: "POST",
41296
41916
  headers: {
@@ -41353,16 +41973,16 @@ Para visualizar:
41353
41973
  process.exit(1);
41354
41974
  }
41355
41975
  });
41356
- vaultCommand.command("sync").description("Sincronizar progresso do curso com o vault local").option("--path <dir>", "Diret\xF3rio base do workspace", path13.join(os10.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
41976
+ vaultCommand.command("sync").description("Sincronizar progresso do curso com o vault local").option("--path <dir>", "Diret\xF3rio base do workspace", path14.join(os10.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
41357
41977
  try {
41358
41978
  const session = await requireSession();
41359
41979
  const activeCourse = await requireActiveCourse();
41360
41980
  const driftWarning = await checkCourseDrift();
41361
41981
  if (driftWarning) process.stderr.write(driftWarning + "\n");
41362
41982
  const courseSlug2 = activeCourse.courseTitle.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
41363
- const vaultPath = path13.join(opts.path, courseSlug2, "vault");
41983
+ const vaultPath = path14.join(opts.path, courseSlug2, "vault");
41364
41984
  try {
41365
- await fs13.access(path13.join(vaultPath, ".ana-vault.json"));
41985
+ await fs14.access(path14.join(vaultPath, ".ana-vault.json"));
41366
41986
  } catch {
41367
41987
  process.stderr.write("\u274C Vault n\xE3o encontrado. Execute 'tostudy vault init' primeiro.\n");
41368
41988
  process.exit(1);
@@ -41370,8 +41990,8 @@ Para visualizar:
41370
41990
  const data = createHttpProvider(session.apiUrl, session.token);
41371
41991
  const deps = { data, logger: logger15 };
41372
41992
  const progress3 = await getProgress({ enrollmentId: activeCourse.enrollmentId }, deps);
41373
- const markerPath = path13.join(vaultPath, ".ana-vault.json");
41374
- const markerRaw = await fs13.readFile(markerPath, "utf-8");
41993
+ const markerPath = path14.join(vaultPath, ".ana-vault.json");
41994
+ const markerRaw = await fs14.readFile(markerPath, "utf-8");
41375
41995
  const marker = JSON.parse(markerRaw);
41376
41996
  marker.lastSyncedAt = (/* @__PURE__ */ new Date()).toISOString();
41377
41997
  marker.progress = {
@@ -41379,10 +41999,10 @@ Para visualizar:
41379
41999
  currentModule: progress3.currentModule.title,
41380
42000
  currentLesson: progress3.currentLesson.title
41381
42001
  };
41382
- await fs13.writeFile(markerPath, JSON.stringify(marker, null, 2), "utf-8");
41383
- const courseIndexPath = path13.join(vaultPath, courseSlug2, "index.md");
42002
+ await fs14.writeFile(markerPath, JSON.stringify(marker, null, 2), "utf-8");
42003
+ const courseIndexPath = path14.join(vaultPath, courseSlug2, "index.md");
41384
42004
  try {
41385
- let indexContent = await fs13.readFile(courseIndexPath, "utf-8");
42005
+ let indexContent = await fs14.readFile(courseIndexPath, "utf-8");
41386
42006
  indexContent = indexContent.replace(/\n---\n\n> 📊 Progresso:.*\n/g, "");
41387
42007
  const titleEnd = indexContent.indexOf("\n");
41388
42008
  if (titleEnd !== -1) {
@@ -41393,7 +42013,7 @@ Para visualizar:
41393
42013
  `;
41394
42014
  indexContent = indexContent.slice(0, titleEnd) + banner + indexContent.slice(titleEnd);
41395
42015
  }
41396
- await fs13.writeFile(courseIndexPath, indexContent, "utf-8");
42016
+ await fs14.writeFile(courseIndexPath, indexContent, "utf-8");
41397
42017
  } catch {
41398
42018
  }
41399
42019
  const syncedAt = marker.lastSyncedAt;