@tostudy-ai/cli 0.7.0 → 0.7.2

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/cli.js CHANGED
@@ -1071,7 +1071,7 @@ function showUpdateNotification(current, latest) {
1071
1071
  [
1072
1072
  "",
1073
1073
  ` Atualiza\xE7\xE3o dispon\xEDvel: ${current} \u2192 ${latest}`,
1074
- " Atualize com: npm i -g @tostudy-ai/cli",
1074
+ " Atualize com: npm i -g @tostudy-ai/cli@latest",
1075
1075
  ""
1076
1076
  ].join("\n")
1077
1077
  );
@@ -1206,7 +1206,7 @@ var init_doctor = __esm({
1206
1206
  ` ${upToDate ? "\u2713" : "\u2717"} \xDAltima ${versionInfo.latest}${versionInfo.updateAvailable ? " (atualiza\xE7\xE3o dispon\xEDvel)" : ""}`
1207
1207
  );
1208
1208
  if (versionInfo.updateAvailable) {
1209
- console.log(" \u2192 npm i -g @tostudy-ai/cli");
1209
+ console.log(" \u2192 npm i -g @tostudy-ai/cli@latest");
1210
1210
  }
1211
1211
  } else {
1212
1212
  console.log(" \u25CB \xDAltima n\xE3o foi poss\xEDvel verificar");
@@ -2334,9 +2334,211 @@ var init_courses2 = __esm({
2334
2334
  }
2335
2335
  });
2336
2336
 
2337
+ // src/workspace/instruction-files.ts
2338
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
2339
+ import { join as join2 } from "node:path";
2340
+ function slugify(title) {
2341
+ return title.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
2342
+ }
2343
+ function buildInstructionContent(ctx, learner) {
2344
+ const sections = [];
2345
+ sections.push(`# ${ctx.courseTitle} \u2014 ToStudy Tutor`);
2346
+ sections.push(`## Seu Papel
2347
+
2348
+ Voc\xEA \xE9 um tutor AI paciente e encorajador, guiando o estudante por este curso usando comandos CLI. Seu tom \xE9 amig\xE1vel mas t\xE9cnico. Responda no idioma que o aluno usar.`);
2349
+ if (learner) {
2350
+ const levelLabels = {
2351
+ beginner: "Iniciante \u2014 explique conceitos com mais contexto e exemplos simples",
2352
+ intermediate: "Intermedi\xE1rio \u2014 foque em padr\xF5es e boas pr\xE1ticas",
2353
+ advanced: "Avan\xE7ado \u2014 desafie com cen\xE1rios complexos e trade-offs"
2354
+ };
2355
+ sections.push(`## Contexto do Aluno
2356
+
2357
+ - **N\xEDvel**: ${levelLabels[learner.learnerLevel]}
2358
+ - **Objetivo**: ${learner.goal}
2359
+ - **Empresa**: ${learner.company}
2360
+ - **Segmento**: ${learner.segment}
2361
+ - **Produtos/Servi\xE7os**: ${learner.productsOrServices}
2362
+ - **Regi\xE3o**: ${learner.region}
2363
+ - **Time**: ${learner.team}
2364
+ - **Adaptar ao contexto real**: ${learner.adaptToRealContext ? "Sim \u2014 use exemplos do projeto real do aluno sempre que poss\xEDvel" : "N\xE3o \u2014 use exemplos gen\xE9ricos"}`);
2365
+ }
2366
+ const progressLines = [
2367
+ `- ${ctx.progress}% completo | ${ctx.moduleCount} m\xF3dulos | ${ctx.lessonCount} li\xE7\xF5es`
2368
+ ];
2369
+ if (ctx.currentModuleTitle) {
2370
+ progressLines.push(`- **M\xF3dulo atual**: ${ctx.currentModuleTitle}`);
2371
+ }
2372
+ if (ctx.currentLessonTitle) {
2373
+ progressLines.push(`- **Li\xE7\xE3o atual**: ${ctx.currentLessonTitle}`);
2374
+ }
2375
+ sections.push(`## Progresso Atual
2376
+
2377
+ ${progressLines.join("\n")}`);
2378
+ sections.push(`## In\xEDcio de Sess\xE3o
2379
+
2380
+ Quando o aluno iniciar uma conversa ou invocar este comando:
2381
+
2382
+ 1. Cumprimente brevemente e mencione o curso
2383
+ 2. Rode \`tostudy progress\` para verificar onde o aluno parou
2384
+ 3. Resuma o estado: "Voc\xEA est\xE1 no M\xF3dulo X, Li\xE7\xE3o Y \u2014 [t\xEDtulo]"
2385
+ 4. Pergunte: "Quer continuar de onde parou ou revisar algo?"`);
2386
+ sections.push(`## Fluxo de Estudo
2387
+
2388
+ Siga esta sequ\xEAncia rigorosamente:
2389
+
2390
+ \`\`\`
2391
+ IN\xCDCIO:
2392
+ tostudy progress \u2192 Ver onde parou
2393
+ tostudy start \u2192 Carregar m\xF3dulo atual
2394
+
2395
+ LOOP DE ESTUDO (repetir para cada li\xE7\xE3o):
2396
+ tostudy lesson \u2192 Ler conte\xFAdo da li\xE7\xE3o
2397
+
2398
+ [Se EXERC\xCDCIO]:
2399
+ \u2192 Aluno implementa a solu\xE7\xE3o
2400
+ \u2192 tostudy hint \u2192 Dica progressiva (se travado)
2401
+ \u2192 tostudy validate <arquivo> \u2192 Validar solu\xE7\xE3o
2402
+ \u2192 [Se falhou]: sugerir hint \u2192 tentar de novo
2403
+ \u2192 [Se passou]: tostudy next \u2192 pr\xF3xima li\xE7\xE3o
2404
+
2405
+ [Se TEORIA/TEXTO]:
2406
+ \u2192 Explicar conceitos-chave
2407
+ \u2192 Fazer perguntas para verificar entendimento
2408
+ \u2192 tostudy next \u2192 pr\xF3xima li\xE7\xE3o
2409
+
2410
+ [Se QUIZ/CHECKPOINT]:
2411
+ \u2192 Aluno escreve respostas em arquivo (ex: checkpoint.md)
2412
+ \u2192 tostudy validate checkpoint.md
2413
+ \u2192 tostudy next \u2192 pr\xF3xima li\xE7\xE3o
2414
+
2415
+ FIM DO M\xD3DULO:
2416
+ \u2192 Parabenizar o aluno
2417
+ \u2192 tostudy start \u2192 Carregar pr\xF3ximo m\xF3dulo
2418
+ \`\`\``);
2419
+ sections.push(`## Guia por Tipo de Li\xE7\xE3o
2420
+
2421
+ **Teoria (text):** Explique os conceitos-chave. Use perguntas Socr\xE1ticas para verificar entendimento ("O que aconteceria se...?"). S\xF3 avance quando o aluno demonstrar compreens\xE3o.
2422
+
2423
+ **Exerc\xEDcio (exercise):** Guie a implementa\xE7\xE3o sem dar a resposta. Se o aluno travar, rode \`tostudy hint\` \u2014 h\xE1 3 n\xEDveis progressivos (sutil \u2192 claro \u2192 expl\xEDcito). Sempre valide com \`tostudy validate <arquivo>\` antes de avan\xE7ar.
2424
+
2425
+ **Quiz/Checkpoint (quiz):** Pe\xE7a ao aluno para escrever as respostas num arquivo e validar com \`tostudy validate respostas.md\`. Discuta as respostas ap\xF3s a valida\xE7\xE3o.
2426
+
2427
+ **V\xEDdeo (video):** Resuma os pontos-chave e aguarde o aluno assistir. Depois discuta o conte\xFAdo.`);
2428
+ const rules = [
2429
+ "**Nunca d\xEA a resposta direta** \u2014 guie com perguntas e dicas progressivas",
2430
+ "**Hints primeiro** \u2014 sempre rode `tostudy hint` antes de explicar a solu\xE7\xE3o",
2431
+ "**Valide antes de avan\xE7ar** \u2014 exerc\xEDcios exigem `tostudy validate` com nota de aprova\xE7\xE3o",
2432
+ "**Celebre progresso** \u2014 reconhe\xE7a quando o aluno completa li\xE7\xF5es e m\xF3dulos",
2433
+ "**Respeite a sequ\xEAncia** \u2014 n\xE3o pule m\xF3dulos nem li\xE7\xF5es",
2434
+ "**Adapte ao n\xEDvel** \u2014 ajuste profundidade e exemplos conforme o perfil do aluno",
2435
+ "**Sempre rode `tostudy lesson`** antes de discutir conte\xFAdo \u2014 n\xE3o invente material"
2436
+ ];
2437
+ if (learner?.adaptToRealContext) {
2438
+ rules.push("**Use contexto real** \u2014 adapte exemplos ao projeto/empresa do aluno");
2439
+ }
2440
+ sections.push(`## Regras de Ouro
2441
+
2442
+ ${rules.map((r, i) => `${i + 1}. ${r}`).join("\n")}`);
2443
+ sections.push(`## Quando Algo D\xE1 Errado
2444
+
2445
+ | Situa\xE7\xE3o | O que fazer |
2446
+ |----------|-------------|
2447
+ | \`tostudy validate\` falhou | Mostrar feedback, sugerir \`tostudy hint\`, tentar de novo |
2448
+ | \`tostudy start\` bloqueado | Guiar: \`tostudy init\` e/ou \`tostudy workspace setup\` |
2449
+ | "Nenhuma li\xE7\xE3o ativa" | Rodar \`tostudy start\` para carregar m\xF3dulo |
2450
+ | Comando retorna erro | Verificar \`tostudy doctor\` para diagn\xF3stico |
2451
+ | Aluno perdido / sem saber o que fazer | Rodar \`tostudy progress\` e resumir estado atual |`);
2452
+ if (ctx.workspaceReady !== false) {
2453
+ sections.push(`## Workspace
2454
+
2455
+ O workspace local organiza os arquivos do curso:
2456
+
2457
+ \`\`\`
2458
+ ~/study/{slug}/
2459
+ \u251C\u2500\u2500 exercises/{m\xF3dulo}/{li\xE7\xE3o}/ \u2190 Exerc\xEDcios extra\xEDdos
2460
+ \u251C\u2500\u2500 generated/ \u2190 Artefatos gerados
2461
+ \u2514\u2500\u2500 diagrams/ \u2190 Diagramas
2462
+ \`\`\`
2463
+
2464
+ Comandos \xFAteis:
2465
+ - \`tostudy export\` \u2014 Extrair exerc\xEDcio para o workspace
2466
+ - \`tostudy open\` \u2014 Abrir workspace no editor
2467
+ - \`tostudy workspace status\` \u2014 Verificar estado do workspace`);
2468
+ }
2469
+ sections.push(`## Comandos CLI
2470
+
2471
+ | Comando | Quando usar |
2472
+ |---------|-------------|
2473
+ | \`tostudy progress\` | No in\xEDcio da sess\xE3o e quando o aluno perguntar "onde estou?" |
2474
+ | \`tostudy start\` | Para carregar o m\xF3dulo atual ou o pr\xF3ximo |
2475
+ | \`tostudy lesson\` | Antes de discutir qualquer conte\xFAdo \u2014 sempre ler primeiro |
2476
+ | \`tostudy next\` | Ap\xF3s completar uma li\xE7\xE3o (teoria discutida ou exerc\xEDcio validado) |
2477
+ | \`tostudy hint\` | Quando o aluno travar \u2014 antes de explicar voc\xEA mesmo |
2478
+ | \`tostudy validate <arquivo>\` | Para validar exerc\xEDcios e checkpoints |
2479
+ | \`tostudy export\` | Para extrair exerc\xEDcio ao workspace local |`);
2480
+ sections.push(`## Refer\xEAncia T\xE9cnica (Modo Agente)
2481
+
2482
+ - Use \`--json\` em qualquer comando para sa\xEDda estruturada (ex: \`tostudy progress --json\`)
2483
+ - \`tostudy validate\` retorna exit code 0 (aprovado) ou 1 (reprovado)
2484
+ - \`tostudy validate --stdin\` aceita solu\xE7\xE3o via pipe
2485
+ - \`tostudy lesson --json\` retorna \`{ type, title, content, hints, acceptanceCriteria }\``);
2486
+ sections.push(`<!-- tostudy-course-id: ${ctx.courseId} -->`);
2487
+ return sections.join("\n\n") + "\n";
2488
+ }
2489
+ function generateInstructionFiles(ctx, learner) {
2490
+ const cwd = process.cwd();
2491
+ const slug = slugify(ctx.courseTitle);
2492
+ const content = buildInstructionContent(ctx, learner);
2493
+ const written = [];
2494
+ const claudeDir = join2(cwd, ".claude", "commands");
2495
+ if (!existsSync2(claudeDir)) {
2496
+ mkdirSync2(claudeDir, { recursive: true });
2497
+ }
2498
+ const claudeFile = `tostudy-${slug}.md`;
2499
+ writeFileSync2(join2(claudeDir, claudeFile), content);
2500
+ written.push(`.claude/commands/${claudeFile}`);
2501
+ const cursorDir = join2(cwd, ".cursor", "rules");
2502
+ if (existsSync2(join2(cwd, ".cursor")) || existsSync2(cursorDir)) {
2503
+ if (!existsSync2(cursorDir)) {
2504
+ mkdirSync2(cursorDir, { recursive: true });
2505
+ }
2506
+ const mdcContent = `---
2507
+ description: ${ctx.courseTitle} \u2014 ToStudy Course Guide
2508
+ globs: ["**/*"]
2509
+ alwaysApply: true
2510
+ ---
2511
+
2512
+ ${content}`;
2513
+ const cursorFile = `tostudy-${slug}.mdc`;
2514
+ writeFileSync2(join2(cursorDir, cursorFile), mdcContent);
2515
+ written.push(`.cursor/rules/${cursorFile}`);
2516
+ }
2517
+ const courseDir = join2(cwd, ".tostudy", "courses", slug);
2518
+ if (!existsSync2(courseDir)) {
2519
+ mkdirSync2(courseDir, { recursive: true });
2520
+ }
2521
+ writeFileSync2(join2(courseDir, "AGENTS.md"), content);
2522
+ written.push(`.tostudy/courses/${slug}/AGENTS.md`);
2523
+ logger3.info("Generated instruction files", {
2524
+ slug,
2525
+ files: written,
2526
+ hasLearnerProfile: !!learner
2527
+ });
2528
+ return slug;
2529
+ }
2530
+ var logger3;
2531
+ var init_instruction_files = __esm({
2532
+ "src/workspace/instruction-files.ts"() {
2533
+ "use strict";
2534
+ init_src();
2535
+ logger3 = createLogger("cli:instruction-files");
2536
+ }
2537
+ });
2538
+
2337
2539
  // src/commands/select.ts
2338
2540
  import { Command as Command6 } from "commander";
2339
- var logger3, selectCommand;
2541
+ var logger4, selectCommand;
2340
2542
  var init_select = __esm({
2341
2543
  "src/commands/select.ts"() {
2342
2544
  "use strict";
@@ -2345,12 +2547,13 @@ var init_select = __esm({
2345
2547
  init_http2();
2346
2548
  init_session();
2347
2549
  init_formatter();
2348
- logger3 = createLogger("cli:select");
2550
+ init_instruction_files();
2551
+ logger4 = createLogger("cli:select");
2349
2552
  selectCommand = new Command6("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").action(async (course, opts) => {
2350
2553
  try {
2351
2554
  const session = await requireSession();
2352
2555
  const data = createHttpProvider(session.apiUrl, session.token);
2353
- const deps = { data, logger: logger3 };
2556
+ const deps = { data, logger: logger4 };
2354
2557
  const courses3 = await listCourses({ userId: session.userId }, deps);
2355
2558
  let courseId = course;
2356
2559
  let enrollmentId = "";
@@ -2377,17 +2580,35 @@ var init_select = __esm({
2377
2580
  courseTags: matched?.tags,
2378
2581
  courseLevel: matched?.level
2379
2582
  });
2583
+ let courseSlug2 = "";
2584
+ try {
2585
+ courseSlug2 = generateInstructionFiles({
2586
+ courseTitle: detail.courseTitle,
2587
+ courseId: detail.courseId,
2588
+ progress: detail.progress,
2589
+ moduleCount: detail.moduleCount,
2590
+ lessonCount: detail.lessonCount,
2591
+ courseDescription: detail.courseDescription
2592
+ });
2593
+ } catch (err) {
2594
+ logger4.warn("Failed to generate instruction files", {
2595
+ error: err instanceof Error ? err.message : String(err)
2596
+ });
2597
+ }
2380
2598
  if (opts.json) {
2381
- output({ ...detail, enrollmentId }, { json: true });
2599
+ output({ ...detail, enrollmentId, courseSlug: courseSlug2 }, { json: true });
2382
2600
  } else {
2601
+ const slashCmd = courseSlug2 ? `/tostudy-${courseSlug2}` : "/tostudy";
2383
2602
  output(
2384
2603
  [
2385
2604
  `\u2713 Curso ativado: ${detail.courseTitle}`,
2386
2605
  ` Progresso: ${detail.progress}% | ${detail.moduleCount} m\xF3dulos | ${detail.lessonCount} li\xE7\xF5es`,
2387
2606
  "",
2388
- "\u2192 tostudy progress para ver seu progresso detalhado",
2389
- "\u2192 tostudy start para come\xE7ar o m\xF3dulo atual",
2390
- "\u2192 tostudy next para avan\xE7ar para a pr\xF3xima li\xE7\xE3o"
2607
+ " Arquivos de contexto criados para seu assistente AI.",
2608
+ "",
2609
+ "\u2192 Abra sua plataforma (claude, codex, cursor...)",
2610
+ `\u2192 No Claude Code, digite: ${slashCmd}`,
2611
+ "\u2192 Em outras plataformas: tostudy init"
2391
2612
  ].join("\n"),
2392
2613
  { json: false }
2393
2614
  );
@@ -2402,7 +2623,7 @@ var init_select = __esm({
2402
2623
 
2403
2624
  // src/commands/progress.ts
2404
2625
  import { Command as Command7 } from "commander";
2405
- var logger4, progressCommand;
2626
+ var logger5, progressCommand;
2406
2627
  var init_progress = __esm({
2407
2628
  "src/commands/progress.ts"() {
2408
2629
  "use strict";
@@ -2411,7 +2632,7 @@ var init_progress = __esm({
2411
2632
  init_http2();
2412
2633
  init_session();
2413
2634
  init_formatter();
2414
- logger4 = createLogger("cli:progress");
2635
+ logger5 = createLogger("cli:progress");
2415
2636
  progressCommand = new Command7("progress").description("Show your progress in the active course").option("--json", "Output structured JSON").action(async (opts) => {
2416
2637
  try {
2417
2638
  const session = await requireSession();
@@ -2419,7 +2640,7 @@ var init_progress = __esm({
2419
2640
  const driftWarning = await checkCourseDrift();
2420
2641
  if (driftWarning) process.stderr.write(driftWarning + "\n");
2421
2642
  const data = createHttpProvider(session.apiUrl, session.token);
2422
- const deps = { data, logger: logger4 };
2643
+ const deps = { data, logger: logger5 };
2423
2644
  const progress3 = await getProgress({ enrollmentId: activeCourse.enrollmentId }, deps);
2424
2645
  if (opts.json) {
2425
2646
  output(progress3, { json: true });
@@ -3678,7 +3899,7 @@ var init_sql = __esm({
3678
3899
  return new SQL([new StringChunk(str)]);
3679
3900
  }
3680
3901
  sql2.raw = raw;
3681
- function join2(chunks, separator) {
3902
+ function join3(chunks, separator) {
3682
3903
  const result = [];
3683
3904
  for (const [i, chunk] of chunks.entries()) {
3684
3905
  if (i > 0 && separator !== void 0) {
@@ -3688,7 +3909,7 @@ var init_sql = __esm({
3688
3909
  }
3689
3910
  return new SQL(result);
3690
3911
  }
3691
- sql2.join = join2;
3912
+ sql2.join = join3;
3692
3913
  function identifier(value) {
3693
3914
  return new Name(value);
3694
3915
  }
@@ -10220,7 +10441,7 @@ var init_select3 = __esm({
10220
10441
  const baseTableName = this.tableName;
10221
10442
  const tableName = getTableLikeName(table);
10222
10443
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
10223
- if (typeof tableName === "string" && this.config.joins?.some((join2) => join2.alias === tableName)) {
10444
+ if (typeof tableName === "string" && this.config.joins?.some((join3) => join3.alias === tableName)) {
10224
10445
  throw new Error(`Alias "${tableName}" is already used in this query`);
10225
10446
  }
10226
10447
  if (!this.isPartialSelect) {
@@ -11747,7 +11968,7 @@ var init_update = __esm({
11747
11968
  createJoin(joinType) {
11748
11969
  return (table, on) => {
11749
11970
  const tableName = getTableLikeName(table);
11750
- if (typeof tableName === "string" && this.config.joins.some((join2) => join2.alias === tableName)) {
11971
+ if (typeof tableName === "string" && this.config.joins.some((join3) => join3.alias === tableName)) {
11751
11972
  throw new Error(`Alias "${tableName}" is already used in this query`);
11752
11973
  }
11753
11974
  if (typeof on === "function") {
@@ -11843,10 +12064,10 @@ var init_update = __esm({
11843
12064
  const fromFields = this.getTableLikeFields(this.config.from);
11844
12065
  fields[tableName] = fromFields;
11845
12066
  }
11846
- for (const join2 of this.config.joins) {
11847
- const tableName2 = getTableLikeName(join2.table);
11848
- if (typeof tableName2 === "string" && !is(join2.table, SQL)) {
11849
- const fromFields = this.getTableLikeFields(join2.table);
12067
+ for (const join3 of this.config.joins) {
12068
+ const tableName2 = getTableLikeName(join3.table);
12069
+ if (typeof tableName2 === "string" && !is(join3.table, SQL)) {
12070
+ const fromFields = this.getTableLikeFields(join3.table);
11850
12071
  fields[tableName2] = fromFields;
11851
12072
  }
11852
12073
  }
@@ -12789,12 +13010,12 @@ var init_session3 = __esm({
12789
13010
  init_tracing();
12790
13011
  init_utils();
12791
13012
  PostgresJsPreparedQuery = class extends PgPreparedQuery {
12792
- constructor(client, queryString, params, logger16, cache, queryMetadata, cacheConfig, fields, _isResponseInArrayMode, customResultMapper) {
13013
+ constructor(client, queryString, params, logger17, cache, queryMetadata, cacheConfig, fields, _isResponseInArrayMode, customResultMapper) {
12793
13014
  super({ sql: queryString, params }, cache, queryMetadata, cacheConfig);
12794
13015
  this.client = client;
12795
13016
  this.queryString = queryString;
12796
13017
  this.params = params;
12797
- this.logger = logger16;
13018
+ this.logger = logger17;
12798
13019
  this.fields = fields;
12799
13020
  this._isResponseInArrayMode = _isResponseInArrayMode;
12800
13021
  this.customResultMapper = customResultMapper;
@@ -12935,11 +13156,11 @@ function construct(client, config2 = {}) {
12935
13156
  client.options.serializers["114"] = transparentParser;
12936
13157
  client.options.serializers["3802"] = transparentParser;
12937
13158
  const dialect = new PgDialect({ casing: config2.casing });
12938
- let logger16;
13159
+ let logger17;
12939
13160
  if (config2.logger === true) {
12940
- logger16 = new DefaultLogger();
13161
+ logger17 = new DefaultLogger();
12941
13162
  } else if (config2.logger !== false) {
12942
- logger16 = config2.logger;
13163
+ logger17 = config2.logger;
12943
13164
  }
12944
13165
  let schema;
12945
13166
  if (config2.schema) {
@@ -12953,7 +13174,7 @@ function construct(client, config2 = {}) {
12953
13174
  tableNamesMap: tablesConfig.tableNamesMap
12954
13175
  };
12955
13176
  }
12956
- const session = new PostgresJsSession(client, dialect, schema, { logger: logger16, cache: config2.cache });
13177
+ const session = new PostgresJsSession(client, dialect, schema, { logger: logger17, cache: config2.cache });
12957
13178
  const db2 = new PostgresJsDatabase(dialect, session, schema);
12958
13179
  db2.$client = client;
12959
13180
  db2.$cache = config2.cache;
@@ -13155,7 +13376,7 @@ __export(util_exports, {
13155
13376
  required: () => required,
13156
13377
  safeExtend: () => safeExtend,
13157
13378
  shallowClone: () => shallowClone,
13158
- slugify: () => slugify,
13379
+ slugify: () => slugify3,
13159
13380
  stringifyPrimitive: () => stringifyPrimitive,
13160
13381
  uint8ArrayToBase64: () => uint8ArrayToBase64,
13161
13382
  uint8ArrayToBase64url: () => uint8ArrayToBase64url,
@@ -13295,7 +13516,7 @@ function randomString(length = 10) {
13295
13516
  function esc(str) {
13296
13517
  return JSON.stringify(str);
13297
13518
  }
13298
- function slugify(input2) {
13519
+ function slugify3(input2) {
13299
13520
  return input2.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
13300
13521
  }
13301
13522
  function isObject(data) {
@@ -23429,7 +23650,7 @@ function _toUpperCase() {
23429
23650
  }
23430
23651
  // @__NO_SIDE_EFFECTS__
23431
23652
  function _slugify() {
23432
- return /* @__PURE__ */ _overwrite((input2) => slugify(input2));
23653
+ return /* @__PURE__ */ _overwrite((input2) => slugify3(input2));
23433
23654
  }
23434
23655
  // @__NO_SIDE_EFFECTS__
23435
23656
  function _array(Class2, element, params) {
@@ -27494,6 +27715,10 @@ var init_users = __esm({
27494
27715
  // Public portfolio active
27495
27716
  followerDiscountPct: smallint("follower_discount_pct").default(0).notNull(),
27496
27717
  // Follower discount: 0, 5, 10, 15, 20
27718
+ // Stripe Integration
27719
+ stripeCustomerId: varchar("stripe_customer_id", { length: 255 }),
27720
+ // Stripe Customer ID (cus_xxx) for payment method reuse
27721
+ metadata: jsonb("metadata").$type().default({}),
27497
27722
  createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
27498
27723
  updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull()
27499
27724
  },
@@ -33953,77 +34178,6 @@ var init_marketing = __esm({
33953
34178
  }
33954
34179
  });
33955
34180
 
33956
- // ../../packages/database/src/schema/user-credits.ts
33957
- var transactionTypeEnum, userCredits2, creditTransactions2;
33958
- var init_user_credits = __esm({
33959
- "../../packages/database/src/schema/user-credits.ts"() {
33960
- "use strict";
33961
- init_pg_core();
33962
- init_users();
33963
- transactionTypeEnum = pgEnum("transaction_type", [
33964
- "initial_grant",
33965
- // Credito inicial de $5
33966
- "purchase",
33967
- // Compra de creditos
33968
- "consumption",
33969
- // Consumo por uso de IA
33970
- "refund",
33971
- // Reembolso
33972
- "adjustment"
33973
- // Ajuste manual admin
33974
- ]);
33975
- userCredits2 = pgTable(
33976
- "user_credits",
33977
- {
33978
- id: uuid("id").primaryKey().defaultRandom(),
33979
- userId: uuid("user_id").references(() => users.id, { onDelete: "cascade" }).notNull().unique(),
33980
- /** Current balance in USD */
33981
- balance: decimal("balance", { precision: 10, scale: 4 }).notNull().default("0"),
33982
- /** Total consumed in USD (absolute value, always positive) */
33983
- totalConsumed: decimal("total_consumed", { precision: 10, scale: 4 }).notNull().default("0"),
33984
- /** Total purchased in USD */
33985
- totalPurchased: decimal("total_purchased", { precision: 10, scale: 4 }).notNull().default("0"),
33986
- createdAt: timestamp("created_at").defaultNow().notNull(),
33987
- updatedAt: timestamp("updated_at").defaultNow().notNull()
33988
- },
33989
- (table) => ({
33990
- userIdIdx: index("user_credits_user_id_idx").on(table.userId)
33991
- })
33992
- );
33993
- creditTransactions2 = pgTable(
33994
- "credit_transactions",
33995
- {
33996
- id: uuid("id").primaryKey().defaultRandom(),
33997
- userId: uuid("user_id").references(() => users.id, { onDelete: "restrict" }).notNull(),
33998
- type: transactionTypeEnum("type").notNull(),
33999
- /** Amount in USD (negative for consumption, positive for purchase/grant) */
34000
- amount: decimal("amount", { precision: 10, scale: 4 }).notNull(),
34001
- /** Balance after this transaction in USD */
34002
- balanceAfter: decimal("balance_after", { precision: 10, scale: 4 }).notNull(),
34003
- description: text("description"),
34004
- metadata: text("metadata"),
34005
- // JSON com detalhes (tokens, modelo, etc)
34006
- // Granular usage tracking columns
34007
- operation: varchar("operation", { length: 50 }),
34008
- // 'brainstorm_message', 'generation_outline', etc.
34009
- model: varchar("model", { length: 100 }),
34010
- // 'claude-sonnet-4-5-20250929'
34011
- inputTokens: integer("input_tokens"),
34012
- outputTokens: integer("output_tokens"),
34013
- latencyMs: integer("latency_ms"),
34014
- // DB FK to course_proposals preserved in migration; Drizzle ref removed for schema archival
34015
- proposalId: uuid("proposal_id"),
34016
- sessionId: uuid("session_id"),
34017
- createdAt: timestamp("created_at").defaultNow().notNull()
34018
- },
34019
- (table) => ({
34020
- userIdIdx: index("credit_transactions_user_id_idx").on(table.userId),
34021
- createdAtIdx: index("credit_transactions_created_at_idx").on(table.createdAt)
34022
- })
34023
- );
34024
- }
34025
- });
34026
-
34027
34181
  // ../../packages/database/src/schema/usage-quotas.ts
34028
34182
  var quotaChangeHistory, userUsageQuotas2, usageTierLimits2;
34029
34183
  var init_usage_quotas = __esm({
@@ -34469,74 +34623,72 @@ var init_course_variants = __esm({
34469
34623
  }
34470
34624
  });
34471
34625
 
34472
- // ../../packages/database/src/schema/_archived/matrix-translations.ts
34473
- var translationStatusEnum, translationEntityTypeEnum, matrixTranslations;
34474
- var init_matrix_translations = __esm({
34475
- "../../packages/database/src/schema/_archived/matrix-translations.ts"() {
34626
+ // ../../packages/database/src/schema/_archived/user-credits.ts
34627
+ var transactionTypeEnum, userCredits2, creditTransactions2;
34628
+ var init_user_credits = __esm({
34629
+ "../../packages/database/src/schema/_archived/user-credits.ts"() {
34476
34630
  "use strict";
34477
34631
  init_pg_core();
34478
34632
  init_users();
34479
- init_course_matrices();
34480
- translationStatusEnum = pgEnum("translation_status", [
34481
- "pending",
34482
- // Translation requested
34483
- "generating",
34484
- // AI translation in progress
34485
- "draft",
34486
- // AI generated, awaiting review
34487
- "approved",
34488
- // Creator approved
34489
- "rejected"
34490
- // Creator rejected, needs regeneration
34491
- ]);
34492
- translationEntityTypeEnum = pgEnum("translation_entity_type", [
34493
- "matrix",
34494
- // CourseMatrix (title, description, coreDocument)
34495
- "module",
34496
- // MatrixModule (title, description, lessonsContent)
34497
- "variant"
34498
- // CourseVariant (name, description)
34633
+ transactionTypeEnum = pgEnum("transaction_type", [
34634
+ "initial_grant",
34635
+ // Credito inicial de $5
34636
+ "purchase",
34637
+ // Compra de creditos
34638
+ "consumption",
34639
+ // Consumo por uso de IA
34640
+ "refund",
34641
+ // Reembolso
34642
+ "adjustment"
34643
+ // Ajuste manual admin
34499
34644
  ]);
34500
- matrixTranslations = pgTable(
34501
- "matrix_translations",
34645
+ userCredits2 = pgTable(
34646
+ "user_credits",
34502
34647
  {
34503
34648
  id: uuid("id").primaryKey().defaultRandom(),
34504
- matrixId: uuid("matrix_id").notNull().references(() => courseMatrices.id, { onDelete: "cascade" }),
34505
- creatorId: uuid("creator_id").notNull().references(() => users.id),
34506
- // Target entity
34507
- entityType: translationEntityTypeEnum("entity_type").notNull(),
34508
- entityId: uuid("entity_id").notNull(),
34509
- // ID of matrix, module, or variant
34510
- // Language
34511
- sourceLanguage: text("source_language").notNull().default("en"),
34512
- targetLanguage: text("target_language").notNull(),
34513
- // Field being translated
34514
- field: text("field").notNull(),
34515
- // 'title', 'description', 'content', 'coreDocument', etc.
34516
- // Translation content
34517
- originalContent: text("original_content").notNull(),
34518
- translatedContent: text("translated_content"),
34519
- // Status
34520
- status: translationStatusEnum("status").notNull().default("pending"),
34521
- // Review
34522
- reviewedAt: timestamp("reviewed_at"),
34523
- reviewNotes: text("review_notes"),
34524
- // Timestamps
34649
+ userId: uuid("user_id").references(() => users.id, { onDelete: "cascade" }).notNull().unique(),
34650
+ /** Current balance in USD */
34651
+ balance: decimal("balance", { precision: 10, scale: 4 }).notNull().default("0"),
34652
+ /** Total consumed in USD (absolute value, always positive) */
34653
+ totalConsumed: decimal("total_consumed", { precision: 10, scale: 4 }).notNull().default("0"),
34654
+ /** Total purchased in USD */
34655
+ totalPurchased: decimal("total_purchased", { precision: 10, scale: 4 }).notNull().default("0"),
34525
34656
  createdAt: timestamp("created_at").defaultNow().notNull(),
34526
34657
  updatedAt: timestamp("updated_at").defaultNow().notNull()
34527
34658
  },
34528
34659
  (table) => ({
34529
- matrixIdIdx: index("matrix_translations_matrix_id_idx").on(table.matrixId),
34530
- entityIdx: index("matrix_translations_entity_idx").on(table.entityType, table.entityId),
34531
- languageIdx: index("matrix_translations_language_idx").on(table.targetLanguage),
34532
- statusIdx: index("matrix_translations_status_idx").on(table.status),
34533
- // Unique constraint: one translation per entity/field/language combination
34534
- entityFieldLangUniq: uniqueIndex("matrix_translations_entity_field_lang_uniq").on(
34535
- table.entityType,
34536
- table.entityId,
34537
- table.field,
34538
- table.targetLanguage
34539
- )
34660
+ userIdIdx: index("user_credits_user_id_idx").on(table.userId)
34661
+ })
34662
+ );
34663
+ creditTransactions2 = pgTable(
34664
+ "credit_transactions",
34665
+ {
34666
+ id: uuid("id").primaryKey().defaultRandom(),
34667
+ userId: uuid("user_id").references(() => users.id, { onDelete: "restrict" }).notNull(),
34668
+ type: transactionTypeEnum("type").notNull(),
34669
+ /** Amount in USD (negative for consumption, positive for purchase/grant) */
34670
+ amount: decimal("amount", { precision: 10, scale: 4 }).notNull(),
34671
+ /** Balance after this transaction in USD */
34672
+ balanceAfter: decimal("balance_after", { precision: 10, scale: 4 }).notNull(),
34673
+ description: text("description"),
34674
+ metadata: text("metadata"),
34675
+ // JSON com detalhes (tokens, modelo, etc)
34676
+ // Granular usage tracking columns
34677
+ operation: varchar("operation", { length: 50 }),
34678
+ // 'brainstorm_message', 'generation_outline', etc.
34679
+ model: varchar("model", { length: 100 }),
34680
+ // 'claude-sonnet-4-5-20250929'
34681
+ inputTokens: integer("input_tokens"),
34682
+ outputTokens: integer("output_tokens"),
34683
+ latencyMs: integer("latency_ms"),
34684
+ // DB FK to course_proposals preserved in migration; Drizzle ref removed for schema archival
34685
+ proposalId: uuid("proposal_id"),
34686
+ sessionId: uuid("session_id"),
34687
+ createdAt: timestamp("created_at").defaultNow().notNull()
34688
+ },
34689
+ (table) => ({
34690
+ userIdIdx: index("credit_transactions_user_id_idx").on(table.userId),
34691
+ createdAtIdx: index("credit_transactions_created_at_idx").on(table.createdAt)
34540
34692
  })
34541
34693
  );
34542
34694
  }
@@ -34550,7 +34702,7 @@ var init_archived = __esm({
34550
34702
  init_course_matrices();
34551
34703
  init_matrix_modules();
34552
34704
  init_course_variants();
34553
- init_matrix_translations();
34705
+ init_user_credits();
34554
34706
  }
34555
34707
  });
34556
34708
 
@@ -35325,76 +35477,89 @@ var init_llm_analytics = __esm({
35325
35477
  init_users();
35326
35478
  init_courses3();
35327
35479
  init_llm_pricing();
35328
- llmInteractions = pgTable("llm_interactions", {
35329
- id: uuid("id").primaryKey().defaultRandom(),
35330
- createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
35331
- // Operation type
35332
- operationType: varchar("operation_type", { length: 50 }).notNull(),
35333
- // Provider (references llm_provider enum from llm-pricing.ts)
35334
- provider: llmProviderEnum("provider").notNull().default("anthropic"),
35335
- // Tracing
35336
- correlationId: varchar("correlation_id", { length: 64 }),
35337
- // Relationships
35338
- userId: uuid("user_id").references(() => users.id, { onDelete: "set null" }),
35339
- creatorId: uuid("creator_id").references(() => users.id, { onDelete: "set null" }),
35340
- courseId: uuid("course_id").references(() => courses.id, { onDelete: "set null" }),
35341
- sessionId: uuid("session_id"),
35342
- variantId: uuid("variant_id"),
35343
- // Denormalized from metadata for faster queries
35344
- // Request
35345
- model: varchar("model", { length: 50 }).notNull(),
35346
- promptText: text("prompt_text"),
35347
- promptTokens: integer("prompt_tokens").notNull(),
35348
- // Response
35349
- responseText: text("response_text"),
35350
- responseTokens: integer("response_tokens").notNull(),
35351
- // Cost & Revenue
35352
- costUsd: decimal("cost_usd", { precision: 10, scale: 6 }).notNull(),
35353
- revenueUsd: decimal("revenue_usd", { precision: 10, scale: 6 }).notNull().default("0"),
35354
- // Cache metrics (prompt caching)
35355
- cacheCreationTokens: integer("cache_creation_tokens").default(0),
35356
- cacheReadTokens: integer("cache_read_tokens").default(0),
35357
- cacheHit: integer("cache_hit").default(0),
35358
- // 0 = false, 1 = true (SQLite-compatible)
35359
- // Performance
35360
- latencyMs: integer("latency_ms").notNull(),
35361
- status: varchar("status", { length: 20 }).notNull(),
35362
- errorMessage: text("error_message"),
35363
- // Streaming metrics (null for non-streaming calls)
35364
- timeToFirstTokenMs: integer("time_to_first_token_ms"),
35365
- streamDurationMs: integer("stream_duration_ms"),
35366
- // Model version and metadata
35367
- modelVersion: varchar("model_version", { length: 100 }),
35368
- metadata: jsonb("metadata").$type()
35369
- }, (table) => ({
35370
- creatorIdx: index("idx_llm_interactions_creator").on(table.creatorId, table.createdAt),
35371
- operationIdx: index("idx_llm_interactions_operation").on(table.operationType, table.createdAt),
35372
- correlationIdx: index("idx_llm_interactions_correlation").on(table.correlationId),
35373
- providerIdx: index("idx_llm_interactions_provider").on(table.provider),
35374
- variantIdx: index("idx_llm_interactions_variant").on(table.variantId),
35375
- creatorVariantDateIdx: index("idx_llm_interactions_creator_variant_date").on(table.creatorId, table.variantId, table.createdAt)
35376
- }));
35377
- llmUsageDaily = pgTable("llm_usage_daily", {
35378
- date: timestamp("date", { mode: "date" }).notNull(),
35379
- operationType: varchar("operation_type", { length: 50 }).notNull(),
35380
- creatorId: uuid("creator_id").references(() => users.id, { onDelete: "restrict" }).notNull(),
35381
- // Aggregated metrics
35382
- totalRequests: integer("total_requests").notNull().default(0),
35383
- totalPromptTokens: integer("total_prompt_tokens").notNull().default(0),
35384
- totalResponseTokens: integer("total_response_tokens").notNull().default(0),
35385
- totalCostUsd: decimal("total_cost_usd", { precision: 12, scale: 4 }).notNull().default("0"),
35386
- totalRevenueUsd: decimal("total_revenue_usd", { precision: 12, scale: 4 }).notNull().default("0"),
35387
- avgLatencyMs: integer("avg_latency_ms"),
35388
- errorCount: integer("error_count").notNull().default(0),
35389
- // Cache aggregated metrics
35390
- totalCacheCreationTokens: integer("total_cache_creation_tokens").notNull().default(0),
35391
- totalCacheReadTokens: integer("total_cache_read_tokens").notNull().default(0),
35392
- totalCacheHits: integer("total_cache_hits").notNull().default(0)
35393
- }, (table) => ({
35394
- pk: primaryKey({ columns: [table.date, table.operationType, table.creatorId] }),
35395
- dateIdx: index("idx_llm_usage_daily_date").on(table.date),
35396
- creatorIdx: index("idx_llm_usage_daily_creator").on(table.creatorId, table.date)
35397
- }));
35480
+ llmInteractions = pgTable(
35481
+ "llm_interactions",
35482
+ {
35483
+ id: uuid("id").primaryKey().defaultRandom(),
35484
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
35485
+ // Operation type
35486
+ operationType: varchar("operation_type", { length: 50 }).notNull(),
35487
+ // Provider (references llm_provider enum from llm-pricing.ts)
35488
+ provider: llmProviderEnum("provider").notNull().default("anthropic"),
35489
+ // Tracing
35490
+ correlationId: varchar("correlation_id", { length: 64 }),
35491
+ // Relationships
35492
+ userId: uuid("user_id").references(() => users.id, { onDelete: "set null" }),
35493
+ creatorId: uuid("creator_id").references(() => users.id, { onDelete: "set null" }),
35494
+ courseId: uuid("course_id").references(() => courses.id, { onDelete: "set null" }),
35495
+ sessionId: uuid("session_id"),
35496
+ variantId: uuid("variant_id"),
35497
+ // Denormalized from metadata for faster queries
35498
+ // Request
35499
+ model: varchar("model", { length: 50 }).notNull(),
35500
+ promptText: text("prompt_text"),
35501
+ promptTokens: integer("prompt_tokens").notNull(),
35502
+ // Response
35503
+ responseText: text("response_text"),
35504
+ responseTokens: integer("response_tokens").notNull(),
35505
+ // Cost & Revenue
35506
+ costUsd: decimal("cost_usd", { precision: 10, scale: 6 }).notNull(),
35507
+ revenueUsd: decimal("revenue_usd", { precision: 10, scale: 6 }).notNull().default("0"),
35508
+ // Cache metrics (prompt caching)
35509
+ cacheCreationTokens: integer("cache_creation_tokens").default(0),
35510
+ cacheReadTokens: integer("cache_read_tokens").default(0),
35511
+ cacheHit: integer("cache_hit").default(0),
35512
+ // 0 = false, 1 = true (SQLite-compatible)
35513
+ // Performance
35514
+ latencyMs: integer("latency_ms").notNull(),
35515
+ status: varchar("status", { length: 20 }).notNull(),
35516
+ errorMessage: text("error_message"),
35517
+ // Streaming metrics (null for non-streaming calls)
35518
+ timeToFirstTokenMs: integer("time_to_first_token_ms"),
35519
+ streamDurationMs: integer("stream_duration_ms"),
35520
+ // Model version and metadata
35521
+ modelVersion: varchar("model_version", { length: 100 }),
35522
+ metadata: jsonb("metadata").$type()
35523
+ },
35524
+ (table) => ({
35525
+ creatorIdx: index("idx_llm_interactions_creator").on(table.creatorId, table.createdAt),
35526
+ operationIdx: index("idx_llm_interactions_operation").on(table.operationType, table.createdAt),
35527
+ correlationIdx: index("idx_llm_interactions_correlation").on(table.correlationId),
35528
+ providerIdx: index("idx_llm_interactions_provider").on(table.provider),
35529
+ variantIdx: index("idx_llm_interactions_variant").on(table.variantId),
35530
+ creatorVariantDateIdx: index("idx_llm_interactions_creator_variant_date").on(
35531
+ table.creatorId,
35532
+ table.variantId,
35533
+ table.createdAt
35534
+ )
35535
+ })
35536
+ );
35537
+ llmUsageDaily = pgTable(
35538
+ "llm_usage_daily",
35539
+ {
35540
+ date: timestamp("date", { mode: "date" }).notNull(),
35541
+ operationType: varchar("operation_type", { length: 50 }).notNull(),
35542
+ creatorId: uuid("creator_id").notNull(),
35543
+ // No FK — sentinel UUID '00000000-...' used for system-level aggregation
35544
+ // Aggregated metrics
35545
+ totalRequests: integer("total_requests").notNull().default(0),
35546
+ totalPromptTokens: integer("total_prompt_tokens").notNull().default(0),
35547
+ totalResponseTokens: integer("total_response_tokens").notNull().default(0),
35548
+ totalCostUsd: decimal("total_cost_usd", { precision: 12, scale: 4 }).notNull().default("0"),
35549
+ totalRevenueUsd: decimal("total_revenue_usd", { precision: 12, scale: 4 }).notNull().default("0"),
35550
+ avgLatencyMs: integer("avg_latency_ms"),
35551
+ errorCount: integer("error_count").notNull().default(0),
35552
+ // Cache aggregated metrics
35553
+ totalCacheCreationTokens: integer("total_cache_creation_tokens").notNull().default(0),
35554
+ totalCacheReadTokens: integer("total_cache_read_tokens").notNull().default(0),
35555
+ totalCacheHits: integer("total_cache_hits").notNull().default(0)
35556
+ },
35557
+ (table) => ({
35558
+ pk: primaryKey({ columns: [table.date, table.operationType, table.creatorId] }),
35559
+ dateIdx: index("idx_llm_usage_daily_date").on(table.date),
35560
+ creatorIdx: index("idx_llm_usage_daily_creator").on(table.creatorId, table.date)
35561
+ })
35562
+ );
35398
35563
  }
35399
35564
  });
35400
35565
 
@@ -36958,7 +37123,12 @@ var init_video_intros = __esm({
36958
37123
  "minimal-dark",
36959
37124
  "gradient-bold",
36960
37125
  "corporate-clean",
36961
- "warm-organic"
37126
+ "warm-organic",
37127
+ "neon-tech",
37128
+ "playful-bright",
37129
+ "culinary-warm",
37130
+ "academic-serif",
37131
+ "music-rhythm"
36962
37132
  ]);
36963
37133
  renderJobStatusEnum = pgEnum("render_job_status", [
36964
37134
  "queued",
@@ -36984,6 +37154,8 @@ var init_video_intros = __esm({
36984
37154
  durationSeconds: integer("duration_seconds"),
36985
37155
  metadata: jsonb("metadata"),
36986
37156
  sceneConfig: jsonb("scene_config").$type(),
37157
+ generationHistory: jsonb("generation_history").default([]).$type(),
37158
+ themeOverrides: jsonb("theme_overrides").$type(),
36987
37159
  createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
36988
37160
  updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull()
36989
37161
  },
@@ -38217,7 +38389,6 @@ __export(schema_exports, {
38217
38389
  creditSubscriptionStatusEnum: () => creditSubscriptionStatusEnum,
38218
38390
  creditSubscriptions: () => creditSubscriptions,
38219
38391
  creditTransactions: () => creditTransactions2,
38220
- creditTransactionsRelations: () => creditTransactionsRelations2,
38221
38392
  creditWalletTransactionTypeEnum: () => creditWalletTransactionTypeEnum,
38222
38393
  creditWalletTransactions: () => creditWalletTransactions,
38223
38394
  creditWallets: () => creditWallets,
@@ -38298,7 +38469,6 @@ __export(schema_exports, {
38298
38469
  marketingContentTypeEnum: () => marketingContentTypeEnum,
38299
38470
  matrixModules: () => matrixModules,
38300
38471
  matrixStatusEnum: () => matrixStatusEnum,
38301
- matrixTranslations: () => matrixTranslations,
38302
38472
  mcpSessions: () => mcpSessions2,
38303
38473
  mcpSessionsRelations: () => mcpSessionsRelations2,
38304
38474
  mediaAssetDomainEnum: () => mediaAssetDomainEnum,
@@ -38509,8 +38679,6 @@ __export(schema_exports, {
38509
38679
  transactionsRelations: () => transactionsRelations2,
38510
38680
  transferStatusEnum: () => transferStatusEnum,
38511
38681
  transferTypeEnum: () => transferTypeEnum,
38512
- translationEntityTypeEnum: () => translationEntityTypeEnum,
38513
- translationStatusEnum: () => translationStatusEnum,
38514
38682
  tutorContentIssues: () => tutorContentIssues,
38515
38683
  tutorContentIssuesRelations: () => tutorContentIssuesRelations,
38516
38684
  tutorEvaluations: () => tutorEvaluations,
@@ -38524,7 +38692,6 @@ __export(schema_exports, {
38524
38692
  userChallengeScores: () => userChallengeScores,
38525
38693
  userChallengeScoresRelations: () => userChallengeScoresRelations,
38526
38694
  userCredits: () => userCredits2,
38527
- userCreditsRelations: () => userCreditsRelations2,
38528
38695
  userFollows: () => userFollows2,
38529
38696
  userFollowsRelations: () => userFollowsRelations2,
38530
38697
  userPathEnrollments: () => userPathEnrollments,
@@ -38561,7 +38728,7 @@ __export(schema_exports, {
38561
38728
  webhookEvents: () => webhookEvents2,
38562
38729
  wishlists: () => wishlists
38563
38730
  });
38564
- var usersRelations2, onboardingAnalyticsRelations2, accountsRelations2, sessionsRelations2, browserSessionsRelations, courseCategoriesRelations, coursesRelations2, certificatesRelations2, enrollmentsRelations2, modulesRelations2, lessonsRelations2, progressRelations2, mentorshipThreadsRelations2, mentorshipMessagesRelations2, reviewsRelations2, payoutsRelations2, payoutTransactionsRelations2, creatorApplicationsRelations2, transactionsRelations2, couponsRelations2, couponUsagesRelations2, userPreferencesRelations2, mcpSessionsRelations2, syncLogsRelations2, slashCommandAnalyticsRelations2, conceptsRelations2, badgesRelations2, userBadgesRelations2, validationAttemptsRelations2, notificationLogsRelations2, mentorshipTemplatesRelations2, notificationsRelations2, funnelEventsRelations2, courseReviewsRelations2, courseReportsRelations2, mentorshipServicesRelations2, mentorAvailabilityRelations2, mentorAvailabilityExceptionsRelations2, mentorshipSessionsRelations2, sessionParticipantsRelations2, sessionResourcesRelations2, sessionWaitlistRelations2, mentorshipTransactionsRelations2, mentorshipPackagesRelations2, mentorshipCreditsRelations2, refundAuditLogRelations2, sessionReviewsRelations2, sessionReviewVotesRelations2, communityPostsRelations2, communityCommentsRelations2, communityLikesRelations2, userFollowsRelations2, sparkChatSessionsRelations2, studyChatSessionsRelations, studyChatMessagesRelations, studyChatArtifactsRelations, studyModuleSessionsIndexRelations, studyLessonContextsIndexRelations, studyChatMessagesV2Relations, generationStateRelations2, creatorTestimonialsRelations2, marketingContentRelations2, userCreditsRelations2, creditTransactionsRelations2, brainstormingsRelations, ideasRelations, coursePublicationsRelations, publicationReviewHistoryRelations, studentNotesRelations2, learningStreaksRelations, dailyGoalsRelations, dailyGoalProgressRelations, countriesRelations, userRegionalSettingsRelations, courseProjectsRelations, sourceExtractionsRelations, projectGenerationStatesRelations, projectContentPoolRelations, projectVariantModulesRelations, exchangeRatesRelations, lessonRefinementsRelations, courseReviewSnapshotsRelations, learningPathsRelations2, pathCoursesRelations2, pathMilestonesRelations2, userPathEnrollmentsRelations, courseGraphsRelations, graphNodesRelations, graphEdgesRelations, projectTopicsRelations, graphNodeProgressRelations, creatorPortfolioCoursesRelations, portfolioViewsRelations, variationAxesRelations, creatorVariationAxesRelations, courseQaReportsRelations, studentWorkspacesRelations, projectSnapshotsRelations, tutorEvaluationsRelations, tutorContentIssuesRelations, mobileRefreshTokensRelations;
38731
+ var usersRelations2, onboardingAnalyticsRelations2, accountsRelations2, sessionsRelations2, browserSessionsRelations, courseCategoriesRelations, coursesRelations2, certificatesRelations2, enrollmentsRelations2, modulesRelations2, lessonsRelations2, progressRelations2, mentorshipThreadsRelations2, mentorshipMessagesRelations2, reviewsRelations2, payoutsRelations2, payoutTransactionsRelations2, creatorApplicationsRelations2, transactionsRelations2, couponsRelations2, couponUsagesRelations2, userPreferencesRelations2, mcpSessionsRelations2, syncLogsRelations2, slashCommandAnalyticsRelations2, conceptsRelations2, badgesRelations2, userBadgesRelations2, validationAttemptsRelations2, notificationLogsRelations2, mentorshipTemplatesRelations2, notificationsRelations2, funnelEventsRelations2, courseReviewsRelations2, courseReportsRelations2, mentorshipServicesRelations2, mentorAvailabilityRelations2, mentorAvailabilityExceptionsRelations2, mentorshipSessionsRelations2, sessionParticipantsRelations2, sessionResourcesRelations2, sessionWaitlistRelations2, mentorshipTransactionsRelations2, mentorshipPackagesRelations2, mentorshipCreditsRelations2, refundAuditLogRelations2, sessionReviewsRelations2, sessionReviewVotesRelations2, communityPostsRelations2, communityCommentsRelations2, communityLikesRelations2, userFollowsRelations2, sparkChatSessionsRelations2, studyChatSessionsRelations, studyChatMessagesRelations, studyChatArtifactsRelations, studyModuleSessionsIndexRelations, studyLessonContextsIndexRelations, studyChatMessagesV2Relations, generationStateRelations2, creatorTestimonialsRelations2, marketingContentRelations2, brainstormingsRelations, ideasRelations, coursePublicationsRelations, publicationReviewHistoryRelations, studentNotesRelations2, learningStreaksRelations, dailyGoalsRelations, dailyGoalProgressRelations, countriesRelations, userRegionalSettingsRelations, courseProjectsRelations, sourceExtractionsRelations, projectGenerationStatesRelations, projectContentPoolRelations, projectVariantModulesRelations, exchangeRatesRelations, lessonRefinementsRelations, courseReviewSnapshotsRelations, learningPathsRelations2, pathCoursesRelations2, pathMilestonesRelations2, userPathEnrollmentsRelations, courseGraphsRelations, graphNodesRelations, graphEdgesRelations, projectTopicsRelations, graphNodeProgressRelations, creatorPortfolioCoursesRelations, portfolioViewsRelations, variationAxesRelations, creatorVariationAxesRelations, courseQaReportsRelations, studentWorkspacesRelations, projectSnapshotsRelations, tutorEvaluationsRelations, tutorContentIssuesRelations, mobileRefreshTokensRelations;
38565
38732
  var init_schema3 = __esm({
38566
38733
  "../../packages/database/src/schema/index.ts"() {
38567
38734
  "use strict";
@@ -38621,7 +38788,6 @@ var init_schema3 = __esm({
38621
38788
  init_generation_state();
38622
38789
  init_security_audit_log();
38623
38790
  init_marketing();
38624
- init_user_credits();
38625
38791
  init_usage_quotas();
38626
38792
  init_brainstormings();
38627
38793
  init_ideas();
@@ -38721,7 +38887,6 @@ var init_schema3 = __esm({
38721
38887
  init_study_module_sessions();
38722
38888
  init_generation_state();
38723
38889
  init_marketing();
38724
- init_user_credits();
38725
38890
  init_brainstormings();
38726
38891
  init_ideas();
38727
38892
  init_course_publications();
@@ -38835,9 +39000,6 @@ var init_schema3 = __esm({
38835
39000
  // Users this user follows
38836
39001
  // Story 21.1: Spark chat sessions
38837
39002
  sparkChatSessions: many(sparkChatSessions2),
38838
- // Creator flow: Token credits
38839
- credits: one(userCredits2),
38840
- creditTransactions: many(creditTransactions2),
38841
39003
  // Creator flow: New brainstormings
38842
39004
  brainstormings: many(brainstormings),
38843
39005
  // Creator flow: Ideas notepad
@@ -39586,18 +39748,6 @@ var init_schema3 = __esm({
39586
39748
  references: [users.id]
39587
39749
  })
39588
39750
  }));
39589
- userCreditsRelations2 = relations(userCredits2, ({ one }) => ({
39590
- user: one(users, {
39591
- fields: [userCredits2.userId],
39592
- references: [users.id]
39593
- })
39594
- }));
39595
- creditTransactionsRelations2 = relations(creditTransactions2, ({ one }) => ({
39596
- user: one(users, {
39597
- fields: [creditTransactions2.userId],
39598
- references: [users.id]
39599
- })
39600
- }));
39601
39751
  brainstormingsRelations = relations(brainstormings, ({ one }) => ({
39602
39752
  creator: one(users, {
39603
39753
  fields: [brainstormings.creatorId],
@@ -40024,7 +40174,6 @@ var init_src4 = __esm({
40024
40174
  init_platform_settings();
40025
40175
  init_marketing();
40026
40176
  init_security_audit_log();
40027
- init_user_credits();
40028
40177
  init_gamification();
40029
40178
  init_creator_portfolio_courses();
40030
40179
  init_portfolio_views();
@@ -40144,6 +40293,15 @@ var init_next_lesson_full = __esm({
40144
40293
  }
40145
40294
  });
40146
40295
 
40296
+ // ../../packages/tostudy-core/src/memory/student-memory.ts
40297
+ var init_student_memory = __esm({
40298
+ "../../packages/tostudy-core/src/memory/student-memory.ts"() {
40299
+ "use strict";
40300
+ init_src4();
40301
+ init_src();
40302
+ }
40303
+ });
40304
+
40147
40305
  // ../../packages/tostudy-core/src/learning/validate-solution-full.ts
40148
40306
  var init_validate_solution_full = __esm({
40149
40307
  "../../packages/tostudy-core/src/learning/validate-solution-full.ts"() {
@@ -40153,6 +40311,7 @@ var init_validate_solution_full = __esm({
40153
40311
  init_exercise_types();
40154
40312
  init_study_state_sync();
40155
40313
  init_sync_enrollment_progress();
40314
+ init_student_memory();
40156
40315
  }
40157
40316
  });
40158
40317
 
@@ -40274,7 +40433,7 @@ async function runStart(opts, deps = defaultDeps2) {
40274
40433
  deps.error(msg);
40275
40434
  }
40276
40435
  }
40277
- var logger5, defaultDeps2, StartBlockedError, startCommand;
40436
+ var logger6, defaultDeps2, StartBlockedError, startCommand;
40278
40437
  var init_start = __esm({
40279
40438
  "src/commands/start.ts"() {
40280
40439
  "use strict";
@@ -40284,7 +40443,7 @@ var init_start = __esm({
40284
40443
  init_session();
40285
40444
  init_status();
40286
40445
  init_formatter();
40287
- logger5 = createLogger("cli:start");
40446
+ logger6 = createLogger("cli:start");
40288
40447
  defaultDeps2 = {
40289
40448
  requireSession,
40290
40449
  requireActiveCourse,
@@ -40297,7 +40456,7 @@ var init_start = __esm({
40297
40456
  output,
40298
40457
  error,
40299
40458
  stderrWrite: (message) => process.stderr.write(message),
40300
- logger: logger5
40459
+ logger: logger6
40301
40460
  };
40302
40461
  StartBlockedError = class extends Error {
40303
40462
  };
@@ -40309,7 +40468,7 @@ var init_start = __esm({
40309
40468
 
40310
40469
  // src/commands/start-next.ts
40311
40470
  import { Command as Command9 } from "commander";
40312
- var logger6, startNextCommand;
40471
+ var logger7, startNextCommand;
40313
40472
  var init_start_next = __esm({
40314
40473
  "src/commands/start-next.ts"() {
40315
40474
  "use strict";
@@ -40318,7 +40477,7 @@ var init_start_next = __esm({
40318
40477
  init_http2();
40319
40478
  init_session();
40320
40479
  init_formatter();
40321
- logger6 = createLogger("cli:start-next");
40480
+ logger7 = createLogger("cli:start-next");
40322
40481
  startNextCommand = new Command9("start-next").description("Transition to the next module after completing the current one").option("--json", "Output structured JSON").action(async (opts) => {
40323
40482
  try {
40324
40483
  const session = await requireSession();
@@ -40326,7 +40485,7 @@ var init_start_next = __esm({
40326
40485
  const driftWarning = await checkCourseDrift();
40327
40486
  if (driftWarning) process.stderr.write(driftWarning + "\n");
40328
40487
  const data = createHttpProvider(session.apiUrl, session.token);
40329
- const deps = { data, logger: logger6 };
40488
+ const deps = { data, logger: logger7 };
40330
40489
  const moduleData = await startNextModule({ enrollmentId: activeCourse.enrollmentId }, deps);
40331
40490
  await setActiveCourse({ ...activeCourse, currentLessonId: moduleData.firstLesson.id });
40332
40491
  if (opts.json) {
@@ -40349,7 +40508,7 @@ var init_start_next = __esm({
40349
40508
 
40350
40509
  // src/commands/next.ts
40351
40510
  import { Command as Command10 } from "commander";
40352
- var logger7, nextCommand;
40511
+ var logger8, nextCommand;
40353
40512
  var init_next = __esm({
40354
40513
  "src/commands/next.ts"() {
40355
40514
  "use strict";
@@ -40358,7 +40517,7 @@ var init_next = __esm({
40358
40517
  init_http2();
40359
40518
  init_session();
40360
40519
  init_formatter();
40361
- logger7 = createLogger("cli:next");
40520
+ logger8 = createLogger("cli:next");
40362
40521
  nextCommand = new Command10("next").description("Advance to the next lesson in the active course").option("--json", "Output structured JSON").action(async (opts) => {
40363
40522
  try {
40364
40523
  const session = await requireSession();
@@ -40366,7 +40525,7 @@ var init_next = __esm({
40366
40525
  const driftWarning = await checkCourseDrift();
40367
40526
  if (driftWarning) process.stderr.write(driftWarning + "\n");
40368
40527
  const data = createHttpProvider(session.apiUrl, session.token);
40369
- const deps = { data, logger: logger7 };
40528
+ const deps = { data, logger: logger8 };
40370
40529
  const lessonData = await nextLesson(
40371
40530
  { enrollmentId: activeCourse.enrollmentId, userConfirmation: "cli-next" },
40372
40531
  deps
@@ -40447,7 +40606,7 @@ function formatLessonContent(data) {
40447
40606
  }
40448
40607
  return lines.join("\n");
40449
40608
  }
40450
- var logger8, lessonCommand;
40609
+ var logger9, lessonCommand;
40451
40610
  var init_lesson = __esm({
40452
40611
  "src/commands/lesson.ts"() {
40453
40612
  "use strict";
@@ -40457,7 +40616,7 @@ var init_lesson = __esm({
40457
40616
  init_session();
40458
40617
  init_formatter();
40459
40618
  init_resolve();
40460
- logger8 = createLogger("cli:lesson");
40619
+ logger9 = createLogger("cli:lesson");
40461
40620
  lessonCommand = new Command11("lesson").description("Show the content of the current lesson").option("--json", "Output structured JSON").action(async (opts) => {
40462
40621
  try {
40463
40622
  const session = await requireSession();
@@ -40465,7 +40624,7 @@ var init_lesson = __esm({
40465
40624
  const driftWarning = await checkCourseDrift();
40466
40625
  if (driftWarning) process.stderr.write(driftWarning + "\n");
40467
40626
  const data = createHttpProvider(session.apiUrl, session.token);
40468
- const deps = { data, logger: logger8 };
40627
+ const deps = { data, logger: logger9 };
40469
40628
  const lessonId = activeCourse.currentLessonId;
40470
40629
  if (!lessonId) {
40471
40630
  error("Nenhuma li\xE7\xE3o ativa encontrada. Rode: tostudy start ou tostudy next");
@@ -40494,7 +40653,7 @@ var init_lesson = __esm({
40494
40653
 
40495
40654
  // src/commands/hint.ts
40496
40655
  import { Command as Command12 } from "commander";
40497
- var logger9, hintCommand;
40656
+ var logger10, hintCommand;
40498
40657
  var init_hint = __esm({
40499
40658
  "src/commands/hint.ts"() {
40500
40659
  "use strict";
@@ -40503,7 +40662,7 @@ var init_hint = __esm({
40503
40662
  init_http2();
40504
40663
  init_session();
40505
40664
  init_formatter();
40506
- logger9 = createLogger("cli:hint");
40665
+ logger10 = createLogger("cli:hint");
40507
40666
  hintCommand = new Command12("hint").description("Get a progressive hint for the current exercise").option("--json", "Output structured JSON").action(async (opts) => {
40508
40667
  try {
40509
40668
  const session = await requireSession();
@@ -40511,7 +40670,7 @@ var init_hint = __esm({
40511
40670
  const driftWarning = await checkCourseDrift();
40512
40671
  if (driftWarning) process.stderr.write(driftWarning + "\n");
40513
40672
  const data = createHttpProvider(session.apiUrl, session.token);
40514
- const deps = { data, logger: logger9 };
40673
+ const deps = { data, logger: logger10 };
40515
40674
  const hint = await getHint(
40516
40675
  { userId: session.userId, enrollmentId: activeCourse.enrollmentId },
40517
40676
  deps
@@ -40802,7 +40961,7 @@ var init_init_template = __esm({
40802
40961
  import fs8 from "node:fs";
40803
40962
  import path7 from "node:path";
40804
40963
  import { Command as Command13 } from "commander";
40805
- var logger10, validateCommand;
40964
+ var logger11, validateCommand;
40806
40965
  var init_validate = __esm({
40807
40966
  "src/commands/validate.ts"() {
40808
40967
  "use strict";
@@ -40812,7 +40971,7 @@ var init_validate = __esm({
40812
40971
  init_session();
40813
40972
  init_formatter();
40814
40973
  init_init_template();
40815
- logger10 = createLogger("cli:validate");
40974
+ logger11 = createLogger("cli:validate");
40816
40975
  validateCommand = new Command13("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) => {
40817
40976
  try {
40818
40977
  const session = await requireSession();
@@ -40871,7 +41030,7 @@ var init_validate = __esm({
40871
41030
  }
40872
41031
  }
40873
41032
  const data = createHttpProvider(session.apiUrl, session.token);
40874
- const deps = { data, logger: logger10 };
41033
+ const deps = { data, logger: logger11 };
40875
41034
  const result = await validateSolution(
40876
41035
  {
40877
41036
  lessonId,
@@ -41217,6 +41376,26 @@ Rode \`tostudy select <n\xFAmero>\` para ativar um curso.`,
41217
41376
  source: "cli"
41218
41377
  });
41219
41378
  await deps.saveCourseLearnerProfile(activeCourse, learnerProfile, artifacts);
41379
+ try {
41380
+ generateInstructionFiles(
41381
+ {
41382
+ courseTitle: matchedCourse.title,
41383
+ courseId: activeCourse.courseId,
41384
+ progress: progressData?.coursePercent ?? matchedCourse.progress ?? 0,
41385
+ moduleCount: progressData?.currentModule?.totalModules ?? 0,
41386
+ lessonCount: progressData?.currentLesson?.totalLessons ?? 0,
41387
+ currentModuleTitle: progressData?.currentModule?.title,
41388
+ currentLessonTitle: progressData?.currentLesson?.title,
41389
+ courseDescription: matchedCourse.description ?? void 0
41390
+ },
41391
+ learnerProfile
41392
+ );
41393
+ deps.logger.info("Instruction files enriched with learner profile");
41394
+ } catch (err) {
41395
+ deps.logger.warn("Failed to update instruction files", {
41396
+ error: err instanceof Error ? err.message : String(err)
41397
+ });
41398
+ }
41220
41399
  try {
41221
41400
  await deps.setLastInitCourseId(activeCourse.courseId);
41222
41401
  } catch (err) {
@@ -41225,7 +41404,7 @@ Rode \`tostudy select <n\xFAmero>\` para ativar um curso.`,
41225
41404
  deps.output(artifacts.tutorInstructions, { json: false });
41226
41405
  deps.output(artifacts.learnerBrief, { json: false });
41227
41406
  }
41228
- var logger11, defaultDeps3, initCommand;
41407
+ var logger12, defaultDeps3, initCommand;
41229
41408
  var init_init = __esm({
41230
41409
  "src/commands/init.ts"() {
41231
41410
  "use strict";
@@ -41237,7 +41416,8 @@ var init_init = __esm({
41237
41416
  init_init_template();
41238
41417
  init_learner_context();
41239
41418
  init_api2();
41240
- logger11 = createLogger("cli:init");
41419
+ init_instruction_files();
41420
+ logger12 = createLogger("cli:init");
41241
41421
  defaultDeps3 = {
41242
41422
  getSession,
41243
41423
  getActiveCourse,
@@ -41251,7 +41431,7 @@ var init_init = __esm({
41251
41431
  saveCourseLearnerProfile,
41252
41432
  buildInitArtifacts,
41253
41433
  output,
41254
- logger: logger11,
41434
+ logger: logger12,
41255
41435
  createHttpProvider
41256
41436
  };
41257
41437
  initCommand = new Command15("init").description("Generate tutor instructions and learner brief for the active course").action(async () => {
@@ -41571,14 +41751,14 @@ import { Command as Command16 } from "commander";
41571
41751
  import path10 from "node:path";
41572
41752
  import os7 from "node:os";
41573
41753
  import fs11 from "node:fs/promises";
41574
- var logger12, workspaceCommand;
41754
+ var logger13, workspaceCommand;
41575
41755
  var init_workspace2 = __esm({
41576
41756
  "src/commands/workspace.ts"() {
41577
41757
  "use strict";
41578
41758
  init_src();
41579
41759
  init_workspace();
41580
41760
  init_session();
41581
- logger12 = createLogger("cli:workspace");
41761
+ logger13 = createLogger("cli:workspace");
41582
41762
  workspaceCommand = new Command16("workspace").description(
41583
41763
  "Gerenciar workspace de estudo local"
41584
41764
  );
@@ -41609,7 +41789,7 @@ Pr\xF3ximo passo: tostudy export
41609
41789
  );
41610
41790
  }
41611
41791
  } catch (err) {
41612
- logger12.error("workspace setup failed", { error: err });
41792
+ logger13.error("workspace setup failed", { error: err });
41613
41793
  process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
41614
41794
  `);
41615
41795
  process.exit(1);
@@ -41711,7 +41891,7 @@ Pr\xF3ximo passo: tostudy export
41711
41891
  import { Command as Command17 } from "commander";
41712
41892
  import path11 from "node:path";
41713
41893
  import os8 from "node:os";
41714
- var logger13, exportCommand;
41894
+ var logger14, exportCommand;
41715
41895
  var init_export = __esm({
41716
41896
  "src/commands/export.ts"() {
41717
41897
  "use strict";
@@ -41720,7 +41900,7 @@ var init_export = __esm({
41720
41900
  init_http2();
41721
41901
  init_session();
41722
41902
  init_resolve();
41723
- logger13 = createLogger("cli:export");
41903
+ logger14 = createLogger("cli:export");
41724
41904
  exportCommand = new Command17("export").description("Extrair exerc\xEDcio atual para o workspace local").option("--tier <tier>", "Tier do exerc\xEDcio: guided, semiGuided, challenging", "guided").option("--path <dir>", "Diret\xF3rio base do workspace", path11.join(os8.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
41725
41905
  try {
41726
41906
  const session = await requireSession();
@@ -41765,7 +41945,7 @@ ${result.files.map((f) => ` \u{1F4C4} ${f}`).join("\n")}
41765
41945
  );
41766
41946
  }
41767
41947
  } catch (err) {
41768
- logger13.error("export failed", { error: err });
41948
+ logger14.error("export failed", { error: err });
41769
41949
  process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
41770
41950
  `);
41771
41951
  process.exit(1);
@@ -41790,13 +41970,13 @@ async function findWorkspacePath(courseTitle, basePath) {
41790
41970
  return null;
41791
41971
  }
41792
41972
  }
41793
- var logger14, openCommand;
41973
+ var logger15, openCommand;
41794
41974
  var init_open = __esm({
41795
41975
  "src/commands/open.ts"() {
41796
41976
  "use strict";
41797
41977
  init_src();
41798
41978
  init_session();
41799
- logger14 = createLogger("cli:open");
41979
+ logger15 = createLogger("cli:open");
41800
41980
  openCommand = new Command18("open").description("Abrir workspace do curso na IDE").option("--path <dir>", "Diret\xF3rio base do workspace", path12.join(os9.homedir(), "study")).action(async (opts) => {
41801
41981
  try {
41802
41982
  const activeCourse = await requireActiveCourse();
@@ -41810,7 +41990,7 @@ var init_open = __esm({
41810
41990
  const editor = process.env["EDITOR"] ?? "code";
41811
41991
  execFile3(editor, [workspacePath], (err) => {
41812
41992
  if (err) {
41813
- logger14.error("open failed", { editor, workspacePath });
41993
+ logger15.error("open failed", { editor, workspacePath });
41814
41994
  process.stderr.write(`\u274C Falha ao abrir: ${err.message}
41815
41995
  `);
41816
41996
  process.exit(1);
@@ -41819,7 +41999,7 @@ var init_open = __esm({
41819
41999
  `);
41820
42000
  });
41821
42001
  } catch (err) {
41822
- logger14.error("open command failed", { error: err });
42002
+ logger15.error("open command failed", { error: err });
41823
42003
  process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
41824
42004
  `);
41825
42005
  process.exit(1);
@@ -41891,7 +42071,7 @@ import { Command as Command19 } from "commander";
41891
42071
  import path14 from "node:path";
41892
42072
  import os10 from "node:os";
41893
42073
  import fs14 from "node:fs/promises";
41894
- var logger15, vaultCommand;
42074
+ var logger16, vaultCommand;
41895
42075
  var init_vault2 = __esm({
41896
42076
  "src/commands/vault.ts"() {
41897
42077
  "use strict";
@@ -41900,7 +42080,7 @@ var init_vault2 = __esm({
41900
42080
  init_courses();
41901
42081
  init_http2();
41902
42082
  init_session();
41903
- logger15 = createLogger("cli:vault");
42083
+ logger16 = createLogger("cli:vault");
41904
42084
  vaultCommand = new Command19("vault").description("Gerenciar vault Obsidian do curso");
41905
42085
  vaultCommand.command("init").description("Gerar vault Obsidian para o curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace", path14.join(os10.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
41906
42086
  try {
@@ -41934,7 +42114,7 @@ var init_vault2 = __esm({
41934
42114
  activeCourse.courseId,
41935
42115
  courseSlug2
41936
42116
  );
41937
- logger15.info("Vault generated", {
42117
+ logger16.info("Vault generated", {
41938
42118
  courseId: activeCourse.courseId,
41939
42119
  vaultPath: result.vaultPath,
41940
42120
  filesWritten: result.filesWritten
@@ -41967,7 +42147,7 @@ Para visualizar:
41967
42147
  );
41968
42148
  }
41969
42149
  } catch (err) {
41970
- logger15.error("vault init failed", { error: err });
42150
+ logger16.error("vault init failed", { error: err });
41971
42151
  process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
41972
42152
  `);
41973
42153
  process.exit(1);
@@ -41988,7 +42168,7 @@ Para visualizar:
41988
42168
  process.exit(1);
41989
42169
  }
41990
42170
  const data = createHttpProvider(session.apiUrl, session.token);
41991
- const deps = { data, logger: logger15 };
42171
+ const deps = { data, logger: logger16 };
41992
42172
  const progress3 = await getProgress({ enrollmentId: activeCourse.enrollmentId }, deps);
41993
42173
  const markerPath = path14.join(vaultPath, ".ana-vault.json");
41994
42174
  const markerRaw = await fs14.readFile(markerPath, "utf-8");
@@ -42042,7 +42222,7 @@ Para visualizar:
42042
42222
  );
42043
42223
  }
42044
42224
  } catch (err) {
42045
- logger15.error("vault sync failed", { error: err });
42225
+ logger16.error("vault sync failed", { error: err });
42046
42226
  process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
42047
42227
  `);
42048
42228
  process.exit(1);
@@ -42105,7 +42285,7 @@ var init_cli = __esm({
42105
42285
  init_export();
42106
42286
  init_open();
42107
42287
  init_vault2();
42108
- CLI_VERSION = "0.6.0";
42288
+ CLI_VERSION = true ? "0.7.2" : "0.7.1";
42109
42289
  }
42110
42290
  });
42111
42291