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