@tostudy-ai/cli 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../node_modules/picocolors/picocolors.js", "../src/cli.ts", "../src/commands/login.ts", "../src/auth/oauth-server.ts", "../src/auth/session.ts", "../src/output/formatter.ts", "../src/commands/logout.ts", "../src/commands/setup.ts", "../src/installer/node-detector.ts", "../src/installer/ide-detector.ts", "../src/commands/doctor.ts", "../src/commands/courses.ts", "../../../packages/logger/src/types.ts", "../../../packages/logger/src/context/async-context.ts", "../../../packages/logger/src/formatters/json.ts", "../../../packages/logger/src/formatters/pretty.ts", "../../../packages/logger/src/sanitize.ts", "../../../packages/logger/src/logger.base.ts", "../../../packages/logger/src/transports/console.ts", "../../../packages/logger/src/transports/file.ts", "../../../packages/logger/src/logger.ts", "../../../packages/logger/src/index.ts", "../../../packages/tostudy-core/src/courses/list-courses.ts", "../../../packages/tostudy-core/src/courses/select-course.ts", "../../../packages/tostudy-core/src/courses/get-progress.ts", "../../../packages/tostudy-core/src/adapters/http.ts", "../src/commands/select.ts", "../src/commands/progress.ts", "../src/commands/start.ts", "../../../packages/tostudy-core/src/lessons/next-lesson.ts", "../../../packages/tostudy-core/src/lessons/get-content.ts", "../../../packages/tostudy-core/src/lessons/get-hint.ts", "../../../packages/tostudy-core/src/lessons/start-module.ts", "../../../packages/tostudy-core/src/lessons/start-next-module.ts", "../src/commands/start-next.ts", "../src/commands/next.ts", "../src/commands/lesson.ts", "../src/commands/hint.ts", "../src/commands/validate.ts", "../../../packages/tostudy-core/src/exercises/validate-solution.ts", "../src/commands/menu.ts", "../src/cli-entry.ts"],
4
- "sourcesContent": ["let p = process || {}, argv = p.argv || [], env = p.env || {}\nlet isColorSupported =\n\t!(!!env.NO_COLOR || argv.includes(\"--no-color\")) &&\n\t(!!env.FORCE_COLOR || argv.includes(\"--color\") || p.platform === \"win32\" || ((p.stdout || {}).isTTY && env.TERM !== \"dumb\") || !!env.CI)\n\nlet formatter = (open, close, replace = open) =>\n\tinput => {\n\t\tlet string = \"\" + input, index = string.indexOf(close, open.length)\n\t\treturn ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close\n\t}\n\nlet replaceClose = (string, close, replace, index) => {\n\tlet result = \"\", cursor = 0\n\tdo {\n\t\tresult += string.substring(cursor, index) + replace\n\t\tcursor = index + close.length\n\t\tindex = string.indexOf(close, cursor)\n\t} while (~index)\n\treturn result + string.substring(cursor)\n}\n\nlet createColors = (enabled = isColorSupported) => {\n\tlet f = enabled ? formatter : () => String\n\treturn {\n\t\tisColorSupported: enabled,\n\t\treset: f(\"\\x1b[0m\", \"\\x1b[0m\"),\n\t\tbold: f(\"\\x1b[1m\", \"\\x1b[22m\", \"\\x1b[22m\\x1b[1m\"),\n\t\tdim: f(\"\\x1b[2m\", \"\\x1b[22m\", \"\\x1b[22m\\x1b[2m\"),\n\t\titalic: f(\"\\x1b[3m\", \"\\x1b[23m\"),\n\t\tunderline: f(\"\\x1b[4m\", \"\\x1b[24m\"),\n\t\tinverse: f(\"\\x1b[7m\", \"\\x1b[27m\"),\n\t\thidden: f(\"\\x1b[8m\", \"\\x1b[28m\"),\n\t\tstrikethrough: f(\"\\x1b[9m\", \"\\x1b[29m\"),\n\n\t\tblack: f(\"\\x1b[30m\", \"\\x1b[39m\"),\n\t\tred: f(\"\\x1b[31m\", \"\\x1b[39m\"),\n\t\tgreen: f(\"\\x1b[32m\", \"\\x1b[39m\"),\n\t\tyellow: f(\"\\x1b[33m\", \"\\x1b[39m\"),\n\t\tblue: f(\"\\x1b[34m\", \"\\x1b[39m\"),\n\t\tmagenta: f(\"\\x1b[35m\", \"\\x1b[39m\"),\n\t\tcyan: f(\"\\x1b[36m\", \"\\x1b[39m\"),\n\t\twhite: f(\"\\x1b[37m\", \"\\x1b[39m\"),\n\t\tgray: f(\"\\x1b[90m\", \"\\x1b[39m\"),\n\n\t\tbgBlack: f(\"\\x1b[40m\", \"\\x1b[49m\"),\n\t\tbgRed: f(\"\\x1b[41m\", \"\\x1b[49m\"),\n\t\tbgGreen: f(\"\\x1b[42m\", \"\\x1b[49m\"),\n\t\tbgYellow: f(\"\\x1b[43m\", \"\\x1b[49m\"),\n\t\tbgBlue: f(\"\\x1b[44m\", \"\\x1b[49m\"),\n\t\tbgMagenta: f(\"\\x1b[45m\", \"\\x1b[49m\"),\n\t\tbgCyan: f(\"\\x1b[46m\", \"\\x1b[49m\"),\n\t\tbgWhite: f(\"\\x1b[47m\", \"\\x1b[49m\"),\n\n\t\tblackBright: f(\"\\x1b[90m\", \"\\x1b[39m\"),\n\t\tredBright: f(\"\\x1b[91m\", \"\\x1b[39m\"),\n\t\tgreenBright: f(\"\\x1b[92m\", \"\\x1b[39m\"),\n\t\tyellowBright: f(\"\\x1b[93m\", \"\\x1b[39m\"),\n\t\tblueBright: f(\"\\x1b[94m\", \"\\x1b[39m\"),\n\t\tmagentaBright: f(\"\\x1b[95m\", \"\\x1b[39m\"),\n\t\tcyanBright: f(\"\\x1b[96m\", \"\\x1b[39m\"),\n\t\twhiteBright: f(\"\\x1b[97m\", \"\\x1b[39m\"),\n\n\t\tbgBlackBright: f(\"\\x1b[100m\", \"\\x1b[49m\"),\n\t\tbgRedBright: f(\"\\x1b[101m\", \"\\x1b[49m\"),\n\t\tbgGreenBright: f(\"\\x1b[102m\", \"\\x1b[49m\"),\n\t\tbgYellowBright: f(\"\\x1b[103m\", \"\\x1b[49m\"),\n\t\tbgBlueBright: f(\"\\x1b[104m\", \"\\x1b[49m\"),\n\t\tbgMagentaBright: f(\"\\x1b[105m\", \"\\x1b[49m\"),\n\t\tbgCyanBright: f(\"\\x1b[106m\", \"\\x1b[49m\"),\n\t\tbgWhiteBright: f(\"\\x1b[107m\", \"\\x1b[49m\"),\n\t}\n}\n\nmodule.exports = createColors()\nmodule.exports.createColors = createColors\n", "import { Command } from \"commander\";\nimport { loginCommand } from \"./commands/login.js\";\nimport { logoutCommand } from \"./commands/logout.js\";\nimport { setupCommand } from \"./commands/setup.js\";\nimport { doctorCommand } from \"./commands/doctor.js\";\nimport { coursesCommand } from \"./commands/courses.js\";\nimport { selectCommand } from \"./commands/select.js\";\nimport { progressCommand } from \"./commands/progress.js\";\nimport { startCommand } from \"./commands/start.js\";\nimport { startNextCommand } from \"./commands/start-next.js\";\nimport { nextCommand } from \"./commands/next.js\";\nimport { lessonCommand } from \"./commands/lesson.js\";\nimport { hintCommand } from \"./commands/hint.js\";\nimport { validateCommand } from \"./commands/validate.js\";\nimport { menuCommand } from \"./commands/menu.js\";\n\nexport function createProgram(): Command {\n const program = new Command();\n\n program\n .name(\"tostudy\")\n .description(\"ToStudy CLI \u2014 study courses from the terminal\")\n .version(\"0.1.1\")\n .option(\"--json\", \"Output structured JSON (for LLM agents)\")\n .option(\"--verbose\", \"Enable debug output\")\n .option(\"--course <id>\", \"Override active course ID\");\n\n // Setup and diagnostic commands\n program.addCommand(setupCommand);\n program.addCommand(doctorCommand);\n\n // Auth commands\n program.addCommand(loginCommand);\n program.addCommand(logoutCommand);\n\n // Phase 1 study commands\n program.addCommand(coursesCommand);\n program.addCommand(selectCommand);\n program.addCommand(progressCommand);\n program.addCommand(startCommand);\n program.addCommand(startNextCommand);\n program.addCommand(nextCommand);\n program.addCommand(lessonCommand);\n program.addCommand(hintCommand);\n program.addCommand(validateCommand);\n program.addCommand(menuCommand);\n\n return program;\n}\n", "import { Command } from \"commander\";\nimport { execFile } from \"node:child_process\";\nimport { startCallbackServer } from \"../auth/oauth-server.js\";\nimport { saveSession } from \"../auth/session.js\";\nimport { error } from \"../output/formatter.js\";\n\nconst DEFAULT_API_URL = \"https://tostudy.ai\";\nconst PORT = 9876;\n\nexport const loginCommand = new Command(\"login\")\n .description(\"Autentica no ToStudy via browser\")\n .option(\"--manual\", \"Login manual (sem browser)\")\n .option(\"--api-url <url>\", \"API URL override\", DEFAULT_API_URL)\n .action(async (opts: { manual?: boolean; apiUrl: string }) => {\n const apiUrl = opts.apiUrl;\n\n if (opts.manual) {\n // Manual flow: print URL for user to open manually\n console.log(`\\n Acesse este endere\u00E7o no seu browser:`);\n console.log(` ${apiUrl}/api/cli/auth/authorize?port=${PORT}\\n`);\n console.log(\" Ap\u00F3s autorizar, o browser ser\u00E1 redirecionado e o login ser\u00E1 conclu\u00EDdo.\");\n console.log(\" Certifique-se de rodar este comando sem --manual para o fluxo autom\u00E1tico.\\n\");\n return;\n }\n\n console.log(\"\\n Abrindo browser para autentica\u00E7\u00E3o...\\n\");\n\n const serverPromise = startCallbackServer(PORT);\n\n // Open browser safely using execFile (not exec \u2014 prevents command injection)\n const authUrl = `${apiUrl}/api/cli/auth/authorize?port=${PORT}`;\n const openCmd = process.platform === \"darwin\" ? \"open\" : \"xdg-open\";\n execFile(openCmd, [authUrl], (err) => {\n if (err) {\n console.log(` N\u00E3o foi poss\u00EDvel abrir o browser automaticamente.`);\n console.log(` Abra manualmente: ${authUrl}\\n`);\n }\n });\n\n try {\n const { code } = await serverPromise;\n\n // Exchange code for JWT\n const res = await fetch(`${apiUrl}/api/cli/auth/exchange`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ code }),\n });\n\n if (!res.ok) {\n const body = (await res.json()) as { error?: string };\n error(body.error ?? \"Falha na autentica\u00E7\u00E3o\");\n }\n\n const { token, userId, userName, expiresAt } = (await res.json()) as {\n token: string;\n userId: string;\n userName: string;\n expiresAt: string;\n };\n\n await saveSession({ token, userId, userName, expiresAt, apiUrl });\n\n console.log(`\\n Logado como ${userName}\\n`);\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : \"Login falhou\";\n error(msg);\n }\n });\n", "import http from \"node:http\";\n\nexport function startCallbackServer(port: number): Promise<{ code: string }> {\n return new Promise((resolve, reject) => {\n const server = http.createServer((req, res) => {\n const url = new URL(req.url!, `http://localhost:${port}`);\n if (url.pathname === \"/callback\") {\n const code = url.searchParams.get(\"code\");\n if (code) {\n res.writeHead(200, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(\"<html><body><h1>Autenticado!</h1><p>Pode fechar esta aba.</p></body></html>\");\n server.close();\n resolve({ code });\n } else {\n res.writeHead(400);\n res.end(\"Missing code\");\n }\n } else {\n res.writeHead(404);\n res.end(\"Not found\");\n }\n });\n\n server.listen(port, () => {});\n server.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\") {\n reject(new Error(`Port ${port} est\u00E1 em uso. Tente novamente.`));\n } else {\n reject(err);\n }\n });\n\n // Timeout after 2 minutes\n setTimeout(() => {\n server.close();\n reject(new Error(\"Login timeout \u2014 nenhuma resposta em 2 minutos\"));\n }, 120_000);\n });\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\nexport interface CliSession {\n token: string;\n userId: string;\n userName: string;\n expiresAt: string;\n apiUrl: string;\n}\n\nexport interface ActiveCourse {\n courseId: string;\n courseTitle: string;\n enrollmentId: string;\n currentLessonId?: string;\n}\n\nfunction getConfigDir(override?: string): string {\n if (override) return override;\n if (process.platform === \"linux\" && process.env[\"XDG_CONFIG_HOME\"]) {\n return path.join(process.env[\"XDG_CONFIG_HOME\"], \"tostudy\");\n }\n return path.join(os.homedir(), \".tostudy\");\n}\n\nexport async function saveSession(session: CliSession, configDir?: string): Promise<void> {\n const dir = getConfigDir(configDir);\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(path.join(dir, \"config.json\"), JSON.stringify(session, null, 2), {\n mode: 0o600,\n });\n}\n\nexport async function getSession(configDir?: string): Promise<CliSession | null> {\n const dir = getConfigDir(configDir);\n const p = path.join(dir, \"config.json\");\n if (!fs.existsSync(p)) return null;\n return JSON.parse(fs.readFileSync(p, \"utf-8\")) as CliSession;\n}\n\nexport async function clearSession(configDir?: string): Promise<void> {\n const dir = getConfigDir(configDir);\n const p = path.join(dir, \"config.json\");\n if (fs.existsSync(p)) fs.unlinkSync(p);\n const ap = path.join(dir, \"active-course.json\");\n if (fs.existsSync(ap)) fs.unlinkSync(ap);\n}\n\nexport async function getActiveCourse(configDir?: string): Promise<ActiveCourse | null> {\n const dir = getConfigDir(configDir);\n const p = path.join(dir, \"active-course.json\");\n if (!fs.existsSync(p)) return null;\n return JSON.parse(fs.readFileSync(p, \"utf-8\")) as ActiveCourse;\n}\n\nexport async function setActiveCourse(course: ActiveCourse, configDir?: string): Promise<void> {\n const dir = getConfigDir(configDir);\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(path.join(dir, \"active-course.json\"), JSON.stringify(course, null, 2), {\n mode: 0o600,\n });\n}\n\nexport async function requireSession(configDir?: string): Promise<CliSession> {\n const session = await getSession(configDir);\n if (!session) {\n process.stderr.write(\"Erro: N\u00E3o autenticado. Rode: tostudy login\\n\");\n process.exit(2);\n }\n const expiresAt = new Date(session.expiresAt);\n if (expiresAt < new Date()) {\n process.stderr.write(\"Erro: Sess\u00E3o expirada. Rode: tostudy login\\n\");\n process.exit(2);\n }\n return session;\n}\n\nexport async function requireActiveCourse(configDir?: string): Promise<ActiveCourse> {\n const course = await getActiveCourse(configDir);\n if (!course) {\n process.stderr.write(\"Erro: Nenhum curso ativo. Rode: tostudy select <curso>\\n\");\n process.exit(3);\n }\n return course;\n}\n", "import type {\n CourseWithProgress,\n ProgressData,\n LessonData,\n ValidationResult,\n HintData,\n ModuleStartData,\n} from \"@repo/tostudy-core/types\";\n\n// ---------------------------------------------------------------------------\n// Core output helpers\n// ---------------------------------------------------------------------------\n\nexport function output(data: unknown, opts: { json?: boolean }): void {\n if (opts.json) {\n process.stdout.write(JSON.stringify(data, null, 2) + \"\\n\");\n } else if (typeof data === \"string\") {\n process.stdout.write(data + \"\\n\");\n } else {\n process.stdout.write(JSON.stringify(data, null, 2) + \"\\n\");\n }\n}\n\nexport function error(msg: string, code: number = 1): never {\n process.stderr.write(`Erro: ${msg}\\n`);\n process.exit(code);\n}\n\nexport function progressBar(percent: number, width: number = 20): string {\n const clamped = Math.max(0, Math.min(100, percent));\n const filled = Math.round((clamped / 100) * width);\n const empty = width - filled;\n return \"\u2588\".repeat(filled) + \"\u2591\".repeat(empty) + ` ${clamped}%`;\n}\n\n// ---------------------------------------------------------------------------\n// Human-readable formatters\n// ---------------------------------------------------------------------------\n\n/** Format a numbered list of enrolled courses with progress bars. */\nexport function formatCourseList(courses: CourseWithProgress[]): string {\n if (courses.length === 0) {\n return [\n \"Nenhum curso encontrado.\",\n \"\",\n \"\u2192 tostudy enroll <curso> para se matricular em um curso\",\n ].join(\"\\n\");\n }\n\n const lines: string[] = [\"Seus cursos:\", \"\"];\n courses.forEach((course, idx) => {\n const bar = progressBar(course.progress);\n lines.push(` ${idx + 1}. ${course.title}`);\n lines.push(` ${bar}`);\n lines.push(` Professor: ${course.creatorName}`);\n lines.push(\"\");\n });\n\n lines.push(\"\u2192 tostudy select <n\u00FAmero> para ativar um curso\");\n lines.push(\"\u2192 tostudy progress para ver seu progresso\");\n\n return lines.join(\"\\n\");\n}\n\n/** Format a full progress snapshot for the active course. */\nexport function formatProgress(data: ProgressData): string {\n const { currentModule, currentLesson } = data;\n const courseBar = progressBar(data.coursePercent);\n const moduleBar = progressBar(data.modulePercent);\n\n const lines: string[] = [\n \"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\",\n `M\u00F3dulo ${currentModule.order} de ${currentModule.totalModules}: ${currentModule.title}`,\n ` Curso: ${courseBar}`,\n ` M\u00F3dulo: ${moduleBar}`,\n \"\",\n `Li\u00E7\u00E3o atual (${currentLesson.order}/${currentLesson.totalLessons}): ${currentLesson.title}`,\n `Li\u00E7\u00F5es conclu\u00EDdas: ${data.completedLessons}`,\n `Tempo restante estimado: ~${data.estimatedMinutesRemaining} min`,\n \"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\",\n \"\",\n \"\u2192 tostudy next para avan\u00E7ar para a pr\u00F3xima li\u00E7\u00E3o\",\n \"\u2192 tostudy lesson para ver o conte\u00FAdo da li\u00E7\u00E3o atual\",\n ];\n\n return lines.join(\"\\n\");\n}\n\n/** Format lesson content returned after advancing. */\nexport function formatLesson(data: LessonData): string {\n const { lesson, wayfinding, progress } = data;\n const courseBar = progressBar(progress.coursePercent);\n const moduleBar = progressBar(progress.modulePercent);\n\n const lines: string[] = [\n `\u2501\u2501\u2501 M\u00F3dulo ${wayfinding.moduleOrder}/${wayfinding.totalModules} \u00B7 Li\u00E7\u00E3o ${wayfinding.lessonOrder}/${wayfinding.totalLessons} \u2501\u2501\u2501`,\n \"\",\n `\uD83D\uDCD6 ${lesson.title}`,\n ` M\u00F3dulo: ${lesson.moduleTitle} | Tipo: ${lesson.type}`,\n \"\",\n lesson.content,\n \"\",\n ` Curso: ${courseBar}`,\n ` M\u00F3dulo: ${moduleBar}`,\n ];\n\n if (lesson.acceptanceCriteria) {\n lines.push(\"\", \"Crit\u00E9rios de aceita\u00E7\u00E3o:\", lesson.acceptanceCriteria);\n }\n\n if (lesson.exerciseContent) {\n lines.push(\"\", \"\u2500\u2500\u2500 Exerc\u00EDcio \u2500\u2500\u2500\", lesson.exerciseContent);\n }\n\n lines.push(\n \"\",\n \"\u2192 tostudy validate <resposta> para validar sua solu\u00E7\u00E3o\",\n \"\u2192 tostudy hint para obter uma dica\",\n \"\u2192 tostudy next para avan\u00E7ar (ap\u00F3s completar)\"\n );\n\n return lines.join(\"\\n\");\n}\n\n/** Format a validation result with criteria checklist. */\nexport function formatValidation(data: ValidationResult): string {\n const statusIcon = data.passed ? \"\u2713\" : \"\u2717\";\n const statusLabel = data.passed ? \"APROVADO\" : \"REPROVADO\";\n const scoreStr = data.score !== null ? ` \u00B7 Pontua\u00E7\u00E3o: ${data.score}/100` : \"\";\n\n const lines: string[] = [`${statusIcon} Valida\u00E7\u00E3o: ${statusLabel}${scoreStr}`, \"\", \"Crit\u00E9rios:\"];\n\n data.criteria.forEach((c) => {\n const icon = c.met ? \" \u2713\" : \" \u2717\";\n lines.push(`${icon} ${c.criteria}`);\n if (c.comment) {\n lines.push(` ${c.comment}`);\n }\n });\n\n lines.push(\"\", `Feedback: ${data.feedback}`, \"\");\n\n if (data.passed) {\n lines.push(\"\u2192 tostudy next para avan\u00E7ar para a pr\u00F3xima li\u00E7\u00E3o\");\n } else {\n lines.push(\n \"\u2192 tostudy hint para obter uma dica\",\n \"\u2192 tostudy validate para tentar novamente\"\n );\n }\n\n return lines.join(\"\\n\");\n}\n\n/** Format a progressive hint response. */\nexport function formatHint(data: HintData): string {\n const levelLabel = data.levelLabel ?? `N\u00EDvel ${data.level}`;\n const lines: string[] = [\n `\uD83D\uDCA1 Dica (${levelLabel} \u00B7 ${data.level}/${data.maxLevel}):`,\n \"\",\n data.hint,\n \"\",\n ];\n\n if (data.level < data.maxLevel) {\n lines.push(`\u2192 tostudy hint para uma dica mais detalhada (n\u00EDvel ${data.level + 1})`);\n } else {\n lines.push(\"\u2192 tostudy validate para tentar sua solu\u00E7\u00E3o\");\n }\n\n return lines.join(\"\\n\");\n}\n\n/** Format module start data (first lesson of a new module). */\nexport function formatModuleStart(data: ModuleStartData): string {\n const { module: mod, firstLesson, wayfinding } = data;\n\n const lines: string[] = [\n `\u2501\u2501\u2501 M\u00F3dulo ${wayfinding.moduleOrder}/${wayfinding.totalModules} \u2501\u2501\u2501`,\n \"\",\n `\uD83D\uDDC2 ${mod.title}`,\n ];\n\n if (mod.description) {\n lines.push(\"\", mod.description);\n }\n\n if (mod.objectives && mod.objectives.length > 0) {\n lines.push(\"\", \"Objetivos:\");\n mod.objectives.forEach((obj) => lines.push(` \u2022 ${obj}`));\n }\n\n lines.push(\"\", \"\u2500\u2500\u2500 Primeira Li\u00E7\u00E3o \u2500\u2500\u2500\", \"\", `\uD83D\uDCD6 ${firstLesson.title}`, \"\", firstLesson.content);\n\n if (firstLesson.lessonIntroContent) {\n lines.push(\"\", firstLesson.lessonIntroContent);\n }\n\n if (firstLesson.exerciseContent) {\n lines.push(\"\", \"\u2500\u2500\u2500 Exerc\u00EDcio \u2500\u2500\u2500\", firstLesson.exerciseContent);\n }\n\n if (firstLesson.acceptanceCriteria) {\n lines.push(\"\", \"Crit\u00E9rios de aceita\u00E7\u00E3o:\", firstLesson.acceptanceCriteria);\n }\n\n lines.push(\n \"\",\n \"\u2192 tostudy validate <resposta> para validar sua solu\u00E7\u00E3o\",\n \"\u2192 tostudy hint para obter uma dica\"\n );\n\n return lines.join(\"\\n\");\n}\n", "import { Command } from \"commander\";\nimport { clearSession } from \"../auth/session.js\";\n\nexport const logoutCommand = new Command(\"logout\")\n .description(\"Remove token local\")\n .action(async () => {\n await clearSession();\n console.log(\"\\n Deslogado com sucesso.\\n\");\n });\n", "import { Command } from \"commander\";\nimport { detectNode } from \"../installer/node-detector.js\";\nimport { detectIDEs } from \"../installer/ide-detector.js\";\nimport { getSession } from \"../auth/session.js\";\n\nexport const setupCommand = new Command(\"setup\")\n .description(\"Configura ambiente para estudar\")\n .option(\"--quick\", \"Setup r\u00E1pido (sem wizard)\")\n .option(\"--ide <ide>\", \"Configura IDE espec\u00EDfica\")\n .action(async (_opts) => {\n console.log(\"\\n ToStudy Setup\\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\\n\");\n\n // Step 1: Check Node.js\n console.log(\" 1. Verificando Node.js...\");\n const node = detectNode();\n if (!node.installed) {\n console.log(\" \u2717 Node.js n\u00E3o encontrado\");\n console.log(\" \u2192 Instale via: https://nodejs.org/ ou `nvm install --lts`\\n\");\n process.exit(1);\n }\n if (!node.meetsMinimum) {\n console.log(` \u2717 Node.js ${node.version} \u00E9 muito antigo (m\u00EDnimo: v18)`);\n console.log(\" \u2192 Atualize via: `nvm install --lts`\\n\");\n process.exit(1);\n }\n console.log(` \u2713 Node.js ${node.version}\\n`);\n\n // Step 2: Check authentication\n console.log(\" 2. Verificando autentica\u00E7\u00E3o...\");\n let session = null;\n try {\n session = await getSession();\n } catch {\n /* session read failure treated as not logged in */\n }\n if (!session) {\n console.log(\" \u2717 N\u00E3o autenticado\");\n console.log(\" \u2192 Rode: tostudy login\\n\");\n process.exit(1);\n }\n console.log(` \u2713 Logado como ${session.userName}\\n`);\n\n // Step 3: Detect IDEs\n console.log(\" 3. Detectando IDEs...\");\n let ides: ReturnType<typeof detectIDEs> = [];\n try {\n ides = detectIDEs();\n } catch {\n /* IDE detection failure is non-fatal */\n }\n const detected = ides.filter((ide) => ide.detected);\n if (detected.length === 0) {\n console.log(\" \u25CB Nenhum IDE detectado\");\n console.log(\" \u2192 Use tostudy diretamente no terminal\\n\");\n } else {\n for (const ide of detected) {\n console.log(` \u2713 ${ide.name} detectado`);\n }\n console.log(\"\");\n }\n\n // Step 4: Summary\n console.log(\" Setup completo!\");\n console.log(\" \u2192 tostudy courses (ver cursos matriculados)\");\n console.log(\" \u2192 tostudy doctor (diagn\u00F3stico completo)\\n\");\n });\n", "import { execFileSync } from \"node:child_process\";\n\nexport interface NodeInfo {\n installed: boolean;\n version: string | null;\n meetsMinimum: boolean; // >= 18\n path: string | null;\n}\n\nexport function detectNode(): NodeInfo {\n try {\n const version = execFileSync(\"node\", [\"--version\"], {\n encoding: \"utf-8\",\n }).trim();\n let nodePath: string | null = null;\n try {\n const whichCmd = process.platform === \"win32\" ? \"where\" : \"which\";\n nodePath = execFileSync(whichCmd, [\"node\"], { encoding: \"utf-8\" }).trim();\n } catch {\n /* path detection optional */\n }\n const major = parseInt(version.replace(\"v\", \"\"), 10);\n return { installed: true, version, meetsMinimum: major >= 18, path: nodePath };\n } catch {\n return { installed: false, version: null, meetsMinimum: false, path: null };\n }\n}\n", "import { execFileSync } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\nexport interface DetectedIDE {\n name: string;\n id: string;\n detected: boolean;\n configPath: string | null;\n}\n\nfunction checkExists(p: string): boolean {\n return fs.existsSync(p);\n}\n\nexport function detectIDEs(): DetectedIDE[] {\n const home = os.homedir();\n\n const ides: DetectedIDE[] = [\n // Claude Code: detected by presence of 'claude' binary\n {\n name: \"Claude Code\",\n id: \"claude-code\",\n detected: false,\n configPath: path.join(home, \".mcp.json\"),\n },\n // Cursor: ~/.cursor directory\n {\n name: \"Cursor\",\n id: \"cursor\",\n detected: checkExists(path.join(home, \".cursor\")),\n configPath: path.join(home, \".cursor\", \"mcp.json\"),\n },\n // VS Code: ~/.vscode directory\n {\n name: \"VS Code\",\n id: \"vscode\",\n detected: checkExists(path.join(home, \".vscode\")),\n configPath: \".vscode/mcp.json\",\n },\n // Claude Desktop: platform-specific config dir\n {\n name: \"Claude Desktop\",\n id: \"desktop\",\n detected: checkExists(\n process.platform === \"darwin\"\n ? path.join(home, \"Library\", \"Application Support\", \"Claude\")\n : process.platform === \"win32\"\n ? path.join(process.env[\"APPDATA\"] ?? home, \"Claude\")\n : path.join(home, \".config\", \"claude\")\n ),\n configPath:\n process.platform === \"darwin\"\n ? path.join(\n home,\n \"Library\",\n \"Application Support\",\n \"Claude\",\n \"claude_desktop_config.json\"\n )\n : process.platform === \"win32\"\n ? path.join(process.env[\"APPDATA\"] ?? home, \"Claude\", \"claude_desktop_config.json\")\n : path.join(home, \".config\", \"claude\", \"claude_desktop_config.json\"),\n },\n // Windsurf: ~/.codeium/windsurf\n {\n name: \"Windsurf\",\n id: \"windsurf\",\n detected: checkExists(path.join(home, \".codeium\", \"windsurf\")),\n configPath: path.join(home, \".codeium\", \"windsurf\", \"mcp_config.json\"),\n },\n // OpenCode: ~/.opencode\n {\n name: \"OpenCode\",\n id: \"opencode\",\n detected: checkExists(path.join(home, \".opencode\")),\n configPath: path.join(home, \".opencode\", \"opencode.json\"),\n },\n // Manual (always available as fallback)\n {\n name: \"Manual\",\n id: \"manual\",\n detected: false,\n configPath: \"mcp.json\",\n },\n ];\n\n // Claude Code detection: check if 'claude' command is in PATH\n const claudeIde = ides.find((ide) => ide.id === \"claude-code\");\n if (claudeIde) {\n try {\n execFileSync(\"which\", [\"claude\"], { encoding: \"utf-8\" });\n claudeIde.detected = true;\n } catch {\n /* not found */\n }\n }\n\n return ides;\n}\n", "import { Command } from \"commander\";\nimport { detectNode } from \"../installer/node-detector.js\";\nimport { detectIDEs } from \"../installer/ide-detector.js\";\nimport { getSession } from \"../auth/session.js\";\nimport { output } from \"../output/formatter.js\";\n\nexport const doctorCommand = new Command(\"doctor\")\n .description(\"Diagn\u00F3stico do ambiente\")\n .option(\"--json\", \"Output JSON\")\n .option(\"--fix\", \"Auto-corrigir problemas (reservado para vers\u00F5es futuras)\")\n .action(async (opts) => {\n const checks: Record<string, unknown> = {};\n\n // Environment checks\n const node = detectNode();\n const envChecks: Record<string, unknown> = {\n os: { platform: process.platform, arch: process.arch },\n node: { ...node },\n pnpm: null as string | null,\n git: null as string | null,\n };\n\n try {\n const { execFileSync } = await import(\"node:child_process\");\n envChecks[\"pnpm\"] = execFileSync(\"pnpm\", [\"--version\"], { encoding: \"utf-8\" }).trim();\n } catch {\n envChecks[\"pnpm\"] = null;\n }\n\n try {\n const { execFileSync } = await import(\"node:child_process\");\n envChecks[\"git\"] = execFileSync(\"git\", [\"--version\"], { encoding: \"utf-8\" })\n .trim()\n .replace(\"git version \", \"\");\n } catch {\n envChecks[\"git\"] = null;\n }\n\n checks[\"environment\"] = envChecks;\n\n // Auth check\n let session = null;\n try {\n session = await getSession();\n } catch {\n /* session read failure is non-fatal */\n }\n checks[\"auth\"] = {\n loggedIn: !!session,\n userName: session?.userName ?? null,\n expiresAt: session?.expiresAt ?? null,\n };\n\n // Connectivity check\n try {\n const apiUrl = session?.apiUrl ?? \"https://tostudy.ai\";\n const start = Date.now();\n const res = await fetch(`${apiUrl}/api/mcp/heartbeat`, {\n method: \"POST\",\n headers: session ? { Authorization: `Bearer ${session.token}` } : {},\n signal: AbortSignal.timeout(5000),\n });\n checks[\"connectivity\"] = { ok: res.ok, latencyMs: Date.now() - start };\n } catch {\n checks[\"connectivity\"] = { ok: false, latencyMs: null };\n }\n\n // IDE detection\n let ides: ReturnType<typeof detectIDEs> = [];\n try {\n ides = detectIDEs();\n } catch {\n /* IDE detection failure is non-fatal */\n }\n checks[\"ides\"] = ides.filter((ide) => ide.detected);\n\n if (opts.json) {\n output(checks, { json: true });\n return;\n }\n\n // Human-readable output\n const pnpmVersion = envChecks[\"pnpm\"] as string | null;\n const gitVersion = envChecks[\"git\"] as string | null;\n const connectivity = checks[\"connectivity\"] as { ok: boolean; latencyMs: number | null };\n\n console.log(\"\\n Ambiente\");\n console.log(\n ` ${node.installed ? \"\u2713\" : \"\u2717\"} Node ${node.version ?? \"n\u00E3o encontrado\"}`\n );\n console.log(\n ` ${node.meetsMinimum ? \"\u2713\" : \"\u2717\"} Vers\u00E3o ${node.meetsMinimum ? \"OK (>= 18)\" : \"Desatualizado\"}`\n );\n console.log(` \u2713 OS ${process.platform} (${process.arch})`);\n console.log(` ${pnpmVersion ? \"\u2713\" : \"\u25CB\"} pnpm ${pnpmVersion ?? \"n\u00E3o encontrado\"}`);\n console.log(` ${gitVersion ? \"\u2713\" : \"\u25CB\"} git ${gitVersion ?? \"n\u00E3o encontrado\"}`);\n\n console.log(\"\\n Autentica\u00E7\u00E3o\");\n console.log(` ${session ? \"\u2713\" : \"\u2717\"} Token ${session ? \"v\u00E1lido\" : \"n\u00E3o logado\"}`);\n if (session) {\n console.log(` \u2713 Usu\u00E1rio ${session.userName}`);\n }\n\n console.log(\"\\n Conectividade\");\n console.log(\n ` ${connectivity.ok ? \"\u2713\" : \"\u2717\"} API ${connectivity.ok ? `OK (${connectivity.latencyMs}ms)` : \"indispon\u00EDvel\"}`\n );\n\n console.log(\"\\n LLM Clients\");\n for (const ide of ides) {\n console.log(\n ` ${ide.detected ? \"\u2713\" : \"\u25CB\"} ${ide.name.padEnd(14)} ${ide.detected ? \"detectado\" : \"n\u00E3o detectado\"}`\n );\n }\n console.log(\"\");\n });\n", "import { Command } from \"commander\";\nimport { createLogger } from \"@repo/logger\";\nimport { listCourses } from \"@repo/tostudy-core/courses\";\nimport { createHttpProvider } from \"@repo/tostudy-core/adapters/http\";\nimport { requireSession } from \"../auth/session.js\";\nimport { output, error, formatCourseList } from \"../output/formatter.js\";\n\nconst logger = createLogger(\"cli:courses\");\n\nexport const coursesCommand = new Command(\"courses\")\n .description(\"List your enrolled courses with progress\")\n .option(\"--json\", \"Output structured JSON\")\n .action(async (opts: { json?: boolean }) => {\n try {\n const session = await requireSession();\n const data = createHttpProvider(session.apiUrl, session.token);\n const deps = { data, logger };\n\n const courses = await listCourses({ userId: session.userId }, deps);\n\n if (opts.json) {\n output(courses, { json: true });\n } else {\n output(formatCourseList(courses), { json: false });\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n error(msg);\n }\n });\n", "// packages/logger/src/types.ts\n\n/**\n * Log levels with numeric priority.\n * Higher number = more severe.\n */\nexport const LOG_LEVELS = {\n trace: 0,\n debug: 1,\n info: 2,\n warn: 3,\n error: 4,\n fatal: 5,\n} as const\n\nexport type LogLevel = keyof typeof LOG_LEVELS\n\n/**\n * Error information for structured error logging.\n */\nexport interface ErrorInfo {\n name: string\n message: string\n stack?: string\n code?: string\n cause?: ErrorInfo\n}\n\n/**\n * Context that follows a request/operation through the system.\n */\nexport interface LogContext {\n // Tracing (required for requests)\n traceId?: string\n spanId?: string\n parentSpanId?: string\n requestId?: string\n\n // User context\n userId?: string\n sessionId?: string\n\n // Technical\n module?: string\n caller?: string\n duration?: number\n\n // Extensible\n [key: string]: unknown\n}\n\n/**\n * Complete log entry structure.\n */\nexport interface LogEntry {\n // Required fields\n timestamp: string\n level: LogLevel\n message: string\n service: string\n environment: string\n\n // Context (tracing, user, etc.)\n context: LogContext\n\n // Additional data\n data?: Record<string, unknown>\n\n // Error details (when level is error/fatal)\n error?: ErrorInfo\n}\n\n/**\n * Logger configuration options.\n */\nexport interface LoggerOptions {\n level?: LogLevel\n format?: 'json' | 'pretty'\n module?: string\n service?: string\n environment?: string\n /** Enable auto-sanitization of sensitive fields */\n sanitize?: boolean\n /** Additional sensitive field patterns to redact */\n sensitiveFields?: string[]\n /**\n * Include caller information (file:line:function) in log entries.\n * - true: Include caller for all log levels\n * - false: Never include caller\n * - 'errors': Include caller only for error/fatal levels (default)\n */\n includeCaller?: boolean | 'errors'\n}\n\nexport function isValidLevel(level: string): level is LogLevel {\n return level in LOG_LEVELS\n}\n", "// Node.js-only async context using AsyncLocalStorage\nimport { AsyncLocalStorage } from 'node:async_hooks'\nimport { randomBytes } from 'node:crypto'\nimport type { LogContext } from '../types'\n\nconst asyncLocalStorage = new AsyncLocalStorage<LogContext>()\n\nexport function withLogContext<T>(ctx: LogContext, fn: () => T): T {\n return asyncLocalStorage.run(ctx, fn)\n}\n\nexport function getLogContext(): LogContext | undefined {\n return asyncLocalStorage.getStore()\n}\n\nexport function generateTraceId(): string {\n return randomBytes(16).toString('hex')\n}\n\nexport function generateSpanId(): string {\n return randomBytes(8).toString('hex')\n}\n\n/**\n * Get the current correlation ID from context.\n * ADR-0002: Used for distributed tracing across services.\n *\n * @returns The correlation ID (traceId, requestId, or undefined)\n */\nexport function getCorrelationId(): string | undefined {\n const ctx = getLogContext()\n return ctx?.traceId ?? ctx?.requestId\n}\n", "// packages/logger/src/formatters/json.ts\nimport type { LogEntry } from '../types'\n\nexport function formatJson(entry: LogEntry): string {\n const { timestamp, level, message, service, environment, context, data, error } = entry\n\n const output: Record<string, unknown> = {\n timestamp,\n level,\n message,\n service,\n environment,\n ...context,\n ...data,\n }\n\n // Include error info at top level for easier querying\n if (error) {\n output.error = error\n }\n\n return JSON.stringify(output)\n}\n", "import pc from 'picocolors'\nimport type { LogEntry, LogLevel } from '../types'\n\nconst LEVEL_COLORS: Record<LogLevel, (s: string) => string> = {\n trace: pc.gray,\n debug: pc.cyan,\n info: pc.green,\n warn: pc.yellow,\n error: pc.red,\n fatal: (s: string) => pc.bgRed(pc.white(s)),\n}\n\nconst LEVEL_WIDTH = 5 // 'ERROR'.length\n\nfunction formatTime(timestamp: string): string {\n const date = new Date(timestamp)\n const hours = String(date.getUTCHours()).padStart(2, '0')\n const minutes = String(date.getUTCMinutes()).padStart(2, '0')\n const seconds = String(date.getUTCSeconds()).padStart(2, '0')\n return `${hours}:${minutes}:${seconds}`\n}\n\nfunction formatLevel(level: LogLevel): string {\n const colorFn = LEVEL_COLORS[level]\n return colorFn(level.toUpperCase().padEnd(LEVEL_WIDTH))\n}\n\nfunction formatData(data: Record<string, unknown>): string {\n const entries = Object.entries(data)\n if (entries.length === 0) return ''\n\n const lines = entries.map(([key, value]) => {\n const formatted = typeof value === 'object'\n ? JSON.stringify(value)\n : String(value)\n return ` ${pc.dim(key + ':')} ${formatted}`\n })\n\n return '\\n' + lines.join('\\n')\n}\n\nexport function formatPretty(entry: LogEntry): string {\n const { timestamp, level, message, service, context, data, error } = entry\n\n const time = formatTime(timestamp)\n const lvl = formatLevel(level)\n const mod = context.module ? pc.dim(`[${context.module}]`) + ' ' : ''\n const svc = pc.dim(`[${service}]`) + ' '\n\n let output = `${pc.dim(time)} ${lvl} ${svc}${mod}${message}`\n\n // Add trace context if present\n const traceInfo: Record<string, unknown> = {}\n if (context.traceId) traceInfo.traceId = context.traceId\n if (context.requestId && context.requestId !== context.traceId) {\n traceInfo.requestId = context.requestId\n }\n if (context.caller) traceInfo.caller = context.caller\n if (context.duration !== undefined) traceInfo.duration = `${context.duration}ms`\n\n const allData = { ...traceInfo, ...data }\n if (Object.keys(allData).length > 0) {\n output += formatData(allData)\n }\n\n // Add error details\n if (error) {\n output += '\\n' + pc.red(` ${error.name}: ${error.message}`)\n if (error.code) {\n output += pc.dim(` (${error.code})`)\n }\n if (error.stack) {\n const stackLines = error.stack.split('\\n').slice(1, 4) // First 3 stack frames\n output += '\\n' + stackLines.map(l => pc.dim(` ${l.trim()}`)).join('\\n')\n }\n if (error.cause) {\n output += '\\n' + pc.dim(` Caused by: ${error.cause.name}: ${error.cause.message}`)\n }\n }\n\n return output\n}\n", "// packages/logger/src/sanitize.ts\n// PII sanitization utilities for secure logging\n\n/**\n * Fields that should be automatically redacted from logs.\n * Case-insensitive matching against object keys.\n */\nexport const SENSITIVE_FIELDS = [\n // Authentication\n 'password', 'senha', 'pwd', 'pass',\n 'token', 'accessToken', 'access_token', 'refreshToken', 'refresh_token',\n 'apiKey', 'api_key', 'apikey', 'secret', 'secretKey', 'secret_key',\n 'authorization', 'auth', 'bearer',\n\n // Payment\n 'creditCard', 'credit_card', 'cardNumber', 'card_number',\n 'cvv', 'cvc', 'securityCode', 'security_code',\n 'accountNumber', 'account_number',\n\n // Personal identification\n 'cpf', 'rg', 'ssn', 'cnh', 'passport',\n 'email', 'phone',\n\n // Crypto\n 'privateKey', 'private_key', 'privatekey',\n 'mnemonic', 'seed', 'seedPhrase', 'seed_phrase',\n] as const\n\nexport type SensitiveField = typeof SENSITIVE_FIELDS[number]\n\n/**\n * Sanitize an email address for logging.\n * @example sanitize.email(\"john.doe@example.com\") => \"j***@example.com\"\n */\nfunction email(value: string): string {\n if (!value || typeof value !== 'string') return '[INVALID_EMAIL]'\n\n const atIndex = value.indexOf('@')\n if (atIndex === -1) return '[INVALID_EMAIL]'\n\n const [user, domain] = [value.slice(0, atIndex), value.slice(atIndex + 1)]\n if (!user || !domain) return '[INVALID_EMAIL]'\n\n const maskedUser = user.length <= 1\n ? '*'\n : user[0] + '*'.repeat(Math.min(user.length - 1, 5))\n\n return `${maskedUser}@${domain}`\n}\n\n/**\n * Sanitize a phone number for logging.\n * @example sanitize.phone(\"+5511999998888\") => \"**********8888\"\n */\nfunction phone(value: string): string {\n if (!value || typeof value !== 'string') return '[INVALID_PHONE]'\n\n const digits = value.replace(/\\D/g, '')\n if (digits.length < 4) return '[INVALID_PHONE]'\n\n return '*'.repeat(digits.length - 4) + digits.slice(-4)\n}\n\n/**\n * Sanitize a CPF for logging.\n * @example sanitize.cpf(\"123.456.789-00\") => \"***.***789-**\"\n */\nfunction cpf(value: string): string {\n if (!value || typeof value !== 'string') return '[INVALID_CPF]'\n\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 11) return '[INVALID_CPF]'\n\n return `***.***${digits.slice(6, 9)}-**`\n}\n\n/**\n * Sanitize a credit card number for logging.\n * @example sanitize.creditCard(\"4111111111111111\") => \"************1111\"\n */\nfunction creditCard(value: string): string {\n if (!value || typeof value !== 'string') return '[INVALID_CARD]'\n\n const digits = value.replace(/\\D/g, '')\n if (digits.length < 4) return '[INVALID_CARD]'\n\n return '*'.repeat(digits.length - 4) + digits.slice(-4)\n}\n\n/**\n * Sanitize an IP address for logging (privacy compliance).\n * @example sanitize.ip(\"192.168.1.100\") => \"192.168.1.xxx\"\n * @example sanitize.ip(\"2001:db8::1\") => \"2001:db8::xxxx\"\n */\nfunction ip(value: string): string {\n if (!value || typeof value !== 'string') return '[INVALID_IP]'\n\n // IPv6\n if (value.includes(':')) {\n const lastColon = value.lastIndexOf(':')\n return value.slice(0, lastColon + 1) + 'xxxx'\n }\n\n // IPv4\n const lastDot = value.lastIndexOf('.')\n if (lastDot === -1) return '[INVALID_IP]'\n\n return value.slice(0, lastDot + 1) + 'xxx'\n}\n\n/**\n * Sanitize a token/secret for logging.\n * @example sanitize.token(\"eyJhbGciOiJIUzI1NiIs...\") => \"eyJh...[REDACTED]...iIs\"\n */\nfunction token(value: string): string {\n if (!value || typeof value !== 'string') return '[REDACTED]'\n\n if (value.length <= 8) return '[REDACTED]'\n\n return `${value.slice(0, 4)}...[REDACTED]...${value.slice(-4)}`\n}\n\n/**\n * Check if a key matches any sensitive field pattern.\n * Uses word boundary matching to avoid false positives (e.g., \"tokens\" matching \"token\").\n * Handles: exact match, camelCase (userPassword), snake_case (api_key), kebab-case (api-key)\n */\nfunction isSensitiveKey(key: string): boolean {\n const lowerKey = key.toLowerCase()\n\n return SENSITIVE_FIELDS.some(field => {\n const lowerField = field.toLowerCase()\n\n // Exact match (case-insensitive)\n if (lowerKey === lowerField) return true\n\n // Match at end (handles camelCase like \"userPassword\", \"apiToken\")\n if (lowerKey.endsWith(lowerField)) return true\n\n // Match at start with uppercase boundary (handles \"passwordHash\", \"tokenExpiry\")\n // We check original key for uppercase boundary\n const fieldIdx = key.toLowerCase().indexOf(lowerField)\n if (fieldIdx === 0) {\n const afterIdx = lowerField.length\n if (afterIdx >= key.length) return true // exact match covered above\n // Check if next char is uppercase (camelCase) or non-alpha\n const nextChar = key[afterIdx]\n if (nextChar && (nextChar === nextChar.toUpperCase() || !/[a-zA-Z]/.test(nextChar))) {\n return true\n }\n }\n\n // Match with underscore/hyphen boundaries (e.g., \"api_key\", \"api-key\", \"user_password\")\n const patterns = [\n `_${lowerField}`, `${lowerField}_`,\n `-${lowerField}`, `${lowerField}-`,\n `_${lowerField}_`, `-${lowerField}-`,\n ]\n return patterns.some(p => lowerKey.includes(p))\n })\n}\n\n/**\n * Recursively sanitize an object, redacting sensitive fields.\n * @example sanitize.object({ password: \"secret\", name: \"John\" })\n * => { password: \"[REDACTED]\", name: \"John\" }\n */\nfunction object<T extends Record<string, unknown>>(\n obj: T,\n additionalSensitiveKeys?: string[]\n): T {\n if (!obj || typeof obj !== 'object') return obj\n\n const sanitized = { ...obj }\n\n for (const [key, value] of Object.entries(sanitized)) {\n // Check if key is sensitive using the isSensitiveKey function\n // or matches additional keys exactly\n const isAdditionalKey = additionalSensitiveKeys?.some(k =>\n key.toLowerCase() === k.toLowerCase()\n )\n\n if (isSensitiveKey(key) || isAdditionalKey) {\n sanitized[key as keyof T] = '[REDACTED]' as T[keyof T]\n continue\n }\n\n // Recursively sanitize nested objects\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n sanitized[key as keyof T] = object(\n value as Record<string, unknown>,\n additionalSensitiveKeys\n ) as T[keyof T]\n continue\n }\n\n // Sanitize arrays of objects\n if (Array.isArray(value)) {\n sanitized[key as keyof T] = value.map(item => {\n if (item && typeof item === 'object' && !Array.isArray(item)) {\n return object(item as Record<string, unknown>, additionalSensitiveKeys)\n }\n return item\n }) as T[keyof T]\n }\n }\n\n return sanitized\n}\n\n/**\n * Sanitize headers object, redacting auth-related headers.\n */\nfunction headers(hdrs: Record<string, string | string[] | undefined>): Record<string, string | string[] | undefined> {\n const sensitiveHeaders = [\n 'authorization',\n 'x-api-key',\n 'x-auth-token',\n 'cookie',\n 'set-cookie',\n ]\n\n const sanitized = { ...hdrs }\n\n for (const key of Object.keys(sanitized)) {\n if (sensitiveHeaders.some(h => key.toLowerCase() === h)) {\n sanitized[key] = '[REDACTED]'\n }\n }\n\n return sanitized\n}\n\n/**\n * Sanitization utilities for secure logging.\n *\n * @example\n * import { sanitize } from '@repo/logger'\n *\n * logger.info('User login', {\n * email: sanitize.email(user.email),\n * ip: sanitize.ip(request.ip),\n * })\n *\n * // Or sanitize entire objects\n * logger.info('Request data', sanitize.object(requestBody))\n */\nexport const sanitize = {\n email,\n phone,\n cpf,\n creditCard,\n ip,\n token,\n object,\n headers,\n isSensitiveKey,\n} as const\n\nexport type Sanitize = typeof sanitize\n", "// packages/logger/src/logger.base.ts\n// Shared logger logic for Node.js and browser environments\n\nimport { LOG_LEVELS, type LogLevel, type LogEntry, type LogContext, type LoggerOptions, type ErrorInfo } from './types'\nimport { formatJson } from './formatters/json'\nimport { formatPretty } from './formatters/pretty'\nimport { sanitize } from './sanitize'\n\n/**\n * Transport interface for log output destinations.\n * Re-export from transports for backwards compatibility.\n */\nexport interface Transport {\n log(entry: LogEntry, formatted: string): void\n}\n\n/**\n * Extract ErrorInfo from an Error object, including cause chain.\n */\nexport function extractErrorInfo(error: Error, includeStack: boolean): ErrorInfo {\n const info: ErrorInfo = {\n name: error.name,\n message: error.message,\n }\n\n if (includeStack && error.stack) {\n info.stack = error.stack\n }\n\n // Extract error code if present\n if ('code' in error && typeof error.code === 'string') {\n info.code = error.code\n }\n\n // Extract cause chain\n if (error.cause instanceof Error) {\n info.cause = extractErrorInfo(error.cause, includeStack)\n }\n\n return info\n}\n\n/**\n * Base configuration for detecting environment.\n */\nexport interface EnvironmentInfo {\n isProd: boolean\n env: string\n}\n\n/**\n * Abstract base logger with shared functionality.\n * Platform-specific implementations extend this class.\n */\nexport abstract class BaseLogger {\n protected level: LogLevel\n protected format: 'json' | 'pretty'\n protected module?: string\n protected service: string\n protected environment: string\n protected additionalContext: LogContext\n protected transports: Transport[]\n protected shouldSanitize: boolean\n protected sensitiveFields?: string[]\n protected includeCaller: boolean | 'errors'\n\n constructor(\n options: LoggerOptions,\n defaults: { level: LogLevel; format: 'json' | 'pretty'; service: string; env: string }\n ) {\n this.level = options.level ?? defaults.level\n this.format = options.format ?? defaults.format\n this.module = options.module\n this.service = options.service ?? defaults.service\n this.environment = options.environment ?? defaults.env\n this.additionalContext = {}\n this.transports = []\n this.shouldSanitize = options.sanitize ?? true\n this.sensitiveFields = options.sensitiveFields\n this.includeCaller = options.includeCaller ?? 'errors'\n }\n\n /**\n * Get the current log context (traceId, spanId, etc).\n * Implemented differently in Node.js (AsyncLocalStorage) vs browser.\n */\n protected abstract getLogContext(): LogContext | undefined\n\n /**\n * Check if environment is production.\n */\n protected abstract isProd(): boolean\n\n /**\n * Get caller information for error logging (Node.js only).\n */\n protected getCaller(): string | undefined {\n return undefined // Browser doesn't support stack introspection\n }\n\n /**\n * Flush any buffered logs (e.g., file transport).\n */\n protected flush(): void {\n // Override in Node.js logger for file transport\n }\n\n protected shouldLog(level: LogLevel): boolean {\n return LOG_LEVELS[level] >= LOG_LEVELS[this.level]\n }\n\n protected buildEntry(\n level: LogLevel,\n message: string,\n data?: Record<string, unknown>,\n error?: ErrorInfo\n ): LogEntry {\n const asyncContext = this.getLogContext() ?? {}\n\n const context: LogContext = {\n ...asyncContext,\n ...this.additionalContext,\n }\n\n if (this.module) {\n context.module = this.module\n }\n\n // Add caller based on includeCaller option (Node.js only)\n const shouldIncludeCaller =\n this.includeCaller === true ||\n (this.includeCaller === 'errors' && (level === 'error' || level === 'fatal'))\n\n if (shouldIncludeCaller) {\n const caller = this.getCaller()\n if (caller) context.caller = caller\n }\n\n return {\n timestamp: new Date().toISOString(),\n level,\n message,\n service: this.service,\n environment: this.environment,\n context,\n data,\n error,\n }\n }\n\n /**\n * Normalizes any data type to Record<string, unknown> for structured logging.\n */\n protected normalizeData(data: unknown): Record<string, unknown> | undefined {\n if (data === null || data === undefined) {\n return undefined\n }\n\n if (data instanceof Error) {\n return {\n error: data.message,\n errorName: data.name,\n stack: data.stack,\n }\n }\n\n if (typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean') {\n return { value: data }\n }\n\n if (Array.isArray(data)) {\n return { items: data }\n }\n\n if (typeof data === 'object') {\n const obj = data as Record<string, unknown>\n return this.shouldSanitize\n ? sanitize.object(obj, this.sensitiveFields)\n : obj\n }\n\n return { value: String(data) }\n }\n\n protected log(level: LogLevel, message: string, data?: unknown, errorObj?: Error): void {\n if (!this.shouldLog(level)) return\n\n const normalizedData = this.normalizeData(data)\n const errorInfo = errorObj ? extractErrorInfo(errorObj, !this.isProd()) : undefined\n const entry = this.buildEntry(level, message, normalizedData, errorInfo)\n\n const formatted = this.format === 'json'\n ? formatJson(entry)\n : formatPretty(entry)\n\n for (const transport of this.transports) {\n transport.log(entry, formatted)\n }\n\n this.flush()\n }\n\n trace(message: string, ...args: unknown[]): void {\n this.log('trace', message, args.length === 1 ? args[0] : args.length > 1 ? args : undefined)\n }\n\n debug(message: string, ...args: unknown[]): void {\n this.log('debug', message, args.length === 1 ? args[0] : args.length > 1 ? args : undefined)\n }\n\n info(message: string, ...args: unknown[]): void {\n this.log('info', message, args.length === 1 ? args[0] : args.length > 1 ? args : undefined)\n }\n\n warn(message: string, ...args: unknown[]): void {\n this.log('warn', message, args.length === 1 ? args[0] : args.length > 1 ? args : undefined)\n }\n\n error(message: string, errorOrData?: Error | unknown, data?: unknown): void {\n if (errorOrData instanceof Error) {\n this.log('error', message, data, errorOrData)\n } else {\n this.log('error', message, errorOrData)\n }\n }\n\n /**\n * Log a fatal error (system-critical).\n */\n fatal(message: string, errorOrData?: Error | unknown, data?: unknown): void {\n if (errorOrData instanceof Error) {\n this.log('fatal', message, data, errorOrData)\n } else {\n this.log('fatal', message, errorOrData)\n }\n }\n\n /**\n * Get the current trace ID from context.\n */\n getTraceId(): string | undefined {\n const ctx = this.getLogContext()\n return ctx?.traceId ?? this.additionalContext.traceId as string | undefined\n }\n\n /**\n * Get the current span ID from context.\n */\n getSpanId(): string | undefined {\n const ctx = this.getLogContext()\n return ctx?.spanId ?? this.additionalContext.spanId as string | undefined\n }\n\n /**\n * Time an async operation and log its duration.\n */\n async time<T>(\n operation: string,\n fn: () => Promise<T>,\n data?: Record<string, unknown>\n ): Promise<T> {\n const start = Date.now()\n try {\n const result = await fn()\n const duration = Date.now() - start\n this.info(`${operation} completed`, { ...data, duration, operation })\n return result\n } catch (error) {\n const duration = Date.now() - start\n this.error(`${operation} failed`, error as Error, { ...data, duration, operation })\n throw error\n }\n }\n\n /**\n * Time a sync operation and log its duration.\n */\n timeSync<T>(\n operation: string,\n fn: () => T,\n data?: Record<string, unknown>\n ): T {\n const start = Date.now()\n try {\n const result = fn()\n const duration = Date.now() - start\n this.info(`${operation} completed`, { ...data, duration, operation })\n return result\n } catch (error) {\n const duration = Date.now() - start\n this.error(`${operation} failed`, error as Error, { ...data, duration, operation })\n throw error\n }\n }\n\n /**\n * Create a child logger with additional context.\n * Must be implemented by subclasses to return correct type.\n */\n abstract child(context: LogContext): BaseLogger\n}\n", "// packages/logger/src/transports/console.ts\n// Node.js console transport using stdout/stderr\n\nimport type { LogEntry } from '../types'\n\nexport interface Transport {\n log(entry: LogEntry, formatted: string): void\n}\n\nexport class ConsoleTransport implements Transport {\n log(entry: LogEntry, formatted: string): void {\n // Use stderr for error/fatal levels\n if (entry.level === 'error' || entry.level === 'fatal') {\n process.stderr.write(formatted + '\\n')\n } else {\n process.stdout.write(formatted + '\\n')\n }\n }\n}\n", "// Node.js-only file transport\nimport { appendFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport type { LogEntry } from '../types'\nimport type { Transport } from './console'\n\nexport interface FileTransportOptions {\n dir: string\n}\n\nexport class FileTransport implements Transport {\n private dir: string\n private initialized = false\n private buffer: { file: string; content: string }[] = []\n\n constructor(options: FileTransportOptions) {\n this.dir = options.dir\n }\n\n private init(): void {\n if (this.initialized) return\n\n if (!existsSync(this.dir)) {\n mkdirSync(this.dir, { recursive: true })\n }\n\n const gitignore = join(this.dir, '.gitignore')\n if (!existsSync(gitignore)) {\n writeFileSync(gitignore, '*.log\\n')\n }\n\n this.initialized = true\n }\n\n log(entry: LogEntry, formatted: string): void {\n this.init()\n\n const line = formatted + '\\n'\n\n // Always write to combined.log\n this.buffer.push({ file: 'combined.log', content: line })\n\n // Also write errors to error.log\n if (entry.level === 'error') {\n this.buffer.push({ file: 'error.log', content: line })\n }\n }\n\n flush(): void {\n for (const { file, content } of this.buffer) {\n const filepath = join(this.dir, file)\n appendFileSync(filepath, content)\n }\n this.buffer = []\n }\n}\n", "// packages/logger/src/logger.ts\n// Node.js logger with file transport support\n\nimport type { LogLevel, LogContext, LoggerOptions } from './types'\nimport { LOG_LEVELS } from './types'\nimport { getLogContext } from './context'\nimport { BaseLogger } from './logger.base'\nimport { ConsoleTransport } from './transports/console'\nimport { FileTransport } from './transports/file'\n\nfunction detectEnvironment(): { isProd: boolean; env: string } {\n const isProd = process.env.NODE_ENV === 'production'\n || !!process.env.VERCEL\n || !!process.env.RAILWAY_ENVIRONMENT\n\n let env: string = process.env.NODE_ENV || 'development'\n if (process.env.VERCEL) env = (process.env.VERCEL_ENV as string) || 'production'\n if (process.env.RAILWAY_ENVIRONMENT) env = process.env.RAILWAY_ENVIRONMENT as string\n\n return { isProd, env }\n}\n\nfunction getDefaultFormat(): 'json' | 'pretty' {\n const override = process.env.LOG_FORMAT as 'json' | 'pretty' | undefined\n if (override === 'json' || override === 'pretty') return override\n\n const { isProd } = detectEnvironment()\n return isProd ? 'json' : 'pretty'\n}\n\nfunction getDefaultLevel(): LogLevel {\n const override = process.env.LOG_LEVEL as LogLevel | undefined\n if (override && override in LOG_LEVELS) return override\n\n const { isProd } = detectEnvironment()\n return isProd ? 'info' : 'debug'\n}\n\nfunction getDefaultService(): string {\n return process.env.SERVICE_NAME\n || process.env.VERCEL_GIT_REPO_SLUG\n || process.env.RAILWAY_SERVICE_NAME\n || 'unknown-service'\n}\n\n/**\n * Extract caller information from stack trace.\n * Returns format: \"filename:line:function\"\n */\nfunction getCaller(): string | undefined {\n const err = new Error()\n const stack = err.stack?.split('\\n')\n\n if (!stack) return undefined\n\n // Find the first stack frame outside the logger\n for (let i = 3; i < stack.length; i++) {\n const line = stack[i]\n if (!line) continue\n\n // Skip internal logger frames\n if (line.includes('/logger/src/')) continue\n if (line.includes('@repo/logger')) continue\n\n // Extract file:line:column\n const match = line.match(/at (?:(.+?) )?\\(?(.+?):(\\d+):(\\d+)\\)?/)\n if (match) {\n const [, fnName, file, lineNum] = match\n const fileName = file?.split('/').pop() || file\n return fnName\n ? `${fileName}:${lineNum}:${fnName}`\n : `${fileName}:${lineNum}`\n }\n }\n\n return undefined\n}\n\nexport class Logger extends BaseLogger {\n private fileTransport?: FileTransport\n private _isProd: boolean\n\n constructor(options: LoggerOptions = {}) {\n const { isProd, env } = detectEnvironment()\n\n super(options, {\n level: getDefaultLevel(),\n format: getDefaultFormat(),\n service: getDefaultService(),\n env,\n })\n\n this._isProd = isProd\n this.transports = [new ConsoleTransport()]\n\n // Add file transport in development (not in prod or Vercel/Railway)\n if (!isProd && !process.env.VERCEL && !process.env.RAILWAY_ENVIRONMENT) {\n this.fileTransport = new FileTransport({ dir: 'logs' })\n this.transports.push(this.fileTransport)\n }\n }\n\n protected getLogContext(): LogContext | undefined {\n return getLogContext()\n }\n\n protected isProd(): boolean {\n return this._isProd\n }\n\n protected override getCaller(): string | undefined {\n return getCaller()\n }\n\n protected override flush(): void {\n this.fileTransport?.flush()\n }\n\n /**\n * Create a child logger with additional context.\n * Child shares transports with parent.\n */\n child(context: LogContext): Logger {\n const child = new Logger({\n level: this.level,\n format: this.format,\n module: this.module,\n service: this.service,\n environment: this.environment,\n sanitize: this.shouldSanitize,\n sensitiveFields: this.sensitiveFields,\n includeCaller: this.includeCaller,\n })\n child.additionalContext = { ...this.additionalContext, ...context }\n // Share transports with parent\n child.transports = this.transports\n child.fileTransport = this.fileTransport\n return child\n }\n}\n", "// packages/logger/src/index.ts\nimport { Logger } from './logger'\n\n// Re-export types\nexport type { LogLevel, LogContext, LogEntry, LoggerOptions, ErrorInfo } from './types'\nexport { LOG_LEVELS, isValidLevel } from './types'\n\n// Re-export Transport interface for custom transports\nexport type { Transport } from './logger.base'\n\n// Re-export context utilities\nexport {\n withLogContext,\n getLogContext,\n generateTraceId,\n generateSpanId,\n getCorrelationId,\n} from './context'\n\n// Re-export span utilities for distributed tracing\nexport {\n withSpan,\n withSpanSync,\n startSpan,\n type Span,\n type SpanOptions,\n} from './context'\n\n// Re-export W3C Trace Context utilities\nexport {\n parseTraceparent,\n formatTraceparent,\n getTraceparent,\n contextFromTraceparent,\n extractTraceContext,\n createTraceHeaders,\n type TraceparentComponents,\n} from './context'\n\n// Re-export sanitization utilities\nexport { sanitize, SENSITIVE_FIELDS, type Sanitize, type SensitiveField } from './sanitize'\n\n// Global singleton logger\nexport const logger = new Logger()\n\n// Factory function for module-scoped loggers\nexport function createLogger(module: string, options?: Omit<import('./types').LoggerOptions, 'module'>): Logger {\n return new Logger({ ...options, module })\n}\n\n// Re-export Logger class for advanced use\nexport { Logger }\n\n// Re-export middleware\nexport { createLoggingMiddleware, type LoggingMiddlewareConfig } from './middleware'\n", "import type { CoreDeps, CourseWithProgress } from \"../types\";\n\nexport interface ListCoursesInput {\n userId: string;\n}\n\nexport async function listCourses(\n input: ListCoursesInput,\n deps: CoreDeps\n): Promise<CourseWithProgress[]> {\n deps.logger.info(\"tostudy-core: listCourses\", { userId: input.userId });\n return deps.data.courses.list(input.userId);\n}\n", "import type { CoreDeps, CourseDetail } from \"../types\";\n\nexport interface SelectCourseInput {\n userId: string;\n courseId: string;\n}\n\nexport async function selectCourse(\n input: SelectCourseInput,\n deps: CoreDeps\n): Promise<CourseDetail> {\n deps.logger.info(\"tostudy-core: selectCourse\", input);\n return deps.data.courses.select(input.userId, input.courseId);\n}\n", "import type { CoreDeps, ProgressData } from \"../types\";\n\nexport interface GetProgressInput {\n enrollmentId: string;\n}\n\nexport async function getProgress(input: GetProgressInput, deps: CoreDeps): Promise<ProgressData> {\n deps.logger.info(\"tostudy-core: getProgress\", input);\n return deps.data.courses.getProgress(input.enrollmentId);\n}\n", "/**\n * HTTP adapter \u2014 client-side DataProvider implementation.\n *\n * Calls the Next.js CLI API routes (`/api/cli/*`) using fetch().\n * The server extracts the user identity from the JWT token sent in the\n * Authorization header, so `userId` params present in the DataProvider\n * interface are intentionally ignored here.\n */\n\nimport type { DataProvider } from \"../types\";\n\n// ---------------------------------------------------------------------------\n// CliApiError\n// ---------------------------------------------------------------------------\n\nexport class CliApiError extends Error {\n constructor(\n message: string,\n public readonly status: number\n ) {\n super(message);\n this.name = \"CliApiError\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal fetch helper\n// ---------------------------------------------------------------------------\n\nasync function apiFetch<T>(url: string, token: string, init?: RequestInit): Promise<T> {\n const response = await fetch(url, {\n ...init,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${token}`,\n ...init?.headers,\n },\n });\n\n const body = await response.json();\n\n if (!response.ok) {\n throw new CliApiError(body.error ?? `API error ${response.status}`, response.status);\n }\n\n return body as T;\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a DataProvider that fetches from the ToStudy CLI API routes.\n *\n * @param apiUrl - Base URL of the Next.js app (e.g. \"https://tostudy.ai\")\n * @param token - JWT bearer token issued during `tostudy auth login`\n */\nexport function createHttpProvider(apiUrl: string, token: string): DataProvider {\n const base = `${apiUrl}/api/cli`;\n\n return {\n courses: {\n list: async (_userId) => {\n const res = await apiFetch<{ courses: any[] }>(`${base}/courses`, token);\n return res.courses;\n },\n\n select: async (_userId, courseId) => {\n const res = await apiFetch<{ course: any }>(`${base}/courses/select`, token, {\n method: \"POST\",\n body: JSON.stringify({ courseId }),\n });\n return res.course;\n },\n\n getProgress: async (enrollmentId) => {\n return apiFetch(`${base}/progress?enrollmentId=${encodeURIComponent(enrollmentId)}`, token);\n },\n },\n\n lessons: {\n next: async (enrollmentId, userConfirmation) => {\n return apiFetch(`${base}/lessons/next`, token, {\n method: \"POST\",\n body: JSON.stringify({ enrollmentId, userConfirmation }),\n });\n },\n\n getContent: async (lessonId, enrollmentId) => {\n const params = new URLSearchParams({ lessonId });\n if (enrollmentId) params.set(\"enrollmentId\", enrollmentId);\n return apiFetch(`${base}/lessons/content?${params.toString()}`, token);\n },\n\n getHint: async (_userId, enrollmentId) => {\n return apiFetch(`${base}/lessons/hint`, token, {\n method: \"POST\",\n body: JSON.stringify({ enrollmentId }),\n });\n },\n\n startModule: async (enrollmentId) => {\n return apiFetch(`${base}/modules/start`, token, {\n method: \"POST\",\n body: JSON.stringify({ enrollmentId }),\n });\n },\n\n startNextModule: async (enrollmentId) => {\n return apiFetch(`${base}/modules/start-next`, token, {\n method: \"POST\",\n body: JSON.stringify({ enrollmentId }),\n });\n },\n },\n\n exercises: {\n validate: async (lessonId, solution, _userId, enrollmentId) => {\n return apiFetch(`${base}/exercises/validate`, token, {\n method: \"POST\",\n body: JSON.stringify({ lessonId, solution, enrollmentId }),\n });\n },\n },\n };\n}\n", "import { Command } from \"commander\";\nimport { createLogger } from \"@repo/logger\";\nimport { listCourses, selectCourse } from \"@repo/tostudy-core/courses\";\nimport { createHttpProvider } from \"@repo/tostudy-core/adapters/http\";\nimport { requireSession, setActiveCourse } from \"../auth/session.js\";\nimport { output, error } from \"../output/formatter.js\";\n\nconst logger = createLogger(\"cli:select\");\n\nexport const selectCommand = new Command(\"select\")\n .description(\"Activate a course by ID or list index number\")\n .argument(\"<course>\", \"Course ID (UUID) or index number from `tostudy courses`\")\n .option(\"--json\", \"Output structured JSON\")\n .action(async (course: string, opts: { json?: boolean }) => {\n try {\n const session = await requireSession();\n const data = createHttpProvider(session.apiUrl, session.token);\n const deps = { data, logger };\n\n // Always list courses first \u2014 we need enrollmentId (not in CourseDetail)\n const courses = await listCourses({ userId: session.userId }, deps);\n\n let courseId = course;\n let enrollmentId = \"\";\n\n if (/^\\d+$/.test(course)) {\n // Index-based selection (1-based)\n const idx = parseInt(course, 10) - 1;\n if (idx < 0 || idx >= courses.length) {\n error(`\u00CDndice ${course} inv\u00E1lido. Voc\u00EA tem ${courses.length} curso(s).`);\n }\n const found = courses[idx]!;\n courseId = found.courseId;\n enrollmentId = found.enrollmentId;\n } else {\n // UUID-based selection\n const found = courses.find((c) => c.courseId === course);\n if (found) {\n enrollmentId = found.enrollmentId;\n }\n }\n\n const detail = await selectCourse({ userId: session.userId, courseId }, deps);\n\n // Persist the active course locally\n await setActiveCourse({\n courseId: detail.courseId,\n courseTitle: detail.courseTitle,\n enrollmentId,\n });\n\n if (opts.json) {\n output({ ...detail, enrollmentId }, { json: true });\n } else {\n output(\n [\n `\u2713 Curso ativado: ${detail.courseTitle}`,\n ` Progresso: ${detail.progress}% | ${detail.moduleCount} m\u00F3dulos | ${detail.lessonCount} li\u00E7\u00F5es`,\n \"\",\n \"\u2192 tostudy progress para ver seu progresso detalhado\",\n \"\u2192 tostudy start para come\u00E7ar o m\u00F3dulo atual\",\n \"\u2192 tostudy next para avan\u00E7ar para a pr\u00F3xima li\u00E7\u00E3o\",\n ].join(\"\\n\"),\n { json: false }\n );\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n error(msg);\n }\n });\n", "import { Command } from \"commander\";\nimport { createLogger } from \"@repo/logger\";\nimport { getProgress } from \"@repo/tostudy-core/courses\";\nimport { createHttpProvider } from \"@repo/tostudy-core/adapters/http\";\nimport { requireSession, requireActiveCourse } from \"../auth/session.js\";\nimport { output, error, formatProgress } from \"../output/formatter.js\";\n\nconst logger = createLogger(\"cli:progress\");\n\nexport const progressCommand = new Command(\"progress\")\n .description(\"Show your progress in the active course\")\n .option(\"--json\", \"Output structured JSON\")\n .action(async (opts: { json?: boolean }) => {\n try {\n const session = await requireSession();\n const activeCourse = await requireActiveCourse();\n const data = createHttpProvider(session.apiUrl, session.token);\n const deps = { data, logger };\n\n const progress = await getProgress({ enrollmentId: activeCourse.enrollmentId }, deps);\n\n if (opts.json) {\n output(progress, { json: true });\n } else {\n output(formatProgress(progress), { json: false });\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n error(msg);\n }\n });\n", "import { Command } from \"commander\";\nimport { createLogger } from \"@repo/logger\";\nimport { startModule } from \"@repo/tostudy-core/lessons\";\nimport { createHttpProvider } from \"@repo/tostudy-core/adapters/http\";\nimport { requireSession, requireActiveCourse } from \"../auth/session.js\";\nimport { output, error, formatModuleStart } from \"../output/formatter.js\";\n\nconst logger = createLogger(\"cli:start\");\n\nexport const startCommand = new Command(\"start\")\n .description(\"Start (or resume) the current module of the active course\")\n .option(\"--json\", \"Output structured JSON\")\n .action(async (opts: { json?: boolean }) => {\n try {\n const session = await requireSession();\n const activeCourse = await requireActiveCourse();\n const data = createHttpProvider(session.apiUrl, session.token);\n const deps = { data, logger };\n\n const moduleData = await startModule({ enrollmentId: activeCourse.enrollmentId }, deps);\n\n if (opts.json) {\n output(moduleData, { json: true });\n } else {\n output(formatModuleStart(moduleData), { json: false });\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n error(msg);\n }\n });\n", "import type { CoreDeps, LessonData } from \"../types\";\n\nexport interface NextLessonInput {\n enrollmentId: string;\n userConfirmation: string;\n}\n\nexport async function nextLesson(input: NextLessonInput, deps: CoreDeps): Promise<LessonData> {\n deps.logger.info(\"tostudy-core: nextLesson\", { enrollmentId: input.enrollmentId });\n return deps.data.lessons.next(input.enrollmentId, input.userConfirmation);\n}\n", "import type { CoreDeps, LessonContent } from \"../types\";\n\nexport interface GetContentInput {\n lessonId: string;\n enrollmentId?: string;\n}\n\nexport async function getContent(input: GetContentInput, deps: CoreDeps): Promise<LessonContent> {\n deps.logger.info(\"tostudy-core: getContent\", { lessonId: input.lessonId });\n return deps.data.lessons.getContent(input.lessonId, input.enrollmentId);\n}\n", "import type { CoreDeps, HintData } from \"../types\";\n\nexport interface GetHintInput {\n userId: string;\n enrollmentId?: string;\n}\n\nexport async function getHint(input: GetHintInput, deps: CoreDeps): Promise<HintData> {\n deps.logger.info(\"tostudy-core: getHint\", { userId: input.userId });\n return deps.data.lessons.getHint(input.userId, input.enrollmentId);\n}\n", "import type { CoreDeps, ModuleStartData } from \"../types\";\n\nexport interface StartModuleInput {\n enrollmentId: string;\n}\n\nexport async function startModule(\n input: StartModuleInput,\n deps: CoreDeps\n): Promise<ModuleStartData> {\n deps.logger.info(\"tostudy-core: startModule\", { enrollmentId: input.enrollmentId });\n return deps.data.lessons.startModule(input.enrollmentId);\n}\n", "import type { CoreDeps, ModuleStartData } from \"../types\";\n\nexport interface StartNextModuleInput {\n enrollmentId: string;\n}\n\nexport async function startNextModule(\n input: StartNextModuleInput,\n deps: CoreDeps\n): Promise<ModuleStartData> {\n deps.logger.info(\"tostudy-core: startNextModule\", { enrollmentId: input.enrollmentId });\n return deps.data.lessons.startNextModule(input.enrollmentId);\n}\n", "import { Command } from \"commander\";\nimport { createLogger } from \"@repo/logger\";\nimport { startNextModule } from \"@repo/tostudy-core/lessons\";\nimport { createHttpProvider } from \"@repo/tostudy-core/adapters/http\";\nimport { requireSession, requireActiveCourse } from \"../auth/session.js\";\nimport { output, error, formatModuleStart } from \"../output/formatter.js\";\n\nconst logger = createLogger(\"cli:start-next\");\n\nexport const startNextCommand = new Command(\"start-next\")\n .description(\"Transition to the next module after completing the current one\")\n .option(\"--json\", \"Output structured JSON\")\n .action(async (opts: { json?: boolean }) => {\n try {\n const session = await requireSession();\n const activeCourse = await requireActiveCourse();\n const data = createHttpProvider(session.apiUrl, session.token);\n const deps = { data, logger };\n\n const moduleData = await startNextModule({ enrollmentId: activeCourse.enrollmentId }, deps);\n\n if (opts.json) {\n output(moduleData, { json: true });\n } else {\n output(formatModuleStart(moduleData), { json: false });\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n error(msg);\n }\n });\n", "import { Command } from \"commander\";\nimport { createLogger } from \"@repo/logger\";\nimport { nextLesson } from \"@repo/tostudy-core/lessons\";\nimport { createHttpProvider } from \"@repo/tostudy-core/adapters/http\";\nimport { requireSession, requireActiveCourse } from \"../auth/session.js\";\nimport { output, error, formatLesson } from \"../output/formatter.js\";\n\nconst logger = createLogger(\"cli:next\");\n\nexport const nextCommand = new Command(\"next\")\n .description(\"Advance to the next lesson in the active course\")\n .option(\"--json\", \"Output structured JSON\")\n .action(async (opts: { json?: boolean }) => {\n try {\n const session = await requireSession();\n const activeCourse = await requireActiveCourse();\n const data = createHttpProvider(session.apiUrl, session.token);\n const deps = { data, logger };\n\n const lessonData = await nextLesson(\n { enrollmentId: activeCourse.enrollmentId, userConfirmation: \"cli-next\" },\n deps\n );\n\n if (opts.json) {\n output(lessonData, { json: true });\n } else {\n output(formatLesson(lessonData), { json: false });\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n error(msg);\n }\n });\n", "import { Command } from \"commander\";\nimport { createLogger } from \"@repo/logger\";\nimport { getContent } from \"@repo/tostudy-core/lessons\";\nimport { createHttpProvider } from \"@repo/tostudy-core/adapters/http\";\nimport type { LessonContent } from \"@repo/tostudy-core/types\";\nimport { requireSession, requireActiveCourse } from \"../auth/session.js\";\nimport { output, error } from \"../output/formatter.js\";\n\nconst logger = createLogger(\"cli:lesson\");\n\n/** Render LessonContent as a human-readable string. */\nfunction formatLessonContent(data: LessonContent): string {\n const lines: string[] = [\n `\u2501\u2501\u2501 Li\u00E7\u00E3o: ${data.title} \u2501\u2501\u2501`,\n \"\",\n `Tipo: ${data.type} | Dura\u00E7\u00E3o estimada: ~${data.estimatedTimeMinutes} min`,\n \"\",\n data.content,\n ];\n\n if (data.acceptanceCriteria) {\n lines.push(\"\", \"Crit\u00E9rios de aceita\u00E7\u00E3o:\", data.acceptanceCriteria);\n }\n\n if (data.hints && data.hints.length > 0) {\n lines.push(\"\", `Dicas dispon\u00EDveis: ${data.hints.length}`);\n }\n\n lines.push(\n \"\",\n \"\u2192 tostudy validate <arquivo> para validar sua solu\u00E7\u00E3o\",\n \"\u2192 tostudy hint para obter uma dica\",\n \"\u2192 tostudy next para avan\u00E7ar para a pr\u00F3xima li\u00E7\u00E3o\"\n );\n\n return lines.join(\"\\n\");\n}\n\nexport const lessonCommand = new Command(\"lesson\")\n .description(\"Show the content of the current lesson\")\n .option(\"--json\", \"Output structured JSON\")\n .action(async (opts: { json?: boolean }) => {\n try {\n const session = await requireSession();\n const activeCourse = await requireActiveCourse();\n const data = createHttpProvider(session.apiUrl, session.token);\n const deps = { data, logger };\n\n const lessonId = activeCourse.currentLessonId;\n if (!lessonId) {\n error(\"Nenhuma li\u00E7\u00E3o ativa encontrada. Rode: tostudy start ou tostudy next\");\n }\n\n const content = await getContent({ lessonId, enrollmentId: activeCourse.enrollmentId }, deps);\n\n if (opts.json) {\n output(content, { json: true });\n } else {\n output(formatLessonContent(content), { json: false });\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n error(msg);\n }\n });\n", "import { Command } from \"commander\";\nimport { createLogger } from \"@repo/logger\";\nimport { getHint } from \"@repo/tostudy-core/lessons\";\nimport { createHttpProvider } from \"@repo/tostudy-core/adapters/http\";\nimport { requireSession, requireActiveCourse } from \"../auth/session.js\";\nimport { output, error, formatHint } from \"../output/formatter.js\";\n\nconst logger = createLogger(\"cli:hint\");\n\nexport const hintCommand = new Command(\"hint\")\n .description(\"Get a progressive hint for the current exercise\")\n .option(\"--json\", \"Output structured JSON\")\n .action(async (opts: { json?: boolean }) => {\n try {\n const session = await requireSession();\n const activeCourse = await requireActiveCourse();\n const data = createHttpProvider(session.apiUrl, session.token);\n const deps = { data, logger };\n\n const hint = await getHint(\n { userId: session.userId, enrollmentId: activeCourse.enrollmentId },\n deps\n );\n\n if (opts.json) {\n output(hint, { json: true });\n } else {\n output(formatHint(hint), { json: false });\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n error(msg);\n }\n });\n", "import fs from \"node:fs\";\nimport { Command } from \"commander\";\nimport { createLogger } from \"@repo/logger\";\nimport { validateSolution } from \"@repo/tostudy-core/exercises\";\nimport { createHttpProvider } from \"@repo/tostudy-core/adapters/http\";\nimport { requireSession, requireActiveCourse } from \"../auth/session.js\";\nimport { output, error, formatValidation } from \"../output/formatter.js\";\n\nconst logger = createLogger(\"cli:validate\");\n\nexport const validateCommand = new Command(\"validate\")\n .description(\"Validate your solution for the current exercise\")\n .argument(\"[file]\", \"Path to the solution file to read\")\n .option(\"--stdin\", \"Read solution from stdin instead of a file\")\n .option(\"--json\", \"Output structured JSON\")\n .action(async (file: string | undefined, opts: { stdin?: boolean; json?: boolean }) => {\n try {\n const session = await requireSession();\n const activeCourse = await requireActiveCourse();\n\n // Resolve lessonId\n const lessonId = activeCourse.currentLessonId;\n if (!lessonId) {\n error(\"Nenhuma li\u00E7\u00E3o ativa encontrada. Rode: tostudy start ou tostudy next\");\n }\n\n // Read solution content\n let solution: string;\n if (opts.stdin) {\n solution = fs.readFileSync(\"/dev/stdin\", \"utf-8\");\n } else if (file) {\n if (!fs.existsSync(file)) {\n error(`Arquivo n\u00E3o encontrado: ${file}`);\n }\n solution = fs.readFileSync(file, \"utf-8\");\n } else {\n error(\"Forne\u00E7a um arquivo ou use --stdin.\\n\\nExemplo: tostudy validate resposta.md\");\n }\n\n const data = createHttpProvider(session.apiUrl, session.token);\n const deps = { data, logger };\n\n const result = await validateSolution(\n {\n lessonId,\n solution,\n userId: session.userId,\n enrollmentId: activeCourse.enrollmentId,\n },\n deps\n );\n\n if (opts.json) {\n output(result, { json: true });\n } else {\n output(formatValidation(result), { json: false });\n }\n\n // Exit code reflects pass/fail for scripting\n process.exit(result.passed ? 0 : 1);\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n error(msg);\n }\n });\n", "import type { CoreDeps, ValidationResult } from \"../types\";\n\nexport interface ValidateSolutionInput {\n lessonId: string;\n /** File CONTENT as string \u2014 the CLI reads the file before calling this function. */\n solution: string;\n userId: string;\n enrollmentId: string;\n}\n\nexport async function validateSolution(\n input: ValidateSolutionInput,\n deps: CoreDeps\n): Promise<ValidationResult> {\n deps.logger.info(\"tostudy-core: validateSolution\", { lessonId: input.lessonId });\n return deps.data.exercises.validate(\n input.lessonId,\n input.solution,\n input.userId,\n input.enrollmentId\n );\n}\n", "import { Command } from \"commander\";\nimport { getSession, getActiveCourse } from \"../auth/session.js\";\nimport { output } from \"../output/formatter.js\";\n\nexport const menuCommand = new Command(\"menu\")\n .description(\"Show available commands and current study context\")\n .action(async () => {\n const session = await getSession();\n const activeCourse = session ? await getActiveCourse() : null;\n\n const lines: string[] = [\n \"\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\",\n \"\u2502 ToStudy CLI \u2014 Menu \u2502\",\n \"\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\",\n \"\",\n ];\n\n if (!session) {\n lines.push(\n \" Status: N\u00E3o autenticado\",\n \"\",\n \" Para come\u00E7ar:\",\n \" tostudy login Autenticar com sua conta ToStudy\",\n \"\"\n );\n } else {\n lines.push(` Usu\u00E1rio: ${session.userName}`);\n\n if (activeCourse) {\n lines.push(` Curso ativo: ${activeCourse.courseTitle}`, \"\");\n } else {\n lines.push(\n \" Curso ativo: (nenhum)\",\n \" \u2192 tostudy courses para ver seus cursos\",\n \" \u2192 tostudy select <n\u00FAmero> para ativar um curso\",\n \"\"\n );\n }\n\n lines.push(\n \" \u2500\u2500\u2500 Navega\u00E7\u00E3o \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\",\n \" tostudy courses Listar seus cursos\",\n \" tostudy select <id> Ativar um curso\",\n \" tostudy progress Ver progresso do curso ativo\",\n \"\",\n \" \u2500\u2500\u2500 Estudo \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\",\n \" tostudy start Iniciar/retomar o m\u00F3dulo atual\",\n \" tostudy start-next Avan\u00E7ar para o pr\u00F3ximo m\u00F3dulo\",\n \" tostudy next Avan\u00E7ar para a pr\u00F3xima li\u00E7\u00E3o\",\n \" tostudy lesson Ver conte\u00FAdo da li\u00E7\u00E3o atual\",\n \"\",\n \" \u2500\u2500\u2500 Exerc\u00EDcios \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\",\n \" tostudy validate <arquivo> Validar sua solu\u00E7\u00E3o\",\n \" tostudy hint Obter uma dica progressiva\",\n \"\",\n \" \u2500\u2500\u2500 Dicas r\u00E1pidas \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\",\n \" Adicione --json a qualquer comando para sa\u00EDda em JSON\",\n \" Adicione --help a qualquer comando para ver op\u00E7\u00F5es\",\n \"\"\n );\n }\n\n output(lines.join(\"\\n\"), { json: false });\n });\n", "/**\n * Entry point for the bundled npm CLI.\n * This file is used by build-npm.mjs as the esbuild entrypoint.\n */\nimport { createProgram } from \"./cli\";\n\nconst program = createProgram();\nprogram.parse();\n"],
5
- "mappings": "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",
6
- "names": ["Command", "token", "Command", "Command", "Command", "execFileSync", "fs", "path", "os", "Command", "Command", "Command", "execFileSync", "Command", "error", "output", "pc", "error", "output", "error", "token", "logger", "Command", "Command", "logger", "Command", "Command", "logger", "Command", "Command", "logger", "Command", "Command", "logger", "Command", "Command", "logger", "Command", "Command", "logger", "Command", "Command", "logger", "Command", "fs", "Command", "logger", "Command", "fs", "Command", "Command", "program", "Command"]
3
+ "sources": ["../src/auth/oauth-server.ts", "../src/auth/session.ts", "../src/output/formatter.ts", "../src/commands/login.ts", "../src/commands/logout.ts", "../src/installer/node-detector.ts", "../src/installer/ide-detector.ts", "../src/commands/setup.ts", "../src/commands/doctor.ts", "../../../packages/logger/src/types.ts", "../../../packages/logger/src/context/async-context.ts", "../../../packages/logger/src/context/span.shared.ts", "../../../packages/logger/src/context/span.ts", "../../../packages/logger/src/context/w3c-trace.ts", "../../../packages/logger/src/context/index.ts", "../../../packages/logger/src/formatters/json.ts", "../../../node_modules/picocolors/picocolors.js", "../../../packages/logger/src/formatters/pretty.ts", "../../../packages/logger/src/sanitize.ts", "../../../packages/logger/src/logger.base.ts", "../../../packages/logger/src/transports/console.ts", "../../../packages/logger/src/transports/file.ts", "../../../packages/logger/src/logger.ts", "../../../packages/logger/src/middleware/trpc.ts", "../../../packages/logger/src/middleware/index.ts", "../../../packages/logger/src/index.ts", "../../../packages/tostudy-core/src/courses/list-courses.ts", "../../../packages/tostudy-core/src/courses/select-course.ts", "../../../packages/tostudy-core/src/courses/get-progress.ts", "../../../packages/tostudy-core/src/courses/index.ts", "../../../packages/tostudy-core/src/adapters/http.ts", "../src/commands/courses.ts", "../src/commands/select.ts", "../src/commands/progress.ts", "../../../packages/tostudy-core/src/lessons/next-lesson.ts", "../../../packages/tostudy-core/src/lessons/get-content.ts", "../../../packages/tostudy-core/src/lessons/get-hint.ts", "../../../packages/tostudy-core/src/lessons/start-module.ts", "../../../packages/tostudy-core/src/lessons/start-next-module.ts", "../../../packages/tostudy-core/src/lessons/index.ts", "../src/commands/start.ts", "../src/commands/start-next.ts", "../src/commands/next.ts", "../src/commands/lesson.ts", "../src/commands/hint.ts", "../../../packages/tostudy-core/src/exercises/validate-solution.ts", "../../../packages/tostudy-core/src/exercises/index.ts", "../src/commands/validate.ts", "../src/commands/menu.ts", "../src/cli.ts", "../src/cli-entry.ts"],
4
+ "sourcesContent": ["import http from \"node:http\";\n\nexport function startCallbackServer(port: number): Promise<{ code: string }> {\n return new Promise((resolve, reject) => {\n const server = http.createServer((req, res) => {\n const url = new URL(req.url!, `http://localhost:${port}`);\n if (url.pathname === \"/callback\") {\n const code = url.searchParams.get(\"code\");\n if (code) {\n res.writeHead(200, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(\"<html><body><h1>Autenticado!</h1><p>Pode fechar esta aba.</p></body></html>\");\n server.close();\n resolve({ code });\n } else {\n res.writeHead(400);\n res.end(\"Missing code\");\n }\n } else {\n res.writeHead(404);\n res.end(\"Not found\");\n }\n });\n\n server.listen(port, () => {});\n server.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\") {\n reject(new Error(`Port ${port} est\u00E1 em uso. Tente novamente.`));\n } else {\n reject(err);\n }\n });\n\n // Timeout after 2 minutes (unref so it doesn't block process exit)\n const timeoutId = setTimeout(() => {\n server.close();\n reject(new Error(\"Login timeout \u2014 nenhuma resposta em 2 minutos\"));\n }, 120_000);\n timeoutId.unref();\n });\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\nexport interface CliSession {\n token: string;\n userId: string;\n userName: string;\n expiresAt: string;\n apiUrl: string;\n}\n\nexport interface ActiveCourse {\n courseId: string;\n courseTitle: string;\n enrollmentId: string;\n currentLessonId?: string;\n}\n\nfunction getConfigDir(override?: string): string {\n if (override) return override;\n if (process.platform === \"linux\" && process.env[\"XDG_CONFIG_HOME\"]) {\n return path.join(process.env[\"XDG_CONFIG_HOME\"], \"tostudy\");\n }\n return path.join(os.homedir(), \".tostudy\");\n}\n\nexport async function saveSession(session: CliSession, configDir?: string): Promise<void> {\n const dir = getConfigDir(configDir);\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(path.join(dir, \"config.json\"), JSON.stringify(session, null, 2), {\n mode: 0o600,\n });\n}\n\nexport async function getSession(configDir?: string): Promise<CliSession | null> {\n const dir = getConfigDir(configDir);\n const p = path.join(dir, \"config.json\");\n if (!fs.existsSync(p)) return null;\n return JSON.parse(fs.readFileSync(p, \"utf-8\")) as CliSession;\n}\n\nexport async function clearSession(configDir?: string): Promise<void> {\n const dir = getConfigDir(configDir);\n const p = path.join(dir, \"config.json\");\n if (fs.existsSync(p)) fs.unlinkSync(p);\n const ap = path.join(dir, \"active-course.json\");\n if (fs.existsSync(ap)) fs.unlinkSync(ap);\n}\n\nexport async function getActiveCourse(configDir?: string): Promise<ActiveCourse | null> {\n const dir = getConfigDir(configDir);\n const p = path.join(dir, \"active-course.json\");\n if (!fs.existsSync(p)) return null;\n return JSON.parse(fs.readFileSync(p, \"utf-8\")) as ActiveCourse;\n}\n\nexport async function setActiveCourse(course: ActiveCourse, configDir?: string): Promise<void> {\n const dir = getConfigDir(configDir);\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(path.join(dir, \"active-course.json\"), JSON.stringify(course, null, 2), {\n mode: 0o600,\n });\n}\n\nexport async function requireSession(configDir?: string): Promise<CliSession> {\n const session = await getSession(configDir);\n if (!session) {\n process.stderr.write(\"Erro: N\u00E3o autenticado. Rode: tostudy login\\n\");\n process.exit(2);\n }\n const expiresAt = new Date(session.expiresAt);\n if (expiresAt < new Date()) {\n process.stderr.write(\"Erro: Sess\u00E3o expirada. Rode: tostudy login\\n\");\n process.exit(2);\n }\n return session;\n}\n\nexport async function requireActiveCourse(configDir?: string): Promise<ActiveCourse> {\n const course = await getActiveCourse(configDir);\n if (!course) {\n process.stderr.write(\"Erro: Nenhum curso ativo. Rode: tostudy select <curso>\\n\");\n process.exit(3);\n }\n return course;\n}\n", "import type {\n CourseWithProgress,\n ProgressData,\n LessonData,\n ValidationResult,\n HintData,\n ModuleStartData,\n} from \"@repo/tostudy-core/types\";\n\n// ---------------------------------------------------------------------------\n// Core output helpers\n// ---------------------------------------------------------------------------\n\nexport function output(data: unknown, opts: { json?: boolean }): void {\n if (opts.json) {\n process.stdout.write(JSON.stringify(data, null, 2) + \"\\n\");\n } else if (typeof data === \"string\") {\n process.stdout.write(data + \"\\n\");\n } else {\n process.stdout.write(JSON.stringify(data, null, 2) + \"\\n\");\n }\n}\n\nexport function error(msg: string, code: number = 1): never {\n process.stderr.write(`Erro: ${msg}\\n`);\n process.exit(code);\n}\n\nexport function progressBar(percent: number, width: number = 20): string {\n const clamped = Math.max(0, Math.min(100, percent));\n const filled = Math.round((clamped / 100) * width);\n const empty = width - filled;\n return \"\u2588\".repeat(filled) + \"\u2591\".repeat(empty) + ` ${clamped}%`;\n}\n\n// ---------------------------------------------------------------------------\n// Human-readable formatters\n// ---------------------------------------------------------------------------\n\n/** Format a numbered list of enrolled courses with progress bars. */\nexport function formatCourseList(courses: CourseWithProgress[]): string {\n if (courses.length === 0) {\n return [\n \"Nenhum curso encontrado.\",\n \"\",\n \"\u2192 tostudy enroll <curso> para se matricular em um curso\",\n ].join(\"\\n\");\n }\n\n const lines: string[] = [\"Seus cursos:\", \"\"];\n courses.forEach((course, idx) => {\n const bar = progressBar(course.progress);\n lines.push(` ${idx + 1}. ${course.title}`);\n lines.push(` ${bar}`);\n lines.push(` Professor: ${course.creatorName}`);\n lines.push(\"\");\n });\n\n lines.push(\"\u2192 tostudy select <n\u00FAmero> para ativar um curso\");\n lines.push(\"\u2192 tostudy progress para ver seu progresso\");\n\n return lines.join(\"\\n\");\n}\n\n/** Format a full progress snapshot for the active course. */\nexport function formatProgress(data: ProgressData): string {\n const { currentModule, currentLesson } = data;\n const courseBar = progressBar(data.coursePercent);\n const moduleBar = progressBar(data.modulePercent);\n\n const lines: string[] = [\n \"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\",\n `M\u00F3dulo ${currentModule.order} de ${currentModule.totalModules}: ${currentModule.title}`,\n ` Curso: ${courseBar}`,\n ` M\u00F3dulo: ${moduleBar}`,\n \"\",\n `Li\u00E7\u00E3o atual (${currentLesson.order}/${currentLesson.totalLessons}): ${currentLesson.title}`,\n `Li\u00E7\u00F5es conclu\u00EDdas: ${data.completedLessons}`,\n `Tempo restante estimado: ~${data.estimatedMinutesRemaining} min`,\n \"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\",\n \"\",\n \"\u2192 tostudy next para avan\u00E7ar para a pr\u00F3xima li\u00E7\u00E3o\",\n \"\u2192 tostudy lesson para ver o conte\u00FAdo da li\u00E7\u00E3o atual\",\n ];\n\n return lines.join(\"\\n\");\n}\n\n/** Format lesson content returned after advancing. */\nexport function formatLesson(data: LessonData): string {\n const { lesson, wayfinding, progress } = data;\n const courseBar = progressBar(progress.coursePercent);\n const moduleBar = progressBar(progress.modulePercent);\n\n const lines: string[] = [\n `\u2501\u2501\u2501 M\u00F3dulo ${wayfinding.moduleOrder}/${wayfinding.totalModules} \u00B7 Li\u00E7\u00E3o ${wayfinding.lessonOrder}/${wayfinding.totalLessons} \u2501\u2501\u2501`,\n \"\",\n `\uD83D\uDCD6 ${lesson.title}`,\n ` M\u00F3dulo: ${lesson.moduleTitle} | Tipo: ${lesson.type}`,\n \"\",\n lesson.content,\n \"\",\n ` Curso: ${courseBar}`,\n ` M\u00F3dulo: ${moduleBar}`,\n ];\n\n if (lesson.acceptanceCriteria) {\n lines.push(\"\", \"Crit\u00E9rios de aceita\u00E7\u00E3o:\", lesson.acceptanceCriteria);\n }\n\n if (lesson.exerciseContent) {\n lines.push(\"\", \"\u2500\u2500\u2500 Exerc\u00EDcio \u2500\u2500\u2500\", lesson.exerciseContent);\n }\n\n lines.push(\n \"\",\n \"\u2192 tostudy validate <resposta> para validar sua solu\u00E7\u00E3o\",\n \"\u2192 tostudy hint para obter uma dica\",\n \"\u2192 tostudy next para avan\u00E7ar (ap\u00F3s completar)\"\n );\n\n return lines.join(\"\\n\");\n}\n\n/** Format a validation result with criteria checklist. */\nexport function formatValidation(data: ValidationResult): string {\n const statusIcon = data.passed ? \"\u2713\" : \"\u2717\";\n const statusLabel = data.passed ? \"APROVADO\" : \"REPROVADO\";\n const scoreStr = data.score !== null ? ` \u00B7 Pontua\u00E7\u00E3o: ${data.score}/100` : \"\";\n\n const lines: string[] = [`${statusIcon} Valida\u00E7\u00E3o: ${statusLabel}${scoreStr}`, \"\", \"Crit\u00E9rios:\"];\n\n data.criteria.forEach((c) => {\n const icon = c.met ? \" \u2713\" : \" \u2717\";\n lines.push(`${icon} ${c.criteria}`);\n if (c.comment) {\n lines.push(` ${c.comment}`);\n }\n });\n\n lines.push(\"\", `Feedback: ${data.feedback}`, \"\");\n\n if (data.passed) {\n lines.push(\"\u2192 tostudy next para avan\u00E7ar para a pr\u00F3xima li\u00E7\u00E3o\");\n } else {\n lines.push(\n \"\u2192 tostudy hint para obter uma dica\",\n \"\u2192 tostudy validate para tentar novamente\"\n );\n }\n\n return lines.join(\"\\n\");\n}\n\n/** Format a progressive hint response. */\nexport function formatHint(data: HintData): string {\n const levelLabel = data.levelLabel ?? `N\u00EDvel ${data.level}`;\n const lines: string[] = [\n `\uD83D\uDCA1 Dica (${levelLabel} \u00B7 ${data.level}/${data.maxLevel}):`,\n \"\",\n data.hint,\n \"\",\n ];\n\n if (data.level < data.maxLevel) {\n lines.push(`\u2192 tostudy hint para uma dica mais detalhada (n\u00EDvel ${data.level + 1})`);\n } else {\n lines.push(\"\u2192 tostudy validate para tentar sua solu\u00E7\u00E3o\");\n }\n\n return lines.join(\"\\n\");\n}\n\n/** Format module start data (first lesson of a new module). */\nexport function formatModuleStart(data: ModuleStartData): string {\n const { module: mod, firstLesson, wayfinding } = data;\n\n const lines: string[] = [\n `\u2501\u2501\u2501 M\u00F3dulo ${wayfinding.moduleOrder}/${wayfinding.totalModules} \u2501\u2501\u2501`,\n \"\",\n `\uD83D\uDDC2 ${mod.title}`,\n ];\n\n if (mod.description) {\n lines.push(\"\", mod.description);\n }\n\n if (mod.objectives && mod.objectives.length > 0) {\n lines.push(\"\", \"Objetivos:\");\n mod.objectives.forEach((obj) => lines.push(` \u2022 ${obj}`));\n }\n\n lines.push(\"\", \"\u2500\u2500\u2500 Primeira Li\u00E7\u00E3o \u2500\u2500\u2500\", \"\", `\uD83D\uDCD6 ${firstLesson.title}`, \"\", firstLesson.content);\n\n if (firstLesson.lessonIntroContent) {\n lines.push(\"\", firstLesson.lessonIntroContent);\n }\n\n if (firstLesson.exerciseContent) {\n lines.push(\"\", \"\u2500\u2500\u2500 Exerc\u00EDcio \u2500\u2500\u2500\", firstLesson.exerciseContent);\n }\n\n if (firstLesson.acceptanceCriteria) {\n lines.push(\"\", \"Crit\u00E9rios de aceita\u00E7\u00E3o:\", firstLesson.acceptanceCriteria);\n }\n\n lines.push(\n \"\",\n \"\u2192 tostudy validate <resposta> para validar sua solu\u00E7\u00E3o\",\n \"\u2192 tostudy hint para obter uma dica\"\n );\n\n return lines.join(\"\\n\");\n}\n", "import { Command } from \"commander\";\nimport { execFile } from \"node:child_process\";\nimport { startCallbackServer } from \"../auth/oauth-server.js\";\nimport { saveSession } from \"../auth/session.js\";\nimport { error } from \"../output/formatter.js\";\n\nconst DEFAULT_API_URL = \"https://tostudy.ai\";\nconst PORT = 9876;\n\nexport const loginCommand = new Command(\"login\")\n .description(\"Autentica no ToStudy via browser\")\n .option(\"--manual\", \"Login manual (sem browser)\")\n .option(\"--api-url <url>\", \"API URL override\", DEFAULT_API_URL)\n .action(async (opts: { manual?: boolean; apiUrl: string }) => {\n const apiUrl = opts.apiUrl;\n\n if (opts.manual) {\n // Manual flow: print URL for user to open manually\n console.log(`\\n Acesse este endere\u00E7o no seu browser:`);\n console.log(` ${apiUrl}/api/cli/auth/authorize?port=${PORT}\\n`);\n console.log(\" Ap\u00F3s autorizar, o browser ser\u00E1 redirecionado e o login ser\u00E1 conclu\u00EDdo.\");\n console.log(\" Certifique-se de rodar este comando sem --manual para o fluxo autom\u00E1tico.\\n\");\n return;\n }\n\n console.log(\"\\n Abrindo browser para autentica\u00E7\u00E3o...\\n\");\n\n const serverPromise = startCallbackServer(PORT);\n\n // Open browser safely using execFile (not exec \u2014 prevents command injection)\n const authUrl = `${apiUrl}/api/cli/auth/authorize?port=${PORT}`;\n const openCmd = process.platform === \"darwin\" ? \"open\" : \"xdg-open\";\n execFile(openCmd, [authUrl], (err) => {\n if (err) {\n console.log(` N\u00E3o foi poss\u00EDvel abrir o browser automaticamente.`);\n console.log(` Abra manualmente: ${authUrl}\\n`);\n }\n });\n\n try {\n const { code } = await serverPromise;\n\n // Exchange code for JWT\n const res = await fetch(`${apiUrl}/api/cli/auth/exchange`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ code }),\n });\n\n if (!res.ok) {\n const body = (await res.json()) as { error?: string };\n error(body.error ?? \"Falha na autentica\u00E7\u00E3o\");\n }\n\n const { token, userId, userName, expiresAt } = (await res.json()) as {\n token: string;\n userId: string;\n userName: string;\n expiresAt: string;\n };\n\n await saveSession({ token, userId, userName, expiresAt, apiUrl });\n\n console.log(`\\n Logado como ${userName}\\n`);\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : \"Login falhou\";\n error(msg);\n }\n });\n", "import { Command } from \"commander\";\nimport { clearSession } from \"../auth/session.js\";\n\nexport const logoutCommand = new Command(\"logout\")\n .description(\"Remove token local\")\n .action(async () => {\n await clearSession();\n console.log(\"\\n Deslogado com sucesso.\\n\");\n });\n", "import { execFileSync } from \"node:child_process\";\n\nexport interface NodeInfo {\n installed: boolean;\n version: string | null;\n meetsMinimum: boolean; // >= 18\n path: string | null;\n}\n\nexport function detectNode(): NodeInfo {\n try {\n const version = execFileSync(\"node\", [\"--version\"], {\n encoding: \"utf-8\",\n }).trim();\n let nodePath: string | null = null;\n try {\n const whichCmd = process.platform === \"win32\" ? \"where\" : \"which\";\n nodePath = execFileSync(whichCmd, [\"node\"], { encoding: \"utf-8\" }).trim();\n } catch {\n /* path detection optional */\n }\n const major = parseInt(version.replace(\"v\", \"\"), 10);\n return { installed: true, version, meetsMinimum: major >= 18, path: nodePath };\n } catch {\n return { installed: false, version: null, meetsMinimum: false, path: null };\n }\n}\n", "import { execFileSync } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\nexport interface DetectedIDE {\n name: string;\n id: string;\n detected: boolean;\n configPath: string | null;\n}\n\nfunction checkExists(p: string): boolean {\n return fs.existsSync(p);\n}\n\nexport function detectIDEs(): DetectedIDE[] {\n const home = os.homedir();\n\n const ides: DetectedIDE[] = [\n // Claude Code: detected by presence of 'claude' binary\n {\n name: \"Claude Code\",\n id: \"claude-code\",\n detected: false,\n configPath: path.join(home, \".mcp.json\"),\n },\n // Cursor: ~/.cursor directory\n {\n name: \"Cursor\",\n id: \"cursor\",\n detected: checkExists(path.join(home, \".cursor\")),\n configPath: path.join(home, \".cursor\", \"mcp.json\"),\n },\n // VS Code: ~/.vscode directory\n {\n name: \"VS Code\",\n id: \"vscode\",\n detected: checkExists(path.join(home, \".vscode\")),\n configPath: \".vscode/mcp.json\",\n },\n // Claude Desktop: platform-specific config dir\n {\n name: \"Claude Desktop\",\n id: \"desktop\",\n detected: checkExists(\n process.platform === \"darwin\"\n ? path.join(home, \"Library\", \"Application Support\", \"Claude\")\n : process.platform === \"win32\"\n ? path.join(process.env[\"APPDATA\"] ?? home, \"Claude\")\n : path.join(home, \".config\", \"claude\")\n ),\n configPath:\n process.platform === \"darwin\"\n ? path.join(\n home,\n \"Library\",\n \"Application Support\",\n \"Claude\",\n \"claude_desktop_config.json\"\n )\n : process.platform === \"win32\"\n ? path.join(process.env[\"APPDATA\"] ?? home, \"Claude\", \"claude_desktop_config.json\")\n : path.join(home, \".config\", \"claude\", \"claude_desktop_config.json\"),\n },\n // Windsurf: ~/.codeium/windsurf\n {\n name: \"Windsurf\",\n id: \"windsurf\",\n detected: checkExists(path.join(home, \".codeium\", \"windsurf\")),\n configPath: path.join(home, \".codeium\", \"windsurf\", \"mcp_config.json\"),\n },\n // OpenCode: ~/.opencode\n {\n name: \"OpenCode\",\n id: \"opencode\",\n detected: checkExists(path.join(home, \".opencode\")),\n configPath: path.join(home, \".opencode\", \"opencode.json\"),\n },\n // Manual (always available as fallback)\n {\n name: \"Manual\",\n id: \"manual\",\n detected: false,\n configPath: \"mcp.json\",\n },\n ];\n\n // Claude Code detection: check if 'claude' command is in PATH\n const claudeIde = ides.find((ide) => ide.id === \"claude-code\");\n if (claudeIde) {\n try {\n execFileSync(\"which\", [\"claude\"], { encoding: \"utf-8\" });\n claudeIde.detected = true;\n } catch {\n /* not found */\n }\n }\n\n return ides;\n}\n", "import { Command } from \"commander\";\nimport { detectNode } from \"../installer/node-detector.js\";\nimport { detectIDEs } from \"../installer/ide-detector.js\";\nimport { getSession } from \"../auth/session.js\";\n\nexport const setupCommand = new Command(\"setup\")\n .description(\"Configura ambiente para estudar\")\n .option(\"--quick\", \"Setup r\u00E1pido (sem wizard)\")\n .option(\"--ide <ide>\", \"Configura IDE espec\u00EDfica\")\n .action(async (_opts) => {\n console.log(\"\\n ToStudy Setup\\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\\n\");\n\n // Step 1: Check Node.js\n console.log(\" 1. Verificando Node.js...\");\n const node = detectNode();\n if (!node.installed) {\n console.log(\" \u2717 Node.js n\u00E3o encontrado\");\n console.log(\" \u2192 Instale via: https://nodejs.org/ ou `nvm install --lts`\\n\");\n process.exit(1);\n }\n if (!node.meetsMinimum) {\n console.log(` \u2717 Node.js ${node.version} \u00E9 muito antigo (m\u00EDnimo: v18)`);\n console.log(\" \u2192 Atualize via: `nvm install --lts`\\n\");\n process.exit(1);\n }\n console.log(` \u2713 Node.js ${node.version}\\n`);\n\n // Step 2: Check authentication\n console.log(\" 2. Verificando autentica\u00E7\u00E3o...\");\n let session = null;\n try {\n session = await getSession();\n } catch {\n /* session read failure treated as not logged in */\n }\n if (!session) {\n console.log(\" \u2717 N\u00E3o autenticado\");\n console.log(\" \u2192 Rode: tostudy login\\n\");\n process.exit(1);\n }\n console.log(` \u2713 Logado como ${session.userName}\\n`);\n\n // Step 3: Detect IDEs\n console.log(\" 3. Detectando IDEs...\");\n let ides: ReturnType<typeof detectIDEs> = [];\n try {\n ides = detectIDEs();\n } catch {\n /* IDE detection failure is non-fatal */\n }\n const detected = ides.filter((ide) => ide.detected);\n if (detected.length === 0) {\n console.log(\" \u25CB Nenhum IDE detectado\");\n console.log(\" \u2192 Use tostudy diretamente no terminal\\n\");\n } else {\n for (const ide of detected) {\n console.log(` \u2713 ${ide.name} detectado`);\n }\n console.log(\"\");\n }\n\n // Step 4: Summary\n console.log(\" Setup completo!\");\n console.log(\" \u2192 tostudy courses (ver cursos matriculados)\");\n console.log(\" \u2192 tostudy doctor (diagn\u00F3stico completo)\\n\");\n });\n", "import { Command } from \"commander\";\nimport { detectNode } from \"../installer/node-detector.js\";\nimport { detectIDEs } from \"../installer/ide-detector.js\";\nimport { getSession } from \"../auth/session.js\";\nimport { output } from \"../output/formatter.js\";\n\nexport const doctorCommand = new Command(\"doctor\")\n .description(\"Diagn\u00F3stico do ambiente\")\n .option(\"--json\", \"Output JSON\")\n .option(\"--fix\", \"Auto-corrigir problemas (reservado para vers\u00F5es futuras)\")\n .action(async (opts) => {\n const checks: Record<string, unknown> = {};\n\n // Environment checks\n const node = detectNode();\n const envChecks: Record<string, unknown> = {\n os: { platform: process.platform, arch: process.arch },\n node: { ...node },\n pnpm: null as string | null,\n git: null as string | null,\n };\n\n try {\n const { execFileSync } = await import(\"node:child_process\");\n envChecks[\"pnpm\"] = execFileSync(\"pnpm\", [\"--version\"], { encoding: \"utf-8\" }).trim();\n } catch {\n envChecks[\"pnpm\"] = null;\n }\n\n try {\n const { execFileSync } = await import(\"node:child_process\");\n envChecks[\"git\"] = execFileSync(\"git\", [\"--version\"], { encoding: \"utf-8\" })\n .trim()\n .replace(\"git version \", \"\");\n } catch {\n envChecks[\"git\"] = null;\n }\n\n checks[\"environment\"] = envChecks;\n\n // Auth check\n let session = null;\n try {\n session = await getSession();\n } catch {\n /* session read failure is non-fatal */\n }\n checks[\"auth\"] = {\n loggedIn: !!session,\n userName: session?.userName ?? null,\n expiresAt: session?.expiresAt ?? null,\n };\n\n // Connectivity check\n try {\n const apiUrl = session?.apiUrl ?? \"https://tostudy.ai\";\n const start = Date.now();\n const res = await fetch(`${apiUrl}/api/health`, {\n signal: AbortSignal.timeout(5000),\n });\n checks[\"connectivity\"] = { ok: res.ok, latencyMs: Date.now() - start };\n } catch {\n checks[\"connectivity\"] = { ok: false, latencyMs: null };\n }\n\n // IDE detection\n let ides: ReturnType<typeof detectIDEs> = [];\n try {\n ides = detectIDEs();\n } catch {\n /* IDE detection failure is non-fatal */\n }\n checks[\"ides\"] = ides.filter((ide) => ide.detected);\n\n if (opts.json) {\n output(checks, { json: true });\n return;\n }\n\n // Human-readable output\n const pnpmVersion = envChecks[\"pnpm\"] as string | null;\n const gitVersion = envChecks[\"git\"] as string | null;\n const connectivity = checks[\"connectivity\"] as { ok: boolean; latencyMs: number | null };\n\n console.log(\"\\n Ambiente\");\n console.log(\n ` ${node.installed ? \"\u2713\" : \"\u2717\"} Node ${node.version ?? \"n\u00E3o encontrado\"}`\n );\n console.log(\n ` ${node.meetsMinimum ? \"\u2713\" : \"\u2717\"} Vers\u00E3o ${node.meetsMinimum ? \"OK (>= 18)\" : \"Desatualizado\"}`\n );\n console.log(` \u2713 OS ${process.platform} (${process.arch})`);\n console.log(` ${pnpmVersion ? \"\u2713\" : \"\u25CB\"} pnpm ${pnpmVersion ?? \"n\u00E3o encontrado\"}`);\n console.log(` ${gitVersion ? \"\u2713\" : \"\u25CB\"} git ${gitVersion ?? \"n\u00E3o encontrado\"}`);\n\n console.log(\"\\n Autentica\u00E7\u00E3o\");\n console.log(` ${session ? \"\u2713\" : \"\u2717\"} Token ${session ? \"v\u00E1lido\" : \"n\u00E3o logado\"}`);\n if (session) {\n console.log(` \u2713 Usu\u00E1rio ${session.userName}`);\n }\n\n console.log(\"\\n Conectividade\");\n console.log(\n ` ${connectivity.ok ? \"\u2713\" : \"\u2717\"} API ${connectivity.ok ? `OK (${connectivity.latencyMs}ms)` : \"indispon\u00EDvel\"}`\n );\n\n console.log(\"\\n LLM Clients\");\n for (const ide of ides) {\n console.log(\n ` ${ide.detected ? \"\u2713\" : \"\u25CB\"} ${ide.name.padEnd(14)} ${ide.detected ? \"detectado\" : \"n\u00E3o detectado\"}`\n );\n }\n console.log(\"\");\n });\n", "// packages/logger/src/types.ts\n\n/**\n * Log levels with numeric priority.\n * Higher number = more severe.\n */\nexport const LOG_LEVELS = {\n trace: 0,\n debug: 1,\n info: 2,\n warn: 3,\n error: 4,\n fatal: 5,\n} as const\n\nexport type LogLevel = keyof typeof LOG_LEVELS\n\n/**\n * Error information for structured error logging.\n */\nexport interface ErrorInfo {\n name: string\n message: string\n stack?: string\n code?: string\n cause?: ErrorInfo\n}\n\n/**\n * Context that follows a request/operation through the system.\n */\nexport interface LogContext {\n // Tracing (required for requests)\n traceId?: string\n spanId?: string\n parentSpanId?: string\n requestId?: string\n\n // User context\n userId?: string\n sessionId?: string\n\n // Technical\n module?: string\n caller?: string\n duration?: number\n\n // Extensible\n [key: string]: unknown\n}\n\n/**\n * Complete log entry structure.\n */\nexport interface LogEntry {\n // Required fields\n timestamp: string\n level: LogLevel\n message: string\n service: string\n environment: string\n\n // Context (tracing, user, etc.)\n context: LogContext\n\n // Additional data\n data?: Record<string, unknown>\n\n // Error details (when level is error/fatal)\n error?: ErrorInfo\n}\n\n/**\n * Logger configuration options.\n */\nexport interface LoggerOptions {\n level?: LogLevel\n format?: 'json' | 'pretty'\n module?: string\n service?: string\n environment?: string\n /** Enable auto-sanitization of sensitive fields */\n sanitize?: boolean\n /** Additional sensitive field patterns to redact */\n sensitiveFields?: string[]\n /**\n * Include caller information (file:line:function) in log entries.\n * - true: Include caller for all log levels\n * - false: Never include caller\n * - 'errors': Include caller only for error/fatal levels (default)\n */\n includeCaller?: boolean | 'errors'\n}\n\nexport function isValidLevel(level: string): level is LogLevel {\n return level in LOG_LEVELS\n}\n", "// Node.js-only async context using AsyncLocalStorage\nimport { AsyncLocalStorage } from 'node:async_hooks'\nimport { randomBytes } from 'node:crypto'\nimport type { LogContext } from '../types'\n\nconst asyncLocalStorage = new AsyncLocalStorage<LogContext>()\n\nexport function withLogContext<T>(ctx: LogContext, fn: () => T): T {\n return asyncLocalStorage.run(ctx, fn)\n}\n\nexport function getLogContext(): LogContext | undefined {\n return asyncLocalStorage.getStore()\n}\n\nexport function generateTraceId(): string {\n return randomBytes(16).toString('hex')\n}\n\nexport function generateSpanId(): string {\n return randomBytes(8).toString('hex')\n}\n\n/**\n * Get the current correlation ID from context.\n * ADR-0002: Used for distributed tracing across services.\n *\n * @returns The correlation ID (traceId, requestId, or undefined)\n */\nexport function getCorrelationId(): string | undefined {\n const ctx = getLogContext()\n return ctx?.traceId ?? ctx?.requestId\n}\n", "// packages/logger/src/context/span.shared.ts\n// Shared span interfaces and implementation\n\nimport type { LogContext } from '../types'\n\nexport interface Span {\n traceId: string\n spanId: string\n parentSpanId?: string\n name: string\n startTime: number\n attributes: Record<string, unknown>\n\n /** Add an attribute to the span */\n setAttribute(key: string, value: unknown): void\n\n /** Record an exception on the span */\n recordException(error: Error): void\n\n /** Get duration in milliseconds */\n getDuration(): number\n\n /** End the span (records duration) */\n end(): void\n}\n\nexport interface SpanOptions {\n /** Span attributes */\n attributes?: Record<string, unknown>\n}\n\nexport class SpanImpl implements Span {\n traceId: string\n spanId: string\n parentSpanId?: string\n name: string\n startTime: number\n attributes: Record<string, unknown>\n private endTime?: number\n\n constructor(\n name: string,\n traceId: string,\n spanId: string,\n parentSpanId?: string,\n attributes?: Record<string, unknown>\n ) {\n this.name = name\n this.traceId = traceId\n this.spanId = spanId\n this.parentSpanId = parentSpanId\n this.startTime = Date.now()\n this.attributes = attributes ?? {}\n }\n\n setAttribute(key: string, value: unknown): void {\n this.attributes[key] = value\n }\n\n recordException(error: Error): void {\n this.setAttribute('error', true)\n this.setAttribute('error.type', error.name)\n this.setAttribute('error.message', error.message)\n }\n\n getDuration(): number {\n const end = this.endTime ?? Date.now()\n return end - this.startTime\n }\n\n end(): void {\n if (!this.endTime) {\n this.endTime = Date.now()\n }\n }\n}\n\n/**\n * Context provider interface for span operations.\n */\nexport interface SpanContextProvider {\n getLogContext(): LogContext | undefined\n withLogContext<T>(ctx: LogContext, fn: () => T): T\n generateSpanId(): string\n}\n\n/**\n * Execute an operation within a new span context.\n * Automatically tracks parent-child relationships and duration.\n */\nexport async function withSpanImpl<T>(\n name: string,\n operation: (span: Span) => Promise<T>,\n provider: SpanContextProvider,\n options?: SpanOptions\n): Promise<T> {\n const parentContext = provider.getLogContext()\n\n const traceId = parentContext?.traceId ?? provider.generateSpanId() + provider.generateSpanId()\n const spanId = provider.generateSpanId()\n const parentSpanId = parentContext?.spanId\n\n const span = new SpanImpl(name, traceId, spanId, parentSpanId, options?.attributes)\n\n const newContext: LogContext = {\n ...parentContext,\n traceId,\n spanId,\n parentSpanId,\n }\n\n try {\n const result = await provider.withLogContext(newContext, () => operation(span))\n span.end()\n return result\n } catch (error) {\n span.recordException(error as Error)\n span.end()\n throw error\n }\n}\n\n/**\n * Synchronous version of withSpan.\n */\nexport function withSpanSyncImpl<T>(\n name: string,\n operation: (span: Span) => T,\n provider: SpanContextProvider,\n options?: SpanOptions\n): T {\n const parentContext = provider.getLogContext()\n\n const traceId = parentContext?.traceId ?? provider.generateSpanId() + provider.generateSpanId()\n const spanId = provider.generateSpanId()\n const parentSpanId = parentContext?.spanId\n\n const span = new SpanImpl(name, traceId, spanId, parentSpanId, options?.attributes)\n\n const newContext: LogContext = {\n ...parentContext,\n traceId,\n spanId,\n parentSpanId,\n }\n\n try {\n const result = provider.withLogContext(newContext, () => operation(span))\n span.end()\n return result\n } catch (error) {\n span.recordException(error as Error)\n span.end()\n throw error\n }\n}\n\n/**\n * Create a span without executing an operation.\n */\nexport function startSpanImpl(\n name: string,\n provider: SpanContextProvider,\n options?: SpanOptions\n): Span {\n const parentContext = provider.getLogContext()\n\n const traceId = parentContext?.traceId ?? provider.generateSpanId() + provider.generateSpanId()\n const spanId = provider.generateSpanId()\n const parentSpanId = parentContext?.spanId\n\n return new SpanImpl(name, traceId, spanId, parentSpanId, options?.attributes)\n}\n", "// packages/logger/src/context/span.ts\n// Node.js span management for distributed tracing\n\nimport { withLogContext, getLogContext, generateSpanId } from './async-context'\nimport {\n type Span,\n type SpanOptions,\n type SpanContextProvider,\n withSpanImpl,\n withSpanSyncImpl,\n startSpanImpl,\n} from './span.shared'\n\n// Re-export shared types\nexport type { Span, SpanOptions } from './span.shared'\n\n// Create Node.js-specific context provider\nconst nodeContextProvider: SpanContextProvider = {\n getLogContext,\n withLogContext,\n generateSpanId,\n}\n\n/**\n * Execute an operation within a new span context.\n * Automatically tracks parent-child relationships and duration.\n *\n * @example\n * const result = await withSpan('processPayment', async (span) => {\n * span.setAttribute('payment.method', 'credit_card')\n * span.setAttribute('payment.amount', 299.90)\n * return await paymentService.process(order)\n * })\n */\nexport async function withSpan<T>(\n name: string,\n operation: (span: Span) => Promise<T>,\n options?: SpanOptions\n): Promise<T> {\n return withSpanImpl(name, operation, nodeContextProvider, options)\n}\n\n/**\n * Synchronous version of withSpan for non-async operations.\n *\n * @example\n * const result = withSpanSync('parseConfig', (span) => {\n * span.setAttribute('config.path', configPath)\n * return JSON.parse(configContent)\n * })\n */\nexport function withSpanSync<T>(\n name: string,\n operation: (span: Span) => T,\n options?: SpanOptions\n): T {\n return withSpanSyncImpl(name, operation, nodeContextProvider, options)\n}\n\n/**\n * Create a span without executing an operation.\n * Useful when you need manual control over the span lifecycle.\n *\n * @example\n * const span = startSpan('longOperation')\n * try {\n * // ... do work ...\n * span.setAttribute('items.processed', count)\n * } finally {\n * span.end()\n * }\n */\nexport function startSpan(name: string, options?: SpanOptions): Span {\n return startSpanImpl(name, nodeContextProvider, options)\n}\n", "// packages/logger/src/context/w3c-trace.ts\n// W3C Trace Context support (https://www.w3.org/TR/trace-context/)\n\nimport type { LogContext } from '../types'\nimport { getLogContext, generateTraceId, generateSpanId } from './async-context'\n\n/**\n * W3C Trace Context version.\n * Currently only version 00 is defined.\n */\nconst TRACE_VERSION = '00'\n\n/**\n * Trace flags.\n * 01 = sampled (trace is being recorded)\n * 00 = not sampled\n */\nconst TRACE_FLAG_SAMPLED = '01'\nconst TRACE_FLAG_NOT_SAMPLED = '00'\n\n/**\n * Regex to validate and parse traceparent header.\n * Format: {version}-{traceId}-{spanId}-{flags}\n * Example: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01\n */\nconst TRACEPARENT_REGEX = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/i\n\n/**\n * Parsed traceparent header components.\n */\nexport interface TraceparentComponents {\n version: string\n traceId: string\n spanId: string\n flags: string\n sampled: boolean\n}\n\n/**\n * Parse a W3C traceparent header value.\n *\n * @param header - The traceparent header value\n * @returns Parsed components or null if invalid\n *\n * @example\n * parseTraceparent('00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01')\n * // { version: '00', traceId: '0af7...', spanId: 'b7ad...', flags: '01', sampled: true }\n */\nexport function parseTraceparent(header: string | null | undefined): TraceparentComponents | null {\n if (!header) return null\n\n const match = header.match(TRACEPARENT_REGEX)\n if (!match) return null\n\n const [, version, traceId, spanId, flags] = match\n\n // Validate version (only 00 is currently supported)\n // Per spec, unknown versions should be accepted but may have different parsing rules\n if (version !== TRACE_VERSION) {\n // For future versions, we still extract the components\n // but downstream code should be aware of the version\n }\n\n return {\n version: version!,\n traceId: traceId!.toLowerCase(),\n spanId: spanId!.toLowerCase(),\n flags: flags!,\n sampled: (parseInt(flags!, 16) & 0x01) === 1,\n }\n}\n\n/**\n * Format a W3C traceparent header value.\n *\n * @param traceId - 32 hex character trace ID\n * @param spanId - 16 hex character span ID\n * @param sampled - Whether the trace is being recorded (default: true)\n * @returns Formatted traceparent header value\n *\n * @example\n * formatTraceparent('0af7651916cd43dd8448eb211c80319c', 'b7ad6b7169203331')\n * // '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01'\n */\nexport function formatTraceparent(\n traceId: string,\n spanId: string,\n sampled: boolean = true\n): string {\n const normalizedTraceId = traceId.toLowerCase().padStart(32, '0')\n const normalizedSpanId = spanId.toLowerCase().padStart(16, '0')\n const flags = sampled ? TRACE_FLAG_SAMPLED : TRACE_FLAG_NOT_SAMPLED\n\n return `${TRACE_VERSION}-${normalizedTraceId}-${normalizedSpanId}-${flags}`\n}\n\n/**\n * Get the current traceparent header value from context.\n * Returns null if no trace context is active.\n *\n * @example\n * const traceparent = getTraceparent()\n * // '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01'\n */\nexport function getTraceparent(): string | null {\n const ctx = getLogContext()\n if (!ctx?.traceId || !ctx?.spanId) return null\n\n return formatTraceparent(ctx.traceId, ctx.spanId)\n}\n\n/**\n * Create a LogContext from a traceparent header.\n * Generates a new spanId for the current operation.\n *\n * @param traceparent - The incoming traceparent header value\n * @returns LogContext with traceId, spanId, and parentSpanId\n *\n * @example\n * const ctx = contextFromTraceparent('00-abc123...-def456...-01')\n * // { traceId: 'abc123...', spanId: 'new123...', parentSpanId: 'def456...' }\n */\nexport function contextFromTraceparent(traceparent: string | null | undefined): LogContext | null {\n const parsed = parseTraceparent(traceparent)\n if (!parsed) return null\n\n return {\n traceId: parsed.traceId,\n spanId: generateSpanId(),\n parentSpanId: parsed.spanId,\n }\n}\n\n/**\n * Extract trace context from HTTP headers.\n * Supports both W3C traceparent and legacy custom headers.\n *\n * Priority:\n * 1. W3C traceparent header (standard)\n * 2. x-correlation-id / x-trace-id (legacy custom)\n *\n * @param headers - Object with get method or plain object\n * @returns LogContext or null if no trace headers found\n */\nexport function extractTraceContext(\n headers: { get?(name: string): string | null } | Record<string, string | undefined>\n): LogContext {\n const get = (name: string): string | null | undefined => {\n if (typeof (headers as { get?: unknown }).get === 'function') {\n return (headers as { get(name: string): string | null }).get(name)\n }\n return (headers as Record<string, string | undefined>)[name]\n }\n\n // Try W3C traceparent first\n const traceparent = get('traceparent')\n if (traceparent) {\n const ctx = contextFromTraceparent(traceparent)\n if (ctx) return ctx\n }\n\n // Fallback to legacy headers\n const traceId = get('x-correlation-id') ?? get('x-trace-id') ?? generateTraceId()\n const parentSpanId = get('x-span-id') ?? undefined\n\n return {\n traceId,\n spanId: generateSpanId(),\n parentSpanId,\n }\n}\n\n/**\n * Create headers object for outgoing requests.\n * Includes both W3C traceparent and legacy headers for compatibility.\n *\n * @param ctx - Optional LogContext (uses current context if not provided)\n * @returns Headers object with trace context\n *\n * @example\n * const headers = createTraceHeaders()\n * // {\n * // 'traceparent': '00-abc123...-def456...-01',\n * // 'x-correlation-id': 'abc123...',\n * // 'x-span-id': 'def456...'\n * // }\n */\nexport function createTraceHeaders(ctx?: LogContext): Record<string, string> {\n const context = ctx ?? getLogContext()\n if (!context?.traceId || !context?.spanId) {\n // Generate new trace context if none exists\n const traceId = generateTraceId()\n const spanId = generateSpanId()\n return {\n traceparent: formatTraceparent(traceId, spanId),\n 'x-correlation-id': traceId,\n 'x-span-id': spanId,\n }\n }\n\n return {\n traceparent: formatTraceparent(context.traceId, context.spanId),\n 'x-correlation-id': context.traceId,\n 'x-span-id': context.spanId,\n }\n}\n", "export {\n withLogContext,\n getLogContext,\n generateTraceId,\n generateSpanId,\n getCorrelationId,\n} from './async-context'\n\nexport {\n withSpan,\n withSpanSync,\n startSpan,\n type Span,\n type SpanOptions,\n} from './span'\n\n// W3C Trace Context support\nexport {\n parseTraceparent,\n formatTraceparent,\n getTraceparent,\n contextFromTraceparent,\n extractTraceContext,\n createTraceHeaders,\n type TraceparentComponents,\n} from './w3c-trace'\n", "// packages/logger/src/formatters/json.ts\nimport type { LogEntry } from '../types'\n\nexport function formatJson(entry: LogEntry): string {\n const { timestamp, level, message, service, environment, context, data, error } = entry\n\n const output: Record<string, unknown> = {\n timestamp,\n level,\n message,\n service,\n environment,\n ...context,\n ...data,\n }\n\n // Include error info at top level for easier querying\n if (error) {\n output.error = error\n }\n\n return JSON.stringify(output)\n}\n", "let p = process || {}, argv = p.argv || [], env = p.env || {}\nlet isColorSupported =\n\t!(!!env.NO_COLOR || argv.includes(\"--no-color\")) &&\n\t(!!env.FORCE_COLOR || argv.includes(\"--color\") || p.platform === \"win32\" || ((p.stdout || {}).isTTY && env.TERM !== \"dumb\") || !!env.CI)\n\nlet formatter = (open, close, replace = open) =>\n\tinput => {\n\t\tlet string = \"\" + input, index = string.indexOf(close, open.length)\n\t\treturn ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close\n\t}\n\nlet replaceClose = (string, close, replace, index) => {\n\tlet result = \"\", cursor = 0\n\tdo {\n\t\tresult += string.substring(cursor, index) + replace\n\t\tcursor = index + close.length\n\t\tindex = string.indexOf(close, cursor)\n\t} while (~index)\n\treturn result + string.substring(cursor)\n}\n\nlet createColors = (enabled = isColorSupported) => {\n\tlet f = enabled ? formatter : () => String\n\treturn {\n\t\tisColorSupported: enabled,\n\t\treset: f(\"\\x1b[0m\", \"\\x1b[0m\"),\n\t\tbold: f(\"\\x1b[1m\", \"\\x1b[22m\", \"\\x1b[22m\\x1b[1m\"),\n\t\tdim: f(\"\\x1b[2m\", \"\\x1b[22m\", \"\\x1b[22m\\x1b[2m\"),\n\t\titalic: f(\"\\x1b[3m\", \"\\x1b[23m\"),\n\t\tunderline: f(\"\\x1b[4m\", \"\\x1b[24m\"),\n\t\tinverse: f(\"\\x1b[7m\", \"\\x1b[27m\"),\n\t\thidden: f(\"\\x1b[8m\", \"\\x1b[28m\"),\n\t\tstrikethrough: f(\"\\x1b[9m\", \"\\x1b[29m\"),\n\n\t\tblack: f(\"\\x1b[30m\", \"\\x1b[39m\"),\n\t\tred: f(\"\\x1b[31m\", \"\\x1b[39m\"),\n\t\tgreen: f(\"\\x1b[32m\", \"\\x1b[39m\"),\n\t\tyellow: f(\"\\x1b[33m\", \"\\x1b[39m\"),\n\t\tblue: f(\"\\x1b[34m\", \"\\x1b[39m\"),\n\t\tmagenta: f(\"\\x1b[35m\", \"\\x1b[39m\"),\n\t\tcyan: f(\"\\x1b[36m\", \"\\x1b[39m\"),\n\t\twhite: f(\"\\x1b[37m\", \"\\x1b[39m\"),\n\t\tgray: f(\"\\x1b[90m\", \"\\x1b[39m\"),\n\n\t\tbgBlack: f(\"\\x1b[40m\", \"\\x1b[49m\"),\n\t\tbgRed: f(\"\\x1b[41m\", \"\\x1b[49m\"),\n\t\tbgGreen: f(\"\\x1b[42m\", \"\\x1b[49m\"),\n\t\tbgYellow: f(\"\\x1b[43m\", \"\\x1b[49m\"),\n\t\tbgBlue: f(\"\\x1b[44m\", \"\\x1b[49m\"),\n\t\tbgMagenta: f(\"\\x1b[45m\", \"\\x1b[49m\"),\n\t\tbgCyan: f(\"\\x1b[46m\", \"\\x1b[49m\"),\n\t\tbgWhite: f(\"\\x1b[47m\", \"\\x1b[49m\"),\n\n\t\tblackBright: f(\"\\x1b[90m\", \"\\x1b[39m\"),\n\t\tredBright: f(\"\\x1b[91m\", \"\\x1b[39m\"),\n\t\tgreenBright: f(\"\\x1b[92m\", \"\\x1b[39m\"),\n\t\tyellowBright: f(\"\\x1b[93m\", \"\\x1b[39m\"),\n\t\tblueBright: f(\"\\x1b[94m\", \"\\x1b[39m\"),\n\t\tmagentaBright: f(\"\\x1b[95m\", \"\\x1b[39m\"),\n\t\tcyanBright: f(\"\\x1b[96m\", \"\\x1b[39m\"),\n\t\twhiteBright: f(\"\\x1b[97m\", \"\\x1b[39m\"),\n\n\t\tbgBlackBright: f(\"\\x1b[100m\", \"\\x1b[49m\"),\n\t\tbgRedBright: f(\"\\x1b[101m\", \"\\x1b[49m\"),\n\t\tbgGreenBright: f(\"\\x1b[102m\", \"\\x1b[49m\"),\n\t\tbgYellowBright: f(\"\\x1b[103m\", \"\\x1b[49m\"),\n\t\tbgBlueBright: f(\"\\x1b[104m\", \"\\x1b[49m\"),\n\t\tbgMagentaBright: f(\"\\x1b[105m\", \"\\x1b[49m\"),\n\t\tbgCyanBright: f(\"\\x1b[106m\", \"\\x1b[49m\"),\n\t\tbgWhiteBright: f(\"\\x1b[107m\", \"\\x1b[49m\"),\n\t}\n}\n\nmodule.exports = createColors()\nmodule.exports.createColors = createColors\n", "import pc from 'picocolors'\nimport type { LogEntry, LogLevel } from '../types'\n\nconst LEVEL_COLORS: Record<LogLevel, (s: string) => string> = {\n trace: pc.gray,\n debug: pc.cyan,\n info: pc.green,\n warn: pc.yellow,\n error: pc.red,\n fatal: (s: string) => pc.bgRed(pc.white(s)),\n}\n\nconst LEVEL_WIDTH = 5 // 'ERROR'.length\n\nfunction formatTime(timestamp: string): string {\n const date = new Date(timestamp)\n const hours = String(date.getUTCHours()).padStart(2, '0')\n const minutes = String(date.getUTCMinutes()).padStart(2, '0')\n const seconds = String(date.getUTCSeconds()).padStart(2, '0')\n return `${hours}:${minutes}:${seconds}`\n}\n\nfunction formatLevel(level: LogLevel): string {\n const colorFn = LEVEL_COLORS[level]\n return colorFn(level.toUpperCase().padEnd(LEVEL_WIDTH))\n}\n\nfunction formatData(data: Record<string, unknown>): string {\n const entries = Object.entries(data)\n if (entries.length === 0) return ''\n\n const lines = entries.map(([key, value]) => {\n const formatted = typeof value === 'object'\n ? JSON.stringify(value)\n : String(value)\n return ` ${pc.dim(key + ':')} ${formatted}`\n })\n\n return '\\n' + lines.join('\\n')\n}\n\nexport function formatPretty(entry: LogEntry): string {\n const { timestamp, level, message, service, context, data, error } = entry\n\n const time = formatTime(timestamp)\n const lvl = formatLevel(level)\n const mod = context.module ? pc.dim(`[${context.module}]`) + ' ' : ''\n const svc = pc.dim(`[${service}]`) + ' '\n\n let output = `${pc.dim(time)} ${lvl} ${svc}${mod}${message}`\n\n // Add trace context if present\n const traceInfo: Record<string, unknown> = {}\n if (context.traceId) traceInfo.traceId = context.traceId\n if (context.requestId && context.requestId !== context.traceId) {\n traceInfo.requestId = context.requestId\n }\n if (context.caller) traceInfo.caller = context.caller\n if (context.duration !== undefined) traceInfo.duration = `${context.duration}ms`\n\n const allData = { ...traceInfo, ...data }\n if (Object.keys(allData).length > 0) {\n output += formatData(allData)\n }\n\n // Add error details\n if (error) {\n output += '\\n' + pc.red(` ${error.name}: ${error.message}`)\n if (error.code) {\n output += pc.dim(` (${error.code})`)\n }\n if (error.stack) {\n const stackLines = error.stack.split('\\n').slice(1, 4) // First 3 stack frames\n output += '\\n' + stackLines.map(l => pc.dim(` ${l.trim()}`)).join('\\n')\n }\n if (error.cause) {\n output += '\\n' + pc.dim(` Caused by: ${error.cause.name}: ${error.cause.message}`)\n }\n }\n\n return output\n}\n", "// packages/logger/src/sanitize.ts\n// PII sanitization utilities for secure logging\n\n/**\n * Fields that should be automatically redacted from logs.\n * Case-insensitive matching against object keys.\n */\nexport const SENSITIVE_FIELDS = [\n // Authentication\n 'password', 'senha', 'pwd', 'pass',\n 'token', 'accessToken', 'access_token', 'refreshToken', 'refresh_token',\n 'apiKey', 'api_key', 'apikey', 'secret', 'secretKey', 'secret_key',\n 'authorization', 'auth', 'bearer',\n\n // Payment\n 'creditCard', 'credit_card', 'cardNumber', 'card_number',\n 'cvv', 'cvc', 'securityCode', 'security_code',\n 'accountNumber', 'account_number',\n\n // Personal identification\n 'cpf', 'rg', 'ssn', 'cnh', 'passport',\n 'email', 'phone',\n\n // Crypto\n 'privateKey', 'private_key', 'privatekey',\n 'mnemonic', 'seed', 'seedPhrase', 'seed_phrase',\n] as const\n\nexport type SensitiveField = typeof SENSITIVE_FIELDS[number]\n\n/**\n * Sanitize an email address for logging.\n * @example sanitize.email(\"john.doe@example.com\") => \"j***@example.com\"\n */\nfunction email(value: string): string {\n if (!value || typeof value !== 'string') return '[INVALID_EMAIL]'\n\n const atIndex = value.indexOf('@')\n if (atIndex === -1) return '[INVALID_EMAIL]'\n\n const [user, domain] = [value.slice(0, atIndex), value.slice(atIndex + 1)]\n if (!user || !domain) return '[INVALID_EMAIL]'\n\n const maskedUser = user.length <= 1\n ? '*'\n : user[0] + '*'.repeat(Math.min(user.length - 1, 5))\n\n return `${maskedUser}@${domain}`\n}\n\n/**\n * Sanitize a phone number for logging.\n * @example sanitize.phone(\"+5511999998888\") => \"**********8888\"\n */\nfunction phone(value: string): string {\n if (!value || typeof value !== 'string') return '[INVALID_PHONE]'\n\n const digits = value.replace(/\\D/g, '')\n if (digits.length < 4) return '[INVALID_PHONE]'\n\n return '*'.repeat(digits.length - 4) + digits.slice(-4)\n}\n\n/**\n * Sanitize a CPF for logging.\n * @example sanitize.cpf(\"123.456.789-00\") => \"***.***789-**\"\n */\nfunction cpf(value: string): string {\n if (!value || typeof value !== 'string') return '[INVALID_CPF]'\n\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 11) return '[INVALID_CPF]'\n\n return `***.***${digits.slice(6, 9)}-**`\n}\n\n/**\n * Sanitize a credit card number for logging.\n * @example sanitize.creditCard(\"4111111111111111\") => \"************1111\"\n */\nfunction creditCard(value: string): string {\n if (!value || typeof value !== 'string') return '[INVALID_CARD]'\n\n const digits = value.replace(/\\D/g, '')\n if (digits.length < 4) return '[INVALID_CARD]'\n\n return '*'.repeat(digits.length - 4) + digits.slice(-4)\n}\n\n/**\n * Sanitize an IP address for logging (privacy compliance).\n * @example sanitize.ip(\"192.168.1.100\") => \"192.168.1.xxx\"\n * @example sanitize.ip(\"2001:db8::1\") => \"2001:db8::xxxx\"\n */\nfunction ip(value: string): string {\n if (!value || typeof value !== 'string') return '[INVALID_IP]'\n\n // IPv6\n if (value.includes(':')) {\n const lastColon = value.lastIndexOf(':')\n return value.slice(0, lastColon + 1) + 'xxxx'\n }\n\n // IPv4\n const lastDot = value.lastIndexOf('.')\n if (lastDot === -1) return '[INVALID_IP]'\n\n return value.slice(0, lastDot + 1) + 'xxx'\n}\n\n/**\n * Sanitize a token/secret for logging.\n * @example sanitize.token(\"eyJhbGciOiJIUzI1NiIs...\") => \"eyJh...[REDACTED]...iIs\"\n */\nfunction token(value: string): string {\n if (!value || typeof value !== 'string') return '[REDACTED]'\n\n if (value.length <= 8) return '[REDACTED]'\n\n return `${value.slice(0, 4)}...[REDACTED]...${value.slice(-4)}`\n}\n\n/**\n * Check if a key matches any sensitive field pattern.\n * Uses word boundary matching to avoid false positives (e.g., \"tokens\" matching \"token\").\n * Handles: exact match, camelCase (userPassword), snake_case (api_key), kebab-case (api-key)\n */\nfunction isSensitiveKey(key: string): boolean {\n const lowerKey = key.toLowerCase()\n\n return SENSITIVE_FIELDS.some(field => {\n const lowerField = field.toLowerCase()\n\n // Exact match (case-insensitive)\n if (lowerKey === lowerField) return true\n\n // Match at end (handles camelCase like \"userPassword\", \"apiToken\")\n if (lowerKey.endsWith(lowerField)) return true\n\n // Match at start with uppercase boundary (handles \"passwordHash\", \"tokenExpiry\")\n // We check original key for uppercase boundary\n const fieldIdx = key.toLowerCase().indexOf(lowerField)\n if (fieldIdx === 0) {\n const afterIdx = lowerField.length\n if (afterIdx >= key.length) return true // exact match covered above\n // Check if next char is uppercase (camelCase) or non-alpha\n const nextChar = key[afterIdx]\n if (nextChar && (nextChar === nextChar.toUpperCase() || !/[a-zA-Z]/.test(nextChar))) {\n return true\n }\n }\n\n // Match with underscore/hyphen boundaries (e.g., \"api_key\", \"api-key\", \"user_password\")\n const patterns = [\n `_${lowerField}`, `${lowerField}_`,\n `-${lowerField}`, `${lowerField}-`,\n `_${lowerField}_`, `-${lowerField}-`,\n ]\n return patterns.some(p => lowerKey.includes(p))\n })\n}\n\n/**\n * Recursively sanitize an object, redacting sensitive fields.\n * @example sanitize.object({ password: \"secret\", name: \"John\" })\n * => { password: \"[REDACTED]\", name: \"John\" }\n */\nfunction object<T extends Record<string, unknown>>(\n obj: T,\n additionalSensitiveKeys?: string[]\n): T {\n if (!obj || typeof obj !== 'object') return obj\n\n const sanitized = { ...obj }\n\n for (const [key, value] of Object.entries(sanitized)) {\n // Check if key is sensitive using the isSensitiveKey function\n // or matches additional keys exactly\n const isAdditionalKey = additionalSensitiveKeys?.some(k =>\n key.toLowerCase() === k.toLowerCase()\n )\n\n if (isSensitiveKey(key) || isAdditionalKey) {\n sanitized[key as keyof T] = '[REDACTED]' as T[keyof T]\n continue\n }\n\n // Recursively sanitize nested objects\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n sanitized[key as keyof T] = object(\n value as Record<string, unknown>,\n additionalSensitiveKeys\n ) as T[keyof T]\n continue\n }\n\n // Sanitize arrays of objects\n if (Array.isArray(value)) {\n sanitized[key as keyof T] = value.map(item => {\n if (item && typeof item === 'object' && !Array.isArray(item)) {\n return object(item as Record<string, unknown>, additionalSensitiveKeys)\n }\n return item\n }) as T[keyof T]\n }\n }\n\n return sanitized\n}\n\n/**\n * Sanitize headers object, redacting auth-related headers.\n */\nfunction headers(hdrs: Record<string, string | string[] | undefined>): Record<string, string | string[] | undefined> {\n const sensitiveHeaders = [\n 'authorization',\n 'x-api-key',\n 'x-auth-token',\n 'cookie',\n 'set-cookie',\n ]\n\n const sanitized = { ...hdrs }\n\n for (const key of Object.keys(sanitized)) {\n if (sensitiveHeaders.some(h => key.toLowerCase() === h)) {\n sanitized[key] = '[REDACTED]'\n }\n }\n\n return sanitized\n}\n\n/**\n * Sanitization utilities for secure logging.\n *\n * @example\n * import { sanitize } from '@repo/logger'\n *\n * logger.info('User login', {\n * email: sanitize.email(user.email),\n * ip: sanitize.ip(request.ip),\n * })\n *\n * // Or sanitize entire objects\n * logger.info('Request data', sanitize.object(requestBody))\n */\nexport const sanitize = {\n email,\n phone,\n cpf,\n creditCard,\n ip,\n token,\n object,\n headers,\n isSensitiveKey,\n} as const\n\nexport type Sanitize = typeof sanitize\n", "// packages/logger/src/logger.base.ts\n// Shared logger logic for Node.js and browser environments\n\nimport { LOG_LEVELS, type LogLevel, type LogEntry, type LogContext, type LoggerOptions, type ErrorInfo } from './types'\nimport { formatJson } from './formatters/json'\nimport { formatPretty } from './formatters/pretty'\nimport { sanitize } from './sanitize'\n\n/**\n * Transport interface for log output destinations.\n * Re-export from transports for backwards compatibility.\n */\nexport interface Transport {\n log(entry: LogEntry, formatted: string): void\n}\n\n/**\n * Extract ErrorInfo from an Error object, including cause chain.\n */\nexport function extractErrorInfo(error: Error, includeStack: boolean): ErrorInfo {\n const info: ErrorInfo = {\n name: error.name,\n message: error.message,\n }\n\n if (includeStack && error.stack) {\n info.stack = error.stack\n }\n\n // Extract error code if present\n if ('code' in error && typeof error.code === 'string') {\n info.code = error.code\n }\n\n // Extract cause chain\n if (error.cause instanceof Error) {\n info.cause = extractErrorInfo(error.cause, includeStack)\n }\n\n return info\n}\n\n/**\n * Base configuration for detecting environment.\n */\nexport interface EnvironmentInfo {\n isProd: boolean\n env: string\n}\n\n/**\n * Abstract base logger with shared functionality.\n * Platform-specific implementations extend this class.\n */\nexport abstract class BaseLogger {\n protected level: LogLevel\n protected format: 'json' | 'pretty'\n protected module?: string\n protected service: string\n protected environment: string\n protected additionalContext: LogContext\n protected transports: Transport[]\n protected shouldSanitize: boolean\n protected sensitiveFields?: string[]\n protected includeCaller: boolean | 'errors'\n\n constructor(\n options: LoggerOptions,\n defaults: { level: LogLevel; format: 'json' | 'pretty'; service: string; env: string }\n ) {\n this.level = options.level ?? defaults.level\n this.format = options.format ?? defaults.format\n this.module = options.module\n this.service = options.service ?? defaults.service\n this.environment = options.environment ?? defaults.env\n this.additionalContext = {}\n this.transports = []\n this.shouldSanitize = options.sanitize ?? true\n this.sensitiveFields = options.sensitiveFields\n this.includeCaller = options.includeCaller ?? 'errors'\n }\n\n /**\n * Get the current log context (traceId, spanId, etc).\n * Implemented differently in Node.js (AsyncLocalStorage) vs browser.\n */\n protected abstract getLogContext(): LogContext | undefined\n\n /**\n * Check if environment is production.\n */\n protected abstract isProd(): boolean\n\n /**\n * Get caller information for error logging (Node.js only).\n */\n protected getCaller(): string | undefined {\n return undefined // Browser doesn't support stack introspection\n }\n\n /**\n * Flush any buffered logs (e.g., file transport).\n */\n protected flush(): void {\n // Override in Node.js logger for file transport\n }\n\n protected shouldLog(level: LogLevel): boolean {\n return LOG_LEVELS[level] >= LOG_LEVELS[this.level]\n }\n\n protected buildEntry(\n level: LogLevel,\n message: string,\n data?: Record<string, unknown>,\n error?: ErrorInfo\n ): LogEntry {\n const asyncContext = this.getLogContext() ?? {}\n\n const context: LogContext = {\n ...asyncContext,\n ...this.additionalContext,\n }\n\n if (this.module) {\n context.module = this.module\n }\n\n // Add caller based on includeCaller option (Node.js only)\n const shouldIncludeCaller =\n this.includeCaller === true ||\n (this.includeCaller === 'errors' && (level === 'error' || level === 'fatal'))\n\n if (shouldIncludeCaller) {\n const caller = this.getCaller()\n if (caller) context.caller = caller\n }\n\n return {\n timestamp: new Date().toISOString(),\n level,\n message,\n service: this.service,\n environment: this.environment,\n context,\n data,\n error,\n }\n }\n\n /**\n * Normalizes any data type to Record<string, unknown> for structured logging.\n */\n protected normalizeData(data: unknown): Record<string, unknown> | undefined {\n if (data === null || data === undefined) {\n return undefined\n }\n\n if (data instanceof Error) {\n return {\n error: data.message,\n errorName: data.name,\n stack: data.stack,\n }\n }\n\n if (typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean') {\n return { value: data }\n }\n\n if (Array.isArray(data)) {\n return { items: data }\n }\n\n if (typeof data === 'object') {\n const obj = data as Record<string, unknown>\n return this.shouldSanitize\n ? sanitize.object(obj, this.sensitiveFields)\n : obj\n }\n\n return { value: String(data) }\n }\n\n protected log(level: LogLevel, message: string, data?: unknown, errorObj?: Error): void {\n if (!this.shouldLog(level)) return\n\n const normalizedData = this.normalizeData(data)\n const errorInfo = errorObj ? extractErrorInfo(errorObj, !this.isProd()) : undefined\n const entry = this.buildEntry(level, message, normalizedData, errorInfo)\n\n const formatted = this.format === 'json'\n ? formatJson(entry)\n : formatPretty(entry)\n\n for (const transport of this.transports) {\n transport.log(entry, formatted)\n }\n\n this.flush()\n }\n\n trace(message: string, ...args: unknown[]): void {\n this.log('trace', message, args.length === 1 ? args[0] : args.length > 1 ? args : undefined)\n }\n\n debug(message: string, ...args: unknown[]): void {\n this.log('debug', message, args.length === 1 ? args[0] : args.length > 1 ? args : undefined)\n }\n\n info(message: string, ...args: unknown[]): void {\n this.log('info', message, args.length === 1 ? args[0] : args.length > 1 ? args : undefined)\n }\n\n warn(message: string, ...args: unknown[]): void {\n this.log('warn', message, args.length === 1 ? args[0] : args.length > 1 ? args : undefined)\n }\n\n error(message: string, errorOrData?: Error | unknown, data?: unknown): void {\n if (errorOrData instanceof Error) {\n this.log('error', message, data, errorOrData)\n } else {\n this.log('error', message, errorOrData)\n }\n }\n\n /**\n * Log a fatal error (system-critical).\n */\n fatal(message: string, errorOrData?: Error | unknown, data?: unknown): void {\n if (errorOrData instanceof Error) {\n this.log('fatal', message, data, errorOrData)\n } else {\n this.log('fatal', message, errorOrData)\n }\n }\n\n /**\n * Get the current trace ID from context.\n */\n getTraceId(): string | undefined {\n const ctx = this.getLogContext()\n return ctx?.traceId ?? this.additionalContext.traceId as string | undefined\n }\n\n /**\n * Get the current span ID from context.\n */\n getSpanId(): string | undefined {\n const ctx = this.getLogContext()\n return ctx?.spanId ?? this.additionalContext.spanId as string | undefined\n }\n\n /**\n * Time an async operation and log its duration.\n */\n async time<T>(\n operation: string,\n fn: () => Promise<T>,\n data?: Record<string, unknown>\n ): Promise<T> {\n const start = Date.now()\n try {\n const result = await fn()\n const duration = Date.now() - start\n this.info(`${operation} completed`, { ...data, duration, operation })\n return result\n } catch (error) {\n const duration = Date.now() - start\n this.error(`${operation} failed`, error as Error, { ...data, duration, operation })\n throw error\n }\n }\n\n /**\n * Time a sync operation and log its duration.\n */\n timeSync<T>(\n operation: string,\n fn: () => T,\n data?: Record<string, unknown>\n ): T {\n const start = Date.now()\n try {\n const result = fn()\n const duration = Date.now() - start\n this.info(`${operation} completed`, { ...data, duration, operation })\n return result\n } catch (error) {\n const duration = Date.now() - start\n this.error(`${operation} failed`, error as Error, { ...data, duration, operation })\n throw error\n }\n }\n\n /**\n * Create a child logger with additional context.\n * Must be implemented by subclasses to return correct type.\n */\n abstract child(context: LogContext): BaseLogger\n}\n", "// packages/logger/src/transports/console.ts\n// Node.js console transport using stdout/stderr\n\nimport type { LogEntry } from '../types'\n\nexport interface Transport {\n log(entry: LogEntry, formatted: string): void\n}\n\nexport class ConsoleTransport implements Transport {\n log(entry: LogEntry, formatted: string): void {\n // Use stderr for error/fatal levels\n if (entry.level === 'error' || entry.level === 'fatal') {\n process.stderr.write(formatted + '\\n')\n } else {\n process.stdout.write(formatted + '\\n')\n }\n }\n}\n", "// Node.js-only file transport\nimport { appendFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport type { LogEntry } from '../types'\nimport type { Transport } from './console'\n\nexport interface FileTransportOptions {\n dir: string\n}\n\nexport class FileTransport implements Transport {\n private dir: string\n private initialized = false\n private buffer: { file: string; content: string }[] = []\n\n constructor(options: FileTransportOptions) {\n this.dir = options.dir\n }\n\n private init(): void {\n if (this.initialized) return\n\n if (!existsSync(this.dir)) {\n mkdirSync(this.dir, { recursive: true })\n }\n\n const gitignore = join(this.dir, '.gitignore')\n if (!existsSync(gitignore)) {\n writeFileSync(gitignore, '*.log\\n')\n }\n\n this.initialized = true\n }\n\n log(entry: LogEntry, formatted: string): void {\n this.init()\n\n const line = formatted + '\\n'\n\n // Always write to combined.log\n this.buffer.push({ file: 'combined.log', content: line })\n\n // Also write errors to error.log\n if (entry.level === 'error') {\n this.buffer.push({ file: 'error.log', content: line })\n }\n }\n\n flush(): void {\n for (const { file, content } of this.buffer) {\n const filepath = join(this.dir, file)\n appendFileSync(filepath, content)\n }\n this.buffer = []\n }\n}\n", "// packages/logger/src/logger.ts\n// Node.js logger with file transport support\n\nimport type { LogLevel, LogContext, LoggerOptions } from './types'\nimport { LOG_LEVELS } from './types'\nimport { getLogContext } from './context'\nimport { BaseLogger } from './logger.base'\nimport { ConsoleTransport } from './transports/console'\nimport { FileTransport } from './transports/file'\n\nfunction detectEnvironment(): { isProd: boolean; env: string } {\n const isProd = process.env.NODE_ENV === 'production'\n || !!process.env.VERCEL\n || !!process.env.RAILWAY_ENVIRONMENT\n\n let env: string = process.env.NODE_ENV || 'development'\n if (process.env.VERCEL) env = (process.env.VERCEL_ENV as string) || 'production'\n if (process.env.RAILWAY_ENVIRONMENT) env = process.env.RAILWAY_ENVIRONMENT as string\n\n return { isProd, env }\n}\n\nfunction getDefaultFormat(): 'json' | 'pretty' {\n const override = process.env.LOG_FORMAT as 'json' | 'pretty' | undefined\n if (override === 'json' || override === 'pretty') return override\n\n const { isProd } = detectEnvironment()\n return isProd ? 'json' : 'pretty'\n}\n\nfunction getDefaultLevel(): LogLevel {\n const override = process.env.LOG_LEVEL as LogLevel | undefined\n if (override && override in LOG_LEVELS) return override\n\n const { isProd } = detectEnvironment()\n return isProd ? 'info' : 'debug'\n}\n\nfunction getDefaultService(): string {\n return process.env.SERVICE_NAME\n || process.env.VERCEL_GIT_REPO_SLUG\n || process.env.RAILWAY_SERVICE_NAME\n || 'unknown-service'\n}\n\n/**\n * Extract caller information from stack trace.\n * Returns format: \"filename:line:function\"\n */\nfunction getCaller(): string | undefined {\n const err = new Error()\n const stack = err.stack?.split('\\n')\n\n if (!stack) return undefined\n\n // Find the first stack frame outside the logger\n for (let i = 3; i < stack.length; i++) {\n const line = stack[i]\n if (!line) continue\n\n // Skip internal logger frames\n if (line.includes('/logger/src/')) continue\n if (line.includes('@repo/logger')) continue\n\n // Extract file:line:column\n const match = line.match(/at (?:(.+?) )?\\(?(.+?):(\\d+):(\\d+)\\)?/)\n if (match) {\n const [, fnName, file, lineNum] = match\n const fileName = file?.split('/').pop() || file\n return fnName\n ? `${fileName}:${lineNum}:${fnName}`\n : `${fileName}:${lineNum}`\n }\n }\n\n return undefined\n}\n\nexport class Logger extends BaseLogger {\n private fileTransport?: FileTransport\n private _isProd: boolean\n\n constructor(options: LoggerOptions = {}) {\n const { isProd, env } = detectEnvironment()\n\n super(options, {\n level: getDefaultLevel(),\n format: getDefaultFormat(),\n service: getDefaultService(),\n env,\n })\n\n this._isProd = isProd\n this.transports = [new ConsoleTransport()]\n\n // Add file transport in development (not in prod or Vercel/Railway)\n if (!isProd && !process.env.VERCEL && !process.env.RAILWAY_ENVIRONMENT) {\n this.fileTransport = new FileTransport({ dir: 'logs' })\n this.transports.push(this.fileTransport)\n }\n }\n\n protected getLogContext(): LogContext | undefined {\n return getLogContext()\n }\n\n protected isProd(): boolean {\n return this._isProd\n }\n\n protected override getCaller(): string | undefined {\n return getCaller()\n }\n\n protected override flush(): void {\n this.fileTransport?.flush()\n }\n\n /**\n * Create a child logger with additional context.\n * Child shares transports with parent.\n */\n child(context: LogContext): Logger {\n const child = new Logger({\n level: this.level,\n format: this.format,\n module: this.module,\n service: this.service,\n environment: this.environment,\n sanitize: this.shouldSanitize,\n sensitiveFields: this.sensitiveFields,\n includeCaller: this.includeCaller,\n })\n child.additionalContext = { ...this.additionalContext, ...context }\n // Share transports with parent\n child.transports = this.transports\n child.fileTransport = this.fileTransport\n return child\n }\n}\n", "// packages/logger/src/middleware/trpc.ts\nimport { withLogContext, extractTraceContext } from '../context'\nimport { Logger } from '../logger'\nimport type { LogContext, LoggerOptions } from '../types'\n\n// Local createLogger to avoid circular dependency with index.ts\nfunction createLogger(module: string, options?: Omit<LoggerOptions, 'module'>): Logger {\n return new Logger({ ...options, module })\n}\n\ninterface MiddlewareOptions {\n ctx: {\n session?: { user?: { id?: string } }\n headers?: { get?(name: string): string | null }\n }\n next: () => Promise<unknown>\n type: string\n path: string\n rawInput: unknown\n getRawInput: () => Promise<unknown>\n meta: unknown\n input: unknown\n signal: AbortSignal\n}\n\nexport interface LoggingMiddlewareConfig {\n /** Service name for logs */\n service?: string\n /** Log request/response details */\n logRequests?: boolean\n /** Log input data (sanitized) */\n logInput?: boolean\n}\n\nconst defaultConfig: LoggingMiddlewareConfig = {\n logRequests: true,\n logInput: false,\n}\n\nexport function createLoggingMiddleware(config: LoggingMiddlewareConfig = {}) {\n const { service, logRequests, logInput } = { ...defaultConfig, ...config }\n const logger = createLogger(service ?? 'trpc')\n\n return async function loggingMiddleware(opts: MiddlewareOptions) {\n const { ctx, next, type, path } = opts\n const startTime = Date.now()\n\n // Extract trace context from headers\n // ADR-0002: Support W3C traceparent, x-correlation-id, and x-trace-id\n const traceContext = extractTraceContext(ctx.headers ?? {})\n\n // Build context\n const logContext: LogContext = {\n ...traceContext,\n requestId: traceContext.traceId,\n }\n\n // Add user ID if authenticated\n if (ctx.session?.user?.id) {\n logContext.userId = ctx.session.user.id\n }\n\n // Log request start\n if (logRequests) {\n const requestData: Record<string, unknown> = {\n type,\n path,\n }\n if (logInput && opts.input) {\n requestData.input = opts.input\n }\n logger.child(logContext).debug('tRPC request started', requestData)\n }\n\n // Run handler within context\n try {\n const result = await withLogContext(logContext, () => next())\n const duration = Date.now() - startTime\n\n // Log success\n if (logRequests) {\n logger.child({ ...logContext, duration }).info('tRPC request completed', {\n type,\n path,\n duration,\n })\n }\n\n return result\n } catch (error) {\n const duration = Date.now() - startTime\n\n // Log error\n logger.child({ ...logContext, duration }).error(\n 'tRPC request failed',\n error as Error,\n { type, path, duration }\n )\n\n throw error\n }\n }\n}\n", "// packages/logger/src/middleware/index.ts\nexport { createLoggingMiddleware, type LoggingMiddlewareConfig } from './trpc'\n", "// packages/logger/src/index.ts\nimport { Logger } from './logger'\n\n// Re-export types\nexport type { LogLevel, LogContext, LogEntry, LoggerOptions, ErrorInfo } from './types'\nexport { LOG_LEVELS, isValidLevel } from './types'\n\n// Re-export Transport interface for custom transports\nexport type { Transport } from './logger.base'\n\n// Re-export context utilities\nexport {\n withLogContext,\n getLogContext,\n generateTraceId,\n generateSpanId,\n getCorrelationId,\n} from './context'\n\n// Re-export span utilities for distributed tracing\nexport {\n withSpan,\n withSpanSync,\n startSpan,\n type Span,\n type SpanOptions,\n} from './context'\n\n// Re-export W3C Trace Context utilities\nexport {\n parseTraceparent,\n formatTraceparent,\n getTraceparent,\n contextFromTraceparent,\n extractTraceContext,\n createTraceHeaders,\n type TraceparentComponents,\n} from './context'\n\n// Re-export sanitization utilities\nexport { sanitize, SENSITIVE_FIELDS, type Sanitize, type SensitiveField } from './sanitize'\n\n// Global singleton logger\nexport const logger = new Logger()\n\n// Factory function for module-scoped loggers\nexport function createLogger(module: string, options?: Omit<import('./types').LoggerOptions, 'module'>): Logger {\n return new Logger({ ...options, module })\n}\n\n// Re-export Logger class for advanced use\nexport { Logger }\n\n// Re-export middleware\nexport { createLoggingMiddleware, type LoggingMiddlewareConfig } from './middleware'\n", "import type { CoreDeps, CourseWithProgress } from \"../types\";\n\nexport interface ListCoursesInput {\n userId: string;\n}\n\nexport async function listCourses(\n input: ListCoursesInput,\n deps: CoreDeps\n): Promise<CourseWithProgress[]> {\n deps.logger.info(\"tostudy-core: listCourses\", { userId: input.userId });\n return deps.data.courses.list(input.userId);\n}\n", "import type { CoreDeps, CourseDetail } from \"../types\";\n\nexport interface SelectCourseInput {\n userId: string;\n courseId: string;\n}\n\nexport async function selectCourse(\n input: SelectCourseInput,\n deps: CoreDeps\n): Promise<CourseDetail> {\n deps.logger.info(\"tostudy-core: selectCourse\", input);\n return deps.data.courses.select(input.userId, input.courseId);\n}\n", "import type { CoreDeps, ProgressData } from \"../types\";\n\nexport interface GetProgressInput {\n enrollmentId: string;\n}\n\nexport async function getProgress(input: GetProgressInput, deps: CoreDeps): Promise<ProgressData> {\n deps.logger.info(\"tostudy-core: getProgress\", input);\n return deps.data.courses.getProgress(input.enrollmentId);\n}\n", "export { listCourses } from \"./list-courses\";\nexport type { ListCoursesInput } from \"./list-courses\";\n\nexport { selectCourse } from \"./select-course\";\nexport type { SelectCourseInput } from \"./select-course\";\n\nexport { getProgress } from \"./get-progress\";\nexport type { GetProgressInput } from \"./get-progress\";\n", "/**\n * HTTP adapter \u2014 client-side DataProvider implementation.\n *\n * Calls the Next.js CLI API routes (`/api/cli/*`) using fetch().\n * The server extracts the user identity from the JWT token sent in the\n * Authorization header, so `userId` params present in the DataProvider\n * interface are intentionally ignored here.\n */\n\nimport type { DataProvider } from \"../types\";\n\n// ---------------------------------------------------------------------------\n// CliApiError\n// ---------------------------------------------------------------------------\n\nexport class CliApiError extends Error {\n constructor(\n message: string,\n public readonly status: number\n ) {\n super(message);\n this.name = \"CliApiError\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal fetch helper\n// ---------------------------------------------------------------------------\n\nasync function apiFetch<T>(url: string, token: string, init?: RequestInit): Promise<T> {\n const response = await fetch(url, {\n ...init,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${token}`,\n ...init?.headers,\n },\n });\n\n const body = await response.json();\n\n if (!response.ok) {\n throw new CliApiError(body.error ?? `API error ${response.status}`, response.status);\n }\n\n return body as T;\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a DataProvider that fetches from the ToStudy CLI API routes.\n *\n * @param apiUrl - Base URL of the Next.js app (e.g. \"https://tostudy.ai\")\n * @param token - JWT bearer token issued during `tostudy auth login`\n */\nexport function createHttpProvider(apiUrl: string, token: string): DataProvider {\n const base = `${apiUrl}/api/cli`;\n\n return {\n courses: {\n list: async (_userId) => {\n const res = await apiFetch<{ courses: any[] }>(`${base}/courses`, token);\n return res.courses;\n },\n\n select: async (_userId, courseId) => {\n const res = await apiFetch<{ course: any }>(`${base}/courses/select`, token, {\n method: \"POST\",\n body: JSON.stringify({ courseId }),\n });\n return res.course;\n },\n\n getProgress: async (enrollmentId) => {\n return apiFetch(`${base}/progress?enrollmentId=${encodeURIComponent(enrollmentId)}`, token);\n },\n },\n\n lessons: {\n next: async (enrollmentId, userConfirmation) => {\n return apiFetch(`${base}/lessons/next`, token, {\n method: \"POST\",\n body: JSON.stringify({ enrollmentId, userConfirmation }),\n });\n },\n\n getContent: async (lessonId, enrollmentId) => {\n const params = new URLSearchParams({ lessonId });\n if (enrollmentId) params.set(\"enrollmentId\", enrollmentId);\n return apiFetch(`${base}/lessons/content?${params.toString()}`, token);\n },\n\n getHint: async (_userId, enrollmentId) => {\n return apiFetch(`${base}/lessons/hint`, token, {\n method: \"POST\",\n body: JSON.stringify({ enrollmentId }),\n });\n },\n\n startModule: async (enrollmentId) => {\n return apiFetch(`${base}/modules/start`, token, {\n method: \"POST\",\n body: JSON.stringify({ enrollmentId }),\n });\n },\n\n startNextModule: async (enrollmentId) => {\n return apiFetch(`${base}/modules/start-next`, token, {\n method: \"POST\",\n body: JSON.stringify({ enrollmentId }),\n });\n },\n },\n\n exercises: {\n validate: async (lessonId, solution, _userId, enrollmentId) => {\n return apiFetch(`${base}/exercises/validate`, token, {\n method: \"POST\",\n body: JSON.stringify({ lessonId, solution, enrollmentId }),\n });\n },\n },\n };\n}\n", "import { Command } from \"commander\";\nimport { createLogger } from \"@repo/logger\";\nimport { listCourses } from \"@repo/tostudy-core/courses\";\nimport { createHttpProvider } from \"@repo/tostudy-core/adapters/http\";\nimport { requireSession } from \"../auth/session.js\";\nimport { output, error, formatCourseList } from \"../output/formatter.js\";\n\nconst logger = createLogger(\"cli:courses\");\n\nexport const coursesCommand = new Command(\"courses\")\n .description(\"List your enrolled courses with progress\")\n .option(\"--json\", \"Output structured JSON\")\n .action(async (opts: { json?: boolean }) => {\n try {\n const session = await requireSession();\n const data = createHttpProvider(session.apiUrl, session.token);\n const deps = { data, logger };\n\n const courses = await listCourses({ userId: session.userId }, deps);\n\n if (opts.json) {\n output(courses, { json: true });\n } else {\n output(formatCourseList(courses), { json: false });\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n error(msg);\n }\n });\n", "import { Command } from \"commander\";\nimport { createLogger } from \"@repo/logger\";\nimport { listCourses, selectCourse } from \"@repo/tostudy-core/courses\";\nimport { createHttpProvider } from \"@repo/tostudy-core/adapters/http\";\nimport { requireSession, setActiveCourse } from \"../auth/session.js\";\nimport { output, error } from \"../output/formatter.js\";\n\nconst logger = createLogger(\"cli:select\");\n\nexport const selectCommand = new Command(\"select\")\n .description(\"Activate a course by ID or list index number\")\n .argument(\"<course>\", \"Course ID (UUID) or index number from `tostudy courses`\")\n .option(\"--json\", \"Output structured JSON\")\n .action(async (course: string, opts: { json?: boolean }) => {\n try {\n const session = await requireSession();\n const data = createHttpProvider(session.apiUrl, session.token);\n const deps = { data, logger };\n\n // Always list courses first \u2014 we need enrollmentId (not in CourseDetail)\n const courses = await listCourses({ userId: session.userId }, deps);\n\n let courseId = course;\n let enrollmentId = \"\";\n\n if (/^\\d+$/.test(course)) {\n // Index-based selection (1-based)\n const idx = parseInt(course, 10) - 1;\n if (idx < 0 || idx >= courses.length) {\n error(`\u00CDndice ${course} inv\u00E1lido. Voc\u00EA tem ${courses.length} curso(s).`);\n }\n const found = courses[idx]!;\n courseId = found.courseId;\n enrollmentId = found.enrollmentId;\n } else {\n // UUID-based selection\n const found = courses.find((c) => c.courseId === course);\n if (found) {\n enrollmentId = found.enrollmentId;\n }\n }\n\n const detail = await selectCourse({ userId: session.userId, courseId }, deps);\n\n // Persist the active course locally\n await setActiveCourse({\n courseId: detail.courseId,\n courseTitle: detail.courseTitle,\n enrollmentId,\n });\n\n if (opts.json) {\n output({ ...detail, enrollmentId }, { json: true });\n } else {\n output(\n [\n `\u2713 Curso ativado: ${detail.courseTitle}`,\n ` Progresso: ${detail.progress}% | ${detail.moduleCount} m\u00F3dulos | ${detail.lessonCount} li\u00E7\u00F5es`,\n \"\",\n \"\u2192 tostudy progress para ver seu progresso detalhado\",\n \"\u2192 tostudy start para come\u00E7ar o m\u00F3dulo atual\",\n \"\u2192 tostudy next para avan\u00E7ar para a pr\u00F3xima li\u00E7\u00E3o\",\n ].join(\"\\n\"),\n { json: false }\n );\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n error(msg);\n }\n });\n", "import { Command } from \"commander\";\nimport { createLogger } from \"@repo/logger\";\nimport { getProgress } from \"@repo/tostudy-core/courses\";\nimport { createHttpProvider } from \"@repo/tostudy-core/adapters/http\";\nimport { requireSession, requireActiveCourse } from \"../auth/session.js\";\nimport { output, error, formatProgress } from \"../output/formatter.js\";\n\nconst logger = createLogger(\"cli:progress\");\n\nexport const progressCommand = new Command(\"progress\")\n .description(\"Show your progress in the active course\")\n .option(\"--json\", \"Output structured JSON\")\n .action(async (opts: { json?: boolean }) => {\n try {\n const session = await requireSession();\n const activeCourse = await requireActiveCourse();\n const data = createHttpProvider(session.apiUrl, session.token);\n const deps = { data, logger };\n\n const progress = await getProgress({ enrollmentId: activeCourse.enrollmentId }, deps);\n\n if (opts.json) {\n output(progress, { json: true });\n } else {\n output(formatProgress(progress), { json: false });\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n error(msg);\n }\n });\n", "import type { CoreDeps, LessonData } from \"../types\";\n\nexport interface NextLessonInput {\n enrollmentId: string;\n userConfirmation: string;\n}\n\nexport async function nextLesson(input: NextLessonInput, deps: CoreDeps): Promise<LessonData> {\n deps.logger.info(\"tostudy-core: nextLesson\", { enrollmentId: input.enrollmentId });\n return deps.data.lessons.next(input.enrollmentId, input.userConfirmation);\n}\n", "import type { CoreDeps, LessonContent } from \"../types\";\n\nexport interface GetContentInput {\n lessonId: string;\n enrollmentId?: string;\n}\n\nexport async function getContent(input: GetContentInput, deps: CoreDeps): Promise<LessonContent> {\n deps.logger.info(\"tostudy-core: getContent\", { lessonId: input.lessonId });\n return deps.data.lessons.getContent(input.lessonId, input.enrollmentId);\n}\n", "import type { CoreDeps, HintData } from \"../types\";\n\nexport interface GetHintInput {\n userId: string;\n enrollmentId?: string;\n}\n\nexport async function getHint(input: GetHintInput, deps: CoreDeps): Promise<HintData> {\n deps.logger.info(\"tostudy-core: getHint\", { userId: input.userId });\n return deps.data.lessons.getHint(input.userId, input.enrollmentId);\n}\n", "import type { CoreDeps, ModuleStartData } from \"../types\";\n\nexport interface StartModuleInput {\n enrollmentId: string;\n}\n\nexport async function startModule(\n input: StartModuleInput,\n deps: CoreDeps\n): Promise<ModuleStartData> {\n deps.logger.info(\"tostudy-core: startModule\", { enrollmentId: input.enrollmentId });\n return deps.data.lessons.startModule(input.enrollmentId);\n}\n", "import type { CoreDeps, ModuleStartData } from \"../types\";\n\nexport interface StartNextModuleInput {\n enrollmentId: string;\n}\n\nexport async function startNextModule(\n input: StartNextModuleInput,\n deps: CoreDeps\n): Promise<ModuleStartData> {\n deps.logger.info(\"tostudy-core: startNextModule\", { enrollmentId: input.enrollmentId });\n return deps.data.lessons.startNextModule(input.enrollmentId);\n}\n", "export { nextLesson } from \"./next-lesson\";\nexport type { NextLessonInput } from \"./next-lesson\";\n\nexport { getContent } from \"./get-content\";\nexport type { GetContentInput } from \"./get-content\";\n\nexport { getHint } from \"./get-hint\";\nexport type { GetHintInput } from \"./get-hint\";\n\nexport { startModule } from \"./start-module\";\nexport type { StartModuleInput } from \"./start-module\";\n\nexport { startNextModule } from \"./start-next-module\";\nexport type { StartNextModuleInput } from \"./start-next-module\";\n", "import { Command } from \"commander\";\nimport { createLogger } from \"@repo/logger\";\nimport { startModule } from \"@repo/tostudy-core/lessons\";\nimport { createHttpProvider } from \"@repo/tostudy-core/adapters/http\";\nimport { requireSession, requireActiveCourse } from \"../auth/session.js\";\nimport { output, error, formatModuleStart } from \"../output/formatter.js\";\n\nconst logger = createLogger(\"cli:start\");\n\nexport const startCommand = new Command(\"start\")\n .description(\"Start (or resume) the current module of the active course\")\n .option(\"--json\", \"Output structured JSON\")\n .action(async (opts: { json?: boolean }) => {\n try {\n const session = await requireSession();\n const activeCourse = await requireActiveCourse();\n const data = createHttpProvider(session.apiUrl, session.token);\n const deps = { data, logger };\n\n const moduleData = await startModule({ enrollmentId: activeCourse.enrollmentId }, deps);\n\n if (opts.json) {\n output(moduleData, { json: true });\n } else {\n output(formatModuleStart(moduleData), { json: false });\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n error(msg);\n }\n });\n", "import { Command } from \"commander\";\nimport { createLogger } from \"@repo/logger\";\nimport { startNextModule } from \"@repo/tostudy-core/lessons\";\nimport { createHttpProvider } from \"@repo/tostudy-core/adapters/http\";\nimport { requireSession, requireActiveCourse } from \"../auth/session.js\";\nimport { output, error, formatModuleStart } from \"../output/formatter.js\";\n\nconst logger = createLogger(\"cli:start-next\");\n\nexport const startNextCommand = new Command(\"start-next\")\n .description(\"Transition to the next module after completing the current one\")\n .option(\"--json\", \"Output structured JSON\")\n .action(async (opts: { json?: boolean }) => {\n try {\n const session = await requireSession();\n const activeCourse = await requireActiveCourse();\n const data = createHttpProvider(session.apiUrl, session.token);\n const deps = { data, logger };\n\n const moduleData = await startNextModule({ enrollmentId: activeCourse.enrollmentId }, deps);\n\n if (opts.json) {\n output(moduleData, { json: true });\n } else {\n output(formatModuleStart(moduleData), { json: false });\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n error(msg);\n }\n });\n", "import { Command } from \"commander\";\nimport { createLogger } from \"@repo/logger\";\nimport { nextLesson } from \"@repo/tostudy-core/lessons\";\nimport { createHttpProvider } from \"@repo/tostudy-core/adapters/http\";\nimport { requireSession, requireActiveCourse } from \"../auth/session.js\";\nimport { output, error, formatLesson } from \"../output/formatter.js\";\n\nconst logger = createLogger(\"cli:next\");\n\nexport const nextCommand = new Command(\"next\")\n .description(\"Advance to the next lesson in the active course\")\n .option(\"--json\", \"Output structured JSON\")\n .action(async (opts: { json?: boolean }) => {\n try {\n const session = await requireSession();\n const activeCourse = await requireActiveCourse();\n const data = createHttpProvider(session.apiUrl, session.token);\n const deps = { data, logger };\n\n const lessonData = await nextLesson(\n { enrollmentId: activeCourse.enrollmentId, userConfirmation: \"cli-next\" },\n deps\n );\n\n if (opts.json) {\n output(lessonData, { json: true });\n } else {\n output(formatLesson(lessonData), { json: false });\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n error(msg);\n }\n });\n", "import { Command } from \"commander\";\nimport { createLogger } from \"@repo/logger\";\nimport { getContent } from \"@repo/tostudy-core/lessons\";\nimport { createHttpProvider } from \"@repo/tostudy-core/adapters/http\";\nimport type { LessonContent } from \"@repo/tostudy-core/types\";\nimport { requireSession, requireActiveCourse } from \"../auth/session.js\";\nimport { output, error } from \"../output/formatter.js\";\n\nconst logger = createLogger(\"cli:lesson\");\n\n/** Render LessonContent as a human-readable string. */\nfunction formatLessonContent(data: LessonContent): string {\n const lines: string[] = [\n `\u2501\u2501\u2501 Li\u00E7\u00E3o: ${data.title} \u2501\u2501\u2501`,\n \"\",\n `Tipo: ${data.type} | Dura\u00E7\u00E3o estimada: ~${data.estimatedTimeMinutes} min`,\n \"\",\n data.content,\n ];\n\n if (data.acceptanceCriteria) {\n lines.push(\"\", \"Crit\u00E9rios de aceita\u00E7\u00E3o:\", data.acceptanceCriteria);\n }\n\n if (data.hints && data.hints.length > 0) {\n lines.push(\"\", `Dicas dispon\u00EDveis: ${data.hints.length}`);\n }\n\n lines.push(\n \"\",\n \"\u2192 tostudy validate <arquivo> para validar sua solu\u00E7\u00E3o\",\n \"\u2192 tostudy hint para obter uma dica\",\n \"\u2192 tostudy next para avan\u00E7ar para a pr\u00F3xima li\u00E7\u00E3o\"\n );\n\n return lines.join(\"\\n\");\n}\n\nexport const lessonCommand = new Command(\"lesson\")\n .description(\"Show the content of the current lesson\")\n .option(\"--json\", \"Output structured JSON\")\n .action(async (opts: { json?: boolean }) => {\n try {\n const session = await requireSession();\n const activeCourse = await requireActiveCourse();\n const data = createHttpProvider(session.apiUrl, session.token);\n const deps = { data, logger };\n\n const lessonId = activeCourse.currentLessonId;\n if (!lessonId) {\n error(\"Nenhuma li\u00E7\u00E3o ativa encontrada. Rode: tostudy start ou tostudy next\");\n }\n\n const content = await getContent({ lessonId, enrollmentId: activeCourse.enrollmentId }, deps);\n\n if (opts.json) {\n output(content, { json: true });\n } else {\n output(formatLessonContent(content), { json: false });\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n error(msg);\n }\n });\n", "import { Command } from \"commander\";\nimport { createLogger } from \"@repo/logger\";\nimport { getHint } from \"@repo/tostudy-core/lessons\";\nimport { createHttpProvider } from \"@repo/tostudy-core/adapters/http\";\nimport { requireSession, requireActiveCourse } from \"../auth/session.js\";\nimport { output, error, formatHint } from \"../output/formatter.js\";\n\nconst logger = createLogger(\"cli:hint\");\n\nexport const hintCommand = new Command(\"hint\")\n .description(\"Get a progressive hint for the current exercise\")\n .option(\"--json\", \"Output structured JSON\")\n .action(async (opts: { json?: boolean }) => {\n try {\n const session = await requireSession();\n const activeCourse = await requireActiveCourse();\n const data = createHttpProvider(session.apiUrl, session.token);\n const deps = { data, logger };\n\n const hint = await getHint(\n { userId: session.userId, enrollmentId: activeCourse.enrollmentId },\n deps\n );\n\n if (opts.json) {\n output(hint, { json: true });\n } else {\n output(formatHint(hint), { json: false });\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n error(msg);\n }\n });\n", "import type { CoreDeps, ValidationResult } from \"../types\";\n\nexport interface ValidateSolutionInput {\n lessonId: string;\n /** File CONTENT as string \u2014 the CLI reads the file before calling this function. */\n solution: string;\n userId: string;\n enrollmentId: string;\n}\n\nexport async function validateSolution(\n input: ValidateSolutionInput,\n deps: CoreDeps\n): Promise<ValidationResult> {\n deps.logger.info(\"tostudy-core: validateSolution\", { lessonId: input.lessonId });\n return deps.data.exercises.validate(\n input.lessonId,\n input.solution,\n input.userId,\n input.enrollmentId\n );\n}\n", "export { validateSolution } from \"./validate-solution\";\nexport type { ValidateSolutionInput } from \"./validate-solution\";\n", "import fs from \"node:fs\";\nimport { Command } from \"commander\";\nimport { createLogger } from \"@repo/logger\";\nimport { validateSolution } from \"@repo/tostudy-core/exercises\";\nimport { createHttpProvider } from \"@repo/tostudy-core/adapters/http\";\nimport { requireSession, requireActiveCourse } from \"../auth/session.js\";\nimport { output, error, formatValidation } from \"../output/formatter.js\";\n\nconst logger = createLogger(\"cli:validate\");\n\nexport const validateCommand = new Command(\"validate\")\n .description(\"Validate your solution for the current exercise\")\n .argument(\"[file]\", \"Path to the solution file to read\")\n .option(\"--stdin\", \"Read solution from stdin instead of a file\")\n .option(\"--json\", \"Output structured JSON\")\n .action(async (file: string | undefined, opts: { stdin?: boolean; json?: boolean }) => {\n try {\n const session = await requireSession();\n const activeCourse = await requireActiveCourse();\n\n // Resolve lessonId\n const lessonId = activeCourse.currentLessonId;\n if (!lessonId) {\n error(\"Nenhuma li\u00E7\u00E3o ativa encontrada. Rode: tostudy start ou tostudy next\");\n }\n\n // Read solution content\n let solution: string;\n if (opts.stdin) {\n solution = fs.readFileSync(\"/dev/stdin\", \"utf-8\");\n } else if (file) {\n if (!fs.existsSync(file)) {\n error(`Arquivo n\u00E3o encontrado: ${file}`);\n }\n solution = fs.readFileSync(file, \"utf-8\");\n } else {\n error(\"Forne\u00E7a um arquivo ou use --stdin.\\n\\nExemplo: tostudy validate resposta.md\");\n }\n\n const data = createHttpProvider(session.apiUrl, session.token);\n const deps = { data, logger };\n\n const result = await validateSolution(\n {\n lessonId,\n solution,\n userId: session.userId,\n enrollmentId: activeCourse.enrollmentId,\n },\n deps\n );\n\n if (opts.json) {\n output(result, { json: true });\n } else {\n output(formatValidation(result), { json: false });\n }\n\n // Exit code reflects pass/fail for scripting\n process.exit(result.passed ? 0 : 1);\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n error(msg);\n }\n });\n", "import { Command } from \"commander\";\nimport { getSession, getActiveCourse } from \"../auth/session.js\";\nimport { output } from \"../output/formatter.js\";\n\nexport const menuCommand = new Command(\"menu\")\n .description(\"Show available commands and current study context\")\n .action(async () => {\n const session = await getSession();\n const activeCourse = session ? await getActiveCourse() : null;\n\n const lines: string[] = [\n \"\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\",\n \"\u2502 ToStudy CLI \u2014 Menu \u2502\",\n \"\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\",\n \"\",\n ];\n\n if (!session) {\n lines.push(\n \" Status: N\u00E3o autenticado\",\n \"\",\n \" Para come\u00E7ar:\",\n \" tostudy login Autenticar com sua conta ToStudy\",\n \"\"\n );\n } else {\n lines.push(` Usu\u00E1rio: ${session.userName}`);\n\n if (activeCourse) {\n lines.push(` Curso ativo: ${activeCourse.courseTitle}`, \"\");\n } else {\n lines.push(\n \" Curso ativo: (nenhum)\",\n \" \u2192 tostudy courses para ver seus cursos\",\n \" \u2192 tostudy select <n\u00FAmero> para ativar um curso\",\n \"\"\n );\n }\n\n lines.push(\n \" \u2500\u2500\u2500 Navega\u00E7\u00E3o \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\",\n \" tostudy courses Listar seus cursos\",\n \" tostudy select <id> Ativar um curso\",\n \" tostudy progress Ver progresso do curso ativo\",\n \"\",\n \" \u2500\u2500\u2500 Estudo \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\",\n \" tostudy start Iniciar/retomar o m\u00F3dulo atual\",\n \" tostudy start-next Avan\u00E7ar para o pr\u00F3ximo m\u00F3dulo\",\n \" tostudy next Avan\u00E7ar para a pr\u00F3xima li\u00E7\u00E3o\",\n \" tostudy lesson Ver conte\u00FAdo da li\u00E7\u00E3o atual\",\n \"\",\n \" \u2500\u2500\u2500 Exerc\u00EDcios \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\",\n \" tostudy validate <arquivo> Validar sua solu\u00E7\u00E3o\",\n \" tostudy hint Obter uma dica progressiva\",\n \"\",\n \" \u2500\u2500\u2500 Dicas r\u00E1pidas \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\",\n \" Adicione --json a qualquer comando para sa\u00EDda em JSON\",\n \" Adicione --help a qualquer comando para ver op\u00E7\u00F5es\",\n \"\"\n );\n }\n\n output(lines.join(\"\\n\"), { json: false });\n });\n", "import { Command } from \"commander\";\nimport { loginCommand } from \"./commands/login.js\";\nimport { logoutCommand } from \"./commands/logout.js\";\nimport { setupCommand } from \"./commands/setup.js\";\nimport { doctorCommand } from \"./commands/doctor.js\";\nimport { coursesCommand } from \"./commands/courses.js\";\nimport { selectCommand } from \"./commands/select.js\";\nimport { progressCommand } from \"./commands/progress.js\";\nimport { startCommand } from \"./commands/start.js\";\nimport { startNextCommand } from \"./commands/start-next.js\";\nimport { nextCommand } from \"./commands/next.js\";\nimport { lessonCommand } from \"./commands/lesson.js\";\nimport { hintCommand } from \"./commands/hint.js\";\nimport { validateCommand } from \"./commands/validate.js\";\nimport { menuCommand } from \"./commands/menu.js\";\n\nexport function createProgram(): Command {\n const program = new Command();\n\n program\n .name(\"tostudy\")\n .description(\"ToStudy CLI \u2014 study courses from the terminal\")\n .version(\"0.1.2\")\n .option(\"--json\", \"Output structured JSON (for LLM agents)\")\n .option(\"--verbose\", \"Enable debug output\")\n .option(\"--course <id>\", \"Override active course ID\");\n\n // Setup and diagnostic commands\n program.addCommand(setupCommand);\n program.addCommand(doctorCommand);\n\n // Auth commands\n program.addCommand(loginCommand);\n program.addCommand(logoutCommand);\n\n // Phase 1 study commands\n program.addCommand(coursesCommand);\n program.addCommand(selectCommand);\n program.addCommand(progressCommand);\n program.addCommand(startCommand);\n program.addCommand(startNextCommand);\n program.addCommand(nextCommand);\n program.addCommand(lessonCommand);\n program.addCommand(hintCommand);\n program.addCommand(validateCommand);\n program.addCommand(menuCommand);\n\n return program;\n}\n", "/**\n * Entry point for the bundled npm CLI.\n * This file is used by build-npm.mjs as the esbuild entrypoint.\n *\n * Uses dynamic import so LOG_LEVEL is set BEFORE any module loads\n * (ESM static imports are hoisted and run before top-level code).\n */\n\n// Suppress @repo/logger output in CLI mode\nif (!process.env.LOG_LEVEL) {\n process.env.LOG_LEVEL = \"fatal\";\n}\n\nconst { createProgram } = await import(\"./cli\");\nconst program = createProgram();\nprogram.parse();\n\nexport {};\n"],
5
+ "mappings": "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",
6
+ "names": ["token", "Command", "execFileSync", "fs", "path", "os", "Command", "Command", "execFileSync", "error", "output", "pc", "error", "output", "error", "token", "Command", "logger", "init_courses", "Command", "logger", "Command", "logger", "Command", "logger", "Command", "logger", "Command", "logger", "Command", "logger", "Command", "logger", "fs", "Command", "logger", "Command", "Command", "program", "init_courses", "createProgram"]
7
7
  }