@tostudy-ai/cli 0.7.0 → 0.7.1
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 +366 -292
- package/dist/cli.js.map +4 -4
- package/package.json +1 -1
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,109 @@ 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
|
|
2346
|
+
|
|
2347
|
+
Voc\xEA \xE9 um tutor AI guiando o estudante neste curso.`);
|
|
2348
|
+
if (learner) {
|
|
2349
|
+
const levelLabels = {
|
|
2350
|
+
beginner: "Iniciante",
|
|
2351
|
+
intermediate: "Intermedi\xE1rio",
|
|
2352
|
+
advanced: "Avan\xE7ado"
|
|
2353
|
+
};
|
|
2354
|
+
sections.push(`## Contexto do Aluno
|
|
2355
|
+
|
|
2356
|
+
- **N\xEDvel**: ${levelLabels[learner.learnerLevel]}
|
|
2357
|
+
- **Objetivo**: ${learner.goal}
|
|
2358
|
+
- **Empresa**: ${learner.company}
|
|
2359
|
+
- **Segmento**: ${learner.segment}
|
|
2360
|
+
- **Produtos/Servi\xE7os**: ${learner.productsOrServices}
|
|
2361
|
+
- **Regi\xE3o**: ${learner.region}
|
|
2362
|
+
- **Time**: ${learner.team}
|
|
2363
|
+
- **Adaptar ao contexto real**: ${learner.adaptToRealContext ? "Sim \u2014 use exemplos do projeto real do aluno" : "N\xE3o \u2014 use exemplos gen\xE9ricos"}`);
|
|
2364
|
+
}
|
|
2365
|
+
sections.push(`## Progresso
|
|
2366
|
+
|
|
2367
|
+
- ${ctx.progress}% completo | ${ctx.moduleCount} m\xF3dulos | ${ctx.lessonCount} li\xE7\xF5es`);
|
|
2368
|
+
sections.push(`## Comandos Dispon\xEDveis
|
|
2369
|
+
|
|
2370
|
+
| Comando | Descri\xE7\xE3o |
|
|
2371
|
+
|---------|-----------|
|
|
2372
|
+
| \`tostudy start\` | Carrega o pr\xF3ximo m\xF3dulo |
|
|
2373
|
+
| \`tostudy next\` | Avan\xE7a para a pr\xF3xima li\xE7\xE3o |
|
|
2374
|
+
| \`tostudy lesson\` | Mostra a li\xE7\xE3o atual |
|
|
2375
|
+
| \`tostudy hint\` | Mostra dicas progressivas |
|
|
2376
|
+
| \`tostudy validate\` | Valida o exerc\xEDcio |
|
|
2377
|
+
| \`tostudy progress\` | Mostra o progresso |`);
|
|
2378
|
+
sections.push(`## Regras
|
|
2379
|
+
|
|
2380
|
+
- Sempre carregue a li\xE7\xE3o antes de propor exerc\xEDcios (\`tostudy lesson\`)
|
|
2381
|
+
- Use \`tostudy hint\` antes de entregar respostas diretas
|
|
2382
|
+
- Valide com \`tostudy validate\` antes de avan\xE7ar
|
|
2383
|
+
- Respeite a sequ\xEAncia dos m\xF3dulos${learner?.adaptToRealContext ? "\n- Adapte exemplos ao contexto real do projeto do estudante" : ""}`);
|
|
2384
|
+
sections.push(`<!-- tostudy-course-id: ${ctx.courseId} -->`);
|
|
2385
|
+
return sections.join("\n\n") + "\n";
|
|
2386
|
+
}
|
|
2387
|
+
function generateInstructionFiles(ctx, learner) {
|
|
2388
|
+
const cwd = process.cwd();
|
|
2389
|
+
const slug = slugify(ctx.courseTitle);
|
|
2390
|
+
const content = buildInstructionContent(ctx, learner);
|
|
2391
|
+
const written = [];
|
|
2392
|
+
const claudeDir = join2(cwd, ".claude", "commands");
|
|
2393
|
+
if (!existsSync2(claudeDir)) {
|
|
2394
|
+
mkdirSync2(claudeDir, { recursive: true });
|
|
2395
|
+
}
|
|
2396
|
+
const claudeFile = `tostudy-${slug}.md`;
|
|
2397
|
+
writeFileSync2(join2(claudeDir, claudeFile), content);
|
|
2398
|
+
written.push(`.claude/commands/${claudeFile}`);
|
|
2399
|
+
const cursorDir = join2(cwd, ".cursor", "rules");
|
|
2400
|
+
if (existsSync2(join2(cwd, ".cursor")) || existsSync2(cursorDir)) {
|
|
2401
|
+
if (!existsSync2(cursorDir)) {
|
|
2402
|
+
mkdirSync2(cursorDir, { recursive: true });
|
|
2403
|
+
}
|
|
2404
|
+
const mdcContent = `---
|
|
2405
|
+
description: ${ctx.courseTitle} \u2014 ToStudy Course Guide
|
|
2406
|
+
globs: ["**/*"]
|
|
2407
|
+
alwaysApply: true
|
|
2408
|
+
---
|
|
2409
|
+
|
|
2410
|
+
${content}`;
|
|
2411
|
+
const cursorFile = `tostudy-${slug}.mdc`;
|
|
2412
|
+
writeFileSync2(join2(cursorDir, cursorFile), mdcContent);
|
|
2413
|
+
written.push(`.cursor/rules/${cursorFile}`);
|
|
2414
|
+
}
|
|
2415
|
+
const courseDir = join2(cwd, ".tostudy", "courses", slug);
|
|
2416
|
+
if (!existsSync2(courseDir)) {
|
|
2417
|
+
mkdirSync2(courseDir, { recursive: true });
|
|
2418
|
+
}
|
|
2419
|
+
writeFileSync2(join2(courseDir, "AGENTS.md"), content);
|
|
2420
|
+
written.push(`.tostudy/courses/${slug}/AGENTS.md`);
|
|
2421
|
+
logger3.info("Generated instruction files", {
|
|
2422
|
+
slug,
|
|
2423
|
+
files: written,
|
|
2424
|
+
hasLearnerProfile: !!learner
|
|
2425
|
+
});
|
|
2426
|
+
return slug;
|
|
2427
|
+
}
|
|
2428
|
+
var logger3;
|
|
2429
|
+
var init_instruction_files = __esm({
|
|
2430
|
+
"src/workspace/instruction-files.ts"() {
|
|
2431
|
+
"use strict";
|
|
2432
|
+
init_src();
|
|
2433
|
+
logger3 = createLogger("cli:instruction-files");
|
|
2434
|
+
}
|
|
2435
|
+
});
|
|
2436
|
+
|
|
2337
2437
|
// src/commands/select.ts
|
|
2338
2438
|
import { Command as Command6 } from "commander";
|
|
2339
|
-
var
|
|
2439
|
+
var logger4, selectCommand;
|
|
2340
2440
|
var init_select = __esm({
|
|
2341
2441
|
"src/commands/select.ts"() {
|
|
2342
2442
|
"use strict";
|
|
@@ -2345,12 +2445,13 @@ var init_select = __esm({
|
|
|
2345
2445
|
init_http2();
|
|
2346
2446
|
init_session();
|
|
2347
2447
|
init_formatter();
|
|
2348
|
-
|
|
2448
|
+
init_instruction_files();
|
|
2449
|
+
logger4 = createLogger("cli:select");
|
|
2349
2450
|
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
2451
|
try {
|
|
2351
2452
|
const session = await requireSession();
|
|
2352
2453
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
2353
|
-
const deps = { data, logger:
|
|
2454
|
+
const deps = { data, logger: logger4 };
|
|
2354
2455
|
const courses3 = await listCourses({ userId: session.userId }, deps);
|
|
2355
2456
|
let courseId = course;
|
|
2356
2457
|
let enrollmentId = "";
|
|
@@ -2377,17 +2478,34 @@ var init_select = __esm({
|
|
|
2377
2478
|
courseTags: matched?.tags,
|
|
2378
2479
|
courseLevel: matched?.level
|
|
2379
2480
|
});
|
|
2481
|
+
let courseSlug2 = "";
|
|
2482
|
+
try {
|
|
2483
|
+
courseSlug2 = generateInstructionFiles({
|
|
2484
|
+
courseTitle: detail.courseTitle,
|
|
2485
|
+
courseId: detail.courseId,
|
|
2486
|
+
progress: detail.progress,
|
|
2487
|
+
moduleCount: detail.moduleCount,
|
|
2488
|
+
lessonCount: detail.lessonCount
|
|
2489
|
+
});
|
|
2490
|
+
} catch (err) {
|
|
2491
|
+
logger4.warn("Failed to generate instruction files", {
|
|
2492
|
+
error: err instanceof Error ? err.message : String(err)
|
|
2493
|
+
});
|
|
2494
|
+
}
|
|
2380
2495
|
if (opts.json) {
|
|
2381
|
-
output({ ...detail, enrollmentId }, { json: true });
|
|
2496
|
+
output({ ...detail, enrollmentId, courseSlug: courseSlug2 }, { json: true });
|
|
2382
2497
|
} else {
|
|
2498
|
+
const slashCmd = courseSlug2 ? `/tostudy-${courseSlug2}` : "/tostudy";
|
|
2383
2499
|
output(
|
|
2384
2500
|
[
|
|
2385
2501
|
`\u2713 Curso ativado: ${detail.courseTitle}`,
|
|
2386
2502
|
` Progresso: ${detail.progress}% | ${detail.moduleCount} m\xF3dulos | ${detail.lessonCount} li\xE7\xF5es`,
|
|
2387
2503
|
"",
|
|
2388
|
-
"
|
|
2389
|
-
"
|
|
2390
|
-
"\u2192
|
|
2504
|
+
" Arquivos de contexto criados para seu assistente AI.",
|
|
2505
|
+
"",
|
|
2506
|
+
"\u2192 Abra sua plataforma (claude, codex, cursor...)",
|
|
2507
|
+
`\u2192 No Claude Code, digite: ${slashCmd}`,
|
|
2508
|
+
"\u2192 Em outras plataformas: tostudy init"
|
|
2391
2509
|
].join("\n"),
|
|
2392
2510
|
{ json: false }
|
|
2393
2511
|
);
|
|
@@ -2402,7 +2520,7 @@ var init_select = __esm({
|
|
|
2402
2520
|
|
|
2403
2521
|
// src/commands/progress.ts
|
|
2404
2522
|
import { Command as Command7 } from "commander";
|
|
2405
|
-
var
|
|
2523
|
+
var logger5, progressCommand;
|
|
2406
2524
|
var init_progress = __esm({
|
|
2407
2525
|
"src/commands/progress.ts"() {
|
|
2408
2526
|
"use strict";
|
|
@@ -2411,7 +2529,7 @@ var init_progress = __esm({
|
|
|
2411
2529
|
init_http2();
|
|
2412
2530
|
init_session();
|
|
2413
2531
|
init_formatter();
|
|
2414
|
-
|
|
2532
|
+
logger5 = createLogger("cli:progress");
|
|
2415
2533
|
progressCommand = new Command7("progress").description("Show your progress in the active course").option("--json", "Output structured JSON").action(async (opts) => {
|
|
2416
2534
|
try {
|
|
2417
2535
|
const session = await requireSession();
|
|
@@ -2419,7 +2537,7 @@ var init_progress = __esm({
|
|
|
2419
2537
|
const driftWarning = await checkCourseDrift();
|
|
2420
2538
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
2421
2539
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
2422
|
-
const deps = { data, logger:
|
|
2540
|
+
const deps = { data, logger: logger5 };
|
|
2423
2541
|
const progress3 = await getProgress({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
2424
2542
|
if (opts.json) {
|
|
2425
2543
|
output(progress3, { json: true });
|
|
@@ -3678,7 +3796,7 @@ var init_sql = __esm({
|
|
|
3678
3796
|
return new SQL([new StringChunk(str)]);
|
|
3679
3797
|
}
|
|
3680
3798
|
sql2.raw = raw;
|
|
3681
|
-
function
|
|
3799
|
+
function join3(chunks, separator) {
|
|
3682
3800
|
const result = [];
|
|
3683
3801
|
for (const [i, chunk] of chunks.entries()) {
|
|
3684
3802
|
if (i > 0 && separator !== void 0) {
|
|
@@ -3688,7 +3806,7 @@ var init_sql = __esm({
|
|
|
3688
3806
|
}
|
|
3689
3807
|
return new SQL(result);
|
|
3690
3808
|
}
|
|
3691
|
-
sql2.join =
|
|
3809
|
+
sql2.join = join3;
|
|
3692
3810
|
function identifier(value) {
|
|
3693
3811
|
return new Name(value);
|
|
3694
3812
|
}
|
|
@@ -10220,7 +10338,7 @@ var init_select3 = __esm({
|
|
|
10220
10338
|
const baseTableName = this.tableName;
|
|
10221
10339
|
const tableName = getTableLikeName(table);
|
|
10222
10340
|
for (const item of extractUsedTable(table)) this.usedTables.add(item);
|
|
10223
|
-
if (typeof tableName === "string" && this.config.joins?.some((
|
|
10341
|
+
if (typeof tableName === "string" && this.config.joins?.some((join3) => join3.alias === tableName)) {
|
|
10224
10342
|
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
10225
10343
|
}
|
|
10226
10344
|
if (!this.isPartialSelect) {
|
|
@@ -11747,7 +11865,7 @@ var init_update = __esm({
|
|
|
11747
11865
|
createJoin(joinType) {
|
|
11748
11866
|
return (table, on) => {
|
|
11749
11867
|
const tableName = getTableLikeName(table);
|
|
11750
|
-
if (typeof tableName === "string" && this.config.joins.some((
|
|
11868
|
+
if (typeof tableName === "string" && this.config.joins.some((join3) => join3.alias === tableName)) {
|
|
11751
11869
|
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
11752
11870
|
}
|
|
11753
11871
|
if (typeof on === "function") {
|
|
@@ -11843,10 +11961,10 @@ var init_update = __esm({
|
|
|
11843
11961
|
const fromFields = this.getTableLikeFields(this.config.from);
|
|
11844
11962
|
fields[tableName] = fromFields;
|
|
11845
11963
|
}
|
|
11846
|
-
for (const
|
|
11847
|
-
const tableName2 = getTableLikeName(
|
|
11848
|
-
if (typeof tableName2 === "string" && !is(
|
|
11849
|
-
const fromFields = this.getTableLikeFields(
|
|
11964
|
+
for (const join3 of this.config.joins) {
|
|
11965
|
+
const tableName2 = getTableLikeName(join3.table);
|
|
11966
|
+
if (typeof tableName2 === "string" && !is(join3.table, SQL)) {
|
|
11967
|
+
const fromFields = this.getTableLikeFields(join3.table);
|
|
11850
11968
|
fields[tableName2] = fromFields;
|
|
11851
11969
|
}
|
|
11852
11970
|
}
|
|
@@ -12789,12 +12907,12 @@ var init_session3 = __esm({
|
|
|
12789
12907
|
init_tracing();
|
|
12790
12908
|
init_utils();
|
|
12791
12909
|
PostgresJsPreparedQuery = class extends PgPreparedQuery {
|
|
12792
|
-
constructor(client, queryString, params,
|
|
12910
|
+
constructor(client, queryString, params, logger17, cache, queryMetadata, cacheConfig, fields, _isResponseInArrayMode, customResultMapper) {
|
|
12793
12911
|
super({ sql: queryString, params }, cache, queryMetadata, cacheConfig);
|
|
12794
12912
|
this.client = client;
|
|
12795
12913
|
this.queryString = queryString;
|
|
12796
12914
|
this.params = params;
|
|
12797
|
-
this.logger =
|
|
12915
|
+
this.logger = logger17;
|
|
12798
12916
|
this.fields = fields;
|
|
12799
12917
|
this._isResponseInArrayMode = _isResponseInArrayMode;
|
|
12800
12918
|
this.customResultMapper = customResultMapper;
|
|
@@ -12935,11 +13053,11 @@ function construct(client, config2 = {}) {
|
|
|
12935
13053
|
client.options.serializers["114"] = transparentParser;
|
|
12936
13054
|
client.options.serializers["3802"] = transparentParser;
|
|
12937
13055
|
const dialect = new PgDialect({ casing: config2.casing });
|
|
12938
|
-
let
|
|
13056
|
+
let logger17;
|
|
12939
13057
|
if (config2.logger === true) {
|
|
12940
|
-
|
|
13058
|
+
logger17 = new DefaultLogger();
|
|
12941
13059
|
} else if (config2.logger !== false) {
|
|
12942
|
-
|
|
13060
|
+
logger17 = config2.logger;
|
|
12943
13061
|
}
|
|
12944
13062
|
let schema;
|
|
12945
13063
|
if (config2.schema) {
|
|
@@ -12953,7 +13071,7 @@ function construct(client, config2 = {}) {
|
|
|
12953
13071
|
tableNamesMap: tablesConfig.tableNamesMap
|
|
12954
13072
|
};
|
|
12955
13073
|
}
|
|
12956
|
-
const session = new PostgresJsSession(client, dialect, schema, { logger:
|
|
13074
|
+
const session = new PostgresJsSession(client, dialect, schema, { logger: logger17, cache: config2.cache });
|
|
12957
13075
|
const db2 = new PostgresJsDatabase(dialect, session, schema);
|
|
12958
13076
|
db2.$client = client;
|
|
12959
13077
|
db2.$cache = config2.cache;
|
|
@@ -13155,7 +13273,7 @@ __export(util_exports, {
|
|
|
13155
13273
|
required: () => required,
|
|
13156
13274
|
safeExtend: () => safeExtend,
|
|
13157
13275
|
shallowClone: () => shallowClone,
|
|
13158
|
-
slugify: () =>
|
|
13276
|
+
slugify: () => slugify3,
|
|
13159
13277
|
stringifyPrimitive: () => stringifyPrimitive,
|
|
13160
13278
|
uint8ArrayToBase64: () => uint8ArrayToBase64,
|
|
13161
13279
|
uint8ArrayToBase64url: () => uint8ArrayToBase64url,
|
|
@@ -13295,7 +13413,7 @@ function randomString(length = 10) {
|
|
|
13295
13413
|
function esc(str) {
|
|
13296
13414
|
return JSON.stringify(str);
|
|
13297
13415
|
}
|
|
13298
|
-
function
|
|
13416
|
+
function slugify3(input2) {
|
|
13299
13417
|
return input2.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
13300
13418
|
}
|
|
13301
13419
|
function isObject(data) {
|
|
@@ -23429,7 +23547,7 @@ function _toUpperCase() {
|
|
|
23429
23547
|
}
|
|
23430
23548
|
// @__NO_SIDE_EFFECTS__
|
|
23431
23549
|
function _slugify() {
|
|
23432
|
-
return /* @__PURE__ */ _overwrite((input2) =>
|
|
23550
|
+
return /* @__PURE__ */ _overwrite((input2) => slugify3(input2));
|
|
23433
23551
|
}
|
|
23434
23552
|
// @__NO_SIDE_EFFECTS__
|
|
23435
23553
|
function _array(Class2, element, params) {
|
|
@@ -27494,6 +27612,10 @@ var init_users = __esm({
|
|
|
27494
27612
|
// Public portfolio active
|
|
27495
27613
|
followerDiscountPct: smallint("follower_discount_pct").default(0).notNull(),
|
|
27496
27614
|
// Follower discount: 0, 5, 10, 15, 20
|
|
27615
|
+
// Stripe Integration
|
|
27616
|
+
stripeCustomerId: varchar("stripe_customer_id", { length: 255 }),
|
|
27617
|
+
// Stripe Customer ID (cus_xxx) for payment method reuse
|
|
27618
|
+
metadata: jsonb("metadata").$type().default({}),
|
|
27497
27619
|
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
|
|
27498
27620
|
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull()
|
|
27499
27621
|
},
|
|
@@ -33953,77 +34075,6 @@ var init_marketing = __esm({
|
|
|
33953
34075
|
}
|
|
33954
34076
|
});
|
|
33955
34077
|
|
|
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
34078
|
// ../../packages/database/src/schema/usage-quotas.ts
|
|
34028
34079
|
var quotaChangeHistory, userUsageQuotas2, usageTierLimits2;
|
|
34029
34080
|
var init_usage_quotas = __esm({
|
|
@@ -34469,74 +34520,72 @@ var init_course_variants = __esm({
|
|
|
34469
34520
|
}
|
|
34470
34521
|
});
|
|
34471
34522
|
|
|
34472
|
-
// ../../packages/database/src/schema/_archived/
|
|
34473
|
-
var
|
|
34474
|
-
var
|
|
34475
|
-
"../../packages/database/src/schema/_archived/
|
|
34523
|
+
// ../../packages/database/src/schema/_archived/user-credits.ts
|
|
34524
|
+
var transactionTypeEnum, userCredits2, creditTransactions2;
|
|
34525
|
+
var init_user_credits = __esm({
|
|
34526
|
+
"../../packages/database/src/schema/_archived/user-credits.ts"() {
|
|
34476
34527
|
"use strict";
|
|
34477
34528
|
init_pg_core();
|
|
34478
34529
|
init_users();
|
|
34479
|
-
|
|
34480
|
-
|
|
34481
|
-
|
|
34482
|
-
|
|
34483
|
-
|
|
34484
|
-
|
|
34485
|
-
|
|
34486
|
-
|
|
34487
|
-
|
|
34488
|
-
|
|
34489
|
-
|
|
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)
|
|
34530
|
+
transactionTypeEnum = pgEnum("transaction_type", [
|
|
34531
|
+
"initial_grant",
|
|
34532
|
+
// Credito inicial de $5
|
|
34533
|
+
"purchase",
|
|
34534
|
+
// Compra de creditos
|
|
34535
|
+
"consumption",
|
|
34536
|
+
// Consumo por uso de IA
|
|
34537
|
+
"refund",
|
|
34538
|
+
// Reembolso
|
|
34539
|
+
"adjustment"
|
|
34540
|
+
// Ajuste manual admin
|
|
34499
34541
|
]);
|
|
34500
|
-
|
|
34501
|
-
"
|
|
34542
|
+
userCredits2 = pgTable(
|
|
34543
|
+
"user_credits",
|
|
34502
34544
|
{
|
|
34503
34545
|
id: uuid("id").primaryKey().defaultRandom(),
|
|
34504
|
-
|
|
34505
|
-
|
|
34506
|
-
|
|
34507
|
-
|
|
34508
|
-
|
|
34509
|
-
|
|
34510
|
-
|
|
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
|
|
34546
|
+
userId: uuid("user_id").references(() => users.id, { onDelete: "cascade" }).notNull().unique(),
|
|
34547
|
+
/** Current balance in USD */
|
|
34548
|
+
balance: decimal("balance", { precision: 10, scale: 4 }).notNull().default("0"),
|
|
34549
|
+
/** Total consumed in USD (absolute value, always positive) */
|
|
34550
|
+
totalConsumed: decimal("total_consumed", { precision: 10, scale: 4 }).notNull().default("0"),
|
|
34551
|
+
/** Total purchased in USD */
|
|
34552
|
+
totalPurchased: decimal("total_purchased", { precision: 10, scale: 4 }).notNull().default("0"),
|
|
34525
34553
|
createdAt: timestamp("created_at").defaultNow().notNull(),
|
|
34526
34554
|
updatedAt: timestamp("updated_at").defaultNow().notNull()
|
|
34527
34555
|
},
|
|
34528
34556
|
(table) => ({
|
|
34529
|
-
|
|
34530
|
-
|
|
34531
|
-
|
|
34532
|
-
|
|
34533
|
-
|
|
34534
|
-
|
|
34535
|
-
|
|
34536
|
-
|
|
34537
|
-
|
|
34538
|
-
|
|
34539
|
-
)
|
|
34557
|
+
userIdIdx: index("user_credits_user_id_idx").on(table.userId)
|
|
34558
|
+
})
|
|
34559
|
+
);
|
|
34560
|
+
creditTransactions2 = pgTable(
|
|
34561
|
+
"credit_transactions",
|
|
34562
|
+
{
|
|
34563
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
34564
|
+
userId: uuid("user_id").references(() => users.id, { onDelete: "restrict" }).notNull(),
|
|
34565
|
+
type: transactionTypeEnum("type").notNull(),
|
|
34566
|
+
/** Amount in USD (negative for consumption, positive for purchase/grant) */
|
|
34567
|
+
amount: decimal("amount", { precision: 10, scale: 4 }).notNull(),
|
|
34568
|
+
/** Balance after this transaction in USD */
|
|
34569
|
+
balanceAfter: decimal("balance_after", { precision: 10, scale: 4 }).notNull(),
|
|
34570
|
+
description: text("description"),
|
|
34571
|
+
metadata: text("metadata"),
|
|
34572
|
+
// JSON com detalhes (tokens, modelo, etc)
|
|
34573
|
+
// Granular usage tracking columns
|
|
34574
|
+
operation: varchar("operation", { length: 50 }),
|
|
34575
|
+
// 'brainstorm_message', 'generation_outline', etc.
|
|
34576
|
+
model: varchar("model", { length: 100 }),
|
|
34577
|
+
// 'claude-sonnet-4-5-20250929'
|
|
34578
|
+
inputTokens: integer("input_tokens"),
|
|
34579
|
+
outputTokens: integer("output_tokens"),
|
|
34580
|
+
latencyMs: integer("latency_ms"),
|
|
34581
|
+
// DB FK to course_proposals preserved in migration; Drizzle ref removed for schema archival
|
|
34582
|
+
proposalId: uuid("proposal_id"),
|
|
34583
|
+
sessionId: uuid("session_id"),
|
|
34584
|
+
createdAt: timestamp("created_at").defaultNow().notNull()
|
|
34585
|
+
},
|
|
34586
|
+
(table) => ({
|
|
34587
|
+
userIdIdx: index("credit_transactions_user_id_idx").on(table.userId),
|
|
34588
|
+
createdAtIdx: index("credit_transactions_created_at_idx").on(table.createdAt)
|
|
34540
34589
|
})
|
|
34541
34590
|
);
|
|
34542
34591
|
}
|
|
@@ -34550,7 +34599,7 @@ var init_archived = __esm({
|
|
|
34550
34599
|
init_course_matrices();
|
|
34551
34600
|
init_matrix_modules();
|
|
34552
34601
|
init_course_variants();
|
|
34553
|
-
|
|
34602
|
+
init_user_credits();
|
|
34554
34603
|
}
|
|
34555
34604
|
});
|
|
34556
34605
|
|
|
@@ -35325,76 +35374,89 @@ var init_llm_analytics = __esm({
|
|
|
35325
35374
|
init_users();
|
|
35326
35375
|
init_courses3();
|
|
35327
35376
|
init_llm_pricing();
|
|
35328
|
-
llmInteractions = pgTable(
|
|
35329
|
-
|
|
35330
|
-
|
|
35331
|
-
|
|
35332
|
-
|
|
35333
|
-
|
|
35334
|
-
|
|
35335
|
-
|
|
35336
|
-
|
|
35337
|
-
|
|
35338
|
-
|
|
35339
|
-
|
|
35340
|
-
|
|
35341
|
-
|
|
35342
|
-
|
|
35343
|
-
|
|
35344
|
-
|
|
35345
|
-
|
|
35346
|
-
|
|
35347
|
-
|
|
35348
|
-
|
|
35349
|
-
|
|
35350
|
-
|
|
35351
|
-
|
|
35352
|
-
|
|
35353
|
-
|
|
35354
|
-
|
|
35355
|
-
|
|
35356
|
-
|
|
35357
|
-
|
|
35358
|
-
|
|
35359
|
-
|
|
35360
|
-
|
|
35361
|
-
|
|
35362
|
-
|
|
35363
|
-
|
|
35364
|
-
|
|
35365
|
-
|
|
35366
|
-
|
|
35367
|
-
|
|
35368
|
-
|
|
35369
|
-
|
|
35370
|
-
|
|
35371
|
-
|
|
35372
|
-
|
|
35373
|
-
|
|
35374
|
-
|
|
35375
|
-
|
|
35376
|
-
|
|
35377
|
-
|
|
35378
|
-
|
|
35379
|
-
|
|
35380
|
-
|
|
35381
|
-
|
|
35382
|
-
|
|
35383
|
-
|
|
35384
|
-
|
|
35385
|
-
|
|
35386
|
-
|
|
35387
|
-
|
|
35388
|
-
|
|
35389
|
-
|
|
35390
|
-
|
|
35391
|
-
|
|
35392
|
-
|
|
35393
|
-
|
|
35394
|
-
|
|
35395
|
-
|
|
35396
|
-
|
|
35397
|
-
|
|
35377
|
+
llmInteractions = pgTable(
|
|
35378
|
+
"llm_interactions",
|
|
35379
|
+
{
|
|
35380
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
35381
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
35382
|
+
// Operation type
|
|
35383
|
+
operationType: varchar("operation_type", { length: 50 }).notNull(),
|
|
35384
|
+
// Provider (references llm_provider enum from llm-pricing.ts)
|
|
35385
|
+
provider: llmProviderEnum("provider").notNull().default("anthropic"),
|
|
35386
|
+
// Tracing
|
|
35387
|
+
correlationId: varchar("correlation_id", { length: 64 }),
|
|
35388
|
+
// Relationships
|
|
35389
|
+
userId: uuid("user_id").references(() => users.id, { onDelete: "set null" }),
|
|
35390
|
+
creatorId: uuid("creator_id").references(() => users.id, { onDelete: "set null" }),
|
|
35391
|
+
courseId: uuid("course_id").references(() => courses.id, { onDelete: "set null" }),
|
|
35392
|
+
sessionId: uuid("session_id"),
|
|
35393
|
+
variantId: uuid("variant_id"),
|
|
35394
|
+
// Denormalized from metadata for faster queries
|
|
35395
|
+
// Request
|
|
35396
|
+
model: varchar("model", { length: 50 }).notNull(),
|
|
35397
|
+
promptText: text("prompt_text"),
|
|
35398
|
+
promptTokens: integer("prompt_tokens").notNull(),
|
|
35399
|
+
// Response
|
|
35400
|
+
responseText: text("response_text"),
|
|
35401
|
+
responseTokens: integer("response_tokens").notNull(),
|
|
35402
|
+
// Cost & Revenue
|
|
35403
|
+
costUsd: decimal("cost_usd", { precision: 10, scale: 6 }).notNull(),
|
|
35404
|
+
revenueUsd: decimal("revenue_usd", { precision: 10, scale: 6 }).notNull().default("0"),
|
|
35405
|
+
// Cache metrics (prompt caching)
|
|
35406
|
+
cacheCreationTokens: integer("cache_creation_tokens").default(0),
|
|
35407
|
+
cacheReadTokens: integer("cache_read_tokens").default(0),
|
|
35408
|
+
cacheHit: integer("cache_hit").default(0),
|
|
35409
|
+
// 0 = false, 1 = true (SQLite-compatible)
|
|
35410
|
+
// Performance
|
|
35411
|
+
latencyMs: integer("latency_ms").notNull(),
|
|
35412
|
+
status: varchar("status", { length: 20 }).notNull(),
|
|
35413
|
+
errorMessage: text("error_message"),
|
|
35414
|
+
// Streaming metrics (null for non-streaming calls)
|
|
35415
|
+
timeToFirstTokenMs: integer("time_to_first_token_ms"),
|
|
35416
|
+
streamDurationMs: integer("stream_duration_ms"),
|
|
35417
|
+
// Model version and metadata
|
|
35418
|
+
modelVersion: varchar("model_version", { length: 100 }),
|
|
35419
|
+
metadata: jsonb("metadata").$type()
|
|
35420
|
+
},
|
|
35421
|
+
(table) => ({
|
|
35422
|
+
creatorIdx: index("idx_llm_interactions_creator").on(table.creatorId, table.createdAt),
|
|
35423
|
+
operationIdx: index("idx_llm_interactions_operation").on(table.operationType, table.createdAt),
|
|
35424
|
+
correlationIdx: index("idx_llm_interactions_correlation").on(table.correlationId),
|
|
35425
|
+
providerIdx: index("idx_llm_interactions_provider").on(table.provider),
|
|
35426
|
+
variantIdx: index("idx_llm_interactions_variant").on(table.variantId),
|
|
35427
|
+
creatorVariantDateIdx: index("idx_llm_interactions_creator_variant_date").on(
|
|
35428
|
+
table.creatorId,
|
|
35429
|
+
table.variantId,
|
|
35430
|
+
table.createdAt
|
|
35431
|
+
)
|
|
35432
|
+
})
|
|
35433
|
+
);
|
|
35434
|
+
llmUsageDaily = pgTable(
|
|
35435
|
+
"llm_usage_daily",
|
|
35436
|
+
{
|
|
35437
|
+
date: timestamp("date", { mode: "date" }).notNull(),
|
|
35438
|
+
operationType: varchar("operation_type", { length: 50 }).notNull(),
|
|
35439
|
+
creatorId: uuid("creator_id").notNull(),
|
|
35440
|
+
// No FK — sentinel UUID '00000000-...' used for system-level aggregation
|
|
35441
|
+
// Aggregated metrics
|
|
35442
|
+
totalRequests: integer("total_requests").notNull().default(0),
|
|
35443
|
+
totalPromptTokens: integer("total_prompt_tokens").notNull().default(0),
|
|
35444
|
+
totalResponseTokens: integer("total_response_tokens").notNull().default(0),
|
|
35445
|
+
totalCostUsd: decimal("total_cost_usd", { precision: 12, scale: 4 }).notNull().default("0"),
|
|
35446
|
+
totalRevenueUsd: decimal("total_revenue_usd", { precision: 12, scale: 4 }).notNull().default("0"),
|
|
35447
|
+
avgLatencyMs: integer("avg_latency_ms"),
|
|
35448
|
+
errorCount: integer("error_count").notNull().default(0),
|
|
35449
|
+
// Cache aggregated metrics
|
|
35450
|
+
totalCacheCreationTokens: integer("total_cache_creation_tokens").notNull().default(0),
|
|
35451
|
+
totalCacheReadTokens: integer("total_cache_read_tokens").notNull().default(0),
|
|
35452
|
+
totalCacheHits: integer("total_cache_hits").notNull().default(0)
|
|
35453
|
+
},
|
|
35454
|
+
(table) => ({
|
|
35455
|
+
pk: primaryKey({ columns: [table.date, table.operationType, table.creatorId] }),
|
|
35456
|
+
dateIdx: index("idx_llm_usage_daily_date").on(table.date),
|
|
35457
|
+
creatorIdx: index("idx_llm_usage_daily_creator").on(table.creatorId, table.date)
|
|
35458
|
+
})
|
|
35459
|
+
);
|
|
35398
35460
|
}
|
|
35399
35461
|
});
|
|
35400
35462
|
|
|
@@ -36958,7 +37020,12 @@ var init_video_intros = __esm({
|
|
|
36958
37020
|
"minimal-dark",
|
|
36959
37021
|
"gradient-bold",
|
|
36960
37022
|
"corporate-clean",
|
|
36961
|
-
"warm-organic"
|
|
37023
|
+
"warm-organic",
|
|
37024
|
+
"neon-tech",
|
|
37025
|
+
"playful-bright",
|
|
37026
|
+
"culinary-warm",
|
|
37027
|
+
"academic-serif",
|
|
37028
|
+
"music-rhythm"
|
|
36962
37029
|
]);
|
|
36963
37030
|
renderJobStatusEnum = pgEnum("render_job_status", [
|
|
36964
37031
|
"queued",
|
|
@@ -36984,6 +37051,8 @@ var init_video_intros = __esm({
|
|
|
36984
37051
|
durationSeconds: integer("duration_seconds"),
|
|
36985
37052
|
metadata: jsonb("metadata"),
|
|
36986
37053
|
sceneConfig: jsonb("scene_config").$type(),
|
|
37054
|
+
generationHistory: jsonb("generation_history").default([]).$type(),
|
|
37055
|
+
themeOverrides: jsonb("theme_overrides").$type(),
|
|
36987
37056
|
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
|
|
36988
37057
|
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull()
|
|
36989
37058
|
},
|
|
@@ -38217,7 +38286,6 @@ __export(schema_exports, {
|
|
|
38217
38286
|
creditSubscriptionStatusEnum: () => creditSubscriptionStatusEnum,
|
|
38218
38287
|
creditSubscriptions: () => creditSubscriptions,
|
|
38219
38288
|
creditTransactions: () => creditTransactions2,
|
|
38220
|
-
creditTransactionsRelations: () => creditTransactionsRelations2,
|
|
38221
38289
|
creditWalletTransactionTypeEnum: () => creditWalletTransactionTypeEnum,
|
|
38222
38290
|
creditWalletTransactions: () => creditWalletTransactions,
|
|
38223
38291
|
creditWallets: () => creditWallets,
|
|
@@ -38298,7 +38366,6 @@ __export(schema_exports, {
|
|
|
38298
38366
|
marketingContentTypeEnum: () => marketingContentTypeEnum,
|
|
38299
38367
|
matrixModules: () => matrixModules,
|
|
38300
38368
|
matrixStatusEnum: () => matrixStatusEnum,
|
|
38301
|
-
matrixTranslations: () => matrixTranslations,
|
|
38302
38369
|
mcpSessions: () => mcpSessions2,
|
|
38303
38370
|
mcpSessionsRelations: () => mcpSessionsRelations2,
|
|
38304
38371
|
mediaAssetDomainEnum: () => mediaAssetDomainEnum,
|
|
@@ -38509,8 +38576,6 @@ __export(schema_exports, {
|
|
|
38509
38576
|
transactionsRelations: () => transactionsRelations2,
|
|
38510
38577
|
transferStatusEnum: () => transferStatusEnum,
|
|
38511
38578
|
transferTypeEnum: () => transferTypeEnum,
|
|
38512
|
-
translationEntityTypeEnum: () => translationEntityTypeEnum,
|
|
38513
|
-
translationStatusEnum: () => translationStatusEnum,
|
|
38514
38579
|
tutorContentIssues: () => tutorContentIssues,
|
|
38515
38580
|
tutorContentIssuesRelations: () => tutorContentIssuesRelations,
|
|
38516
38581
|
tutorEvaluations: () => tutorEvaluations,
|
|
@@ -38524,7 +38589,6 @@ __export(schema_exports, {
|
|
|
38524
38589
|
userChallengeScores: () => userChallengeScores,
|
|
38525
38590
|
userChallengeScoresRelations: () => userChallengeScoresRelations,
|
|
38526
38591
|
userCredits: () => userCredits2,
|
|
38527
|
-
userCreditsRelations: () => userCreditsRelations2,
|
|
38528
38592
|
userFollows: () => userFollows2,
|
|
38529
38593
|
userFollowsRelations: () => userFollowsRelations2,
|
|
38530
38594
|
userPathEnrollments: () => userPathEnrollments,
|
|
@@ -38561,7 +38625,7 @@ __export(schema_exports, {
|
|
|
38561
38625
|
webhookEvents: () => webhookEvents2,
|
|
38562
38626
|
wishlists: () => wishlists
|
|
38563
38627
|
});
|
|
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,
|
|
38628
|
+
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
38629
|
var init_schema3 = __esm({
|
|
38566
38630
|
"../../packages/database/src/schema/index.ts"() {
|
|
38567
38631
|
"use strict";
|
|
@@ -38621,7 +38685,6 @@ var init_schema3 = __esm({
|
|
|
38621
38685
|
init_generation_state();
|
|
38622
38686
|
init_security_audit_log();
|
|
38623
38687
|
init_marketing();
|
|
38624
|
-
init_user_credits();
|
|
38625
38688
|
init_usage_quotas();
|
|
38626
38689
|
init_brainstormings();
|
|
38627
38690
|
init_ideas();
|
|
@@ -38721,7 +38784,6 @@ var init_schema3 = __esm({
|
|
|
38721
38784
|
init_study_module_sessions();
|
|
38722
38785
|
init_generation_state();
|
|
38723
38786
|
init_marketing();
|
|
38724
|
-
init_user_credits();
|
|
38725
38787
|
init_brainstormings();
|
|
38726
38788
|
init_ideas();
|
|
38727
38789
|
init_course_publications();
|
|
@@ -38835,9 +38897,6 @@ var init_schema3 = __esm({
|
|
|
38835
38897
|
// Users this user follows
|
|
38836
38898
|
// Story 21.1: Spark chat sessions
|
|
38837
38899
|
sparkChatSessions: many(sparkChatSessions2),
|
|
38838
|
-
// Creator flow: Token credits
|
|
38839
|
-
credits: one(userCredits2),
|
|
38840
|
-
creditTransactions: many(creditTransactions2),
|
|
38841
38900
|
// Creator flow: New brainstormings
|
|
38842
38901
|
brainstormings: many(brainstormings),
|
|
38843
38902
|
// Creator flow: Ideas notepad
|
|
@@ -39586,18 +39645,6 @@ var init_schema3 = __esm({
|
|
|
39586
39645
|
references: [users.id]
|
|
39587
39646
|
})
|
|
39588
39647
|
}));
|
|
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
39648
|
brainstormingsRelations = relations(brainstormings, ({ one }) => ({
|
|
39602
39649
|
creator: one(users, {
|
|
39603
39650
|
fields: [brainstormings.creatorId],
|
|
@@ -40024,7 +40071,6 @@ var init_src4 = __esm({
|
|
|
40024
40071
|
init_platform_settings();
|
|
40025
40072
|
init_marketing();
|
|
40026
40073
|
init_security_audit_log();
|
|
40027
|
-
init_user_credits();
|
|
40028
40074
|
init_gamification();
|
|
40029
40075
|
init_creator_portfolio_courses();
|
|
40030
40076
|
init_portfolio_views();
|
|
@@ -40144,6 +40190,15 @@ var init_next_lesson_full = __esm({
|
|
|
40144
40190
|
}
|
|
40145
40191
|
});
|
|
40146
40192
|
|
|
40193
|
+
// ../../packages/tostudy-core/src/memory/student-memory.ts
|
|
40194
|
+
var init_student_memory = __esm({
|
|
40195
|
+
"../../packages/tostudy-core/src/memory/student-memory.ts"() {
|
|
40196
|
+
"use strict";
|
|
40197
|
+
init_src4();
|
|
40198
|
+
init_src();
|
|
40199
|
+
}
|
|
40200
|
+
});
|
|
40201
|
+
|
|
40147
40202
|
// ../../packages/tostudy-core/src/learning/validate-solution-full.ts
|
|
40148
40203
|
var init_validate_solution_full = __esm({
|
|
40149
40204
|
"../../packages/tostudy-core/src/learning/validate-solution-full.ts"() {
|
|
@@ -40153,6 +40208,7 @@ var init_validate_solution_full = __esm({
|
|
|
40153
40208
|
init_exercise_types();
|
|
40154
40209
|
init_study_state_sync();
|
|
40155
40210
|
init_sync_enrollment_progress();
|
|
40211
|
+
init_student_memory();
|
|
40156
40212
|
}
|
|
40157
40213
|
});
|
|
40158
40214
|
|
|
@@ -40274,7 +40330,7 @@ async function runStart(opts, deps = defaultDeps2) {
|
|
|
40274
40330
|
deps.error(msg);
|
|
40275
40331
|
}
|
|
40276
40332
|
}
|
|
40277
|
-
var
|
|
40333
|
+
var logger6, defaultDeps2, StartBlockedError, startCommand;
|
|
40278
40334
|
var init_start = __esm({
|
|
40279
40335
|
"src/commands/start.ts"() {
|
|
40280
40336
|
"use strict";
|
|
@@ -40284,7 +40340,7 @@ var init_start = __esm({
|
|
|
40284
40340
|
init_session();
|
|
40285
40341
|
init_status();
|
|
40286
40342
|
init_formatter();
|
|
40287
|
-
|
|
40343
|
+
logger6 = createLogger("cli:start");
|
|
40288
40344
|
defaultDeps2 = {
|
|
40289
40345
|
requireSession,
|
|
40290
40346
|
requireActiveCourse,
|
|
@@ -40297,7 +40353,7 @@ var init_start = __esm({
|
|
|
40297
40353
|
output,
|
|
40298
40354
|
error,
|
|
40299
40355
|
stderrWrite: (message) => process.stderr.write(message),
|
|
40300
|
-
logger:
|
|
40356
|
+
logger: logger6
|
|
40301
40357
|
};
|
|
40302
40358
|
StartBlockedError = class extends Error {
|
|
40303
40359
|
};
|
|
@@ -40309,7 +40365,7 @@ var init_start = __esm({
|
|
|
40309
40365
|
|
|
40310
40366
|
// src/commands/start-next.ts
|
|
40311
40367
|
import { Command as Command9 } from "commander";
|
|
40312
|
-
var
|
|
40368
|
+
var logger7, startNextCommand;
|
|
40313
40369
|
var init_start_next = __esm({
|
|
40314
40370
|
"src/commands/start-next.ts"() {
|
|
40315
40371
|
"use strict";
|
|
@@ -40318,7 +40374,7 @@ var init_start_next = __esm({
|
|
|
40318
40374
|
init_http2();
|
|
40319
40375
|
init_session();
|
|
40320
40376
|
init_formatter();
|
|
40321
|
-
|
|
40377
|
+
logger7 = createLogger("cli:start-next");
|
|
40322
40378
|
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
40379
|
try {
|
|
40324
40380
|
const session = await requireSession();
|
|
@@ -40326,7 +40382,7 @@ var init_start_next = __esm({
|
|
|
40326
40382
|
const driftWarning = await checkCourseDrift();
|
|
40327
40383
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
40328
40384
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
40329
|
-
const deps = { data, logger:
|
|
40385
|
+
const deps = { data, logger: logger7 };
|
|
40330
40386
|
const moduleData = await startNextModule({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
40331
40387
|
await setActiveCourse({ ...activeCourse, currentLessonId: moduleData.firstLesson.id });
|
|
40332
40388
|
if (opts.json) {
|
|
@@ -40349,7 +40405,7 @@ var init_start_next = __esm({
|
|
|
40349
40405
|
|
|
40350
40406
|
// src/commands/next.ts
|
|
40351
40407
|
import { Command as Command10 } from "commander";
|
|
40352
|
-
var
|
|
40408
|
+
var logger8, nextCommand;
|
|
40353
40409
|
var init_next = __esm({
|
|
40354
40410
|
"src/commands/next.ts"() {
|
|
40355
40411
|
"use strict";
|
|
@@ -40358,7 +40414,7 @@ var init_next = __esm({
|
|
|
40358
40414
|
init_http2();
|
|
40359
40415
|
init_session();
|
|
40360
40416
|
init_formatter();
|
|
40361
|
-
|
|
40417
|
+
logger8 = createLogger("cli:next");
|
|
40362
40418
|
nextCommand = new Command10("next").description("Advance to the next lesson in the active course").option("--json", "Output structured JSON").action(async (opts) => {
|
|
40363
40419
|
try {
|
|
40364
40420
|
const session = await requireSession();
|
|
@@ -40366,7 +40422,7 @@ var init_next = __esm({
|
|
|
40366
40422
|
const driftWarning = await checkCourseDrift();
|
|
40367
40423
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
40368
40424
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
40369
|
-
const deps = { data, logger:
|
|
40425
|
+
const deps = { data, logger: logger8 };
|
|
40370
40426
|
const lessonData = await nextLesson(
|
|
40371
40427
|
{ enrollmentId: activeCourse.enrollmentId, userConfirmation: "cli-next" },
|
|
40372
40428
|
deps
|
|
@@ -40447,7 +40503,7 @@ function formatLessonContent(data) {
|
|
|
40447
40503
|
}
|
|
40448
40504
|
return lines.join("\n");
|
|
40449
40505
|
}
|
|
40450
|
-
var
|
|
40506
|
+
var logger9, lessonCommand;
|
|
40451
40507
|
var init_lesson = __esm({
|
|
40452
40508
|
"src/commands/lesson.ts"() {
|
|
40453
40509
|
"use strict";
|
|
@@ -40457,7 +40513,7 @@ var init_lesson = __esm({
|
|
|
40457
40513
|
init_session();
|
|
40458
40514
|
init_formatter();
|
|
40459
40515
|
init_resolve();
|
|
40460
|
-
|
|
40516
|
+
logger9 = createLogger("cli:lesson");
|
|
40461
40517
|
lessonCommand = new Command11("lesson").description("Show the content of the current lesson").option("--json", "Output structured JSON").action(async (opts) => {
|
|
40462
40518
|
try {
|
|
40463
40519
|
const session = await requireSession();
|
|
@@ -40465,7 +40521,7 @@ var init_lesson = __esm({
|
|
|
40465
40521
|
const driftWarning = await checkCourseDrift();
|
|
40466
40522
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
40467
40523
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
40468
|
-
const deps = { data, logger:
|
|
40524
|
+
const deps = { data, logger: logger9 };
|
|
40469
40525
|
const lessonId = activeCourse.currentLessonId;
|
|
40470
40526
|
if (!lessonId) {
|
|
40471
40527
|
error("Nenhuma li\xE7\xE3o ativa encontrada. Rode: tostudy start ou tostudy next");
|
|
@@ -40494,7 +40550,7 @@ var init_lesson = __esm({
|
|
|
40494
40550
|
|
|
40495
40551
|
// src/commands/hint.ts
|
|
40496
40552
|
import { Command as Command12 } from "commander";
|
|
40497
|
-
var
|
|
40553
|
+
var logger10, hintCommand;
|
|
40498
40554
|
var init_hint = __esm({
|
|
40499
40555
|
"src/commands/hint.ts"() {
|
|
40500
40556
|
"use strict";
|
|
@@ -40503,7 +40559,7 @@ var init_hint = __esm({
|
|
|
40503
40559
|
init_http2();
|
|
40504
40560
|
init_session();
|
|
40505
40561
|
init_formatter();
|
|
40506
|
-
|
|
40562
|
+
logger10 = createLogger("cli:hint");
|
|
40507
40563
|
hintCommand = new Command12("hint").description("Get a progressive hint for the current exercise").option("--json", "Output structured JSON").action(async (opts) => {
|
|
40508
40564
|
try {
|
|
40509
40565
|
const session = await requireSession();
|
|
@@ -40511,7 +40567,7 @@ var init_hint = __esm({
|
|
|
40511
40567
|
const driftWarning = await checkCourseDrift();
|
|
40512
40568
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
40513
40569
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
40514
|
-
const deps = { data, logger:
|
|
40570
|
+
const deps = { data, logger: logger10 };
|
|
40515
40571
|
const hint = await getHint(
|
|
40516
40572
|
{ userId: session.userId, enrollmentId: activeCourse.enrollmentId },
|
|
40517
40573
|
deps
|
|
@@ -40802,7 +40858,7 @@ var init_init_template = __esm({
|
|
|
40802
40858
|
import fs8 from "node:fs";
|
|
40803
40859
|
import path7 from "node:path";
|
|
40804
40860
|
import { Command as Command13 } from "commander";
|
|
40805
|
-
var
|
|
40861
|
+
var logger11, validateCommand;
|
|
40806
40862
|
var init_validate = __esm({
|
|
40807
40863
|
"src/commands/validate.ts"() {
|
|
40808
40864
|
"use strict";
|
|
@@ -40812,7 +40868,7 @@ var init_validate = __esm({
|
|
|
40812
40868
|
init_session();
|
|
40813
40869
|
init_formatter();
|
|
40814
40870
|
init_init_template();
|
|
40815
|
-
|
|
40871
|
+
logger11 = createLogger("cli:validate");
|
|
40816
40872
|
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
40873
|
try {
|
|
40818
40874
|
const session = await requireSession();
|
|
@@ -40871,7 +40927,7 @@ var init_validate = __esm({
|
|
|
40871
40927
|
}
|
|
40872
40928
|
}
|
|
40873
40929
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
40874
|
-
const deps = { data, logger:
|
|
40930
|
+
const deps = { data, logger: logger11 };
|
|
40875
40931
|
const result = await validateSolution(
|
|
40876
40932
|
{
|
|
40877
40933
|
lessonId,
|
|
@@ -41217,6 +41273,23 @@ Rode \`tostudy select <n\xFAmero>\` para ativar um curso.`,
|
|
|
41217
41273
|
source: "cli"
|
|
41218
41274
|
});
|
|
41219
41275
|
await deps.saveCourseLearnerProfile(activeCourse, learnerProfile, artifacts);
|
|
41276
|
+
try {
|
|
41277
|
+
generateInstructionFiles(
|
|
41278
|
+
{
|
|
41279
|
+
courseTitle: matchedCourse.title,
|
|
41280
|
+
courseId: activeCourse.courseId,
|
|
41281
|
+
progress: progressData?.coursePercent ?? matchedCourse.progress ?? 0,
|
|
41282
|
+
moduleCount: progressData?.currentModule?.totalModules ?? 0,
|
|
41283
|
+
lessonCount: progressData?.currentLesson?.totalLessons ?? 0
|
|
41284
|
+
},
|
|
41285
|
+
learnerProfile
|
|
41286
|
+
);
|
|
41287
|
+
deps.logger.info("Instruction files enriched with learner profile");
|
|
41288
|
+
} catch (err) {
|
|
41289
|
+
deps.logger.warn("Failed to update instruction files", {
|
|
41290
|
+
error: err instanceof Error ? err.message : String(err)
|
|
41291
|
+
});
|
|
41292
|
+
}
|
|
41220
41293
|
try {
|
|
41221
41294
|
await deps.setLastInitCourseId(activeCourse.courseId);
|
|
41222
41295
|
} catch (err) {
|
|
@@ -41225,7 +41298,7 @@ Rode \`tostudy select <n\xFAmero>\` para ativar um curso.`,
|
|
|
41225
41298
|
deps.output(artifacts.tutorInstructions, { json: false });
|
|
41226
41299
|
deps.output(artifacts.learnerBrief, { json: false });
|
|
41227
41300
|
}
|
|
41228
|
-
var
|
|
41301
|
+
var logger12, defaultDeps3, initCommand;
|
|
41229
41302
|
var init_init = __esm({
|
|
41230
41303
|
"src/commands/init.ts"() {
|
|
41231
41304
|
"use strict";
|
|
@@ -41237,7 +41310,8 @@ var init_init = __esm({
|
|
|
41237
41310
|
init_init_template();
|
|
41238
41311
|
init_learner_context();
|
|
41239
41312
|
init_api2();
|
|
41240
|
-
|
|
41313
|
+
init_instruction_files();
|
|
41314
|
+
logger12 = createLogger("cli:init");
|
|
41241
41315
|
defaultDeps3 = {
|
|
41242
41316
|
getSession,
|
|
41243
41317
|
getActiveCourse,
|
|
@@ -41251,7 +41325,7 @@ var init_init = __esm({
|
|
|
41251
41325
|
saveCourseLearnerProfile,
|
|
41252
41326
|
buildInitArtifacts,
|
|
41253
41327
|
output,
|
|
41254
|
-
logger:
|
|
41328
|
+
logger: logger12,
|
|
41255
41329
|
createHttpProvider
|
|
41256
41330
|
};
|
|
41257
41331
|
initCommand = new Command15("init").description("Generate tutor instructions and learner brief for the active course").action(async () => {
|
|
@@ -41571,14 +41645,14 @@ import { Command as Command16 } from "commander";
|
|
|
41571
41645
|
import path10 from "node:path";
|
|
41572
41646
|
import os7 from "node:os";
|
|
41573
41647
|
import fs11 from "node:fs/promises";
|
|
41574
|
-
var
|
|
41648
|
+
var logger13, workspaceCommand;
|
|
41575
41649
|
var init_workspace2 = __esm({
|
|
41576
41650
|
"src/commands/workspace.ts"() {
|
|
41577
41651
|
"use strict";
|
|
41578
41652
|
init_src();
|
|
41579
41653
|
init_workspace();
|
|
41580
41654
|
init_session();
|
|
41581
|
-
|
|
41655
|
+
logger13 = createLogger("cli:workspace");
|
|
41582
41656
|
workspaceCommand = new Command16("workspace").description(
|
|
41583
41657
|
"Gerenciar workspace de estudo local"
|
|
41584
41658
|
);
|
|
@@ -41609,7 +41683,7 @@ Pr\xF3ximo passo: tostudy export
|
|
|
41609
41683
|
);
|
|
41610
41684
|
}
|
|
41611
41685
|
} catch (err) {
|
|
41612
|
-
|
|
41686
|
+
logger13.error("workspace setup failed", { error: err });
|
|
41613
41687
|
process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
|
|
41614
41688
|
`);
|
|
41615
41689
|
process.exit(1);
|
|
@@ -41711,7 +41785,7 @@ Pr\xF3ximo passo: tostudy export
|
|
|
41711
41785
|
import { Command as Command17 } from "commander";
|
|
41712
41786
|
import path11 from "node:path";
|
|
41713
41787
|
import os8 from "node:os";
|
|
41714
|
-
var
|
|
41788
|
+
var logger14, exportCommand;
|
|
41715
41789
|
var init_export = __esm({
|
|
41716
41790
|
"src/commands/export.ts"() {
|
|
41717
41791
|
"use strict";
|
|
@@ -41720,7 +41794,7 @@ var init_export = __esm({
|
|
|
41720
41794
|
init_http2();
|
|
41721
41795
|
init_session();
|
|
41722
41796
|
init_resolve();
|
|
41723
|
-
|
|
41797
|
+
logger14 = createLogger("cli:export");
|
|
41724
41798
|
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
41799
|
try {
|
|
41726
41800
|
const session = await requireSession();
|
|
@@ -41765,7 +41839,7 @@ ${result.files.map((f) => ` \u{1F4C4} ${f}`).join("\n")}
|
|
|
41765
41839
|
);
|
|
41766
41840
|
}
|
|
41767
41841
|
} catch (err) {
|
|
41768
|
-
|
|
41842
|
+
logger14.error("export failed", { error: err });
|
|
41769
41843
|
process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
|
|
41770
41844
|
`);
|
|
41771
41845
|
process.exit(1);
|
|
@@ -41790,13 +41864,13 @@ async function findWorkspacePath(courseTitle, basePath) {
|
|
|
41790
41864
|
return null;
|
|
41791
41865
|
}
|
|
41792
41866
|
}
|
|
41793
|
-
var
|
|
41867
|
+
var logger15, openCommand;
|
|
41794
41868
|
var init_open = __esm({
|
|
41795
41869
|
"src/commands/open.ts"() {
|
|
41796
41870
|
"use strict";
|
|
41797
41871
|
init_src();
|
|
41798
41872
|
init_session();
|
|
41799
|
-
|
|
41873
|
+
logger15 = createLogger("cli:open");
|
|
41800
41874
|
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
41875
|
try {
|
|
41802
41876
|
const activeCourse = await requireActiveCourse();
|
|
@@ -41810,7 +41884,7 @@ var init_open = __esm({
|
|
|
41810
41884
|
const editor = process.env["EDITOR"] ?? "code";
|
|
41811
41885
|
execFile3(editor, [workspacePath], (err) => {
|
|
41812
41886
|
if (err) {
|
|
41813
|
-
|
|
41887
|
+
logger15.error("open failed", { editor, workspacePath });
|
|
41814
41888
|
process.stderr.write(`\u274C Falha ao abrir: ${err.message}
|
|
41815
41889
|
`);
|
|
41816
41890
|
process.exit(1);
|
|
@@ -41819,7 +41893,7 @@ var init_open = __esm({
|
|
|
41819
41893
|
`);
|
|
41820
41894
|
});
|
|
41821
41895
|
} catch (err) {
|
|
41822
|
-
|
|
41896
|
+
logger15.error("open command failed", { error: err });
|
|
41823
41897
|
process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
|
|
41824
41898
|
`);
|
|
41825
41899
|
process.exit(1);
|
|
@@ -41891,7 +41965,7 @@ import { Command as Command19 } from "commander";
|
|
|
41891
41965
|
import path14 from "node:path";
|
|
41892
41966
|
import os10 from "node:os";
|
|
41893
41967
|
import fs14 from "node:fs/promises";
|
|
41894
|
-
var
|
|
41968
|
+
var logger16, vaultCommand;
|
|
41895
41969
|
var init_vault2 = __esm({
|
|
41896
41970
|
"src/commands/vault.ts"() {
|
|
41897
41971
|
"use strict";
|
|
@@ -41900,7 +41974,7 @@ var init_vault2 = __esm({
|
|
|
41900
41974
|
init_courses();
|
|
41901
41975
|
init_http2();
|
|
41902
41976
|
init_session();
|
|
41903
|
-
|
|
41977
|
+
logger16 = createLogger("cli:vault");
|
|
41904
41978
|
vaultCommand = new Command19("vault").description("Gerenciar vault Obsidian do curso");
|
|
41905
41979
|
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
41980
|
try {
|
|
@@ -41934,7 +42008,7 @@ var init_vault2 = __esm({
|
|
|
41934
42008
|
activeCourse.courseId,
|
|
41935
42009
|
courseSlug2
|
|
41936
42010
|
);
|
|
41937
|
-
|
|
42011
|
+
logger16.info("Vault generated", {
|
|
41938
42012
|
courseId: activeCourse.courseId,
|
|
41939
42013
|
vaultPath: result.vaultPath,
|
|
41940
42014
|
filesWritten: result.filesWritten
|
|
@@ -41967,7 +42041,7 @@ Para visualizar:
|
|
|
41967
42041
|
);
|
|
41968
42042
|
}
|
|
41969
42043
|
} catch (err) {
|
|
41970
|
-
|
|
42044
|
+
logger16.error("vault init failed", { error: err });
|
|
41971
42045
|
process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
|
|
41972
42046
|
`);
|
|
41973
42047
|
process.exit(1);
|
|
@@ -41988,7 +42062,7 @@ Para visualizar:
|
|
|
41988
42062
|
process.exit(1);
|
|
41989
42063
|
}
|
|
41990
42064
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
41991
|
-
const deps = { data, logger:
|
|
42065
|
+
const deps = { data, logger: logger16 };
|
|
41992
42066
|
const progress3 = await getProgress({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
41993
42067
|
const markerPath = path14.join(vaultPath, ".ana-vault.json");
|
|
41994
42068
|
const markerRaw = await fs14.readFile(markerPath, "utf-8");
|
|
@@ -42042,7 +42116,7 @@ Para visualizar:
|
|
|
42042
42116
|
);
|
|
42043
42117
|
}
|
|
42044
42118
|
} catch (err) {
|
|
42045
|
-
|
|
42119
|
+
logger16.error("vault sync failed", { error: err });
|
|
42046
42120
|
process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
|
|
42047
42121
|
`);
|
|
42048
42122
|
process.exit(1);
|
|
@@ -42105,7 +42179,7 @@ var init_cli = __esm({
|
|
|
42105
42179
|
init_export();
|
|
42106
42180
|
init_open();
|
|
42107
42181
|
init_vault2();
|
|
42108
|
-
CLI_VERSION = "0.
|
|
42182
|
+
CLI_VERSION = true ? "0.7.1" : "0.7.1";
|
|
42109
42183
|
}
|
|
42110
42184
|
});
|
|
42111
42185
|
|