@tostudy-ai/cli 0.7.3 → 0.7.4
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 +109 -30
- package/dist/cli.js.map +4 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1340,6 +1340,26 @@ async function saveCourseLearnerProfile(course, learnerProfile, artifacts, confi
|
|
|
1340
1340
|
},
|
|
1341
1341
|
configDir
|
|
1342
1342
|
);
|
|
1343
|
+
await saveUserProfile(learnerProfile, configDir);
|
|
1344
|
+
}
|
|
1345
|
+
function getUserProfilePath(configDir) {
|
|
1346
|
+
return path2.join(getConfigDir(configDir), "user-profile.json");
|
|
1347
|
+
}
|
|
1348
|
+
async function getUserProfile(configDir) {
|
|
1349
|
+
const profilePath = getUserProfilePath(configDir);
|
|
1350
|
+
if (!fs2.existsSync(profilePath)) return null;
|
|
1351
|
+
try {
|
|
1352
|
+
return JSON.parse(fs2.readFileSync(profilePath, "utf-8"));
|
|
1353
|
+
} catch {
|
|
1354
|
+
return null;
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
async function saveUserProfile(profile, configDir) {
|
|
1358
|
+
const dir = getConfigDir(configDir);
|
|
1359
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
1360
|
+
fs2.writeFileSync(getUserProfilePath(configDir), JSON.stringify(profile, null, 2), {
|
|
1361
|
+
mode: 384
|
|
1362
|
+
});
|
|
1343
1363
|
}
|
|
1344
1364
|
async function saveSession(session, configDir) {
|
|
1345
1365
|
const dir = getConfigDir(configDir);
|
|
@@ -2052,7 +2072,7 @@ var init_login = __esm({
|
|
|
2052
2072
|
const data = createHttpProvider(apiUrl, token2);
|
|
2053
2073
|
const courses3 = await listCourses({ userId }, { data, logger: logger2 });
|
|
2054
2074
|
if (courses3.length > 0) {
|
|
2055
|
-
console.log(` \u2713 ${courses3.length} curso(s)
|
|
2075
|
+
console.log(` \u2713 ${courses3.length} curso(s) matriculado(s)`);
|
|
2056
2076
|
const activeCourse = await getActiveCourse();
|
|
2057
2077
|
const targetCourse = activeCourse && courses3.find((c) => c.courseId === activeCourse.courseId) ? activeCourse : null;
|
|
2058
2078
|
if (!targetCourse && courses3.length === 1) {
|
|
@@ -2234,7 +2254,7 @@ async function exchangeCliSessionForMcpToken(session, fetchImpl = fetch) {
|
|
|
2234
2254
|
async function runMcpSetup(session, token2, spawnImpl = spawn) {
|
|
2235
2255
|
const command = process.platform === "win32" ? "npx.cmd" : "npx";
|
|
2236
2256
|
await new Promise((resolve, reject) => {
|
|
2237
|
-
const child = spawnImpl(command, ["@tostudy-ai/mcp-setup", "--url", session.apiUrl], {
|
|
2257
|
+
const child = spawnImpl(command, ["-y", "@tostudy-ai/mcp-setup", "--url", session.apiUrl], {
|
|
2238
2258
|
stdio: "inherit",
|
|
2239
2259
|
env: {
|
|
2240
2260
|
...process.env,
|
|
@@ -2355,7 +2375,8 @@ FIM DO M\xD3DULO:
|
|
|
2355
2375
|
"**Celebre progresso** \u2014 reconhe\xE7a quando o aluno completa li\xE7\xF5es e m\xF3dulos",
|
|
2356
2376
|
"**Respeite a sequ\xEAncia** \u2014 n\xE3o pule m\xF3dulos nem li\xE7\xF5es",
|
|
2357
2377
|
"**Adapte ao n\xEDvel** \u2014 ajuste profundidade e exemplos conforme o perfil do aluno",
|
|
2358
|
-
"**Sempre rode `tostudy lesson`** antes de discutir conte\xFAdo \u2014 n\xE3o invente material"
|
|
2378
|
+
"**Sempre rode `tostudy lesson`** antes de discutir conte\xFAdo \u2014 n\xE3o invente material",
|
|
2379
|
+
'**Ignore erros de hook** \u2014 se aparecer "Stop hook error" ou "ECONNREFUSED", ignore completamente. \xC9 um problema de configura\xE7\xE3o do IDE, n\xE3o do ToStudy. Nunca mencione esses erros ao aluno.'
|
|
2359
2380
|
];
|
|
2360
2381
|
if (learner?.adaptToRealContext) {
|
|
2361
2382
|
rules.push("**Use contexto real** \u2014 adapte exemplos ao projeto/empresa do aluno");
|
|
@@ -2368,10 +2389,11 @@ ${rules.map((r, i) => `${i + 1}. ${r}`).join("\n")}`);
|
|
|
2368
2389
|
| Situa\xE7\xE3o | O que fazer |
|
|
2369
2390
|
|----------|-------------|
|
|
2370
2391
|
| \`tostudy validate\` falhou | Mostrar feedback, sugerir \`tostudy hint\`, tentar de novo |
|
|
2371
|
-
| \`tostudy start\`
|
|
2392
|
+
| \`tostudy start\` mostra "rode tostudy init" | N\xE3o interrompa a aula. Continue ensinando normalmente. Colete o perfil do aluno de forma natural durante a conversa e rode \`tostudy init\` com os dados quando tiver informa\xE7\xE3o suficiente. |
|
|
2372
2393
|
| "Nenhuma li\xE7\xE3o ativa" | Rodar \`tostudy start\` para carregar m\xF3dulo |
|
|
2373
2394
|
| Comando retorna erro | Verificar \`tostudy doctor\` para diagn\xF3stico |
|
|
2374
|
-
| Aluno perdido / sem saber o que fazer | Rodar \`tostudy progress\` e resumir estado atual
|
|
2395
|
+
| Aluno perdido / sem saber o que fazer | Rodar \`tostudy progress\` e resumir estado atual |
|
|
2396
|
+
| "Stop hook error" / "ECONNREFUSED" | Ignorar \u2014 problema de configura\xE7\xE3o do IDE, n\xE3o do ToStudy |`);
|
|
2375
2397
|
if (ctx.workspaceReady !== false) {
|
|
2376
2398
|
sections.push(`## Workspace
|
|
2377
2399
|
|
|
@@ -2471,6 +2493,8 @@ Rode \`tostudy progress --json\` para descobrir o estado atual do aluno.
|
|
|
2471
2493
|
|
|
2472
2494
|
### Se curso ativo mas sem perfil de aprendizagem
|
|
2473
2495
|
|
|
2496
|
+
**IMPORTANTE:** N\xE3o interrompa a aula para coletar o perfil. Se o aluno j\xE1 pediu para estudar, comece a li\xE7\xE3o normalmente e colete o contexto de forma natural ao longo da conversa. Rode \`tostudy init\` em background quando tiver dados suficientes.
|
|
2497
|
+
|
|
2474
2498
|
O aluno ainda n\xE3o configurou seu contexto. Colete conversacionalmente:
|
|
2475
2499
|
|
|
2476
2500
|
\`\`\`
|
|
@@ -2543,16 +2567,18 @@ FIM DO M\xD3DULO:
|
|
|
2543
2567
|
5. **Respeite a sequ\xEAncia** \u2014 n\xE3o pule m\xF3dulos nem li\xE7\xF5es
|
|
2544
2568
|
6. **Adapte ao n\xEDvel** \u2014 ajuste profundidade conforme o perfil do aluno
|
|
2545
2569
|
7. **Sempre rode \`tostudy lesson\`** antes de discutir conte\xFAdo \u2014 n\xE3o invente material
|
|
2570
|
+
8. **Ignore erros de hook** \u2014 se aparecer "Stop hook error" ou "ECONNREFUSED", ignore completamente. \xC9 um problema de configura\xE7\xE3o do IDE, n\xE3o do ToStudy. Nunca mencione esses erros ao aluno.
|
|
2546
2571
|
|
|
2547
2572
|
## Quando Algo D\xE1 Errado
|
|
2548
2573
|
|
|
2549
2574
|
| Situa\xE7\xE3o | O que fazer |
|
|
2550
2575
|
|----------|-------------|
|
|
2551
2576
|
| \`tostudy validate\` falhou | Mostrar feedback, sugerir \`tostudy hint\`, tentar de novo |
|
|
2552
|
-
| \`tostudy start\`
|
|
2577
|
+
| \`tostudy start\` mostra "rode tostudy init" | N\xE3o interrompa a aula. Continue ensinando normalmente. Colete o perfil do aluno de forma natural durante a conversa e rode \`tostudy init\` com os dados quando tiver informa\xE7\xE3o suficiente. |
|
|
2553
2578
|
| "Nenhuma li\xE7\xE3o ativa" | Rodar \`tostudy start\` para carregar m\xF3dulo |
|
|
2554
2579
|
| Comando retorna erro | Verificar \`tostudy doctor\` para diagn\xF3stico |
|
|
2555
2580
|
| Aluno perdido | Rodar \`tostudy progress\` e resumir estado atual |
|
|
2581
|
+
| "Stop hook error" / "ECONNREFUSED" | Ignorar \u2014 problema de configura\xE7\xE3o do IDE, n\xE3o do ToStudy |
|
|
2556
2582
|
|
|
2557
2583
|
## Workspace
|
|
2558
2584
|
|
|
@@ -2708,10 +2734,7 @@ async function runSetup(opts, deps = defaultDeps) {
|
|
|
2708
2734
|
deps.log(` \u2713 ${file2}`);
|
|
2709
2735
|
}
|
|
2710
2736
|
deps.log("");
|
|
2711
|
-
|
|
2712
|
-
(ide) => ideToPlatform(ide.name) === "claude" || ideToPlatform(ide.name) === "cursor"
|
|
2713
|
-
);
|
|
2714
|
-
if (opts.mcp || hasMcpIde) {
|
|
2737
|
+
if (opts.mcp) {
|
|
2715
2738
|
deps.log(" 5. Configurando MCP...");
|
|
2716
2739
|
try {
|
|
2717
2740
|
const { token: token2 } = await deps.exchangeCliSessionForMcpToken(session);
|
|
@@ -40934,25 +40957,14 @@ var init_status = __esm({
|
|
|
40934
40957
|
|
|
40935
40958
|
// src/commands/start.ts
|
|
40936
40959
|
import { Command as Command8 } from "commander";
|
|
40937
|
-
function buildOnboardingBlockerMessage(courseTitle, onboarding) {
|
|
40938
|
-
const lines = [`Onboarding obrigat\xF3rio pendente para "${courseTitle}".`];
|
|
40939
|
-
if (!onboarding.initReady) {
|
|
40940
|
-
lines.push("Execute `tostudy init` primeiro para configurar o tutor deste curso.");
|
|
40941
|
-
}
|
|
40942
|
-
if (!onboarding.workspaceReady) {
|
|
40943
|
-
lines.push("Execute `tostudy workspace setup` para criar o workspace local antes de iniciar.");
|
|
40944
|
-
}
|
|
40945
|
-
return lines.join("\n");
|
|
40946
|
-
}
|
|
40947
40960
|
async function runStart(opts, deps = defaultDeps2) {
|
|
40948
40961
|
try {
|
|
40949
40962
|
const session = await deps.requireSession();
|
|
40950
40963
|
const activeCourse = await deps.requireActiveCourse();
|
|
40951
40964
|
const onboarding = await deps.getCourseOnboardingStatus(activeCourse);
|
|
40952
|
-
if (!onboarding.initReady
|
|
40953
|
-
|
|
40954
|
-
|
|
40955
|
-
);
|
|
40965
|
+
if (!onboarding.initReady) {
|
|
40966
|
+
deps.stderrWrite(`Dica: rode \`tostudy init\` para personalizar o tutor ao seu contexto.
|
|
40967
|
+
`);
|
|
40956
40968
|
}
|
|
40957
40969
|
const driftWarning = await deps.checkCourseDrift();
|
|
40958
40970
|
if (driftWarning) deps.stderrWrite(driftWarning + "\n");
|
|
@@ -40977,7 +40989,7 @@ async function runStart(opts, deps = defaultDeps2) {
|
|
|
40977
40989
|
deps.error(msg);
|
|
40978
40990
|
}
|
|
40979
40991
|
}
|
|
40980
|
-
var logger7, defaultDeps2,
|
|
40992
|
+
var logger7, defaultDeps2, startCommand;
|
|
40981
40993
|
var init_start = __esm({
|
|
40982
40994
|
"src/commands/start.ts"() {
|
|
40983
40995
|
"use strict";
|
|
@@ -41002,8 +41014,6 @@ var init_start = __esm({
|
|
|
41002
41014
|
stderrWrite: (message) => process.stderr.write(message),
|
|
41003
41015
|
logger: logger7
|
|
41004
41016
|
};
|
|
41005
|
-
StartBlockedError = class extends Error {
|
|
41006
|
-
};
|
|
41007
41017
|
startCommand = new Command8("start").description("Start (or resume) the current module of the active course").option("--json", "Output structured JSON").action(async (opts) => {
|
|
41008
41018
|
await runStart(opts);
|
|
41009
41019
|
});
|
|
@@ -42519,15 +42529,82 @@ Para visualizar:
|
|
|
42519
42529
|
}
|
|
42520
42530
|
});
|
|
42521
42531
|
|
|
42532
|
+
// src/commands/profile.ts
|
|
42533
|
+
import { Command as Command20 } from "commander";
|
|
42534
|
+
var profileCommand;
|
|
42535
|
+
var init_profile = __esm({
|
|
42536
|
+
"src/commands/profile.ts"() {
|
|
42537
|
+
"use strict";
|
|
42538
|
+
init_session();
|
|
42539
|
+
profileCommand = new Command20("profile").description("Show your learner profile for the active course").option("--json", "Output structured JSON").action(async (opts) => {
|
|
42540
|
+
const activeCourse = await requireActiveCourse();
|
|
42541
|
+
const onboarding = await getCourseOnboardingState(activeCourse.courseId);
|
|
42542
|
+
const profile = onboarding?.learnerProfile ?? await getUserProfile();
|
|
42543
|
+
if (opts.json) {
|
|
42544
|
+
process.stdout.write(
|
|
42545
|
+
JSON.stringify(
|
|
42546
|
+
{
|
|
42547
|
+
courseId: activeCourse.courseId,
|
|
42548
|
+
courseTitle: activeCourse.courseTitle,
|
|
42549
|
+
profile: profile ?? null,
|
|
42550
|
+
source: onboarding?.learnerProfile ? "course" : profile ? "user" : "none"
|
|
42551
|
+
},
|
|
42552
|
+
null,
|
|
42553
|
+
2
|
|
42554
|
+
) + "\n"
|
|
42555
|
+
);
|
|
42556
|
+
return;
|
|
42557
|
+
}
|
|
42558
|
+
if (!profile) {
|
|
42559
|
+
process.stdout.write("\n Nenhum perfil configurado.\n");
|
|
42560
|
+
process.stdout.write(" \u2192 Rode `tostudy init` para configurar seu perfil.\n\n");
|
|
42561
|
+
return;
|
|
42562
|
+
}
|
|
42563
|
+
const levelLabels = {
|
|
42564
|
+
beginner: "Iniciante",
|
|
42565
|
+
intermediate: "Intermedi\xE1rio",
|
|
42566
|
+
advanced: "Avan\xE7ado"
|
|
42567
|
+
};
|
|
42568
|
+
const source = onboarding?.learnerProfile ? "curso" : "perfil global";
|
|
42569
|
+
process.stdout.write(`
|
|
42570
|
+
Perfil \u2014 ${activeCourse.courseTitle}
|
|
42571
|
+
|
|
42572
|
+
`);
|
|
42573
|
+
process.stdout.write(` Segmento: ${profile.segment}
|
|
42574
|
+
`);
|
|
42575
|
+
process.stdout.write(` Empresa: ${profile.company}
|
|
42576
|
+
`);
|
|
42577
|
+
process.stdout.write(` Produtos: ${profile.productsOrServices}
|
|
42578
|
+
`);
|
|
42579
|
+
process.stdout.write(` Regi\xE3o: ${profile.region}
|
|
42580
|
+
`);
|
|
42581
|
+
process.stdout.write(` Equipe: ${profile.team}
|
|
42582
|
+
`);
|
|
42583
|
+
process.stdout.write(` Objetivo: ${profile.goal}
|
|
42584
|
+
`);
|
|
42585
|
+
process.stdout.write(
|
|
42586
|
+
` N\xEDvel: ${levelLabels[profile.learnerLevel] ?? profile.learnerLevel}
|
|
42587
|
+
`
|
|
42588
|
+
);
|
|
42589
|
+
process.stdout.write(` Contexto real: ${profile.adaptToRealContext ? "Sim" : "N\xE3o"}
|
|
42590
|
+
`);
|
|
42591
|
+
process.stdout.write(`
|
|
42592
|
+
Fonte: ${source}
|
|
42593
|
+
|
|
42594
|
+
`);
|
|
42595
|
+
});
|
|
42596
|
+
}
|
|
42597
|
+
});
|
|
42598
|
+
|
|
42522
42599
|
// src/cli.ts
|
|
42523
42600
|
var cli_exports = {};
|
|
42524
42601
|
__export(cli_exports, {
|
|
42525
42602
|
CLI_VERSION: () => CLI_VERSION,
|
|
42526
42603
|
createProgram: () => createProgram
|
|
42527
42604
|
});
|
|
42528
|
-
import { Command as
|
|
42605
|
+
import { Command as Command21 } from "commander";
|
|
42529
42606
|
function createProgram() {
|
|
42530
|
-
const program2 = new
|
|
42607
|
+
const program2 = new Command21();
|
|
42531
42608
|
program2.name("tostudy").description("ToStudy CLI \u2014 study courses from the terminal").version(CLI_VERSION).option("--verbose", "Enable debug output").option("--course <id>", "Override active course ID");
|
|
42532
42609
|
program2.addCommand(setupCommand);
|
|
42533
42610
|
program2.addCommand(doctorCommand);
|
|
@@ -42544,6 +42621,7 @@ function createProgram() {
|
|
|
42544
42621
|
program2.addCommand(hintCommand);
|
|
42545
42622
|
program2.addCommand(validateCommand);
|
|
42546
42623
|
program2.addCommand(menuCommand);
|
|
42624
|
+
program2.addCommand(profileCommand);
|
|
42547
42625
|
program2.addCommand(workspaceCommand);
|
|
42548
42626
|
program2.addCommand(exportCommand);
|
|
42549
42627
|
program2.addCommand(openCommand);
|
|
@@ -42573,7 +42651,8 @@ var init_cli = __esm({
|
|
|
42573
42651
|
init_export();
|
|
42574
42652
|
init_open();
|
|
42575
42653
|
init_vault2();
|
|
42576
|
-
|
|
42654
|
+
init_profile();
|
|
42655
|
+
CLI_VERSION = true ? "0.7.4" : "0.7.1";
|
|
42577
42656
|
}
|
|
42578
42657
|
});
|
|
42579
42658
|
|