@tostudy-ai/cli 0.18.4 → 0.18.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -40,7 +40,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
40
40
  mod
41
41
  ));
42
42
 
43
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/@parisgroup-ai/logger/dist/sanitize-Cu_Xsxno.mjs
43
+ // ../../node_modules/@parisgroup-ai/logger/dist/sanitize-CP9aWCdx.mjs
44
44
  function isSensitiveKey(key) {
45
45
  if (matchesSensitiveField(key)) return true;
46
46
  return matchesPluralOfSensitiveField(key);
@@ -148,8 +148,8 @@ function sanitizeEntryData(obj, additionalSensitiveKeys, includeStack, redactMas
148
148
  });
149
149
  }
150
150
  var SENSITIVE_FIELDS;
151
- var init_sanitize_Cu_Xsxno = __esm({
152
- "../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/@parisgroup-ai/logger/dist/sanitize-Cu_Xsxno.mjs"() {
151
+ var init_sanitize_CP9aWCdx = __esm({
152
+ "../../node_modules/@parisgroup-ai/logger/dist/sanitize-CP9aWCdx.mjs"() {
153
153
  SENSITIVE_FIELDS = [
154
154
  "password",
155
155
  "senha",
@@ -208,9 +208,9 @@ var init_sanitize_Cu_Xsxno = __esm({
208
208
  }
209
209
  });
210
210
 
211
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/picocolors/picocolors.js
211
+ // ../../node_modules/picocolors/picocolors.js
212
212
  var require_picocolors = __commonJS({
213
- "../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/picocolors/picocolors.js"(exports, module) {
213
+ "../../node_modules/picocolors/picocolors.js"(exports, module) {
214
214
  var p = process || {};
215
215
  var argv = p.argv || [];
216
216
  var env = p.env || {};
@@ -280,7 +280,7 @@ var require_picocolors = __commonJS({
280
280
  }
281
281
  });
282
282
 
283
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/@parisgroup-ai/logger/dist/logger.base-DkCKo9Cu.mjs
283
+ // ../../node_modules/@parisgroup-ai/logger/dist/logger.base-B6ycMyex.mjs
284
284
  function formatJson(entry) {
285
285
  const { timestamp, level, message, service, environment, context, data, error: error49 } = entry;
286
286
  const output3 = {
@@ -376,17 +376,19 @@ function extractErrorInfo(error49, includeStack, visited = /* @__PURE__ */ new W
376
376
  if (includeStack && error49.stack) info.stack = error49.stack;
377
377
  if ("code" in error49 && typeof error49.code === "string") info.code = error49.code;
378
378
  visited.add(error49);
379
- if (error49.cause instanceof Error) if (visited.has(error49.cause)) info.cause = {
380
- name: error49.cause.name,
381
- message: "[Circular]"
382
- };
383
- else info.cause = extractErrorInfo(error49.cause, includeStack, visited);
379
+ if (error49.cause instanceof Error) {
380
+ if (visited.has(error49.cause)) info.cause = {
381
+ name: error49.cause.name,
382
+ message: "[Circular]"
383
+ };
384
+ else info.cause = extractErrorInfo(error49.cause, includeStack, visited);
385
+ }
384
386
  return info;
385
387
  }
386
388
  var import_picocolors, LOG_LEVELS, LEVEL_COLORS, LEVEL_WIDTH, BaseLogger;
387
- var init_logger_base_DkCKo9Cu = __esm({
388
- "../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/@parisgroup-ai/logger/dist/logger.base-DkCKo9Cu.mjs"() {
389
- init_sanitize_Cu_Xsxno();
389
+ var init_logger_base_B6ycMyex = __esm({
390
+ "../../node_modules/@parisgroup-ai/logger/dist/logger.base-B6ycMyex.mjs"() {
391
+ init_sanitize_CP9aWCdx();
390
392
  import_picocolors = __toESM(require_picocolors(), 1);
391
393
  LOG_LEVELS = {
392
394
  trace: 0,
@@ -593,7 +595,7 @@ var init_logger_base_DkCKo9Cu = __esm({
593
595
  }
594
596
  });
595
597
 
596
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/@parisgroup-ai/logger/dist/index.mjs
598
+ // ../../node_modules/@parisgroup-ai/logger/dist/index.mjs
597
599
  import { AsyncLocalStorage } from "node:async_hooks";
598
600
  import { appendFileSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
599
601
  import { join } from "node:path";
@@ -706,9 +708,9 @@ function createLogger(module, options) {
706
708
  }
707
709
  var asyncLocalStorage, ConsoleTransport, FileTransport, HttpTransport, SINGLETON_KEY$1, SEVERITY, OtlpLogsTransport, SINGLETON_KEY, Logger, logger;
708
710
  var init_dist = __esm({
709
- "../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/@parisgroup-ai/logger/dist/index.mjs"() {
710
- init_logger_base_DkCKo9Cu();
711
- init_sanitize_Cu_Xsxno();
711
+ "../../node_modules/@parisgroup-ai/logger/dist/index.mjs"() {
712
+ init_logger_base_B6ycMyex();
713
+ init_sanitize_CP9aWCdx();
712
714
  asyncLocalStorage = new AsyncLocalStorage();
713
715
  ConsoleTransport = class {
714
716
  log(entry, formatted) {
@@ -743,7 +745,10 @@ var init_dist = __esm({
743
745
  });
744
746
  }
745
747
  flush() {
746
- for (const { file: file2, content } of this.buffer) appendFileSync(join(this.dir, file2), content);
748
+ for (const { file: file2, content } of this.buffer) {
749
+ const filepath = join(this.dir, file2);
750
+ appendFileSync(filepath, content);
751
+ }
747
752
  this.buffer = [];
748
753
  }
749
754
  };
@@ -1029,6 +1034,13 @@ var init_errors_pt_br = __esm({
1029
1034
  enrollDone: "Matriculado. Rode `tostudy courses` e depois `tostudy select <n>`.",
1030
1035
  enrollDoneWebOnly: "Matriculado. Este curso n\xE3o abre no terminal. Continue no navegador:",
1031
1036
  enrollPaid: "Este curso \xE9 pago. A matr\xEDcula fica no navegador e nada \xE9 debitado por aqui:",
1037
+ suggestCommandDescription: "Sugere at\xE9 3 cursos gratuitos para matricular no terminal.",
1038
+ suggestEmpty: "Nenhum curso gratuito dispon\xEDvel para o terminal.",
1039
+ suggestNoWorkspace: "Sem contexto nesta pasta. Usei s\xF3 o perfil.",
1040
+ suggestNoOverlap: "Sem coincid\xEAncia com o perfil.",
1041
+ suggestEmptyProfile: "Perfil vazio. Mostrando cursos gratuitos em aberto.",
1042
+ suggestReason: "Motivo:",
1043
+ suggestPaidHeader: "Pagos. A matr\xEDcula fica no navegador e nada \xE9 debitado por aqui:",
1032
1044
  enrollmentNotEntitled: "\u{1F6AB} Sua matr\xEDcula neste curso n\xE3o est\xE1 mais ativa (reembolso, cancelamento ou preview expirado).\nPara voltar a estudar, adquira o curso novamente em https://tostudy.ai.\n",
1033
1045
  creator: {
1034
1046
  loginBrowserOnly: "`--creator` s\xF3 funciona no login pelo browser. Rode `tostudy login --creator` sem --code, --magic-link ou --manual.",
@@ -1131,6 +1143,13 @@ var init_errors_en_us = __esm({
1131
1143
  enrollDone: "Enrolled. Run `tostudy courses`, then `tostudy select <n>`.",
1132
1144
  enrollDoneWebOnly: "Enrolled. This course does not open in the terminal. Continue in the browser:",
1133
1145
  enrollPaid: "This course is paid. Enrollment stays in the browser and nothing is charged here:",
1146
+ suggestCommandDescription: "Suggest up to 3 free courses to enroll in from the terminal.",
1147
+ suggestEmpty: "No free course is available for the terminal.",
1148
+ suggestNoWorkspace: "No context in this folder. Only the profile was used.",
1149
+ suggestNoOverlap: "No word in the profile matched.",
1150
+ suggestEmptyProfile: "Profile is empty. Showing open free courses.",
1151
+ suggestReason: "Why:",
1152
+ suggestPaidHeader: "Paid. Enrollment stays in the browser and nothing is charged here:",
1134
1153
  enrollmentNotEntitled: "\u{1F6AB} Your enrollment in this course is no longer active (refund, cancellation, or expired preview).\nTo study again, purchase the course at https://tostudy.ai.\n",
1135
1154
  creator: {
1136
1155
  loginBrowserOnly: "`--creator` only works with the browser login. Run `tostudy login --creator` without --code, --magic-link or --manual.",
@@ -1486,17 +1505,17 @@ var init_session_store = __esm({
1486
1505
  }
1487
1506
  });
1488
1507
 
1489
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/slug.ts
1508
+ // ../../packages/tostudy-core/src/slug.ts
1490
1509
  function slugify(text2, maxLength = 60) {
1491
1510
  return text2.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, maxLength).replace(/-+$/, "");
1492
1511
  }
1493
1512
  var init_slug = __esm({
1494
- "../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/slug.ts"() {
1513
+ "../../packages/tostudy-core/src/slug.ts"() {
1495
1514
  "use strict";
1496
1515
  }
1497
1516
  });
1498
1517
 
1499
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/lessons/workspace-tokens.ts
1518
+ // ../../packages/tostudy-core/src/lessons/workspace-tokens.ts
1500
1519
  function resolveWorkspaceTokensInText(text2, paths) {
1501
1520
  return text2.replace(WORKSPACE_TOKEN, () => paths.workspace).replace(VAULT_TOKEN, () => paths.vault);
1502
1521
  }
@@ -1523,7 +1542,7 @@ function resolveWorkspaceTokens(value, paths) {
1523
1542
  }
1524
1543
  var WORKSPACE_TOKEN, VAULT_TOKEN;
1525
1544
  var init_workspace_tokens = __esm({
1526
- "../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/lessons/workspace-tokens.ts"() {
1545
+ "../../packages/tostudy-core/src/lessons/workspace-tokens.ts"() {
1527
1546
  "use strict";
1528
1547
  init_slug();
1529
1548
  WORKSPACE_TOKEN = /\$WORKSPACE(?![A-Za-z0-9_])/g;
@@ -2732,6 +2751,7 @@ async function readWorkspaceState(workspacePath) {
2732
2751
  };
2733
2752
  if (typeof raw2.currentLessonId === "string") state.currentLessonId = raw2.currentLessonId;
2734
2753
  if (typeof raw2.currentModuleId === "string") state.currentModuleId = raw2.currentModuleId;
2754
+ if (typeof raw2.retryLessonId === "string") state.retryLessonId = raw2.retryLessonId;
2735
2755
  if (Array.isArray(raw2.courseTags)) state.courseTags = raw2.courseTags;
2736
2756
  if (raw2.courseLevel === "beginner" || raw2.courseLevel === "intermediate" || raw2.courseLevel === "advanced" || raw2.courseLevel === null) {
2737
2757
  state.courseLevel = raw2.courseLevel;
@@ -3150,7 +3170,7 @@ var init_guards = __esm({
3150
3170
  });
3151
3171
 
3152
3172
  // src/cli.ts
3153
- import { Command as Command38 } from "commander";
3173
+ import { Command as Command39 } from "commander";
3154
3174
 
3155
3175
  // src/commands/login.ts
3156
3176
  init_dist();
@@ -3158,25 +3178,25 @@ import { Command } from "commander";
3158
3178
  import { execFile as execFile2 } from "node:child_process";
3159
3179
  import { randomBytes } from "node:crypto";
3160
3180
 
3161
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/courses/list-courses.ts
3181
+ // ../../packages/tostudy-core/src/courses/list-courses.ts
3162
3182
  async function listCourses(input2, deps) {
3163
3183
  deps.logger.info("tostudy-core: listCourses", { userId: input2.userId });
3164
3184
  return deps.data.courses.list(input2.userId);
3165
3185
  }
3166
3186
 
3167
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/courses/select-course.ts
3187
+ // ../../packages/tostudy-core/src/courses/select-course.ts
3168
3188
  async function selectCourse(input2, deps) {
3169
3189
  deps.logger.info("tostudy-core: selectCourse", input2);
3170
3190
  return deps.data.courses.select(input2.userId, input2.courseId);
3171
3191
  }
3172
3192
 
3173
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/courses/get-progress.ts
3193
+ // ../../packages/tostudy-core/src/courses/get-progress.ts
3174
3194
  async function getProgress(input2, deps) {
3175
3195
  deps.logger.info("tostudy-core: getProgress", input2);
3176
3196
  return deps.data.courses.getProgress(input2.enrollmentId);
3177
3197
  }
3178
3198
 
3179
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/adapters/http.ts
3199
+ // ../../packages/tostudy-core/src/adapters/http.ts
3180
3200
  var CliApiError = class extends Error {
3181
3201
  constructor(message, status, code) {
3182
3202
  super(message);
@@ -3796,7 +3816,7 @@ init_workspace_state();
3796
3816
  init_formatter();
3797
3817
 
3798
3818
  // src/version.ts
3799
- var CLI_VERSION = true ? "0.18.4" : "0.7.1";
3819
+ var CLI_VERSION = true ? "0.18.6" : "0.7.1";
3800
3820
 
3801
3821
  // src/update-checker.ts
3802
3822
  init_config_dir();
@@ -4292,10 +4312,295 @@ var coursesCommand = new Command5("courses").description("List your enrolled cou
4292
4312
  }
4293
4313
  });
4294
4314
 
4295
- // src/commands/enroll.ts
4315
+ // src/commands/suggest.ts
4296
4316
  import { Command as Command6 } from "commander";
4297
4317
  init_guards();
4298
4318
  init_errors();
4319
+
4320
+ // src/learner-brief/api.ts
4321
+ async function fetchLearnerBrief(input2) {
4322
+ const response = await cliApiFetch(
4323
+ `${input2.apiUrl}/api/cli/student/learner-brief`,
4324
+ input2.token
4325
+ );
4326
+ return response.brief;
4327
+ }
4328
+ async function upsertLearnerBrief(input2) {
4329
+ const response = await cliApiFetch(
4330
+ `${input2.apiUrl}/api/cli/student/learner-brief`,
4331
+ input2.token,
4332
+ {
4333
+ method: "POST",
4334
+ body: JSON.stringify({ text: input2.text, source: input2.source })
4335
+ }
4336
+ );
4337
+ return response.brief;
4338
+ }
4339
+
4340
+ // src/commands/suggest.ts
4341
+ init_user_profile();
4342
+ init_formatter();
4343
+
4344
+ // src/commands/suggest-score.ts
4345
+ var STOP_WORDS = /* @__PURE__ */ new Set([
4346
+ "de",
4347
+ "da",
4348
+ "do",
4349
+ "das",
4350
+ "dos",
4351
+ "para",
4352
+ "com",
4353
+ "uma",
4354
+ "um",
4355
+ "the",
4356
+ "and",
4357
+ "for",
4358
+ "you",
4359
+ "seu",
4360
+ "sua",
4361
+ "curso",
4362
+ "course"
4363
+ ]);
4364
+ var TOKEN_SPLIT = /[^\p{L}\p{N}]+/u;
4365
+ var MAX_RESULTS = 3;
4366
+ var MAX_REASON_TOKENS = 3;
4367
+ var LEVEL_BONUS = 2;
4368
+ function tokensOf(value, dropStops) {
4369
+ const seen = /* @__PURE__ */ new Set();
4370
+ const tokens = [];
4371
+ for (const raw2 of value.toLowerCase().split(TOKEN_SPLIT)) {
4372
+ if (raw2.length < 3 || seen.has(raw2)) continue;
4373
+ if (dropStops && STOP_WORDS.has(raw2)) continue;
4374
+ seen.add(raw2);
4375
+ tokens.push(raw2);
4376
+ }
4377
+ return tokens;
4378
+ }
4379
+ function tokenSet(parts) {
4380
+ return new Set(tokensOf(parts.join(" "), false));
4381
+ }
4382
+ function haystack(course) {
4383
+ return tokenSet([
4384
+ course.title,
4385
+ course.tags.join(" "),
4386
+ course.description,
4387
+ course.level,
4388
+ course.category
4389
+ ]);
4390
+ }
4391
+ function haystackWithoutLevel(course) {
4392
+ return tokenSet([course.title, course.tags.join(" "), course.description, course.category]);
4393
+ }
4394
+ function rankSuggestions(courses, query) {
4395
+ const text2 = query.text.trim();
4396
+ const level = query.level;
4397
+ if (text2 === "" && level === null) {
4398
+ return courses.slice(0, MAX_RESULTS).map((course) => ({
4399
+ course,
4400
+ reason: "empty-profile"
4401
+ }));
4402
+ }
4403
+ const textTokens = tokensOf(text2, true);
4404
+ const levelTokens = level === null ? [] : tokensOf(level, false);
4405
+ const scored = courses.map((course) => {
4406
+ const stack = haystack(course);
4407
+ const outsideLevel = haystackWithoutLevel(course);
4408
+ const hits = [];
4409
+ const seen = /* @__PURE__ */ new Set();
4410
+ for (const token of textTokens) {
4411
+ if (seen.has(token) || !stack.has(token)) continue;
4412
+ seen.add(token);
4413
+ hits.push(token);
4414
+ }
4415
+ for (const token of levelTokens) {
4416
+ if (seen.has(token) || !outsideLevel.has(token)) continue;
4417
+ seen.add(token);
4418
+ hits.push(token);
4419
+ }
4420
+ const levelBonus = level !== null && course.level.toLowerCase() === level.trim().toLowerCase() ? LEVEL_BONUS : 0;
4421
+ return {
4422
+ course,
4423
+ score: hits.length + levelBonus,
4424
+ reason: hits.slice(0, MAX_REASON_TOKENS).join(",") || "no-overlap"
4425
+ };
4426
+ });
4427
+ scored.sort((left, right) => {
4428
+ if (right.score !== left.score) return right.score - left.score;
4429
+ return left.course.title.localeCompare(right.course.title);
4430
+ });
4431
+ return scored.slice(0, MAX_RESULTS).map(({ course, reason }) => ({ course, reason }));
4432
+ }
4433
+
4434
+ // src/commands/suggest-workspace.ts
4435
+ import fs11 from "node:fs";
4436
+ import path13 from "node:path";
4437
+ var DOC_LINE_LIMIT = 40;
4438
+ var MIN_TOKEN_LENGTH = 3;
4439
+ var FENCE_LINE = /^[ \t]{0,3}```/;
4440
+ function readWorkspaceSignals(cwd) {
4441
+ const packagePath = path13.join(cwd, "package.json");
4442
+ const readmePath = path13.join(cwd, "README.md");
4443
+ const agentsPath = path13.join(cwd, "AGENTS.md");
4444
+ const hasPackage = fs11.existsSync(packagePath);
4445
+ const hasReadme = fs11.existsSync(readmePath);
4446
+ const hasAgents = fs11.existsSync(agentsPath);
4447
+ if (!hasPackage && !hasReadme && !hasAgents) {
4448
+ return { tokens: [], found: false };
4449
+ }
4450
+ const tokens = [];
4451
+ if (hasPackage) tokens.push(...readPackageTokens(packagePath));
4452
+ const docPath = hasReadme ? readmePath : hasAgents ? agentsPath : null;
4453
+ if (docPath) tokens.push(...readDocTokens(docPath));
4454
+ return { tokens: dedupe(tokens), found: true };
4455
+ }
4456
+ function readPackageTokens(filePath) {
4457
+ const raw2 = readUtf8(filePath);
4458
+ if (raw2 === null) return [];
4459
+ let parsed;
4460
+ try {
4461
+ parsed = JSON.parse(raw2);
4462
+ } catch {
4463
+ return [];
4464
+ }
4465
+ if (!isRecord(parsed)) return [];
4466
+ const names = [
4467
+ ...dependencyNames(parsed.dependencies),
4468
+ ...dependencyNames(parsed.devDependencies)
4469
+ ];
4470
+ return tokenize(names.join("\n"));
4471
+ }
4472
+ function readDocTokens(filePath) {
4473
+ const raw2 = readUtf8(filePath);
4474
+ if (raw2 === null) return [];
4475
+ const lines = raw2.split(/\r?\n/).slice(0, DOC_LINE_LIMIT);
4476
+ return tokenize(stripFencedBlocks(lines));
4477
+ }
4478
+ function stripFencedBlocks(lines) {
4479
+ const kept = [];
4480
+ let inFence = false;
4481
+ for (const line of lines) {
4482
+ if (FENCE_LINE.test(line)) {
4483
+ inFence = !inFence;
4484
+ continue;
4485
+ }
4486
+ if (!inFence) kept.push(line);
4487
+ }
4488
+ return kept.join("\n");
4489
+ }
4490
+ function dependencyNames(value) {
4491
+ if (!isRecord(value)) return [];
4492
+ return Object.keys(value);
4493
+ }
4494
+ function isRecord(value) {
4495
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4496
+ }
4497
+ function tokenize(text2) {
4498
+ return text2.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter((token) => token.length >= MIN_TOKEN_LENGTH);
4499
+ }
4500
+ function dedupe(tokens) {
4501
+ return [...new Set(tokens)];
4502
+ }
4503
+ function readUtf8(filePath) {
4504
+ try {
4505
+ return fs11.readFileSync(filePath, "utf8");
4506
+ } catch {
4507
+ return null;
4508
+ }
4509
+ }
4510
+
4511
+ // src/commands/suggest.ts
4512
+ var defaultSuggestDeps = {
4513
+ requireSession,
4514
+ fetchCandidates: async () => {
4515
+ const session = await requireSession();
4516
+ return cliApiFetch(`${session.apiUrl}/api/cli/courses/suggest`, session.token, {
4517
+ method: "GET"
4518
+ });
4519
+ },
4520
+ readBrief: async () => {
4521
+ const session = await requireSession();
4522
+ return fetchLearnerBrief({ apiUrl: session.apiUrl, token: session.token });
4523
+ },
4524
+ readProfile: () => getUserProfile(),
4525
+ readWorkspace: () => readWorkspaceSignals(process.cwd())
4526
+ };
4527
+ function suggestionQuery(brief, profile, workspaceTokens) {
4528
+ const parts = [];
4529
+ const briefText = brief?.text.trim() ?? "";
4530
+ if (briefText !== "") parts.push(briefText);
4531
+ if (profile) {
4532
+ parts.push(
4533
+ profile.goal,
4534
+ profile.segment,
4535
+ profile.productsOrServices,
4536
+ profile.team,
4537
+ profile.learnerLevel
4538
+ );
4539
+ }
4540
+ const workspaceText = workspaceTokens.join(" ");
4541
+ if (workspaceText !== "") parts.push(workspaceText);
4542
+ return {
4543
+ text: parts.map((part) => part.trim()).filter((part) => part !== "").join(" "),
4544
+ level: profile?.learnerLevel ?? null
4545
+ };
4546
+ }
4547
+ function reasonText(reason, copy) {
4548
+ if (reason === "empty-profile") return copy.suggestEmptyProfile;
4549
+ if (reason === "no-overlap") return copy.suggestNoOverlap;
4550
+ return reason;
4551
+ }
4552
+ function formatBlock(ranked, lineFor) {
4553
+ const copy = getErrors();
4554
+ const lines = [];
4555
+ for (const [index, row] of ranked.entries()) {
4556
+ lines.push(`${index + 1}. ${row.course.title}`);
4557
+ lines.push(`${copy.suggestReason} ${reasonText(row.reason, copy)}`);
4558
+ lines.push(lineFor(row));
4559
+ }
4560
+ return lines;
4561
+ }
4562
+ function formatSuggestResult(free, paid, workspaceFound, enrollUrlFor) {
4563
+ const copy = getErrors();
4564
+ if (free.length === 0 && paid.length === 0) return copy.suggestEmpty;
4565
+ const lines = [];
4566
+ lines.push(...formatBlock(free, (row) => `tostudy enroll ${row.course.id}`));
4567
+ if (paid.length > 0) {
4568
+ if (lines.length > 0) lines.push("");
4569
+ lines.push(copy.suggestPaidHeader);
4570
+ lines.push(...formatBlock(paid, (row) => enrollUrlFor(row.course.id)));
4571
+ }
4572
+ if (!workspaceFound) lines.push(copy.suggestNoWorkspace);
4573
+ return lines.join("\n");
4574
+ }
4575
+ async function runSuggest(deps = defaultSuggestDeps) {
4576
+ const session = await deps.requireSession();
4577
+ const [candidates, brief, profile] = await Promise.all([
4578
+ deps.fetchCandidates(),
4579
+ deps.readBrief(),
4580
+ deps.readProfile()
4581
+ ]);
4582
+ const workspace = deps.readWorkspace();
4583
+ const query = suggestionQuery(brief, profile, workspace.tokens);
4584
+ const origin = session.apiUrl.replace(/\/$/, "");
4585
+ return formatSuggestResult(
4586
+ rankSuggestions(candidates.free, query),
4587
+ rankSuggestions(candidates.paid, query),
4588
+ workspace.found,
4589
+ (courseId) => `${origin}/enroll/${courseId}`
4590
+ );
4591
+ }
4592
+ var suggestCommand = new Command6("suggest").description(getErrors().suggestCommandDescription).action(async () => {
4593
+ try {
4594
+ output(await runSuggest(), { json: false });
4595
+ } catch (err) {
4596
+ error(err instanceof Error ? err.message : String(err));
4597
+ }
4598
+ });
4599
+
4600
+ // src/commands/enroll.ts
4601
+ import { Command as Command7 } from "commander";
4602
+ init_guards();
4603
+ init_errors();
4299
4604
  init_formatter();
4300
4605
  var COURSE_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
4301
4606
  function formatEnrollResult(result) {
@@ -4328,7 +4633,7 @@ async function runEnroll(courseId, deps = {
4328
4633
  });
4329
4634
  return formatEnrollResult(result);
4330
4635
  }
4331
- var enrollCommand = new Command6("enroll").description(getErrors().enrollCommandDescription).argument("<courseId>", "Published course ID (UUID)").action(async (courseId) => {
4636
+ var enrollCommand = new Command7("enroll").description(getErrors().enrollCommandDescription).argument("<courseId>", "Published course ID (UUID)").action(async (courseId) => {
4332
4637
  try {
4333
4638
  output(await runEnroll(courseId), { json: false });
4334
4639
  } catch (err) {
@@ -4338,7 +4643,7 @@ var enrollCommand = new Command6("enroll").description(getErrors().enrollCommand
4338
4643
 
4339
4644
  // src/commands/select.ts
4340
4645
  init_dist();
4341
- import { Command as Command7 } from "commander";
4646
+ import { Command as Command8 } from "commander";
4342
4647
  import os7 from "node:os";
4343
4648
  init_guards();
4344
4649
  init_workspace_marker();
@@ -4371,26 +4676,6 @@ init_dist();
4371
4676
  init_workspace_marker();
4372
4677
  init_workspace_state();
4373
4678
 
4374
- // src/learner-brief/api.ts
4375
- async function fetchLearnerBrief(input2) {
4376
- const response = await cliApiFetch(
4377
- `${input2.apiUrl}/api/cli/student/learner-brief`,
4378
- input2.token
4379
- );
4380
- return response.brief;
4381
- }
4382
- async function upsertLearnerBrief(input2) {
4383
- const response = await cliApiFetch(
4384
- `${input2.apiUrl}/api/cli/student/learner-brief`,
4385
- input2.token,
4386
- {
4387
- method: "POST",
4388
- body: JSON.stringify({ text: input2.text, source: input2.source })
4389
- }
4390
- );
4391
- return response.brief;
4392
- }
4393
-
4394
4679
  // src/learner-brief/bootstrap.ts
4395
4680
  import readline from "node:readline/promises";
4396
4681
  import { stdin as processStdin, stdout as processStdout } from "node:process";
@@ -4782,7 +5067,7 @@ function isInteractiveTerminal(json2) {
4782
5067
 
4783
5068
  // src/commands/select.ts
4784
5069
  var logger8 = createLogger("cli:select");
4785
- var selectCommand = new Command7("select").description("Activate a course by ID or list index number").argument("<course>", "Course ID (UUID) or index number from `tostudy courses`").option("--json", "Output structured JSON").option(
5070
+ var selectCommand = new Command8("select").description("Activate a course by ID or list index number").argument("<course>", "Course ID (UUID) or index number from `tostudy courses`").option("--json", "Output structured JSON").option(
4786
5071
  "--root-agents",
4787
5072
  "Add the ToStudy block to an existing AGENTS.md in this folder without asking"
4788
5073
  ).action(async (course, opts) => {
@@ -4910,13 +5195,13 @@ var selectCommand = new Command7("select").description("Activate a course by ID
4910
5195
 
4911
5196
  // src/commands/progress.ts
4912
5197
  init_dist();
4913
- import { Command as Command8 } from "commander";
5198
+ import { Command as Command9 } from "commander";
4914
5199
  init_guards();
4915
5200
  init_course_state();
4916
5201
  init_formatter();
4917
5202
  init_errors();
4918
5203
  var logger9 = createLogger("cli:progress");
4919
- var progressCommand = new Command8("progress").description("Show your progress in the active course").option("--json", "Output structured JSON").action(async (opts) => {
5204
+ var progressCommand = new Command9("progress").description("Show your progress in the active course").option("--json", "Output structured JSON").action(async (opts) => {
4920
5205
  try {
4921
5206
  const session = await requireSession();
4922
5207
  const activeCourse = await requireActiveCourse();
@@ -4942,39 +5227,39 @@ var progressCommand = new Command8("progress").description("Show your progress i
4942
5227
 
4943
5228
  // src/commands/start.ts
4944
5229
  init_dist();
4945
- import { Command as Command9 } from "commander";
5230
+ import { Command as Command10 } from "commander";
4946
5231
 
4947
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/lessons/next-lesson.ts
5232
+ // ../../packages/tostudy-core/src/lessons/next-lesson.ts
4948
5233
  async function nextLesson(input2, deps) {
4949
5234
  deps.logger.info("tostudy-core: nextLesson", { enrollmentId: input2.enrollmentId });
4950
5235
  return deps.data.lessons.next(input2.enrollmentId, input2.userConfirmation);
4951
5236
  }
4952
5237
 
4953
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/lessons/get-content.ts
5238
+ // ../../packages/tostudy-core/src/lessons/get-content.ts
4954
5239
  async function getContent(input2, deps) {
4955
5240
  deps.logger.info("tostudy-core: getContent", { lessonId: input2.lessonId });
4956
5241
  return deps.data.lessons.getContent(input2.lessonId, input2.enrollmentId);
4957
5242
  }
4958
5243
 
4959
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/lessons/get-hint.ts
5244
+ // ../../packages/tostudy-core/src/lessons/get-hint.ts
4960
5245
  async function getHint(input2, deps) {
4961
5246
  deps.logger.info("tostudy-core: getHint", { userId: input2.userId });
4962
5247
  return deps.data.lessons.getHint(input2.userId, input2.enrollmentId);
4963
5248
  }
4964
5249
 
4965
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/lessons/start-module.ts
5250
+ // ../../packages/tostudy-core/src/lessons/start-module.ts
4966
5251
  async function startModule(input2, deps) {
4967
5252
  deps.logger.info("tostudy-core: startModule", { enrollmentId: input2.enrollmentId });
4968
5253
  return deps.data.lessons.startModule(input2.enrollmentId);
4969
5254
  }
4970
5255
 
4971
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/lessons/start-next-module.ts
5256
+ // ../../packages/tostudy-core/src/lessons/start-next-module.ts
4972
5257
  async function startNextModule(input2, deps) {
4973
5258
  deps.logger.info("tostudy-core: startNextModule", { enrollmentId: input2.enrollmentId });
4974
5259
  return deps.data.lessons.startNextModule(input2.enrollmentId);
4975
5260
  }
4976
5261
 
4977
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/lessons/index.ts
5262
+ // ../../packages/tostudy-core/src/lessons/index.ts
4978
5263
  init_workspace_tokens();
4979
5264
 
4980
5265
  // src/commands/start.ts
@@ -5051,20 +5336,20 @@ async function runStart(opts, deps = defaultDeps3) {
5051
5336
  deps.error(msg);
5052
5337
  }
5053
5338
  }
5054
- var startCommand = new Command9("start").description("Start (or resume) the current module of the active course").option("--json", "Output structured JSON").action(async (opts) => {
5339
+ var startCommand = new Command10("start").description("Start (or resume) the current module of the active course").option("--json", "Output structured JSON").action(async (opts) => {
5055
5340
  await runStart(opts);
5056
5341
  });
5057
5342
 
5058
5343
  // src/commands/start-next.ts
5059
5344
  init_dist();
5060
- import { Command as Command10 } from "commander";
5345
+ import { Command as Command11 } from "commander";
5061
5346
  init_guards();
5062
5347
  init_course_state();
5063
5348
  init_workspace_state();
5064
5349
  init_formatter();
5065
5350
  init_errors();
5066
5351
  var logger11 = createLogger("cli:start-next");
5067
- var startNextCommand = new Command10("start-next").description("Transition to the next module after completing the current one").option("--json", "Output structured JSON").action(async (opts) => {
5352
+ var startNextCommand = new Command11("start-next").description("Transition to the next module after completing the current one").option("--json", "Output structured JSON").action(async (opts) => {
5068
5353
  try {
5069
5354
  const session = await requireSession();
5070
5355
  const activeCourse = await requireActiveCourse();
@@ -5107,14 +5392,14 @@ var startNextCommand = new Command10("start-next").description("Transition to th
5107
5392
 
5108
5393
  // src/commands/next.ts
5109
5394
  init_dist();
5110
- import { Command as Command11 } from "commander";
5395
+ import { Command as Command12 } from "commander";
5111
5396
  init_guards();
5112
5397
  init_course_state();
5113
5398
  init_workspace_state();
5114
5399
  init_formatter();
5115
5400
  init_errors();
5116
5401
  var logger12 = createLogger("cli:next");
5117
- var nextCommand = new Command11("next").description("Advance to the next lesson in the active course").option("--json", "Output structured JSON").action(async (opts) => {
5402
+ var nextCommand = new Command12("next").description("Advance to the next lesson in the active course").option("--json", "Output structured JSON").action(async (opts) => {
5118
5403
  try {
5119
5404
  const session = await requireSession();
5120
5405
  const activeCourse = await requireActiveCourse();
@@ -5192,14 +5477,14 @@ var nextCommand = new Command11("next").description("Advance to the next lesson
5192
5477
 
5193
5478
  // src/commands/lesson.ts
5194
5479
  init_dist();
5195
- import { Command as Command12 } from "commander";
5480
+ import { Command as Command13 } from "commander";
5196
5481
  init_guards();
5197
5482
  init_course_state();
5198
5483
  init_formatter();
5199
5484
  init_resolve();
5200
5485
  init_workspace_tokens();
5201
5486
  init_errors();
5202
- import path13 from "node:path";
5487
+ import path14 from "node:path";
5203
5488
  var logger13 = createLogger("cli:lesson");
5204
5489
  function adjustTimeEstimate(type, baseMinutes) {
5205
5490
  if (type === "exercise") return Math.max(baseMinutes, 30);
@@ -5216,7 +5501,7 @@ function formatLessonContent(data, workspacePath, courseTitle) {
5216
5501
  const isPractical = isPracticalType(data.type) || isCheckpoint(data.type, data.title);
5217
5502
  const lines = [`\u2501\u2501\u2501 Li\xE7\xE3o: ${data.title} \u2501\u2501\u2501`];
5218
5503
  if (isPractical && workspacePath) {
5219
- const base = path13.basename(workspacePath) === ".tostudy" ? path13.dirname(workspacePath) : workspacePath;
5504
+ const base = path14.basename(workspacePath) === ".tostudy" ? path14.dirname(workspacePath) : workspacePath;
5220
5505
  const slug = courseSlug(courseTitle);
5221
5506
  const vaultPath = resolveVaultPath(workspacePath, slug);
5222
5507
  lines.push(
@@ -5250,7 +5535,7 @@ function formatLessonContent(data, workspacePath, courseTitle) {
5250
5535
  }
5251
5536
  return lines.join("\n");
5252
5537
  }
5253
- var lessonCommand = new Command12("lesson").description("Show the content of the current lesson").option("--json", "Output structured JSON").option(
5538
+ var lessonCommand = new Command13("lesson").description("Show the content of the current lesson").option("--json", "Output structured JSON").option(
5254
5539
  "--read <lessonId>",
5255
5540
  "Read a specific lesson by id (works on archived / read-only courses)"
5256
5541
  ).action(async (opts) => {
@@ -5321,7 +5606,7 @@ var lessonCommand = new Command12("lesson").description("Show the content of the
5321
5606
 
5322
5607
  // src/commands/knowledge.ts
5323
5608
  init_dist();
5324
- import { Command as Command13 } from "commander";
5609
+ import { Command as Command14 } from "commander";
5325
5610
  init_guards();
5326
5611
  init_formatter();
5327
5612
  var logger14 = createLogger("cli:knowledge");
@@ -5341,7 +5626,7 @@ function formatKnowledge(data) {
5341
5626
  });
5342
5627
  return lines.join("\n").trimEnd();
5343
5628
  }
5344
- var knowledgeCommand = new Command13("knowledge").description("Show the active course's knowledge base (base de conhecimento)").option("--json", "Output structured JSON").action(async (opts) => {
5629
+ var knowledgeCommand = new Command14("knowledge").description("Show the active course's knowledge base (base de conhecimento)").option("--json", "Output structured JSON").action(async (opts) => {
5345
5630
  try {
5346
5631
  const activeCourse = await requireActiveCourse();
5347
5632
  if (!activeCourse.courseId) {
@@ -5372,13 +5657,13 @@ var knowledgeCommand = new Command13("knowledge").description("Show the active c
5372
5657
 
5373
5658
  // src/commands/hint.ts
5374
5659
  init_dist();
5375
- import { Command as Command14 } from "commander";
5660
+ import { Command as Command15 } from "commander";
5376
5661
  init_guards();
5377
5662
  init_course_state();
5378
5663
  init_formatter();
5379
5664
  init_errors();
5380
5665
  var logger15 = createLogger("cli:hint");
5381
- var hintCommand = new Command14("hint").description("Get a progressive hint for the current exercise").option("--json", "Output structured JSON").action(async (opts) => {
5666
+ var hintCommand = new Command15("hint").description("Get a progressive hint for the current exercise").option("--json", "Output structured JSON").action(async (opts) => {
5382
5667
  try {
5383
5668
  const session = await requireSession();
5384
5669
  const activeCourse = await requireActiveCourse();
@@ -5427,11 +5712,11 @@ var hintCommand = new Command14("hint").description("Get a progressive hint for
5427
5712
 
5428
5713
  // src/commands/validate.ts
5429
5714
  init_dist();
5430
- import fs11 from "node:fs";
5431
- import path14 from "node:path";
5432
- import { Command as Command15 } from "commander";
5715
+ import fs12 from "node:fs";
5716
+ import path15 from "node:path";
5717
+ import { Command as Command16 } from "commander";
5433
5718
 
5434
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/exercises/validate-solution.ts
5719
+ // ../../packages/tostudy-core/src/exercises/validate-solution.ts
5435
5720
  async function validateSolution(input2, deps) {
5436
5721
  deps.logger.info("tostudy-core: validateSolution", { lessonId: input2.lessonId });
5437
5722
  if (input2.metadata !== void 0) {
@@ -5451,7 +5736,7 @@ async function validateSolution(input2, deps) {
5451
5736
  );
5452
5737
  }
5453
5738
 
5454
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/classic/external.js
5739
+ // ../../node_modules/zod/v4/classic/external.js
5455
5740
  var external_exports = {};
5456
5741
  __export(external_exports, {
5457
5742
  $brand: () => $brand,
@@ -5692,7 +5977,7 @@ __export(external_exports, {
5692
5977
  xor: () => xor
5693
5978
  });
5694
5979
 
5695
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/core/index.js
5980
+ // ../../node_modules/zod/v4/core/index.js
5696
5981
  var core_exports2 = {};
5697
5982
  __export(core_exports2, {
5698
5983
  $ZodAny: () => $ZodAny,
@@ -5970,7 +6255,7 @@ __export(core_exports2, {
5970
6255
  version: () => version
5971
6256
  });
5972
6257
 
5973
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/core/core.js
6258
+ // ../../node_modules/zod/v4/core/core.js
5974
6259
  var NEVER = Object.freeze({
5975
6260
  status: "aborted"
5976
6261
  });
@@ -6045,7 +6330,7 @@ function config(newConfig) {
6045
6330
  return globalConfig;
6046
6331
  }
6047
6332
 
6048
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/core/util.js
6333
+ // ../../node_modules/zod/v4/core/util.js
6049
6334
  var util_exports = {};
6050
6335
  __export(util_exports, {
6051
6336
  BIGINT_FORMAT_RANGES: () => BIGINT_FORMAT_RANGES,
@@ -6218,10 +6503,10 @@ function mergeDefs(...defs) {
6218
6503
  function cloneDef(schema) {
6219
6504
  return mergeDefs(schema._zod.def);
6220
6505
  }
6221
- function getElementAtPath(obj, path28) {
6222
- if (!path28)
6506
+ function getElementAtPath(obj, path29) {
6507
+ if (!path29)
6223
6508
  return obj;
6224
- return path28.reduce((acc, key) => acc?.[key], obj);
6509
+ return path29.reduce((acc, key) => acc?.[key], obj);
6225
6510
  }
6226
6511
  function promiseAllObject(promisesObj) {
6227
6512
  const keys = Object.keys(promisesObj);
@@ -6604,11 +6889,11 @@ function aborted(x, startIndex = 0) {
6604
6889
  }
6605
6890
  return false;
6606
6891
  }
6607
- function prefixIssues(path28, issues) {
6892
+ function prefixIssues(path29, issues) {
6608
6893
  return issues.map((iss) => {
6609
6894
  var _a2;
6610
6895
  (_a2 = iss).path ?? (_a2.path = []);
6611
- iss.path.unshift(path28);
6896
+ iss.path.unshift(path29);
6612
6897
  return iss;
6613
6898
  });
6614
6899
  }
@@ -6724,7 +7009,7 @@ var Class = class {
6724
7009
  }
6725
7010
  };
6726
7011
 
6727
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/core/errors.js
7012
+ // ../../node_modules/zod/v4/core/errors.js
6728
7013
  var initializer = (inst, def) => {
6729
7014
  inst.name = "$ZodError";
6730
7015
  Object.defineProperty(inst, "_zod", {
@@ -6791,7 +7076,7 @@ function formatError(error49, mapper = (issue2) => issue2.message) {
6791
7076
  }
6792
7077
  function treeifyError(error49, mapper = (issue2) => issue2.message) {
6793
7078
  const result = { errors: [] };
6794
- const processError = (error50, path28 = []) => {
7079
+ const processError = (error50, path29 = []) => {
6795
7080
  var _a2, _b;
6796
7081
  for (const issue2 of error50.issues) {
6797
7082
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -6801,7 +7086,7 @@ function treeifyError(error49, mapper = (issue2) => issue2.message) {
6801
7086
  } else if (issue2.code === "invalid_element") {
6802
7087
  processError({ issues: issue2.issues }, issue2.path);
6803
7088
  } else {
6804
- const fullpath = [...path28, ...issue2.path];
7089
+ const fullpath = [...path29, ...issue2.path];
6805
7090
  if (fullpath.length === 0) {
6806
7091
  result.errors.push(mapper(issue2));
6807
7092
  continue;
@@ -6833,8 +7118,8 @@ function treeifyError(error49, mapper = (issue2) => issue2.message) {
6833
7118
  }
6834
7119
  function toDotPath(_path) {
6835
7120
  const segs = [];
6836
- const path28 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
6837
- for (const seg of path28) {
7121
+ const path29 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
7122
+ for (const seg of path29) {
6838
7123
  if (typeof seg === "number")
6839
7124
  segs.push(`[${seg}]`);
6840
7125
  else if (typeof seg === "symbol")
@@ -6860,7 +7145,7 @@ function prettifyError(error49) {
6860
7145
  return lines.join("\n");
6861
7146
  }
6862
7147
 
6863
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/core/parse.js
7148
+ // ../../node_modules/zod/v4/core/parse.js
6864
7149
  var _parse = (_Err) => (schema, value, _ctx, _params) => {
6865
7150
  const ctx = _ctx ? Object.assign(_ctx, { async: false }) : { async: false };
6866
7151
  const result = schema._zod.run({ value, issues: [] }, ctx);
@@ -6948,7 +7233,7 @@ var _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {
6948
7233
  };
6949
7234
  var safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync($ZodRealError);
6950
7235
 
6951
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/core/regexes.js
7236
+ // ../../node_modules/zod/v4/core/regexes.js
6952
7237
  var regexes_exports = {};
6953
7238
  __export(regexes_exports, {
6954
7239
  base64: () => base64,
@@ -7105,7 +7390,7 @@ var sha512_hex = /^[0-9a-fA-F]{128}$/;
7105
7390
  var sha512_base64 = /* @__PURE__ */ fixedBase64(86, "==");
7106
7391
  var sha512_base64url = /* @__PURE__ */ fixedBase64url(86);
7107
7392
 
7108
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/core/checks.js
7393
+ // ../../node_modules/zod/v4/core/checks.js
7109
7394
  var $ZodCheck = /* @__PURE__ */ $constructor("$ZodCheck", (inst, def) => {
7110
7395
  var _a2;
7111
7396
  inst._zod ?? (inst._zod = {});
@@ -7653,7 +7938,7 @@ var $ZodCheckOverwrite = /* @__PURE__ */ $constructor("$ZodCheckOverwrite", (ins
7653
7938
  };
7654
7939
  });
7655
7940
 
7656
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/core/doc.js
7941
+ // ../../node_modules/zod/v4/core/doc.js
7657
7942
  var Doc = class {
7658
7943
  constructor(args = []) {
7659
7944
  this.content = [];
@@ -7689,14 +7974,14 @@ var Doc = class {
7689
7974
  }
7690
7975
  };
7691
7976
 
7692
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/core/versions.js
7977
+ // ../../node_modules/zod/v4/core/versions.js
7693
7978
  var version = {
7694
7979
  major: 4,
7695
7980
  minor: 3,
7696
7981
  patch: 6
7697
7982
  };
7698
7983
 
7699
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/core/schemas.js
7984
+ // ../../node_modules/zod/v4/core/schemas.js
7700
7985
  var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
7701
7986
  var _a2;
7702
7987
  inst ?? (inst = {});
@@ -9667,7 +9952,7 @@ function handleRefineResult(result, payload, input2, inst) {
9667
9952
  }
9668
9953
  }
9669
9954
 
9670
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/index.js
9955
+ // ../../node_modules/zod/v4/locales/index.js
9671
9956
  var locales_exports = {};
9672
9957
  __export(locales_exports, {
9673
9958
  ar: () => ar_default,
@@ -9721,7 +10006,7 @@ __export(locales_exports, {
9721
10006
  zhTW: () => zh_TW_default
9722
10007
  });
9723
10008
 
9724
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/ar.js
10009
+ // ../../node_modules/zod/v4/locales/ar.js
9725
10010
  var error2 = () => {
9726
10011
  const Sizable = {
9727
10012
  string: { unit: "\u062D\u0631\u0641", verb: "\u0623\u0646 \u064A\u062D\u0648\u064A" },
@@ -9828,7 +10113,7 @@ function ar_default() {
9828
10113
  };
9829
10114
  }
9830
10115
 
9831
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/az.js
10116
+ // ../../node_modules/zod/v4/locales/az.js
9832
10117
  var error3 = () => {
9833
10118
  const Sizable = {
9834
10119
  string: { unit: "simvol", verb: "olmal\u0131d\u0131r" },
@@ -9934,7 +10219,7 @@ function az_default() {
9934
10219
  };
9935
10220
  }
9936
10221
 
9937
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/be.js
10222
+ // ../../node_modules/zod/v4/locales/be.js
9938
10223
  function getBelarusianPlural(count, one, few, many) {
9939
10224
  const absCount = Math.abs(count);
9940
10225
  const lastDigit = absCount % 10;
@@ -10091,7 +10376,7 @@ function be_default() {
10091
10376
  };
10092
10377
  }
10093
10378
 
10094
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/bg.js
10379
+ // ../../node_modules/zod/v4/locales/bg.js
10095
10380
  var error5 = () => {
10096
10381
  const Sizable = {
10097
10382
  string: { unit: "\u0441\u0438\u043C\u0432\u043E\u043B\u0430", verb: "\u0434\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430" },
@@ -10212,7 +10497,7 @@ function bg_default() {
10212
10497
  };
10213
10498
  }
10214
10499
 
10215
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/ca.js
10500
+ // ../../node_modules/zod/v4/locales/ca.js
10216
10501
  var error6 = () => {
10217
10502
  const Sizable = {
10218
10503
  string: { unit: "car\xE0cters", verb: "contenir" },
@@ -10321,7 +10606,7 @@ function ca_default() {
10321
10606
  };
10322
10607
  }
10323
10608
 
10324
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/cs.js
10609
+ // ../../node_modules/zod/v4/locales/cs.js
10325
10610
  var error7 = () => {
10326
10611
  const Sizable = {
10327
10612
  string: { unit: "znak\u016F", verb: "m\xEDt" },
@@ -10433,7 +10718,7 @@ function cs_default() {
10433
10718
  };
10434
10719
  }
10435
10720
 
10436
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/da.js
10721
+ // ../../node_modules/zod/v4/locales/da.js
10437
10722
  var error8 = () => {
10438
10723
  const Sizable = {
10439
10724
  string: { unit: "tegn", verb: "havde" },
@@ -10549,7 +10834,7 @@ function da_default() {
10549
10834
  };
10550
10835
  }
10551
10836
 
10552
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/de.js
10837
+ // ../../node_modules/zod/v4/locales/de.js
10553
10838
  var error9 = () => {
10554
10839
  const Sizable = {
10555
10840
  string: { unit: "Zeichen", verb: "zu haben" },
@@ -10658,7 +10943,7 @@ function de_default() {
10658
10943
  };
10659
10944
  }
10660
10945
 
10661
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/en.js
10946
+ // ../../node_modules/zod/v4/locales/en.js
10662
10947
  var error10 = () => {
10663
10948
  const Sizable = {
10664
10949
  string: { unit: "characters", verb: "to have" },
@@ -10767,7 +11052,7 @@ function en_default() {
10767
11052
  };
10768
11053
  }
10769
11054
 
10770
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/eo.js
11055
+ // ../../node_modules/zod/v4/locales/eo.js
10771
11056
  var error11 = () => {
10772
11057
  const Sizable = {
10773
11058
  string: { unit: "karaktrojn", verb: "havi" },
@@ -10877,7 +11162,7 @@ function eo_default() {
10877
11162
  };
10878
11163
  }
10879
11164
 
10880
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/es.js
11165
+ // ../../node_modules/zod/v4/locales/es.js
10881
11166
  var error12 = () => {
10882
11167
  const Sizable = {
10883
11168
  string: { unit: "caracteres", verb: "tener" },
@@ -11010,7 +11295,7 @@ function es_default() {
11010
11295
  };
11011
11296
  }
11012
11297
 
11013
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/fa.js
11298
+ // ../../node_modules/zod/v4/locales/fa.js
11014
11299
  var error13 = () => {
11015
11300
  const Sizable = {
11016
11301
  string: { unit: "\u06A9\u0627\u0631\u0627\u06A9\u062A\u0631", verb: "\u062F\u0627\u0634\u062A\u0647 \u0628\u0627\u0634\u062F" },
@@ -11125,7 +11410,7 @@ function fa_default() {
11125
11410
  };
11126
11411
  }
11127
11412
 
11128
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/fi.js
11413
+ // ../../node_modules/zod/v4/locales/fi.js
11129
11414
  var error14 = () => {
11130
11415
  const Sizable = {
11131
11416
  string: { unit: "merkki\xE4", subject: "merkkijonon" },
@@ -11238,7 +11523,7 @@ function fi_default() {
11238
11523
  };
11239
11524
  }
11240
11525
 
11241
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/fr.js
11526
+ // ../../node_modules/zod/v4/locales/fr.js
11242
11527
  var error15 = () => {
11243
11528
  const Sizable = {
11244
11529
  string: { unit: "caract\xE8res", verb: "avoir" },
@@ -11347,7 +11632,7 @@ function fr_default() {
11347
11632
  };
11348
11633
  }
11349
11634
 
11350
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/fr-CA.js
11635
+ // ../../node_modules/zod/v4/locales/fr-CA.js
11351
11636
  var error16 = () => {
11352
11637
  const Sizable = {
11353
11638
  string: { unit: "caract\xE8res", verb: "avoir" },
@@ -11455,7 +11740,7 @@ function fr_CA_default() {
11455
11740
  };
11456
11741
  }
11457
11742
 
11458
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/he.js
11743
+ // ../../node_modules/zod/v4/locales/he.js
11459
11744
  var error17 = () => {
11460
11745
  const TypeNames = {
11461
11746
  string: { label: "\u05DE\u05D7\u05E8\u05D5\u05D6\u05EA", gender: "f" },
@@ -11650,7 +11935,7 @@ function he_default() {
11650
11935
  };
11651
11936
  }
11652
11937
 
11653
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/hu.js
11938
+ // ../../node_modules/zod/v4/locales/hu.js
11654
11939
  var error18 = () => {
11655
11940
  const Sizable = {
11656
11941
  string: { unit: "karakter", verb: "legyen" },
@@ -11759,7 +12044,7 @@ function hu_default() {
11759
12044
  };
11760
12045
  }
11761
12046
 
11762
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/hy.js
12047
+ // ../../node_modules/zod/v4/locales/hy.js
11763
12048
  function getArmenianPlural(count, one, many) {
11764
12049
  return Math.abs(count) === 1 ? one : many;
11765
12050
  }
@@ -11907,7 +12192,7 @@ function hy_default() {
11907
12192
  };
11908
12193
  }
11909
12194
 
11910
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/id.js
12195
+ // ../../node_modules/zod/v4/locales/id.js
11911
12196
  var error20 = () => {
11912
12197
  const Sizable = {
11913
12198
  string: { unit: "karakter", verb: "memiliki" },
@@ -12014,7 +12299,7 @@ function id_default() {
12014
12299
  };
12015
12300
  }
12016
12301
 
12017
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/is.js
12302
+ // ../../node_modules/zod/v4/locales/is.js
12018
12303
  var error21 = () => {
12019
12304
  const Sizable = {
12020
12305
  string: { unit: "stafi", verb: "a\xF0 hafa" },
@@ -12124,7 +12409,7 @@ function is_default() {
12124
12409
  };
12125
12410
  }
12126
12411
 
12127
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/it.js
12412
+ // ../../node_modules/zod/v4/locales/it.js
12128
12413
  var error22 = () => {
12129
12414
  const Sizable = {
12130
12415
  string: { unit: "caratteri", verb: "avere" },
@@ -12233,7 +12518,7 @@ function it_default() {
12233
12518
  };
12234
12519
  }
12235
12520
 
12236
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/ja.js
12521
+ // ../../node_modules/zod/v4/locales/ja.js
12237
12522
  var error23 = () => {
12238
12523
  const Sizable = {
12239
12524
  string: { unit: "\u6587\u5B57", verb: "\u3067\u3042\u308B" },
@@ -12341,7 +12626,7 @@ function ja_default() {
12341
12626
  };
12342
12627
  }
12343
12628
 
12344
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/ka.js
12629
+ // ../../node_modules/zod/v4/locales/ka.js
12345
12630
  var error24 = () => {
12346
12631
  const Sizable = {
12347
12632
  string: { unit: "\u10E1\u10D8\u10DB\u10D1\u10DD\u10DA\u10DD", verb: "\u10E3\u10DC\u10D3\u10D0 \u10E8\u10D4\u10D8\u10EA\u10D0\u10D5\u10D3\u10D4\u10E1" },
@@ -12454,7 +12739,7 @@ function ka_default() {
12454
12739
  };
12455
12740
  }
12456
12741
 
12457
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/km.js
12742
+ // ../../node_modules/zod/v4/locales/km.js
12458
12743
  var error25 = () => {
12459
12744
  const Sizable = {
12460
12745
  string: { unit: "\u178F\u17BD\u17A2\u1780\u17D2\u179F\u179A", verb: "\u1782\u17BD\u179A\u1798\u17B6\u1793" },
@@ -12565,12 +12850,12 @@ function km_default() {
12565
12850
  };
12566
12851
  }
12567
12852
 
12568
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/kh.js
12853
+ // ../../node_modules/zod/v4/locales/kh.js
12569
12854
  function kh_default() {
12570
12855
  return km_default();
12571
12856
  }
12572
12857
 
12573
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/ko.js
12858
+ // ../../node_modules/zod/v4/locales/ko.js
12574
12859
  var error26 = () => {
12575
12860
  const Sizable = {
12576
12861
  string: { unit: "\uBB38\uC790", verb: "to have" },
@@ -12682,7 +12967,7 @@ function ko_default() {
12682
12967
  };
12683
12968
  }
12684
12969
 
12685
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/lt.js
12970
+ // ../../node_modules/zod/v4/locales/lt.js
12686
12971
  var capitalizeFirstCharacter = (text2) => {
12687
12972
  return text2.charAt(0).toUpperCase() + text2.slice(1);
12688
12973
  };
@@ -12886,7 +13171,7 @@ function lt_default() {
12886
13171
  };
12887
13172
  }
12888
13173
 
12889
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/mk.js
13174
+ // ../../node_modules/zod/v4/locales/mk.js
12890
13175
  var error28 = () => {
12891
13176
  const Sizable = {
12892
13177
  string: { unit: "\u0437\u043D\u0430\u0446\u0438", verb: "\u0434\u0430 \u0438\u043C\u0430\u0430\u0442" },
@@ -12996,7 +13281,7 @@ function mk_default() {
12996
13281
  };
12997
13282
  }
12998
13283
 
12999
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/ms.js
13284
+ // ../../node_modules/zod/v4/locales/ms.js
13000
13285
  var error29 = () => {
13001
13286
  const Sizable = {
13002
13287
  string: { unit: "aksara", verb: "mempunyai" },
@@ -13104,7 +13389,7 @@ function ms_default() {
13104
13389
  };
13105
13390
  }
13106
13391
 
13107
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/nl.js
13392
+ // ../../node_modules/zod/v4/locales/nl.js
13108
13393
  var error30 = () => {
13109
13394
  const Sizable = {
13110
13395
  string: { unit: "tekens", verb: "heeft" },
@@ -13215,7 +13500,7 @@ function nl_default() {
13215
13500
  };
13216
13501
  }
13217
13502
 
13218
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/no.js
13503
+ // ../../node_modules/zod/v4/locales/no.js
13219
13504
  var error31 = () => {
13220
13505
  const Sizable = {
13221
13506
  string: { unit: "tegn", verb: "\xE5 ha" },
@@ -13324,7 +13609,7 @@ function no_default() {
13324
13609
  };
13325
13610
  }
13326
13611
 
13327
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/ota.js
13612
+ // ../../node_modules/zod/v4/locales/ota.js
13328
13613
  var error32 = () => {
13329
13614
  const Sizable = {
13330
13615
  string: { unit: "harf", verb: "olmal\u0131d\u0131r" },
@@ -13434,7 +13719,7 @@ function ota_default() {
13434
13719
  };
13435
13720
  }
13436
13721
 
13437
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/ps.js
13722
+ // ../../node_modules/zod/v4/locales/ps.js
13438
13723
  var error33 = () => {
13439
13724
  const Sizable = {
13440
13725
  string: { unit: "\u062A\u0648\u06A9\u064A", verb: "\u0648\u0644\u0631\u064A" },
@@ -13549,7 +13834,7 @@ function ps_default() {
13549
13834
  };
13550
13835
  }
13551
13836
 
13552
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/pl.js
13837
+ // ../../node_modules/zod/v4/locales/pl.js
13553
13838
  var error34 = () => {
13554
13839
  const Sizable = {
13555
13840
  string: { unit: "znak\xF3w", verb: "mie\u0107" },
@@ -13659,7 +13944,7 @@ function pl_default() {
13659
13944
  };
13660
13945
  }
13661
13946
 
13662
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/pt.js
13947
+ // ../../node_modules/zod/v4/locales/pt.js
13663
13948
  var error35 = () => {
13664
13949
  const Sizable = {
13665
13950
  string: { unit: "caracteres", verb: "ter" },
@@ -13768,7 +14053,7 @@ function pt_default() {
13768
14053
  };
13769
14054
  }
13770
14055
 
13771
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/ru.js
14056
+ // ../../node_modules/zod/v4/locales/ru.js
13772
14057
  function getRussianPlural(count, one, few, many) {
13773
14058
  const absCount = Math.abs(count);
13774
14059
  const lastDigit = absCount % 10;
@@ -13925,7 +14210,7 @@ function ru_default() {
13925
14210
  };
13926
14211
  }
13927
14212
 
13928
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/sl.js
14213
+ // ../../node_modules/zod/v4/locales/sl.js
13929
14214
  var error37 = () => {
13930
14215
  const Sizable = {
13931
14216
  string: { unit: "znakov", verb: "imeti" },
@@ -14035,7 +14320,7 @@ function sl_default() {
14035
14320
  };
14036
14321
  }
14037
14322
 
14038
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/sv.js
14323
+ // ../../node_modules/zod/v4/locales/sv.js
14039
14324
  var error38 = () => {
14040
14325
  const Sizable = {
14041
14326
  string: { unit: "tecken", verb: "att ha" },
@@ -14146,7 +14431,7 @@ function sv_default() {
14146
14431
  };
14147
14432
  }
14148
14433
 
14149
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/ta.js
14434
+ // ../../node_modules/zod/v4/locales/ta.js
14150
14435
  var error39 = () => {
14151
14436
  const Sizable = {
14152
14437
  string: { unit: "\u0B8E\u0BB4\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1\u0B95\u0BCD\u0B95\u0BB3\u0BCD", verb: "\u0B95\u0BCA\u0BA3\u0BCD\u0B9F\u0BBF\u0BB0\u0BC1\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD" },
@@ -14257,7 +14542,7 @@ function ta_default() {
14257
14542
  };
14258
14543
  }
14259
14544
 
14260
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/th.js
14545
+ // ../../node_modules/zod/v4/locales/th.js
14261
14546
  var error40 = () => {
14262
14547
  const Sizable = {
14263
14548
  string: { unit: "\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23", verb: "\u0E04\u0E27\u0E23\u0E21\u0E35" },
@@ -14368,7 +14653,7 @@ function th_default() {
14368
14653
  };
14369
14654
  }
14370
14655
 
14371
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/tr.js
14656
+ // ../../node_modules/zod/v4/locales/tr.js
14372
14657
  var error41 = () => {
14373
14658
  const Sizable = {
14374
14659
  string: { unit: "karakter", verb: "olmal\u0131" },
@@ -14474,7 +14759,7 @@ function tr_default() {
14474
14759
  };
14475
14760
  }
14476
14761
 
14477
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/uk.js
14762
+ // ../../node_modules/zod/v4/locales/uk.js
14478
14763
  var error42 = () => {
14479
14764
  const Sizable = {
14480
14765
  string: { unit: "\u0441\u0438\u043C\u0432\u043E\u043B\u0456\u0432", verb: "\u043C\u0430\u0442\u0438\u043C\u0435" },
@@ -14583,12 +14868,12 @@ function uk_default() {
14583
14868
  };
14584
14869
  }
14585
14870
 
14586
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/ua.js
14871
+ // ../../node_modules/zod/v4/locales/ua.js
14587
14872
  function ua_default() {
14588
14873
  return uk_default();
14589
14874
  }
14590
14875
 
14591
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/ur.js
14876
+ // ../../node_modules/zod/v4/locales/ur.js
14592
14877
  var error43 = () => {
14593
14878
  const Sizable = {
14594
14879
  string: { unit: "\u062D\u0631\u0648\u0641", verb: "\u06C1\u0648\u0646\u0627" },
@@ -14699,7 +14984,7 @@ function ur_default() {
14699
14984
  };
14700
14985
  }
14701
14986
 
14702
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/uz.js
14987
+ // ../../node_modules/zod/v4/locales/uz.js
14703
14988
  var error44 = () => {
14704
14989
  const Sizable = {
14705
14990
  string: { unit: "belgi", verb: "bo\u2018lishi kerak" },
@@ -14809,7 +15094,7 @@ function uz_default() {
14809
15094
  };
14810
15095
  }
14811
15096
 
14812
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/vi.js
15097
+ // ../../node_modules/zod/v4/locales/vi.js
14813
15098
  var error45 = () => {
14814
15099
  const Sizable = {
14815
15100
  string: { unit: "k\xFD t\u1EF1", verb: "c\xF3" },
@@ -14918,7 +15203,7 @@ function vi_default() {
14918
15203
  };
14919
15204
  }
14920
15205
 
14921
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/zh-CN.js
15206
+ // ../../node_modules/zod/v4/locales/zh-CN.js
14922
15207
  var error46 = () => {
14923
15208
  const Sizable = {
14924
15209
  string: { unit: "\u5B57\u7B26", verb: "\u5305\u542B" },
@@ -15028,7 +15313,7 @@ function zh_CN_default() {
15028
15313
  };
15029
15314
  }
15030
15315
 
15031
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/zh-TW.js
15316
+ // ../../node_modules/zod/v4/locales/zh-TW.js
15032
15317
  var error47 = () => {
15033
15318
  const Sizable = {
15034
15319
  string: { unit: "\u5B57\u5143", verb: "\u64C1\u6709" },
@@ -15136,7 +15421,7 @@ function zh_TW_default() {
15136
15421
  };
15137
15422
  }
15138
15423
 
15139
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/locales/yo.js
15424
+ // ../../node_modules/zod/v4/locales/yo.js
15140
15425
  var error48 = () => {
15141
15426
  const Sizable = {
15142
15427
  string: { unit: "\xE0mi", verb: "n\xED" },
@@ -15244,7 +15529,7 @@ function yo_default() {
15244
15529
  };
15245
15530
  }
15246
15531
 
15247
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/core/registries.js
15532
+ // ../../node_modules/zod/v4/core/registries.js
15248
15533
  var _a;
15249
15534
  var $output = /* @__PURE__ */ Symbol("ZodOutput");
15250
15535
  var $input = /* @__PURE__ */ Symbol("ZodInput");
@@ -15294,7 +15579,7 @@ function registry() {
15294
15579
  (_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());
15295
15580
  var globalRegistry = globalThis.__zod_globalRegistry;
15296
15581
 
15297
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/core/api.js
15582
+ // ../../node_modules/zod/v4/core/api.js
15298
15583
  // @__NO_SIDE_EFFECTS__
15299
15584
  function _string(Class2, params) {
15300
15585
  return new Class2({
@@ -16333,7 +16618,7 @@ function _stringFormat(Class2, format, fnOrRegex, _params = {}) {
16333
16618
  return inst;
16334
16619
  }
16335
16620
 
16336
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/core/to-json-schema.js
16621
+ // ../../node_modules/zod/v4/core/to-json-schema.js
16337
16622
  function initializeContext(params) {
16338
16623
  let target = params?.target ?? "draft-2020-12";
16339
16624
  if (target === "draft-4")
@@ -16685,7 +16970,7 @@ var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) =
16685
16970
  return finalize(ctx, schema);
16686
16971
  };
16687
16972
 
16688
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/core/json-schema-processors.js
16973
+ // ../../node_modules/zod/v4/core/json-schema-processors.js
16689
16974
  var formatMap = {
16690
16975
  guid: "uuid",
16691
16976
  url: "uri",
@@ -17236,7 +17521,7 @@ function toJSONSchema(input2, params) {
17236
17521
  return finalize(ctx, input2);
17237
17522
  }
17238
17523
 
17239
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/core/json-schema-generator.js
17524
+ // ../../node_modules/zod/v4/core/json-schema-generator.js
17240
17525
  var JSONSchemaGenerator = class {
17241
17526
  /** @deprecated Access via ctx instead */
17242
17527
  get metadataRegistry() {
@@ -17311,10 +17596,10 @@ var JSONSchemaGenerator = class {
17311
17596
  }
17312
17597
  };
17313
17598
 
17314
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/core/json-schema.js
17599
+ // ../../node_modules/zod/v4/core/json-schema.js
17315
17600
  var json_schema_exports = {};
17316
17601
 
17317
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/classic/schemas.js
17602
+ // ../../node_modules/zod/v4/classic/schemas.js
17318
17603
  var schemas_exports2 = {};
17319
17604
  __export(schemas_exports2, {
17320
17605
  ZodAny: () => ZodAny,
@@ -17483,7 +17768,7 @@ __export(schemas_exports2, {
17483
17768
  xor: () => xor
17484
17769
  });
17485
17770
 
17486
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/classic/checks.js
17771
+ // ../../node_modules/zod/v4/classic/checks.js
17487
17772
  var checks_exports2 = {};
17488
17773
  __export(checks_exports2, {
17489
17774
  endsWith: () => _endsWith,
@@ -17517,7 +17802,7 @@ __export(checks_exports2, {
17517
17802
  uppercase: () => _uppercase
17518
17803
  });
17519
17804
 
17520
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/classic/iso.js
17805
+ // ../../node_modules/zod/v4/classic/iso.js
17521
17806
  var iso_exports = {};
17522
17807
  __export(iso_exports, {
17523
17808
  ZodISODate: () => ZodISODate,
@@ -17558,7 +17843,7 @@ function duration2(params) {
17558
17843
  return _isoDuration(ZodISODuration, params);
17559
17844
  }
17560
17845
 
17561
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/classic/errors.js
17846
+ // ../../node_modules/zod/v4/classic/errors.js
17562
17847
  var initializer2 = (inst, issues) => {
17563
17848
  $ZodError.init(inst, issues);
17564
17849
  inst.name = "ZodError";
@@ -17598,7 +17883,7 @@ var ZodRealError = $constructor("ZodError", initializer2, {
17598
17883
  Parent: Error
17599
17884
  });
17600
17885
 
17601
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/classic/parse.js
17886
+ // ../../node_modules/zod/v4/classic/parse.js
17602
17887
  var parse2 = /* @__PURE__ */ _parse(ZodRealError);
17603
17888
  var parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError);
17604
17889
  var safeParse2 = /* @__PURE__ */ _safeParse(ZodRealError);
@@ -17612,7 +17897,7 @@ var safeDecode2 = /* @__PURE__ */ _safeDecode(ZodRealError);
17612
17897
  var safeEncodeAsync2 = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
17613
17898
  var safeDecodeAsync2 = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
17614
17899
 
17615
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/classic/schemas.js
17900
+ // ../../node_modules/zod/v4/classic/schemas.js
17616
17901
  var ZodType = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
17617
17902
  $ZodType.init(inst, def);
17618
17903
  Object.assign(inst["~standard"], {
@@ -18691,7 +18976,7 @@ function preprocess(fn, schema) {
18691
18976
  return pipe(transform(fn), schema);
18692
18977
  }
18693
18978
 
18694
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/classic/compat.js
18979
+ // ../../node_modules/zod/v4/classic/compat.js
18695
18980
  var ZodIssueCode = {
18696
18981
  invalid_type: "invalid_type",
18697
18982
  too_big: "too_big",
@@ -18717,7 +19002,7 @@ var ZodFirstPartyTypeKind;
18717
19002
  /* @__PURE__ */ (function(ZodFirstPartyTypeKind2) {
18718
19003
  })(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
18719
19004
 
18720
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/classic/from-json-schema.js
19005
+ // ../../node_modules/zod/v4/classic/from-json-schema.js
18721
19006
  var z = {
18722
19007
  ...schemas_exports2,
18723
19008
  ...checks_exports2,
@@ -18811,13 +19096,13 @@ function resolveRef(ref, ctx) {
18811
19096
  if (!ref.startsWith("#")) {
18812
19097
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
18813
19098
  }
18814
- const path28 = ref.slice(1).split("/").filter(Boolean);
18815
- if (path28.length === 0) {
19099
+ const path29 = ref.slice(1).split("/").filter(Boolean);
19100
+ if (path29.length === 0) {
18816
19101
  return ctx.rootSchema;
18817
19102
  }
18818
19103
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
18819
- if (path28[0] === defsKey) {
18820
- const key = path28[1];
19104
+ if (path29[0] === defsKey) {
19105
+ const key = path29[1];
18821
19106
  if (!key || !ctx.defs[key]) {
18822
19107
  throw new Error(`Reference not found: ${ref}`);
18823
19108
  }
@@ -19191,7 +19476,7 @@ function fromJSONSchema(schema, params) {
19191
19476
  return convertSchema(schema, ctx);
19192
19477
  }
19193
19478
 
19194
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/classic/coerce.js
19479
+ // ../../node_modules/zod/v4/classic/coerce.js
19195
19480
  var coerce_exports = {};
19196
19481
  __export(coerce_exports, {
19197
19482
  bigint: () => bigint3,
@@ -19216,10 +19501,10 @@ function date4(params) {
19216
19501
  return _coercedDate(ZodDate, params);
19217
19502
  }
19218
19503
 
19219
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/node_modules/zod/v4/classic/external.js
19504
+ // ../../node_modules/zod/v4/classic/external.js
19220
19505
  config(en_default());
19221
19506
 
19222
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/validators/src/business-constants.ts
19507
+ // ../../packages/validators/src/business-constants.ts
19223
19508
  var MONETARY_BOUNDS = {
19224
19509
  /** Maximum price in cents (999,999.99 in currency units) */
19225
19510
  maxPriceCents: 99999999,
@@ -19252,7 +19537,7 @@ var SESSION_POLICY = {
19252
19537
  var MAX_RESCHEDULES = SESSION_POLICY.maxReschedules;
19253
19538
  var PLATFORM_CURRENCIES = ["USD", "BRL", "EUR", "GBP", "ARS", "MXN", "CAD"];
19254
19539
 
19255
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/validators/src/mentorship.ts
19540
+ // ../../packages/validators/src/mentorship.ts
19256
19541
  var serviceTypeValues = ["one_on_one", "group", "workshop"];
19257
19542
  var sessionStatusValues = [
19258
19543
  "scheduled",
@@ -19352,7 +19637,7 @@ var updateSessionStatusSchema = external_exports.object({
19352
19637
  notes: external_exports.string().max(5e3, "Notes must be at most 5000 characters").optional().nullable()
19353
19638
  });
19354
19639
 
19355
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/exercises/enrollment-levels.ts
19640
+ // ../../packages/tostudy-core/src/exercises/enrollment-levels.ts
19356
19641
  async function getEnrollmentLevels(input2, deps) {
19357
19642
  deps.logger.info("tostudy-core: getEnrollmentLevels", { enrollmentId: input2.enrollmentId });
19358
19643
  return deps.data.exercises.getEnrollmentLevels(input2.enrollmentId);
@@ -19615,7 +19900,7 @@ async function clearRetryPin() {
19615
19900
  await updateWorkspaceState(ws.workspacePath, { retryLessonId: void 0 });
19616
19901
  }
19617
19902
  }
19618
- var validateCommand = new Command15("validate").description("Validate your solution for the current exercise").argument("[file]", "Path to the solution file to read").option("--stdin", "Read solution from stdin instead of a file").option("--json", "Output structured JSON").action(async (file2, opts) => {
19903
+ var validateCommand = new Command16("validate").description("Validate your solution for the current exercise").argument("[file]", "Path to the solution file to read").option("--stdin", "Read solution from stdin instead of a file").option("--json", "Output structured JSON").action(async (file2, opts) => {
19619
19904
  try {
19620
19905
  const session = await requireSession();
19621
19906
  const activeCourse = await requireActiveCourse();
@@ -19644,21 +19929,21 @@ var validateCommand = new Command15("validate").description("Validate your solut
19644
19929
  }
19645
19930
  let solution;
19646
19931
  if (opts.stdin) {
19647
- solution = fs11.readFileSync("/dev/stdin", "utf-8");
19932
+ solution = fs12.readFileSync("/dev/stdin", "utf-8");
19648
19933
  } else if (file2) {
19649
- if (!fs11.existsSync(file2)) {
19934
+ if (!fs12.existsSync(file2)) {
19650
19935
  if (opts.json)
19651
19936
  jsonError("file_not_found", { message: `Arquivo n\xE3o encontrado: ${file2}` });
19652
19937
  error(`Arquivo n\xE3o encontrado: ${file2}`);
19653
19938
  }
19654
- solution = fs11.readFileSync(file2, "utf-8");
19939
+ solution = fs12.readFileSync(file2, "utf-8");
19655
19940
  } else {
19656
19941
  if (opts.json)
19657
19942
  jsonError("no_solution_provided", { message: "Forne\xE7a um arquivo ou use --stdin" });
19658
19943
  error("Forne\xE7a um arquivo ou use --stdin.\n\nExemplo: tostudy validate resposta.md");
19659
19944
  }
19660
19945
  if (file2 && activeCourse.courseTags?.length) {
19661
- const ext = path14.extname(file2).toLowerCase();
19946
+ const ext = path15.extname(file2).toLowerCase();
19662
19947
  const LANG_EXTENSIONS = {
19663
19948
  ".html": ["html", "html5"],
19664
19949
  ".css": ["css"],
@@ -19753,13 +20038,13 @@ var validateCommand = new Command15("validate").description("Validate your solut
19753
20038
 
19754
20039
  // src/commands/retry.ts
19755
20040
  init_dist();
19756
- import { Command as Command16 } from "commander";
20041
+ import { Command as Command17 } from "commander";
19757
20042
  init_guards();
19758
20043
  init_workspace_state();
19759
20044
  init_formatter();
19760
20045
  var logger17 = createLogger("cli:retry");
19761
20046
  var LESSON_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
19762
- var retryCommand = new Command16("retry").description("Revalidate a lesson you already completed (your grade keeps the best attempt)").argument("[lessonId]", "Id of the completed lesson (see: tostudy grades --course <slug> --json)").option("--clear", "Cancel the pending retry; validate goes back to the current lesson").option("--json", "Output structured JSON").action(async (lessonId, opts) => {
20047
+ var retryCommand = new Command17("retry").description("Revalidate a lesson you already completed (your grade keeps the best attempt)").argument("[lessonId]", "Id of the completed lesson (see: tostudy grades --course <slug> --json)").option("--clear", "Cancel the pending retry; validate goes back to the current lesson").option("--json", "Output structured JSON").action(async (lessonId, opts) => {
19763
20048
  try {
19764
20049
  if (opts.clear) {
19765
20050
  const ws2 = await findWorkspaceState();
@@ -19820,8 +20105,8 @@ var retryCommand = new Command16("retry").description("Revalidate a lesson you a
19820
20105
  init_session_store();
19821
20106
  init_workspace_state();
19822
20107
  init_formatter();
19823
- import { Command as Command17 } from "commander";
19824
- var menuCommand = new Command17("menu").description("Show available commands and current study context").action(async () => {
20108
+ import { Command as Command18 } from "commander";
20109
+ var menuCommand = new Command18("menu").description("Show available commands and current study context").action(async () => {
19825
20110
  const session = await getSession();
19826
20111
  const wsResult = session ? await findWorkspaceState() : null;
19827
20112
  const activeCourse = wsResult?.state ?? null;
@@ -19878,7 +20163,7 @@ var menuCommand = new Command17("menu").description("Show available commands and
19878
20163
 
19879
20164
  // src/commands/init.ts
19880
20165
  init_dist();
19881
- import { Command as Command18 } from "commander";
20166
+ import { Command as Command19 } from "commander";
19882
20167
  init_session_store();
19883
20168
  init_course_state();
19884
20169
  init_workspace_state();
@@ -20194,7 +20479,7 @@ Rode \`tostudy select <n\xFAmero>\` para ativar um curso.`,
20194
20479
  deps.output(artifacts.learnerBrief, { json: false });
20195
20480
  }
20196
20481
  }
20197
- var initCommand = new Command18("init").description("Generate tutor instructions and learner brief for the active course").option("--segment <segment>", "Learner segment/niche").option("--company <company>", "Company or business type").option("--products <products>", "Main products or services").option("--region <region>", "Operating region").option("--team <team>", "Team involved").option("--goal <goal>", "Primary learning goal").option("--level <level>", "Learner level: beginner, intermediate, advanced").option("--adapt-context", "Adapt examples to learner's real context").option(
20482
+ var initCommand = new Command19("init").description("Generate tutor instructions and learner brief for the active course").option("--segment <segment>", "Learner segment/niche").option("--company <company>", "Company or business type").option("--products <products>", "Main products or services").option("--region <region>", "Operating region").option("--team <team>", "Team involved").option("--goal <goal>", "Primary learning goal").option("--level <level>", "Learner level: beginner, intermediate, advanced").option("--adapt-context", "Adapt examples to learner's real context").option(
20198
20483
  "--root-agents",
20199
20484
  "Add the ToStudy block to an existing AGENTS.md in this folder without asking"
20200
20485
  ).option("--json", "Output structured JSON").action(async (opts) => {
@@ -20203,18 +20488,18 @@ var initCommand = new Command18("init").description("Generate tutor instructions
20203
20488
 
20204
20489
  // src/commands/workspace.ts
20205
20490
  init_dist();
20206
- import { Command as Command19 } from "commander";
20491
+ import { Command as Command20 } from "commander";
20207
20492
 
20208
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/workspace/setup-workspace.ts
20209
- import fs12 from "node:fs/promises";
20210
- import path15 from "node:path";
20493
+ // ../../packages/tostudy-core/src/workspace/setup-workspace.ts
20494
+ import fs13 from "node:fs/promises";
20495
+ import path16 from "node:path";
20211
20496
  var WORKSPACE_DIRS = ["exercises", "generated", "notes", "diagrams", "vault"];
20212
20497
  async function setupWorkspace(input2) {
20213
- const workspacePath = path15.join(input2.basePath, input2.courseSlug);
20498
+ const workspacePath = path16.join(input2.basePath, input2.courseSlug);
20214
20499
  for (const dir of WORKSPACE_DIRS) {
20215
- await fs12.mkdir(path15.join(workspacePath, dir), { recursive: true });
20500
+ await fs13.mkdir(path16.join(workspacePath, dir), { recursive: true });
20216
20501
  }
20217
- const configPath = path15.join(workspacePath, ".ana-config.json");
20502
+ const configPath = path16.join(workspacePath, ".ana-config.json");
20218
20503
  const config2 = {
20219
20504
  courseId: input2.courseId,
20220
20505
  courseSlug: input2.courseSlug,
@@ -20224,7 +20509,7 @@ async function setupWorkspace(input2) {
20224
20509
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
20225
20510
  lastAccessedAt: (/* @__PURE__ */ new Date()).toISOString()
20226
20511
  };
20227
- await fs12.writeFile(configPath, JSON.stringify(config2, null, 2), "utf-8");
20512
+ await fs13.writeFile(configPath, JSON.stringify(config2, null, 2), "utf-8");
20228
20513
  const readme = [
20229
20514
  `# ${input2.courseName}`,
20230
20515
  "",
@@ -20249,15 +20534,15 @@ async function setupWorkspace(input2) {
20249
20534
  "tostudy vault sync # Sincronizar progresso",
20250
20535
  "```"
20251
20536
  ].join("\n");
20252
- await fs12.writeFile(path15.join(workspacePath, "README.md"), readme, "utf-8");
20537
+ await fs13.writeFile(path16.join(workspacePath, "README.md"), readme, "utf-8");
20253
20538
  return { workspacePath, directories: WORKSPACE_DIRS, configPath };
20254
20539
  }
20255
20540
 
20256
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/workspace/extract-exercise.ts
20257
- import fs13 from "node:fs/promises";
20258
- import path16 from "node:path";
20541
+ // ../../packages/tostudy-core/src/workspace/extract-exercise.ts
20542
+ import fs14 from "node:fs/promises";
20543
+ import path17 from "node:path";
20259
20544
 
20260
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/workspace/templates.ts
20545
+ // ../../packages/tostudy-core/src/workspace/templates.ts
20261
20546
  var VITE_VERSION = "^6.0.0";
20262
20547
  var REACT_VERSION = "^19.0.0";
20263
20548
  var TEMPLATES = {
@@ -20340,7 +20625,7 @@ function getScaffoldTemplate(template) {
20340
20625
  return TEMPLATES[template] ?? null;
20341
20626
  }
20342
20627
 
20343
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/workspace/extract-exercise.ts
20628
+ // ../../packages/tostudy-core/src/workspace/extract-exercise.ts
20344
20629
  init_workspace_tokens();
20345
20630
  function padOrder(n) {
20346
20631
  return String(n).padStart(2, "0");
@@ -20367,16 +20652,16 @@ async function extractExercise(input2) {
20367
20652
  const lessonData = resolveWorkspaceTokens(input2.lessonData, paths);
20368
20653
  const moduleDir = `${padOrder(lessonData.moduleOrder)}-${lessonData.moduleSlug}`;
20369
20654
  const lessonDir = `${padOrder(lessonData.lessonOrder)}-${lessonData.lessonSlug}`;
20370
- const exercisePath = path16.join(workspacePath, "exercises", moduleDir, lessonDir);
20371
- await fs13.mkdir(exercisePath, { recursive: true });
20655
+ const exercisePath = path17.join(workspacePath, "exercises", moduleDir, lessonDir);
20656
+ await fs14.mkdir(exercisePath, { recursive: true });
20372
20657
  const extractedFiles = [];
20373
20658
  let hasStarterCode = false;
20374
20659
  if (lessonData.sandpackConfig?.files) {
20375
20660
  for (const [filePath, fileData] of Object.entries(lessonData.sandpackConfig.files)) {
20376
20661
  const cleanPath = filePath.startsWith("/") ? filePath.slice(1) : filePath;
20377
- const fullPath = path16.join(exercisePath, cleanPath);
20378
- await fs13.mkdir(path16.dirname(fullPath), { recursive: true });
20379
- await fs13.writeFile(fullPath, fileData.code, "utf-8");
20662
+ const fullPath = path17.join(exercisePath, cleanPath);
20663
+ await fs14.mkdir(path17.dirname(fullPath), { recursive: true });
20664
+ await fs14.writeFile(fullPath, fileData.code, "utf-8");
20380
20665
  extractedFiles.push(cleanPath);
20381
20666
  hasStarterCode = true;
20382
20667
  }
@@ -20384,13 +20669,13 @@ async function extractExercise(input2) {
20384
20669
  const tierData = getTierData(lessonData.structuredData, exerciseTier2);
20385
20670
  const tierCode = tierData?.code;
20386
20671
  if (tierCode) {
20387
- await fs13.writeFile(path16.join(exercisePath, "exercise.js"), tierCode, "utf-8");
20672
+ await fs14.writeFile(path17.join(exercisePath, "exercise.js"), tierCode, "utf-8");
20388
20673
  extractedFiles.push("exercise.js");
20389
20674
  hasStarterCode = true;
20390
20675
  } else {
20391
20676
  const starter = getStarterCode(lessonData.structuredData);
20392
20677
  if (starter) {
20393
- await fs13.writeFile(path16.join(exercisePath, "exercise.js"), starter, "utf-8");
20678
+ await fs14.writeFile(path17.join(exercisePath, "exercise.js"), starter, "utf-8");
20394
20679
  extractedFiles.push("exercise.js");
20395
20680
  hasStarterCode = true;
20396
20681
  }
@@ -20408,8 +20693,8 @@ async function extractExercise(input2) {
20408
20693
  ...exerciseDeps
20409
20694
  }
20410
20695
  };
20411
- await fs13.writeFile(
20412
- path16.join(exercisePath, "package.json"),
20696
+ await fs14.writeFile(
20697
+ path17.join(exercisePath, "package.json"),
20413
20698
  JSON.stringify(pkgJson, null, 2),
20414
20699
  "utf-8"
20415
20700
  );
@@ -20421,20 +20706,20 @@ async function extractExercise(input2) {
20421
20706
  );
20422
20707
  for (const [configFile, configContent] of Object.entries(scaffold.configs)) {
20423
20708
  if (!sandpackFileNames.has(configFile)) {
20424
- await fs13.writeFile(path16.join(exercisePath, configFile), configContent, "utf-8");
20709
+ await fs14.writeFile(path17.join(exercisePath, configFile), configContent, "utf-8");
20425
20710
  extractedFiles.push(configFile);
20426
20711
  }
20427
20712
  }
20428
20713
  const setupSh = `#!/bin/sh
20429
20714
  ${scaffold.setupScript}
20430
20715
  `;
20431
- await fs13.writeFile(path16.join(exercisePath, "setup.sh"), setupSh, "utf-8");
20716
+ await fs14.writeFile(path17.join(exercisePath, "setup.sh"), setupSh, "utf-8");
20432
20717
  extractedFiles.push("setup.sh");
20433
20718
  }
20434
20719
  }
20435
20720
  const readme = generateReadme(lessonData, exerciseTier2);
20436
- const readmePath = path16.join(exercisePath, "README.md");
20437
- await fs13.writeFile(readmePath, readme, "utf-8");
20721
+ const readmePath = path17.join(exercisePath, "README.md");
20722
+ await fs14.writeFile(readmePath, readme, "utf-8");
20438
20723
  extractedFiles.push("README.md");
20439
20724
  return {
20440
20725
  exercisePath,
@@ -20479,10 +20764,10 @@ function generateReadme(lessonData, tier) {
20479
20764
  return sections.join("\n");
20480
20765
  }
20481
20766
 
20482
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/workspace/export-artifact.ts
20767
+ // ../../packages/tostudy-core/src/workspace/export-artifact.ts
20483
20768
  init_slug();
20484
20769
 
20485
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/workspace/lesson-exercise-data.ts
20770
+ // ../../packages/tostudy-core/src/workspace/lesson-exercise-data.ts
20486
20771
  init_slug();
20487
20772
 
20488
20773
  // src/commands/workspace.ts
@@ -20490,11 +20775,11 @@ init_guards();
20490
20775
  init_course_state();
20491
20776
  init_resolve();
20492
20777
  init_errors();
20493
- import path17 from "node:path";
20778
+ import path18 from "node:path";
20494
20779
  import os8 from "node:os";
20495
- import fs14 from "node:fs/promises";
20780
+ import fs15 from "node:fs/promises";
20496
20781
  var logger19 = createLogger("cli:workspace");
20497
- var workspaceCommand = new Command19("workspace").description(
20782
+ var workspaceCommand = new Command20("workspace").description(
20498
20783
  getErrors().workspaceCommandDescription
20499
20784
  );
20500
20785
  workspaceCommand.command("setup").description(getErrors().workspaceSetupDescription).option("--path <dir>", "Diret\xF3rio base do workspace (omita para usar a pasta atual)").option("--json", "Output structured JSON").action(async (opts) => {
@@ -20506,14 +20791,14 @@ workspaceCommand.command("setup").description(getErrors().workspaceSetupDescript
20506
20791
  let directories;
20507
20792
  if (!opts.path && cwdIsWorkspace) {
20508
20793
  const resolvedCwd = await resolveCwdWorkspacePath(process.cwd());
20509
- workspacePath = resolvedCwd ?? path17.join(process.cwd(), ".tostudy");
20510
- await fs14.mkdir(workspacePath, { recursive: true });
20794
+ workspacePath = resolvedCwd ?? path18.join(process.cwd(), ".tostudy");
20795
+ await fs15.mkdir(workspacePath, { recursive: true });
20511
20796
  directories = ["exercises", "generated", "notes", "diagrams"];
20512
20797
  for (const dir of directories) {
20513
- await fs14.mkdir(path17.join(workspacePath, dir), { recursive: true });
20798
+ await fs15.mkdir(path18.join(workspacePath, dir), { recursive: true });
20514
20799
  }
20515
- const configPath = path17.join(workspacePath, ".ana-config.json");
20516
- await fs14.writeFile(
20800
+ const configPath = path18.join(workspacePath, ".ana-config.json");
20801
+ await fs15.writeFile(
20517
20802
  configPath,
20518
20803
  JSON.stringify(
20519
20804
  {
@@ -20531,7 +20816,7 @@ workspaceCommand.command("setup").description(getErrors().workspaceSetupDescript
20531
20816
  "utf-8"
20532
20817
  );
20533
20818
  } else {
20534
- const basePath = opts.path ?? path17.join(os8.homedir(), "study");
20819
+ const basePath = opts.path ?? path18.join(os8.homedir(), "study");
20535
20820
  const result2 = await setupWorkspace({
20536
20821
  courseId: activeCourse.courseId,
20537
20822
  courseSlug: courseSlug(activeCourse.courseTitle),
@@ -20565,7 +20850,7 @@ Pr\xF3ximo passo: tostudy export
20565
20850
  process.exit(1);
20566
20851
  }
20567
20852
  });
20568
- workspaceCommand.command("status").description("Mostrar status do workspace do curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace", path17.join(os8.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
20853
+ workspaceCommand.command("status").description("Mostrar status do workspace do curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace", path18.join(os8.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
20569
20854
  try {
20570
20855
  const activeCourse = await requireActiveCourse();
20571
20856
  const onboardingState = await getCourseOnboardingState(activeCourse.courseId);
@@ -20582,40 +20867,40 @@ workspaceCommand.command("status").description("Mostrar status do workspace do c
20582
20867
  const workspacePath = ws.workspacePath;
20583
20868
  let configData = null;
20584
20869
  try {
20585
- const raw2 = await fs14.readFile(path17.join(workspacePath, ".ana-config.json"), "utf-8");
20870
+ const raw2 = await fs15.readFile(path18.join(workspacePath, ".ana-config.json"), "utf-8");
20586
20871
  configData = JSON.parse(raw2);
20587
20872
  } catch {
20588
20873
  configData = null;
20589
20874
  }
20590
- const exercisesDir = path17.join(workspacePath, "exercises");
20875
+ const exercisesDir = path18.join(workspacePath, "exercises");
20591
20876
  let exerciseCount = 0;
20592
20877
  try {
20593
- const moduleDirs = await fs14.readdir(exercisesDir);
20878
+ const moduleDirs = await fs15.readdir(exercisesDir);
20594
20879
  for (const modDir of moduleDirs) {
20595
- const modPath = path17.join(exercisesDir, modDir);
20596
- const stat = await fs14.stat(modPath);
20880
+ const modPath = path18.join(exercisesDir, modDir);
20881
+ const stat = await fs15.stat(modPath);
20597
20882
  if (stat.isDirectory()) {
20598
- const lessonDirs = await fs14.readdir(modPath);
20883
+ const lessonDirs = await fs15.readdir(modPath);
20599
20884
  for (const lessonDir of lessonDirs) {
20600
- const lessonPath2 = path17.join(modPath, lessonDir);
20601
- const lstat = await fs14.stat(lessonPath2);
20885
+ const lessonPath2 = path18.join(modPath, lessonDir);
20886
+ const lstat = await fs15.stat(lessonPath2);
20602
20887
  if (lstat.isDirectory()) exerciseCount++;
20603
20888
  }
20604
20889
  }
20605
20890
  }
20606
20891
  } catch {
20607
20892
  }
20608
- const generatedDir = path17.join(workspacePath, "generated");
20893
+ const generatedDir = path18.join(workspacePath, "generated");
20609
20894
  let artifactCount = 0;
20610
20895
  try {
20611
- const files = await fs14.readdir(generatedDir);
20896
+ const files = await fs15.readdir(generatedDir);
20612
20897
  artifactCount = files.length;
20613
20898
  } catch {
20614
20899
  }
20615
- const diagramsDir = path17.join(workspacePath, "diagrams");
20900
+ const diagramsDir = path18.join(workspacePath, "diagrams");
20616
20901
  let diagramCount = 0;
20617
20902
  try {
20618
- const files = await fs14.readdir(diagramsDir);
20903
+ const files = await fs15.readdir(diagramsDir);
20619
20904
  diagramCount = files.length;
20620
20905
  } catch {
20621
20906
  }
@@ -20662,16 +20947,16 @@ workspaceCommand.command("status").description("Mostrar status do workspace do c
20662
20947
 
20663
20948
  // src/commands/export.ts
20664
20949
  init_dist();
20665
- import { Command as Command20 } from "commander";
20950
+ import { Command as Command21 } from "commander";
20666
20951
  init_guards();
20667
20952
  init_course_state();
20668
20953
  init_resolve();
20669
20954
  init_errors();
20670
- import path18 from "node:path";
20955
+ import path19 from "node:path";
20671
20956
  import os9 from "node:os";
20672
- import fs15 from "node:fs/promises";
20957
+ import fs16 from "node:fs/promises";
20673
20958
  var logger20 = createLogger("cli:export");
20674
- var exportCommand = new Command20("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", path18.join(os9.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
20959
+ var exportCommand = new Command21("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", path19.join(os9.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
20675
20960
  try {
20676
20961
  const session = await requireSession();
20677
20962
  const activeCourse = await requireActiveCourse();
@@ -20689,21 +20974,21 @@ var exportCommand = new Command20("export").description("Extrair exerc\xEDcio at
20689
20974
  opts.path
20690
20975
  );
20691
20976
  if (ws.found && ws.source === "cwd" && ws.workspacePath) {
20692
- const configPath = path18.join(ws.workspacePath, ".ana-config.json");
20977
+ const configPath = path19.join(ws.workspacePath, ".ana-config.json");
20693
20978
  let hasConfig = false;
20694
20979
  try {
20695
- await fs15.access(configPath);
20980
+ await fs16.access(configPath);
20696
20981
  hasConfig = true;
20697
20982
  } catch {
20698
20983
  }
20699
20984
  if (!hasConfig) {
20700
20985
  const slug = courseSlug(activeCourse.courseTitle);
20701
20986
  logger20.info("Auto-initializing workspace", { workspacePath: ws.workspacePath });
20702
- await fs15.mkdir(ws.workspacePath, { recursive: true });
20987
+ await fs16.mkdir(ws.workspacePath, { recursive: true });
20703
20988
  for (const dir of ["exercises", "generated", "notes", "diagrams"]) {
20704
- await fs15.mkdir(path18.join(ws.workspacePath, dir), { recursive: true });
20989
+ await fs16.mkdir(path19.join(ws.workspacePath, dir), { recursive: true });
20705
20990
  }
20706
- await fs15.writeFile(
20991
+ await fs16.writeFile(
20707
20992
  configPath,
20708
20993
  JSON.stringify(
20709
20994
  {
@@ -20721,7 +21006,7 @@ var exportCommand = new Command20("export").description("Extrair exerc\xEDcio at
20721
21006
  "utf-8"
20722
21007
  );
20723
21008
  await setCourseWorkspacePath(activeCourse.courseId, ws.workspacePath);
20724
- const isNamespaced = ws.workspacePath === path18.join(process.cwd(), ".tostudy");
21009
+ const isNamespaced = ws.workspacePath === path19.join(process.cwd(), ".tostudy");
20725
21010
  process.stderr.write(
20726
21011
  isNamespaced ? `\u2728 Workspace inicializado em .tostudy/ (isolado do projeto).
20727
21012
  ` : `\u2728 Workspace inicializado nesta pasta.
@@ -20776,12 +21061,12 @@ init_guards();
20776
21061
  init_course_state();
20777
21062
  init_resolve();
20778
21063
  init_errors();
20779
- import { Command as Command21 } from "commander";
21064
+ import { Command as Command22 } from "commander";
20780
21065
  import { execFile as execFile3 } from "node:child_process";
20781
- import path19 from "node:path";
21066
+ import path20 from "node:path";
20782
21067
  import os10 from "node:os";
20783
21068
  var logger21 = createLogger("cli:open");
20784
- var openCommand = new Command21("open").description("Abrir workspace do curso na IDE").option("--path <dir>", "Diret\xF3rio base do workspace", path19.join(os10.homedir(), "study")).action(async (opts) => {
21069
+ var openCommand = new Command22("open").description("Abrir workspace do curso na IDE").option("--path <dir>", "Diret\xF3rio base do workspace", path20.join(os10.homedir(), "study")).action(async (opts) => {
20785
21070
  try {
20786
21071
  const activeCourse = await requireActiveCourse();
20787
21072
  const onboardingState = await getCourseOnboardingState(activeCourse.courseId);
@@ -20816,36 +21101,36 @@ var openCommand = new Command21("open").description("Abrir workspace do curso na
20816
21101
 
20817
21102
  // src/commands/vault.ts
20818
21103
  init_dist();
20819
- import { Command as Command22 } from "commander";
21104
+ import { Command as Command23 } from "commander";
20820
21105
 
20821
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/vault/generate-vault-files.ts
21106
+ // ../../packages/tostudy-core/src/vault/generate-vault-files.ts
20822
21107
  init_slug();
20823
21108
 
20824
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/vault/write-vault.ts
20825
- import fs16 from "node:fs/promises";
20826
- import path20 from "node:path";
21109
+ // ../../packages/tostudy-core/src/vault/write-vault.ts
21110
+ import fs17 from "node:fs/promises";
21111
+ import path21 from "node:path";
20827
21112
 
20828
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/vault/types.ts
21113
+ // ../../packages/tostudy-core/src/vault/types.ts
20829
21114
  var VAULT_MARKER_FILENAME = ".ana-vault.json";
20830
21115
  var VAULT_MARKER_VERSION = 1;
20831
21116
 
20832
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/tostudy-core/src/vault/write-vault.ts
21117
+ // ../../packages/tostudy-core/src/vault/write-vault.ts
20833
21118
  async function writeVaultFiles(files, outputPath, courseId, courseSlug2) {
20834
21119
  for (const file2 of files) {
20835
- const fullPath = path20.join(outputPath, file2.relativePath);
20836
- await fs16.mkdir(path20.dirname(fullPath), { recursive: true });
20837
- await fs16.writeFile(fullPath, file2.content, "utf-8");
21120
+ const fullPath = path21.join(outputPath, file2.relativePath);
21121
+ await fs17.mkdir(path21.dirname(fullPath), { recursive: true });
21122
+ await fs17.writeFile(fullPath, file2.content, "utf-8");
20838
21123
  }
20839
- const vaultPath = path20.join(outputPath, courseSlug2);
21124
+ const vaultPath = path21.join(outputPath, courseSlug2);
20840
21125
  const marker = {
20841
21126
  courseId,
20842
21127
  courseSlug: courseSlug2,
20843
21128
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
20844
21129
  version: VAULT_MARKER_VERSION
20845
21130
  };
20846
- await fs16.mkdir(vaultPath, { recursive: true });
20847
- await fs16.writeFile(
20848
- path20.join(vaultPath, VAULT_MARKER_FILENAME),
21131
+ await fs17.mkdir(vaultPath, { recursive: true });
21132
+ await fs17.writeFile(
21133
+ path21.join(vaultPath, VAULT_MARKER_FILENAME),
20849
21134
  JSON.stringify(marker, null, 2),
20850
21135
  "utf-8"
20851
21136
  );
@@ -20858,12 +21143,12 @@ init_guards();
20858
21143
  init_course_state();
20859
21144
  init_resolve();
20860
21145
  init_errors();
20861
- import path21 from "node:path";
21146
+ import path22 from "node:path";
20862
21147
  import os11 from "node:os";
20863
- import fs17 from "node:fs/promises";
21148
+ import fs18 from "node:fs/promises";
20864
21149
  var logger22 = createLogger("cli:vault");
20865
- var vaultCommand = new Command22("vault").description("Gerenciar vault Obsidian do curso");
20866
- vaultCommand.command("init").description("Gerar vault Obsidian para o curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace", path21.join(os11.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
21150
+ var vaultCommand = new Command23("vault").description("Gerenciar vault Obsidian do curso");
21151
+ vaultCommand.command("init").description("Gerar vault Obsidian para o curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace", path22.join(os11.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
20867
21152
  try {
20868
21153
  const session = await requireSession();
20869
21154
  const activeCourse = await requireActiveCourse();
@@ -20944,7 +21229,7 @@ Para visualizar:
20944
21229
  process.exit(1);
20945
21230
  }
20946
21231
  });
20947
- vaultCommand.command("sync").description("Sincronizar progresso do curso com o vault local").option("--path <dir>", "Diret\xF3rio base do workspace", path21.join(os11.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
21232
+ vaultCommand.command("sync").description("Sincronizar progresso do curso com o vault local").option("--path <dir>", "Diret\xF3rio base do workspace", path22.join(os11.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
20948
21233
  try {
20949
21234
  const session = await requireSession();
20950
21235
  const activeCourse = await requireActiveCourse();
@@ -20970,8 +21255,8 @@ vaultCommand.command("sync").description("Sincronizar progresso do curso com o v
20970
21255
  const data = createHttpProvider(session.apiUrl, session.token);
20971
21256
  const deps = { data, logger: logger22 };
20972
21257
  const progress = await getProgress({ enrollmentId: activeCourse.enrollmentId }, deps);
20973
- const markerPath = path21.join(vaultPath, ".ana-vault.json");
20974
- const markerRaw = await fs17.readFile(markerPath, "utf-8");
21258
+ const markerPath = path22.join(vaultPath, ".ana-vault.json");
21259
+ const markerRaw = await fs18.readFile(markerPath, "utf-8");
20975
21260
  const marker = JSON.parse(markerRaw);
20976
21261
  marker.lastSyncedAt = (/* @__PURE__ */ new Date()).toISOString();
20977
21262
  marker.progress = {
@@ -20979,10 +21264,10 @@ vaultCommand.command("sync").description("Sincronizar progresso do curso com o v
20979
21264
  currentModule: progress.currentModule.title,
20980
21265
  currentLesson: progress.currentLesson.title
20981
21266
  };
20982
- await fs17.writeFile(markerPath, JSON.stringify(marker, null, 2), "utf-8");
20983
- const courseIndexPath = path21.join(vaultPath, slug, "index.md");
21267
+ await fs18.writeFile(markerPath, JSON.stringify(marker, null, 2), "utf-8");
21268
+ const courseIndexPath = path22.join(vaultPath, slug, "index.md");
20984
21269
  try {
20985
- let indexContent = await fs17.readFile(courseIndexPath, "utf-8");
21270
+ let indexContent = await fs18.readFile(courseIndexPath, "utf-8");
20986
21271
  indexContent = indexContent.replace(/\n---\n\n> 📊 Progresso:.*\n/g, "");
20987
21272
  const titleEnd = indexContent.indexOf("\n");
20988
21273
  if (titleEnd !== -1) {
@@ -20993,7 +21278,7 @@ vaultCommand.command("sync").description("Sincronizar progresso do curso com o v
20993
21278
  `;
20994
21279
  indexContent = indexContent.slice(0, titleEnd) + banner + indexContent.slice(titleEnd);
20995
21280
  }
20996
- await fs17.writeFile(courseIndexPath, indexContent, "utf-8");
21281
+ await fs18.writeFile(courseIndexPath, indexContent, "utf-8");
20997
21282
  } catch {
20998
21283
  }
20999
21284
  const syncedAt = marker.lastSyncedAt;
@@ -21034,10 +21319,10 @@ init_dist();
21034
21319
  init_formatter();
21035
21320
  init_errors();
21036
21321
  import os13 from "node:os";
21037
- import path25 from "node:path";
21038
- import { Command as Command24 } from "commander";
21322
+ import path26 from "node:path";
21323
+ import { Command as Command25 } from "commander";
21039
21324
 
21040
- // ../../../../../Users/cleitonparis/www/pg/apps/cursos/packages/validators/src/authored-course.ts
21325
+ // ../../packages/validators/src/authored-course.ts
21041
21326
  import { createHash } from "node:crypto";
21042
21327
  var AUTHORED_LIMITS = {
21043
21328
  maxModules: 15,
@@ -21308,12 +21593,12 @@ function assembleAuthoredCourse(manifest, files) {
21308
21593
  init_guards();
21309
21594
 
21310
21595
  // src/creator/state.ts
21311
- import fs18 from "node:fs/promises";
21312
- import path22 from "node:path";
21313
- var STATE_FILE = path22.join(".tostudy", "creator.json");
21596
+ import fs19 from "node:fs/promises";
21597
+ import path23 from "node:path";
21598
+ var STATE_FILE = path23.join(".tostudy", "creator.json");
21314
21599
  async function readCreatorState(root) {
21315
21600
  try {
21316
- const parsed = JSON.parse(await fs18.readFile(path22.join(root, STATE_FILE), "utf-8"));
21601
+ const parsed = JSON.parse(await fs19.readFile(path23.join(root, STATE_FILE), "utf-8"));
21317
21602
  const hashes = parsed.baseHashes;
21318
21603
  const wellFormed = Array.isArray(hashes) && hashes.every(
21319
21604
  (mod) => Array.isArray(mod) && // wire shape of authoredCoursePushSchema.baseHashes; anything else is not a base we can send
@@ -21329,9 +21614,9 @@ async function readCreatorState(root) {
21329
21614
  }
21330
21615
  }
21331
21616
  async function writeCreatorState(root, state) {
21332
- const file2 = path22.join(root, STATE_FILE);
21333
- await fs18.mkdir(path22.dirname(file2), { recursive: true });
21334
- await fs18.writeFile(file2, JSON.stringify(state, null, 2) + "\n", "utf-8");
21617
+ const file2 = path23.join(root, STATE_FILE);
21618
+ await fs19.mkdir(path23.dirname(file2), { recursive: true });
21619
+ await fs19.writeFile(file2, JSON.stringify(state, null, 2) + "\n", "utf-8");
21335
21620
  }
21336
21621
  function changedSlots(baseHashes, remoteHashes, incomingHashes) {
21337
21622
  const changed = [];
@@ -21348,9 +21633,9 @@ function changedSlots(baseHashes, remoteHashes, incomingHashes) {
21348
21633
  // src/creator/workspace.ts
21349
21634
  init_errors();
21350
21635
  import { randomUUID } from "node:crypto";
21351
- import fs19 from "node:fs/promises";
21636
+ import fs20 from "node:fs/promises";
21352
21637
  import os12 from "node:os";
21353
- import path23 from "node:path";
21638
+ import path24 from "node:path";
21354
21639
  var MANIFEST_FILE2 = "tostudy.json";
21355
21640
  var STATE_GITIGNORE_ENTRY = ".tostudy/creator.json";
21356
21641
  var CreatorWorkspaceError = class extends Error {
@@ -21364,10 +21649,10 @@ var CreatorWorkspaceError = class extends Error {
21364
21649
  file;
21365
21650
  };
21366
21651
  function assertInsideRoot(root, relPath) {
21367
- const abs = path23.resolve(root, relPath);
21368
- const back = path23.relative(path23.resolve(root), abs);
21369
- const escapes = back === "" || back === ".." || back.startsWith(`..${path23.sep}`) || path23.isAbsolute(back);
21370
- if (path23.isAbsolute(relPath) || escapes) {
21652
+ const abs = path24.resolve(root, relPath);
21653
+ const back = path24.relative(path24.resolve(root), abs);
21654
+ const escapes = back === "" || back === ".." || back.startsWith(`..${path24.sep}`) || path24.isAbsolute(back);
21655
+ if (path24.isAbsolute(relPath) || escapes) {
21371
21656
  throw new CreatorWorkspaceError(
21372
21657
  "PATH_OUTSIDE_ROOT",
21373
21658
  fillTemplate(getErrors().creator.pathOutsideRoot, { path: relPath }),
@@ -21377,9 +21662,9 @@ function assertInsideRoot(root, relPath) {
21377
21662
  return abs;
21378
21663
  }
21379
21664
  function assertNotHome(dir, home = os12.homedir()) {
21380
- const resolvedHome = path23.resolve(home);
21381
- const resolved = path23.resolve(dir);
21382
- const prefix = resolved.endsWith(path23.sep) ? resolved : resolved + path23.sep;
21665
+ const resolvedHome = path24.resolve(home);
21666
+ const resolved = path24.resolve(dir);
21667
+ const prefix = resolved.endsWith(path24.sep) ? resolved : resolved + path24.sep;
21383
21668
  if (resolved === resolvedHome || resolvedHome.startsWith(prefix)) {
21384
21669
  throw new CreatorWorkspaceError("REFUSED_AT_HOME", getErrors().creator.refusedAtHome);
21385
21670
  }
@@ -21398,7 +21683,7 @@ function manifestLessonPaths(manifestRaw) {
21398
21683
  async function readManifest(root) {
21399
21684
  let text2;
21400
21685
  try {
21401
- text2 = await fs19.readFile(path23.join(root, MANIFEST_FILE2), "utf-8");
21686
+ text2 = await fs20.readFile(path24.join(root, MANIFEST_FILE2), "utf-8");
21402
21687
  } catch {
21403
21688
  throw new CreatorWorkspaceError(
21404
21689
  "MANIFEST_MISSING",
@@ -21417,7 +21702,7 @@ async function readManifest(root) {
21417
21702
  }
21418
21703
  }
21419
21704
  async function readCourseId(dir) {
21420
- const manifest = await readManifest(path23.resolve(dir));
21705
+ const manifest = await readManifest(path24.resolve(dir));
21421
21706
  const courseId = manifest?.courseId;
21422
21707
  if (typeof courseId !== "string" || courseId.length === 0) {
21423
21708
  throw new CreatorWorkspaceError(
@@ -21431,23 +21716,23 @@ async function readCourseId(dir) {
21431
21716
  async function readInside(root, realRoot, relPath) {
21432
21717
  let real;
21433
21718
  try {
21434
- real = await fs19.realpath(path23.resolve(root, relPath));
21719
+ real = await fs20.realpath(path24.resolve(root, relPath));
21435
21720
  } catch {
21436
21721
  return null;
21437
21722
  }
21438
- if (!real.startsWith(realRoot + path23.sep)) {
21723
+ if (!real.startsWith(realRoot + path24.sep)) {
21439
21724
  throw new CreatorWorkspaceError(
21440
21725
  "PATH_OUTSIDE_ROOT",
21441
21726
  fillTemplate(getErrors().creator.pathOutsideRoot, { path: relPath }),
21442
21727
  relPath
21443
21728
  );
21444
21729
  }
21445
- return fs19.readFile(real, "utf-8");
21730
+ return fs20.readFile(real, "utf-8");
21446
21731
  }
21447
21732
  async function readWorkspace(dir) {
21448
- const root = path23.resolve(dir);
21733
+ const root = path24.resolve(dir);
21449
21734
  const manifestRaw = await readManifest(root);
21450
- const realRoot = await fs19.realpath(root);
21735
+ const realRoot = await fs20.realpath(root);
21451
21736
  const files = {};
21452
21737
  for (const relPath of manifestLessonPaths(manifestRaw).flat()) {
21453
21738
  assertInsideRoot(root, relPath);
@@ -21459,18 +21744,18 @@ async function readWorkspace(dir) {
21459
21744
  return { manifestRaw, files, root };
21460
21745
  }
21461
21746
  async function ensureGitignore(root) {
21462
- const file2 = path23.join(root, ".gitignore");
21463
- const current = await fs19.readFile(file2, "utf-8").catch(() => "");
21747
+ const file2 = path24.join(root, ".gitignore");
21748
+ const current = await fs20.readFile(file2, "utf-8").catch(() => "");
21464
21749
  if (current.split(/\r?\n/).some((line) => line.trim() === STATE_GITIGNORE_ENTRY)) return false;
21465
21750
  const separator = current.length === 0 || current.endsWith("\n") ? "" : "\n";
21466
- await fs19.writeFile(file2, `${current}${separator}${STATE_GITIGNORE_ENTRY}
21751
+ await fs20.writeFile(file2, `${current}${separator}${STATE_GITIGNORE_ENTRY}
21467
21752
  `, "utf-8");
21468
21753
  return true;
21469
21754
  }
21470
21755
  async function scaffoldWorkspace(dir, home) {
21471
- const root = path23.resolve(dir);
21756
+ const root = path24.resolve(dir);
21472
21757
  assertNotHome(root, home);
21473
- await fs19.mkdir(root, { recursive: true });
21758
+ await fs20.mkdir(root, { recursive: true });
21474
21759
  const files = [];
21475
21760
  let courseId = randomUUID();
21476
21761
  let manifestCreated = true;
@@ -21481,11 +21766,11 @@ async function scaffoldWorkspace(dir, home) {
21481
21766
  modules: [{ title: "", description: "", objectives: [], lessons: [] }]
21482
21767
  };
21483
21768
  try {
21484
- await fs19.writeFile(path23.join(root, MANIFEST_FILE2), JSON.stringify(manifest, null, 2) + "\n", {
21769
+ await fs20.writeFile(path24.join(root, MANIFEST_FILE2), JSON.stringify(manifest, null, 2) + "\n", {
21485
21770
  encoding: "utf-8",
21486
21771
  flag: "wx"
21487
21772
  });
21488
- await fs19.mkdir(path23.join(root, "modules", "01"), { recursive: true });
21773
+ await fs20.mkdir(path24.join(root, "modules", "01"), { recursive: true });
21489
21774
  files.push(MANIFEST_FILE2, "modules/01/");
21490
21775
  } catch (err) {
21491
21776
  if (err.code !== "EEXIST") throw err;
@@ -21547,8 +21832,8 @@ async function validateWorkspace(dir, opts = {}) {
21547
21832
  }
21548
21833
 
21549
21834
  // src/creator/pull.ts
21550
- import fs20 from "node:fs/promises";
21551
- import path24 from "node:path";
21835
+ import fs21 from "node:fs/promises";
21836
+ import path25 from "node:path";
21552
21837
  init_errors();
21553
21838
  function stripToSchema(schema, value) {
21554
21839
  const current = structuredClone(value);
@@ -21573,17 +21858,17 @@ function stripToSchema(schema, value) {
21573
21858
  }
21574
21859
  async function exists(file2) {
21575
21860
  try {
21576
- await fs20.access(file2);
21861
+ await fs21.access(file2);
21577
21862
  return true;
21578
21863
  } catch {
21579
21864
  return false;
21580
21865
  }
21581
21866
  }
21582
21867
  async function assertWritableInside(realRoot, root, rel) {
21583
- const abs = path24.resolve(root, rel);
21868
+ const abs = path25.resolve(root, rel);
21584
21869
  let target;
21585
21870
  try {
21586
- target = await fs20.lstat(abs);
21871
+ target = await fs21.lstat(abs);
21587
21872
  } catch {
21588
21873
  target = void 0;
21589
21874
  }
@@ -21594,10 +21879,10 @@ async function assertWritableInside(realRoot, root, rel) {
21594
21879
  rel
21595
21880
  );
21596
21881
  }
21597
- let dir = path24.dirname(abs);
21598
- while (!await exists(dir)) dir = path24.dirname(dir);
21599
- const realDir = await fs20.realpath(dir);
21600
- if (realDir !== realRoot && !realDir.startsWith(realRoot + path24.sep)) {
21882
+ let dir = path25.dirname(abs);
21883
+ while (!await exists(dir)) dir = path25.dirname(dir);
21884
+ const realDir = await fs21.realpath(dir);
21885
+ if (realDir !== realRoot && !realDir.startsWith(realRoot + path25.sep)) {
21601
21886
  throw new CreatorWorkspaceError(
21602
21887
  "PATH_OUTSIDE_ROOT",
21603
21888
  fillTemplate(getErrors().creator.pathOutsideRoot, { path: rel }),
@@ -21606,7 +21891,7 @@ async function assertWritableInside(realRoot, root, rel) {
21606
21891
  }
21607
21892
  }
21608
21893
  async function applyPull(root, manifestRaw, remoteModules) {
21609
- const realRoot = await fs20.realpath(root);
21894
+ const realRoot = await fs21.realpath(root);
21610
21895
  const local = manifestLessonPaths(manifestRaw);
21611
21896
  const localShape = local.map((mod) => mod.length);
21612
21897
  const remoteShape = remoteModules.map((mod) => mod.lessons.length);
@@ -21625,7 +21910,7 @@ async function applyPull(root, manifestRaw, remoteModules) {
21625
21910
  assertInsideRoot(root, rel);
21626
21911
  const contract = stripped.data;
21627
21912
  const sidecarRel = sidecarPath(rel);
21628
- if (await exists(path24.resolve(root, sidecarRel))) {
21913
+ if (await exists(path25.resolve(root, sidecarRel))) {
21629
21914
  const { teachingContent, ...rest } = contract;
21630
21915
  planned.push({ rel: sidecarRel, text: String(teachingContent ?? "") });
21631
21916
  planned.push({ rel, text: `${JSON.stringify(rest, null, 2)}
@@ -21641,9 +21926,9 @@ async function applyPull(root, manifestRaw, remoteModules) {
21641
21926
  await assertWritableInside(realRoot, root, file2.rel);
21642
21927
  }
21643
21928
  for (const file2 of planned) {
21644
- const abs = path24.resolve(root, file2.rel);
21645
- await fs20.mkdir(path24.dirname(abs), { recursive: true });
21646
- await fs20.writeFile(abs, file2.text, "utf-8");
21929
+ const abs = path25.resolve(root, file2.rel);
21930
+ await fs21.mkdir(path25.dirname(abs), { recursive: true });
21931
+ await fs21.writeFile(abs, file2.text, "utf-8");
21647
21932
  }
21648
21933
  return { kind: "written", files: planned.map((file2) => file2.rel) };
21649
21934
  }
@@ -21977,7 +22262,7 @@ function installCreatorSkill(input2) {
21977
22262
  // src/commands/brief-open.ts
21978
22263
  init_guards();
21979
22264
  init_formatter();
21980
- import { Command as Command23 } from "commander";
22265
+ import { Command as Command24 } from "commander";
21981
22266
  import { execFile as execFile4 } from "node:child_process";
21982
22267
  import { platform } from "node:process";
21983
22268
  var BRIEF_URL = "https://tostudy.ai/student/settings/learner-brief";
@@ -22002,7 +22287,7 @@ function openUrl(url2, options = {}) {
22002
22287
  }
22003
22288
  });
22004
22289
  }
22005
- var briefOpenCommand = new Command23("brief-open").description("Open the learner brief editor in your web browser").action(async () => {
22290
+ var briefOpenCommand = new Command24("brief-open").description("Open the learner brief editor in your web browser").action(async () => {
22006
22291
  await requireSession();
22007
22292
  output(`Abrindo ${BRIEF_URL} no navegador...`, { json: false });
22008
22293
  openUrl(BRIEF_URL);
@@ -22010,7 +22295,7 @@ var briefOpenCommand = new Command23("brief-open").description("Open the learner
22010
22295
 
22011
22296
  // src/commands/creator.ts
22012
22297
  var logger23 = createLogger("cli:creator");
22013
- var creatorCommand = new Command24("creator").description(
22298
+ var creatorCommand = new Command25("creator").description(
22014
22299
  "Author a course with your own AI agent: init, validate, push, pull, audit, status, open"
22015
22300
  );
22016
22301
  function fail(err, opts, context) {
@@ -22024,7 +22309,7 @@ function fail(err, opts, context) {
22024
22309
  creatorCommand.command("init").description("Create an authoring workspace (tostudy.json, modules/01) and install the skill").argument("[dir]", "Workspace folder", ".").option("--all-runtimes", "Install the skill for every supported runtime, detected or not").option("--json", "Output structured JSON").action(async (dir, opts) => {
22025
22310
  try {
22026
22311
  const home = os13.homedir();
22027
- const scaffold = await scaffoldWorkspace(path25.resolve(process.cwd(), dir), home);
22312
+ const scaffold = await scaffoldWorkspace(path26.resolve(process.cwd(), dir), home);
22028
22313
  const kept = [];
22029
22314
  const installed = installCreatorSkill({
22030
22315
  cwd: scaffold.root,
@@ -22307,8 +22592,8 @@ creatorCommand.command("open").description("Open the course in the creator porta
22307
22592
  init_guards();
22308
22593
  init_course_state();
22309
22594
  init_user_profile();
22310
- import { Command as Command25 } from "commander";
22311
- var profileCommand = new Command25("profile").description("Show your learner profile for the active course").option("--json", "Output structured JSON").action(async (opts) => {
22595
+ import { Command as Command26 } from "commander";
22596
+ var profileCommand = new Command26("profile").description("Show your learner profile for the active course").option("--json", "Output structured JSON").action(async (opts) => {
22312
22597
  const activeCourse = await requireActiveCourse();
22313
22598
  const onboarding = await getCourseOnboardingState(activeCourse.courseId);
22314
22599
  const profile = onboarding?.learnerProfile ?? await getUserProfile();
@@ -22370,10 +22655,10 @@ var profileCommand = new Command25("profile").description("Show your learner pro
22370
22655
  init_dist();
22371
22656
  init_guards();
22372
22657
  init_formatter();
22373
- import { Command as Command26 } from "commander";
22658
+ import { Command as Command27 } from "commander";
22374
22659
  init_workspace_state();
22375
22660
  var logger24 = createLogger("cli:sync");
22376
- var syncCommand = new Command26("sync").description("Regenerate instruction files with updated progress").option("--json", "Output structured JSON").option(
22661
+ var syncCommand = new Command27("sync").description("Regenerate instruction files with updated progress").option("--json", "Output structured JSON").option(
22377
22662
  "--all-runtimes",
22378
22663
  "Write instruction files for every supported runtime, even undetected ones"
22379
22664
  ).option(
@@ -22445,10 +22730,10 @@ var syncCommand = new Command26("sync").description("Regenerate instruction file
22445
22730
  // src/commands/brief.ts
22446
22731
  init_dist();
22447
22732
  init_guards();
22448
- import { Command as Command27 } from "commander";
22733
+ import { Command as Command28 } from "commander";
22449
22734
  init_formatter();
22450
22735
  var logger25 = createLogger("cli:brief");
22451
- var briefCommand = new Command27("brief").description("Show your base learner brief (T1) status and content").option("--json", "Output structured JSON").action(async (opts) => {
22736
+ var briefCommand = new Command28("brief").description("Show your base learner brief (T1) status and content").option("--json", "Output structured JSON").action(async (opts) => {
22452
22737
  try {
22453
22738
  const session = await requireSession();
22454
22739
  const cached2 = await readBriefCache();
@@ -22489,10 +22774,10 @@ var briefCommand = new Command27("brief").description("Show your base learner br
22489
22774
  // src/commands/brief-create.ts
22490
22775
  init_dist();
22491
22776
  init_guards();
22492
- import { Command as Command28 } from "commander";
22777
+ import { Command as Command29 } from "commander";
22493
22778
  init_formatter();
22494
22779
  var logger26 = createLogger("cli:brief-create");
22495
- var briefCreateCommand = new Command28("brief-create").description("Create your base learner brief via interactive prompts (T1 bootstrap)").action(async () => {
22780
+ var briefCreateCommand = new Command29("brief-create").description("Create your base learner brief via interactive prompts (T1 bootstrap)").action(async () => {
22496
22781
  try {
22497
22782
  const session = await requireSession();
22498
22783
  const answers = await collectBootstrapAnswers({ userName: session.userName });
@@ -22525,22 +22810,22 @@ var briefCreateCommand = new Command28("brief-create").description("Create your
22525
22810
  init_dist();
22526
22811
  init_guards();
22527
22812
  init_workspace_state();
22528
- import fs22 from "node:fs";
22529
- import { Command as Command29 } from "commander";
22813
+ import fs23 from "node:fs";
22814
+ import { Command as Command30 } from "commander";
22530
22815
 
22531
22816
  // src/sessions/storage.ts
22532
22817
  init_dist();
22533
- import fs21 from "node:fs";
22534
- import path26 from "node:path";
22818
+ import fs22 from "node:fs";
22819
+ import path27 from "node:path";
22535
22820
  var logger27 = createLogger("cli:sessions");
22536
22821
  function sessionsDir(workspacePath) {
22537
- return path26.join(workspacePath, ".tostudy", "sessions");
22822
+ return path27.join(workspacePath, ".tostudy", "sessions");
22538
22823
  }
22539
22824
  async function saveModuleSummary(workspacePath, input2) {
22540
22825
  const dir = sessionsDir(workspacePath);
22541
- fs21.mkdirSync(dir, { recursive: true });
22826
+ fs22.mkdirSync(dir, { recursive: true });
22542
22827
  const filename = `module-${input2.moduleId}-summary.md`;
22543
- const filePath = path26.join(dir, filename);
22828
+ const filePath = path27.join(dir, filename);
22544
22829
  const header = [
22545
22830
  "---",
22546
22831
  `moduleId: ${input2.moduleId}`,
@@ -22549,17 +22834,17 @@ async function saveModuleSummary(workspacePath, input2) {
22549
22834
  "---",
22550
22835
  ""
22551
22836
  ].join("\n");
22552
- fs21.writeFileSync(filePath, header + input2.summary, { mode: 384 });
22837
+ fs22.writeFileSync(filePath, header + input2.summary, { mode: 384 });
22553
22838
  logger27.debug("Module summary saved", { moduleId: input2.moduleId, path: filePath });
22554
22839
  return filePath;
22555
22840
  }
22556
22841
  async function loadSessionContext(workspacePath) {
22557
22842
  const dir = sessionsDir(workspacePath);
22558
- if (!fs21.existsSync(dir)) return { moduleSummaries: [] };
22559
- const files = fs21.readdirSync(dir).filter((f) => f.startsWith("module-") && f.endsWith("-summary.md")).sort();
22843
+ if (!fs22.existsSync(dir)) return { moduleSummaries: [] };
22844
+ const files = fs22.readdirSync(dir).filter((f) => f.startsWith("module-") && f.endsWith("-summary.md")).sort();
22560
22845
  const summaries = [];
22561
22846
  for (const file2 of files) {
22562
- const content = fs21.readFileSync(path26.join(dir, file2), "utf-8");
22847
+ const content = fs22.readFileSync(path27.join(dir, file2), "utf-8");
22563
22848
  const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
22564
22849
  if (!frontmatterMatch) continue;
22565
22850
  const meta3 = frontmatterMatch[1];
@@ -22575,7 +22860,7 @@ async function loadSessionContext(workspacePath) {
22575
22860
  // src/commands/compact.ts
22576
22861
  init_formatter();
22577
22862
  var logger28 = createLogger("cli:compact");
22578
- var compactCommand = new Command29("compact").description("Save a module study summary (LLM-generated, from stdin)").option("--module-id <id>", "Module ID").option("--module-title <title>", "Module title").option("--json", "Output structured JSON").action(async (opts) => {
22863
+ var compactCommand = new Command30("compact").description("Save a module study summary (LLM-generated, from stdin)").option("--module-id <id>", "Module ID").option("--module-title <title>", "Module title").option("--json", "Output structured JSON").action(async (opts) => {
22579
22864
  try {
22580
22865
  const activeCourse = await requireActiveCourse();
22581
22866
  const ws = await findWorkspaceState();
@@ -22583,7 +22868,7 @@ var compactCommand = new Command29("compact").description("Save a module study s
22583
22868
  if (opts.json) jsonError("no_workspace");
22584
22869
  error("Nenhum workspace encontrado.");
22585
22870
  }
22586
- const summary = fs22.readFileSync("/dev/stdin", "utf-8").trim();
22871
+ const summary = fs23.readFileSync("/dev/stdin", "utf-8").trim();
22587
22872
  if (!summary) {
22588
22873
  if (opts.json) jsonError("empty_summary", { message: "Summary vazio" });
22589
22874
  error("Summary vazio. Envie o conte\xFAdo via stdin.");
@@ -22613,12 +22898,12 @@ var compactCommand = new Command29("compact").description("Save a module study s
22613
22898
  // src/commands/context.ts
22614
22899
  init_dist();
22615
22900
  init_workspace_state();
22616
- import { Command as Command30 } from "commander";
22901
+ import { Command as Command31 } from "commander";
22617
22902
  init_course_state();
22618
22903
  init_formatter();
22619
22904
  init_errors();
22620
22905
  var logger29 = createLogger("cli:context");
22621
- var contextCommand = new Command30("context").description("Load session context (workspace state + module summaries) for LLM consumption").option("--json", "Output structured JSON").action(async (opts) => {
22906
+ var contextCommand = new Command31("context").description("Load session context (workspace state + module summaries) for LLM consumption").option("--json", "Output structured JSON").action(async (opts) => {
22622
22907
  try {
22623
22908
  const ws = await findWorkspaceState();
22624
22909
  if (!ws) {
@@ -22670,13 +22955,13 @@ var contextCommand = new Command30("context").description("Load session context
22670
22955
 
22671
22956
  // src/commands/memory.ts
22672
22957
  init_dist();
22673
- import { Command as Command31 } from "commander";
22958
+ import { Command as Command32 } from "commander";
22674
22959
  init_workspace_state();
22675
22960
  init_guards();
22676
22961
  init_formatter();
22677
22962
  init_errors();
22678
22963
  var logger30 = createLogger("cli:memory");
22679
- var memoryCommand = new Command31("memory").description("Load accumulated student memory (learning profile + recent lessons) for the tutor").option("--json", "Output structured JSON").action(async (opts) => {
22964
+ var memoryCommand = new Command32("memory").description("Load accumulated student memory (learning profile + recent lessons) for the tutor").option("--json", "Output structured JSON").action(async (opts) => {
22680
22965
  try {
22681
22966
  const ws = await findWorkspaceState();
22682
22967
  if (!ws) {
@@ -22707,14 +22992,14 @@ var memoryCommand = new Command31("memory").description("Load accumulated studen
22707
22992
 
22708
22993
  // src/commands/insight.ts
22709
22994
  init_dist();
22710
- import { Command as Command32 } from "commander";
22995
+ import { Command as Command33 } from "commander";
22711
22996
  init_workspace_state();
22712
22997
  init_guards();
22713
22998
  init_formatter();
22714
22999
  init_errors();
22715
23000
  var logger31 = createLogger("cli:insight");
22716
23001
  var VALID_TYPES = ["difficulty", "breakthrough", "question"];
22717
- var insightCommand = new Command32("insight").description(
23002
+ var insightCommand = new Command33("insight").description(
22718
23003
  "Persist a student cognitive insight (difficulty | breakthrough | question) into course memory"
22719
23004
  ).argument("<type>", "difficulty | breakthrough | question").argument("<content>", 'Short description, e.g. "confunde async/await com promises"').option("--module-id <id>", "Module the insight relates to").option("--json", "Output structured JSON").action(async (type, content, opts) => {
22720
23005
  try {
@@ -22762,7 +23047,7 @@ var insightCommand = new Command32("insight").description(
22762
23047
 
22763
23048
  // src/commands/level.ts
22764
23049
  init_dist();
22765
- import { Command as Command33 } from "commander";
23050
+ import { Command as Command34 } from "commander";
22766
23051
  init_guards();
22767
23052
  init_formatter();
22768
23053
  var logger32 = createLogger("cli:level");
@@ -22777,7 +23062,7 @@ var LEVEL_LABELS2 = {
22777
23062
  function isExerciseLevel2(value) {
22778
23063
  return ALL_LEVELS.includes(value);
22779
23064
  }
22780
- var levelCommand = new Command33("level").description("Show or set the exercise scaffolding level for the active course").argument("[level]", "Target level: L0, L1, L2, L3, or L4").option("--json", "Output structured JSON").action(async (rawLevel, opts) => {
23065
+ var levelCommand = new Command34("level").description("Show or set the exercise scaffolding level for the active course").argument("[level]", "Target level: L0, L1, L2, L3, or L4").option("--json", "Output structured JSON").action(async (rawLevel, opts) => {
22781
23066
  try {
22782
23067
  const session = await requireSession();
22783
23068
  const activeCourse = await requireActiveCourse();
@@ -22842,10 +23127,10 @@ init_dist();
22842
23127
  init_guards();
22843
23128
  init_formatter();
22844
23129
  init_errors();
22845
- import { Command as Command34 } from "commander";
23130
+ import { Command as Command35 } from "commander";
22846
23131
  var logger33 = createLogger("cli:theory");
22847
23132
  var EXERCISE_LEVELS2 = ["L0", "L1", "L2", "L3", "L4"];
22848
- var theoryCommand = new Command34("theory").description("Request more theory on the current lesson (escape hatch)").option("--focus <text>", "Optional focus area in PT-BR (max 500 chars)").option("--level <L0|L1|L2|L3|L4>", "Override current exercise level (otherwise auto-detect)").option("--lesson <uuid>", "Override lesson ID (defaults to current workspace lesson)").option("--json", "Output structured JSON").action(async (opts) => {
23133
+ var theoryCommand = new Command35("theory").description("Request more theory on the current lesson (escape hatch)").option("--focus <text>", "Optional focus area in PT-BR (max 500 chars)").option("--level <L0|L1|L2|L3|L4>", "Override current exercise level (otherwise auto-detect)").option("--lesson <uuid>", "Override lesson ID (defaults to current workspace lesson)").option("--json", "Output structured JSON").action(async (opts) => {
22849
23134
  try {
22850
23135
  const session = await requireSession();
22851
23136
  const active = await requireActiveCourse();
@@ -22940,7 +23225,7 @@ var theoryCommand = new Command34("theory").description("Request more theory on
22940
23225
  // src/commands/export-grades.ts
22941
23226
  init_dist();
22942
23227
  init_guards();
22943
- import { Command as Command35 } from "commander";
23228
+ import { Command as Command36 } from "commander";
22944
23229
 
22945
23230
  // src/formatters/grades.ts
22946
23231
  function formatGradesJson(attempts) {
@@ -23308,7 +23593,7 @@ async function runExportGrades(opts, deps = defaultDeps5) {
23308
23593
  if (!rendered.endsWith("\n")) rendered += "\n";
23309
23594
  deps.stdoutWrite(rendered);
23310
23595
  }
23311
- var exportGradesCommand = new Command35("export-grades").description("Exporta o hist\xF3rico de valida\xE7\xF5es (notas) do curso ativo").option(
23596
+ var exportGradesCommand = new Command36("export-grades").description("Exporta o hist\xF3rico de valida\xE7\xF5es (notas) do curso ativo").option(
23312
23597
  "--course <slug>",
23313
23598
  "Slug do curso (gerado a partir do t\xEDtulo). Sem a flag, exporta o curso ativo."
23314
23599
  ).option("--format <json|csv|md>", "Formato de sa\xEDda (default: json)", "json").addHelpText(
@@ -23332,7 +23617,7 @@ C\xF3digos de sa\xEDda:
23332
23617
 
23333
23618
  // src/commands/grades.ts
23334
23619
  init_dist();
23335
- import { Command as Command36 } from "commander";
23620
+ import { Command as Command37 } from "commander";
23336
23621
  init_guards();
23337
23622
  var logger35 = createLogger("cli:grades");
23338
23623
  var defaultDeps6 = {
@@ -23488,7 +23773,7 @@ async function runGrades(opts, deps = defaultDeps6) {
23488
23773
  );
23489
23774
  deps.stdoutWrite(formatGradesAllEnrollmentsTable(summaries) + "\n");
23490
23775
  }
23491
- var gradesCommand = new Command36("grades").description("Mostra um resumo das notas (todas as matr\xEDculas ou um curso espec\xEDfico)").option(
23776
+ var gradesCommand = new Command37("grades").description("Mostra um resumo das notas (todas as matr\xEDculas ou um curso espec\xEDfico)").option(
23492
23777
  "--course <slug>",
23493
23778
  "Slug do curso (gerado a partir do t\xEDtulo). Sem a flag, lista todos os cursos."
23494
23779
  ).addHelpText(
@@ -23512,7 +23797,7 @@ C\xF3digos de sa\xEDda:
23512
23797
  // src/commands/review.ts
23513
23798
  init_dist();
23514
23799
  init_guards();
23515
- import { Command as Command37 } from "commander";
23800
+ import { Command as Command38 } from "commander";
23516
23801
  import { createInterface } from "node:readline/promises";
23517
23802
  import { stdin as defaultStdin, stdout as defaultStdout } from "node:process";
23518
23803
  var logger36 = createLogger("cli:review");
@@ -23662,7 +23947,7 @@ async function runReview(slug, opts, deps = defaultDeps7) {
23662
23947
  }) + "\n"
23663
23948
  );
23664
23949
  }
23665
- var reviewCommand = new Command37("review").description("Revisa a \xFAltima tentativa de valida\xE7\xE3o de uma li\xE7\xE3o").argument("<slug>", "Slug do curso (gerado a partir do t\xEDtulo)").option("--json", "Sa\xEDda em JSON (sem prompt interativo)").addHelpText(
23950
+ var reviewCommand = new Command38("review").description("Revisa a \xFAltima tentativa de valida\xE7\xE3o de uma li\xE7\xE3o").argument("<slug>", "Slug do curso (gerado a partir do t\xEDtulo)").option("--json", "Sa\xEDda em JSON (sem prompt interativo)").addHelpText(
23666
23951
  "after",
23667
23952
  `
23668
23953
  Exemplos:
@@ -23685,12 +23970,12 @@ C\xF3digos de sa\xEDda:
23685
23970
 
23686
23971
  // src/cli.ts
23687
23972
  function createProgram() {
23688
- const program = new Command38();
23973
+ const program = new Command39();
23689
23974
  program.name("tostudy").description("ToStudy CLI \u2014 study courses from the terminal").version(CLI_VERSION).option("--verbose", "Enable debug output").option("--course <id>", "Override active course ID").option("--locale <code>", "Output locale (pt-BR | en-US); defaults to LANG env then pt-BR").addHelpText(
23690
23975
  "before",
23691
23976
  [
23692
23977
  "",
23693
- " Come\xE7ando: login \u2192 enroll <id> \u2192 courses \u2192 select <n> \u2192 start",
23978
+ " Come\xE7ando: login \u2192 suggest \u2192 enroll <id> \u2192 courses \u2192 select <n> \u2192 start",
23694
23979
  " Estudando: next \xB7 lesson \xB7 hint \xB7 validate \xB7 theory \xB7 progress",
23695
23980
  " Com d\xFAvida: tostudy menu (mostra onde voc\xEA est\xE1 e o que fazer)",
23696
23981
  ""
@@ -23702,6 +23987,7 @@ function createProgram() {
23702
23987
  program.addCommand(loginCommand);
23703
23988
  program.addCommand(logoutCommand);
23704
23989
  program.addCommand(coursesCommand);
23990
+ program.addCommand(suggestCommand);
23705
23991
  program.addCommand(enrollCommand);
23706
23992
  program.addCommand(selectCommand);
23707
23993
  program.addCommand(progressCommand);
@@ -23738,12 +24024,12 @@ function createProgram() {
23738
24024
 
23739
24025
  // src/auto-updater.ts
23740
24026
  init_config_dir();
23741
- import fs23 from "node:fs";
23742
- import path27 from "node:path";
24027
+ import fs24 from "node:fs";
24028
+ import path28 from "node:path";
23743
24029
  import { spawn as spawn2 } from "node:child_process";
23744
24030
  var PACKAGE_NAME2 = "@tostudy-ai/cli";
23745
24031
  function detectManager(entryRealPath) {
23746
- const p = entryRealPath.split(path27.sep).join("/");
24032
+ const p = entryRealPath.split(path28.sep).join("/");
23747
24033
  if (p.includes("/pnpm/")) return { cmd: "pnpm", args: ["add", "-g", `${PACKAGE_NAME2}@latest`] };
23748
24034
  if (p.includes("/.bun/")) return { cmd: "bun", args: ["add", "-g", `${PACKAGE_NAME2}@latest`] };
23749
24035
  if (p.includes(`/node_modules/${PACKAGE_NAME2}/`))
@@ -23751,10 +24037,10 @@ function detectManager(entryRealPath) {
23751
24037
  return null;
23752
24038
  }
23753
24039
  function installDir(entryRealPath) {
23754
- const normalized = entryRealPath.split(path27.sep).join("/");
24040
+ const normalized = entryRealPath.split(path28.sep).join("/");
23755
24041
  const marker = `/node_modules/${PACKAGE_NAME2}/`;
23756
24042
  const idx = normalized.indexOf(marker);
23757
- if (idx === -1) return path27.dirname(entryRealPath);
24043
+ if (idx === -1) return path28.dirname(entryRealPath);
23758
24044
  return entryRealPath.slice(0, idx + marker.length - 1);
23759
24045
  }
23760
24046
  function maybeAutoUpdate(currentVersion, opts = {}) {
@@ -23770,10 +24056,10 @@ function maybeAutoUpdate(currentVersion, opts = {}) {
23770
24056
  if (cache.attemptedVersion === cache.latest) return;
23771
24057
  const entryPath = opts.entryPath ?? argv[1];
23772
24058
  if (!entryPath) return;
23773
- const real = fs23.realpathSync(entryPath);
24059
+ const real = fs24.realpathSync(entryPath);
23774
24060
  const mgr = detectManager(real);
23775
24061
  if (!mgr) return;
23776
- fs23.accessSync(installDir(real), fs23.constants.W_OK);
24062
+ fs24.accessSync(installDir(real), fs24.constants.W_OK);
23777
24063
  writeCache({ ...cache, attemptedVersion: cache.latest }, configDir);
23778
24064
  process.stderr.write(
23779
24065
  `