@tostudy-ai/cli 0.18.10 → 0.18.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -1043,6 +1043,7 @@ var init_errors_pt_br = __esm({
1043
1043
  suggestReasonMatch: "combina com o seu perfil em",
1044
1044
  suggestReasonAnd: "e",
1045
1045
  suggestPaidHeader: "Pagos. A matr\xEDcula fica no navegador e nada \xE9 debitado por aqui:",
1046
+ loginAccountOwnerManaged: "Esta conta agora \xE9 gerenciada por voc\xEA no ToStudy (senha ou login social), ent\xE3o c\xF3digos e magic-links da imers\xE3o n\xE3o funcionam mais. Rode `tostudy login` (sem --magic-link) para entrar pelo navegador.",
1046
1047
  enrollmentNotEntitled: "\u{1F6AB} Sua matr\xEDcula neste curso n\xE3o est\xE1 mais ativa (reembolso, cancelamento ou preview expirado).\nPara voltar a estudar, adquira o curso novamente em https://tostudy.ai.\n",
1047
1048
  creator: {
1048
1049
  loginBrowserOnly: "`--creator` s\xF3 funciona no login pelo browser. Rode `tostudy login --creator` sem --code, --magic-link ou --manual.",
@@ -1154,6 +1155,7 @@ var init_errors_en_us = __esm({
1154
1155
  suggestReasonMatch: "matches your profile on",
1155
1156
  suggestReasonAnd: "and",
1156
1157
  suggestPaidHeader: "Paid. Enrollment stays in the browser and nothing is charged here:",
1158
+ loginAccountOwnerManaged: "You now manage this account on ToStudy (password or social login), so immersion codes and magic links no longer work. Run `tostudy login` (without --magic-link) to sign in through the browser.",
1157
1159
  enrollmentNotEntitled: "\u{1F6AB} Your enrollment in this course is no longer active (refund, cancellation, or expired preview).\nTo study again, purchase the course at https://tostudy.ai.\n",
1158
1160
  creator: {
1159
1161
  loginBrowserOnly: "`--creator` only works with the browser login. Run `tostudy login --creator` without --code, --magic-link or --manual.",
@@ -1840,12 +1842,30 @@ var init_formatter = __esm({
1840
1842
  }
1841
1843
  });
1842
1844
 
1845
+ // src/io/has-binary.ts
1846
+ import { execFileSync } from "node:child_process";
1847
+ function locatorCommand() {
1848
+ return process.platform === "win32" ? "where" : "which";
1849
+ }
1850
+ function hasBinary(name) {
1851
+ try {
1852
+ execFileSync(locatorCommand(), [name], { encoding: "utf-8", stdio: "pipe", timeout: 3e3 });
1853
+ return true;
1854
+ } catch {
1855
+ return false;
1856
+ }
1857
+ }
1858
+ var init_has_binary = __esm({
1859
+ "src/io/has-binary.ts"() {
1860
+ "use strict";
1861
+ }
1862
+ });
1863
+
1843
1864
  // src/installer/ide-detector.ts
1844
1865
  var ide_detector_exports = {};
1845
1866
  __export(ide_detector_exports, {
1846
1867
  detectIDEs: () => detectIDEs
1847
1868
  });
1848
- import { execFileSync } from "node:child_process";
1849
1869
  import fs3 from "node:fs";
1850
1870
  import path4 from "node:path";
1851
1871
  import os3 from "node:os";
@@ -1935,11 +1955,7 @@ function detectIDEs(home = os3.homedir()) {
1935
1955
  ];
1936
1956
  const claudeIde = ides.find((ide) => ide.id === "claude-code");
1937
1957
  if (claudeIde) {
1938
- try {
1939
- execFileSync("which", ["claude"], { encoding: "utf-8" });
1940
- claudeIde.detected = true;
1941
- } catch {
1942
- }
1958
+ claudeIde.detected = hasBinary("claude");
1943
1959
  }
1944
1960
  for (const [id, bin] of [
1945
1961
  ["grok", "grok"],
@@ -1947,11 +1963,7 @@ function detectIDEs(home = os3.homedir()) {
1947
1963
  ]) {
1948
1964
  const ide = ides.find((i) => i.id === id);
1949
1965
  if (ide && !ide.detected) {
1950
- try {
1951
- execFileSync("which", [bin], { encoding: "utf-8" });
1952
- ide.detected = true;
1953
- } catch {
1954
- }
1966
+ ide.detected = hasBinary(bin);
1955
1967
  }
1956
1968
  }
1957
1969
  return ides;
@@ -1959,6 +1971,7 @@ function detectIDEs(home = os3.homedir()) {
1959
1971
  var init_ide_detector = __esm({
1960
1972
  "src/installer/ide-detector.ts"() {
1961
1973
  "use strict";
1974
+ init_has_binary();
1962
1975
  }
1963
1976
  });
1964
1977
 
@@ -2331,14 +2344,6 @@ __export(runtime_registry_exports, {
2331
2344
  import { execFileSync as execFileSync2 } from "node:child_process";
2332
2345
  import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync, writeFileSync as writeFileSync2 } from "node:fs";
2333
2346
  import { dirname, join as join2 } from "node:path";
2334
- function hasBinary(name) {
2335
- try {
2336
- execFileSync2("which", [name], { encoding: "utf-8", stdio: "pipe" });
2337
- return true;
2338
- } catch {
2339
- return false;
2340
- }
2341
- }
2342
2347
  function writeFile2(absDir, fileName, body) {
2343
2348
  mkdirSync2(absDir, { recursive: true });
2344
2349
  writeFileSync2(join2(absDir, fileName), body);
@@ -2465,6 +2470,7 @@ var init_runtime_registry = __esm({
2465
2470
  "use strict";
2466
2471
  init_dist();
2467
2472
  init_slug();
2473
+ init_has_binary();
2468
2474
  init_instruction_template_v3();
2469
2475
  logger2 = createLogger("cli:runtime-registry");
2470
2476
  detectOpencode = (home) => existsSync2(join2(home, ".opencode")) || existsSync2(join2(home, ".config", "opencode"));
@@ -3486,6 +3492,10 @@ async function persistSession(data, apiUrl) {
3486
3492
  apiUrl
3487
3493
  });
3488
3494
  }
3495
+ function exchangeErrorMessage(code) {
3496
+ if (code === "account_owner_managed") return getErrors().loginAccountOwnerManaged;
3497
+ return code ?? "Falha na autentica\xE7\xE3o";
3498
+ }
3489
3499
  async function loginWithCode(code, apiUrl) {
3490
3500
  assertTrustedApiUrl(apiUrl);
3491
3501
  const res = await fetch(`${apiUrl}/api/cli/auth/exchange`, {
@@ -3495,7 +3505,7 @@ async function loginWithCode(code, apiUrl) {
3495
3505
  });
3496
3506
  if (!res.ok) {
3497
3507
  const body = await res.json().catch(() => ({}));
3498
- throw new Error(body.error ?? "Falha na autentica\xE7\xE3o");
3508
+ throw new Error(exchangeErrorMessage(body.error));
3499
3509
  }
3500
3510
  const data = await res.json();
3501
3511
  await persistSession(data, apiUrl);
@@ -3519,7 +3529,7 @@ async function loginWithMagicLink(magicLinkUrl, apiUrl) {
3519
3529
  });
3520
3530
  if (!res.ok) {
3521
3531
  const body = await res.json().catch(() => ({}));
3522
- throw new Error(body.error ?? "Falha na autentica\xE7\xE3o");
3532
+ throw new Error(exchangeErrorMessage(body.error));
3523
3533
  }
3524
3534
  const data = await res.json();
3525
3535
  await persistSession(data, apiUrl);
@@ -3840,7 +3850,7 @@ init_workspace_state();
3840
3850
  init_formatter();
3841
3851
 
3842
3852
  // src/version.ts
3843
- var CLI_VERSION = true ? "0.18.10" : "0.7.1";
3853
+ var CLI_VERSION = true ? "0.18.13" : "0.7.1";
3844
3854
 
3845
3855
  // src/update-checker.ts
3846
3856
  init_config_dir();
@@ -20184,8 +20194,9 @@ var menuCommand = new Command18("menu").description("Show available commands and
20184
20194
  } else {
20185
20195
  lines.push(
20186
20196
  " Curso ativo: (nenhum)",
20187
- " \u2192 tostudy courses para ver seus cursos",
20197
+ " \u2192 tostudy courses para ver seus cursos",
20188
20198
  " \u2192 tostudy select <n\xFAmero> para ativar um curso",
20199
+ " \u2192 tostudy suggest se voc\xEA ainda n\xE3o tem nenhum curso",
20189
20200
  ""
20190
20201
  );
20191
20202
  }