@theokit/sdk 4.21.1 → 4.22.0

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.
@@ -542,7 +542,7 @@ var LinuxSandbox = class extends LocalSandbox {
542
542
  this.cwd = config.workDir ?? process.cwd();
543
543
  this.bin = opts.bin ?? "bwrap";
544
544
  this.env = opts.env ?? allowlistedEnv();
545
- this.seccompPath = this.network ? void 0 : restrictedSeccompPath();
545
+ this.seccompPath = seccompPathParaRede(this.network);
546
546
  }
547
547
  /** Extracted for test visibility — delegates to the pure `wrapCommandForSandbox` (M57, single wrap SoT). */
548
548
  wrapCommand(command) {
@@ -558,6 +558,32 @@ var LinuxSandbox = class extends LocalSandbox {
558
558
  command
559
559
  );
560
560
  }
561
+ /**
562
+ * M75 review (arquitetura, HIGH) — sem este override a classe MENTIA.
563
+ *
564
+ * `LinuxSandbox` se documenta como "kernel-enforced sandbox backend", mas sobrescrevia apenas
565
+ * `execute`. `uploadFile` continuava o herdado de `LocalSandbox`, que escreve direto no host via
566
+ * `fs/promises` e aceita caminho ABSOLUTO — sem bwrap, sem seccomp, sem restrição de caminho. E
567
+ * `SandboxBackend.writeFile` delega a ele. O resultado era uma classe incoerente: ler, buscar e
568
+ * listar passavam pelo confinamento; escrever, não.
569
+ *
570
+ * Rotear pelo `execute` embrulhado resolve na raiz: a escrita passa a viver sob a MESMA política
571
+ * do resto — se o bwrap nega o caminho, a escrita falha, como deve. O conteúdo vai por stdin (não
572
+ * por argv) porque argv tem limite de tamanho e conteúdo de arquivo não tem.
573
+ */
574
+ async uploadFile(caminho, conteudo) {
575
+ if (this.mode === "danger-full-access") return super.uploadFile(caminho, conteudo);
576
+ const alvo = caminho.startsWith("/") ? caminho : `${this.cwd}/${caminho}`;
577
+ const b64 = Buffer.from(conteudo).toString("base64");
578
+ const r = await this.execute(
579
+ `mkdir -p ${shellQuote(path.dirname(alvo))} && printf %s ${shellQuote(b64)} | base64 -d > ${shellQuote(alvo)}`
580
+ );
581
+ if (r.exitCode !== 0) {
582
+ throw new Error(
583
+ `uploadFile bloqueado ou falhou sob confinamento (${alvo}): ${r.stderr.trim() || `exit ${r.exitCode}`}`
584
+ );
585
+ }
586
+ }
561
587
  execute(command, opts) {
562
588
  const wrapped = this.wrapCommand(command);
563
589
  if (wrapped === null) return super.execute(command, opts);
@@ -632,28 +658,34 @@ var avisouInterativo = false;
632
658
  function resetInteractiveWarnLatch() {
633
659
  avisouInterativo = false;
634
660
  }
661
+ function seccompPathParaRede(redeLiberada) {
662
+ return redeLiberada ? void 0 : restrictedSeccompPath();
663
+ }
664
+ function decidirConfinamento(opts) {
665
+ if (opts.mode === "danger-full-access") return null;
666
+ const detection = (opts.detect ?? detectBwrapMemoizado)();
667
+ if (detection.ok) return detection.bin;
668
+ if (!avisouInterativo) {
669
+ avisouInterativo = true;
670
+ const warn = opts.warn ?? ((m) => console.warn(redactSecrets(m)));
671
+ warn(
672
+ `[sandbox] OS-level enforcement unavailable (${detection.reason}) \u2014 interactive session runs WITHOUT kernel confinement (sandbox_mode=${opts.mode}).`
673
+ );
674
+ }
675
+ return null;
676
+ }
635
677
  function interactiveWrapCommand(opts) {
636
678
  return (command, cwd) => {
637
- if (opts.mode === "danger-full-access") return null;
638
- const detection = (opts.detect ?? detectBwrapMemoizado)();
639
- if (!detection.ok) {
640
- if (!avisouInterativo) {
641
- avisouInterativo = true;
642
- const warn = opts.warn ?? ((m) => console.warn(redactSecrets(m)));
643
- warn(
644
- `[sandbox] OS-level enforcement unavailable (${detection.reason}) \u2014 interactive session runs WITHOUT kernel confinement (sandbox_mode=${opts.mode}).`
645
- );
646
- }
647
- return null;
648
- }
679
+ const bin = decidirConfinamento(opts);
680
+ if (bin === null) return null;
649
681
  return wrapCommandForSandbox(
650
682
  opts.mode,
651
683
  {
652
684
  cwd,
653
685
  network: opts.network ?? false,
654
686
  env: allowlistedEnv(),
655
- bin: detection.bin,
656
- seccompPath: restrictedSeccompPath()
687
+ bin,
688
+ seccompPath: seccompPathParaRede(opts.network ?? false)
657
689
  },
658
690
  command
659
691
  );