@tostudy-ai/cli 0.18.22 → 0.18.24

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
@@ -657,6 +657,23 @@ function parseOtlpResourceAttributes(raw2) {
657
657
  }
658
658
  return out;
659
659
  }
660
+ function parseOtlpHeaders(raw2) {
661
+ if (!raw2) return {};
662
+ const out = {};
663
+ for (const pair of raw2.split(",")) {
664
+ const eq = pair.indexOf("=");
665
+ if (eq <= 0) continue;
666
+ const key = pair.slice(0, eq).trim();
667
+ if (!key) continue;
668
+ const value = pair.slice(eq + 1).trim();
669
+ try {
670
+ out[key] = decodeURIComponent(value);
671
+ } catch {
672
+ out[key] = value;
673
+ }
674
+ }
675
+ return out;
676
+ }
660
677
  function detectEnvironment() {
661
678
  const isProd = process.env.NODE_ENV === "production" || !!process.env.VERCEL || !!process.env.RAILWAY_ENVIRONMENT;
662
679
  let env = process.env.NODE_ENV || "development";
@@ -908,7 +925,8 @@ var init_dist = __esm({
908
925
  });
909
926
  if (!response.ok) throw new Error(`OTLP log ingest failed: ${response.status} ${response.statusText}`);
910
927
  } catch (error49) {
911
- if (this.buffer.length < this.maxBufferSize * 3) this.buffer.unshift(...batch);
928
+ const room = Math.max(0, this.maxBufferSize * 3 - this.buffer.length);
929
+ if (room > 0) this.buffer.unshift(...batch.slice(-room));
912
930
  this.onError?.(error49, batch.length);
913
931
  } finally {
914
932
  this.flushing = false;
@@ -958,6 +976,10 @@ var init_dist = __esm({
958
976
  endpoint: otlpEndpoint,
959
977
  serviceName: process.env.OTEL_SERVICE_NAME || getDefaultService(),
960
978
  resourceAttributes: parseOtlpResourceAttributes(process.env.OTEL_RESOURCE_ATTRIBUTES),
979
+ headers: {
980
+ ...parseOtlpHeaders(process.env.OTEL_EXPORTER_OTLP_HEADERS),
981
+ ...parseOtlpHeaders(process.env.OTEL_EXPORTER_OTLP_LOGS_HEADERS)
982
+ },
961
983
  onError: (err, count) => {
962
984
  process.stderr.write(`[logger] OTLP transport error: ${err.message} (${count} entries)
963
985
  `);
@@ -1045,7 +1067,7 @@ var init_errors_pt_br = __esm({
1045
1067
  suggestReasonMatch: "combina com o seu perfil em",
1046
1068
  suggestReasonAnd: "e",
1047
1069
  suggestPaidHeader: "Pagos. A matr\xEDcula fica no navegador e nada \xE9 debitado por aqui:",
1048
- 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.",
1070
+ loginAccountOwnerManaged: "Esta conta agora \xE9 gerenciada por voc\xEA na 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.",
1049
1071
  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",
1050
1072
  creator: {
1051
1073
  loginBrowserOnly: "`--creator` s\xF3 funciona no login pelo browser. Rode `tostudy login --creator` sem --code, --magic-link ou --manual.",
@@ -1325,11 +1347,27 @@ import path2 from "node:path";
1325
1347
  import { chmod, readFile, rm, writeFile } from "node:fs/promises";
1326
1348
  import { execFile } from "node:child_process";
1327
1349
  import { promisify } from "node:util";
1328
- function fileBelongsTo(secrets, owner) {
1350
+ function identityOf(secrets) {
1351
+ if (secrets.userId) return { userId: secrets.userId, sessionId: secrets.sessionId };
1352
+ try {
1353
+ const claims = JSON.parse(
1354
+ Buffer.from(secrets.accessToken.split(".")[1] ?? "", "base64url").toString("utf-8")
1355
+ );
1356
+ if (typeof claims.userId !== "string") return null;
1357
+ return {
1358
+ userId: claims.userId,
1359
+ ...typeof claims.sid === "string" ? { sessionId: claims.sid } : {}
1360
+ };
1361
+ } catch {
1362
+ return null;
1363
+ }
1364
+ }
1365
+ function belongsTo(secrets, owner) {
1329
1366
  if (!owner) return true;
1330
- if (!secrets.userId) return false;
1331
- if (secrets.userId !== owner.userId) return false;
1332
- if (secrets.sessionId && owner.sessionId && secrets.sessionId !== owner.sessionId) return false;
1367
+ const identity = identityOf(secrets);
1368
+ if (!identity) return null;
1369
+ if (identity.userId !== owner.userId) return false;
1370
+ if (identity.sessionId && owner.sessionId && identity.sessionId !== owner.sessionId) return false;
1333
1371
  return true;
1334
1372
  }
1335
1373
  function getStoreKey(configDir) {
@@ -1413,10 +1451,9 @@ async function loadStoredSessionSecrets(configDir, owner) {
1413
1451
  let legacyFile = null;
1414
1452
  try {
1415
1453
  const fromFile = await loadFallback(configDir);
1416
- if (fromFile && fileBelongsTo(fromFile, owner)) {
1417
- return fromFile;
1418
- }
1419
- if (fromFile && !fromFile.userId) legacyFile = fromFile;
1454
+ const verdict = fromFile && belongsTo(fromFile, owner);
1455
+ if (fromFile && verdict === true) return fromFile;
1456
+ if (fromFile && verdict === null) legacyFile = fromFile;
1420
1457
  } catch {
1421
1458
  }
1422
1459
  try {
@@ -1428,7 +1465,8 @@ async function loadStoredSessionSecrets(configDir, owner) {
1428
1465
  account,
1429
1466
  "-w"
1430
1467
  ]);
1431
- return JSON.parse(stdout2.trim());
1468
+ const fromKeychain = JSON.parse(stdout2.trim());
1469
+ return belongsTo(fromKeychain, owner) === false ? legacyFile : fromKeychain;
1432
1470
  } catch {
1433
1471
  return legacyFile;
1434
1472
  }
@@ -3579,7 +3617,7 @@ async function loginWithMagicLink(magicLinkUrl, apiUrl) {
3579
3617
  await persistSession(data, apiUrl);
3580
3618
  return data;
3581
3619
  }
3582
- var loginCommand = new Command("login").description("Autentica no ToStudy via browser").option("--manual", "Login manual (sem browser)").option("--code <code>", "Login n\xE3o-interativo via c\xF3digo de autentica\xE7\xE3o").option("--magic-link <url>", "Login via URL de magic-link (recupera\xE7\xE3o)").option("--creator", "Request the creator scope (author courses with your own AI agent)").option("--api-url <url>", "API URL override", DEFAULT_API_URL).action(
3620
+ var loginCommand = new Command("login").description("Autentica na ToStudy via browser").option("--manual", "Login manual (sem browser)").option("--code <code>", "Login n\xE3o-interativo via c\xF3digo de autentica\xE7\xE3o").option("--magic-link <url>", "Login via URL de magic-link (recupera\xE7\xE3o)").option("--creator", "Request the creator scope (author courses with your own AI agent)").option("--api-url <url>", "API URL override", DEFAULT_API_URL).action(
3583
3621
  async (opts) => {
3584
3622
  const apiUrl = opts.apiUrl;
3585
3623
  if (opts.creator && (opts.code || opts.magicLink || opts.manual)) {
@@ -3790,7 +3828,7 @@ import { spawn } from "node:child_process";
3790
3828
  import { hostname } from "node:os";
3791
3829
 
3792
3830
  // src/version.ts
3793
- var CLI_VERSION = true ? "0.18.22" : "0.7.1";
3831
+ var CLI_VERSION = true ? "0.18.24" : "0.7.1";
3794
3832
 
3795
3833
  // src/installer/mcp-setup.ts
3796
3834
  function safeServerError(text2) {
@@ -5236,9 +5274,9 @@ function buildPipelineDeps(opts = {}) {
5236
5274
  init_runtime_registry();
5237
5275
  import readline2 from "node:readline/promises";
5238
5276
  import { stdin, stdout } from "node:process";
5239
- var ROOT_AGENTS_QUESTION = "Esta pasta j\xE1 tem um AGENTS.md. Adicionar o bloco do ToStudy nele? [s/N] ";
5277
+ var ROOT_AGENTS_QUESTION = "Esta pasta j\xE1 tem um AGENTS.md. Adicionar o bloco da ToStudy nele? [s/N] ";
5240
5278
  function rootAgentsSkippedHint() {
5241
- return " AGENTS.md desta pasta n\xE3o foi alterado \u2014 rode `tostudy sync --root-agents` para adicionar o bloco do ToStudy.";
5279
+ return " AGENTS.md desta pasta n\xE3o foi alterado \u2014 rode `tostudy sync --root-agents` para adicionar o bloco da ToStudy.";
5242
5280
  }
5243
5281
  async function askViaReadline(question) {
5244
5282
  const rl = readline2.createInterface({ input: stdin, output: stdout });
@@ -20711,7 +20749,7 @@ async function setupWorkspace(input2) {
20711
20749
  const readme = [
20712
20750
  `# ${input2.courseName}`,
20713
20751
  "",
20714
- "Workspace de estudo gerado pelo ToStudy.",
20752
+ "Workspace de estudo gerado pela ToStudy.",
20715
20753
  "",
20716
20754
  "## Estrutura",
20717
20755
  "",