{
  "name": "sandbox-tools",
  "title": "Sandbox & Code Execution",
  "description": "How to use the code execution sandbox, pre-installed CLI tools, and language runtimes",
  "guid": "sk_plat_sbox",
  "category": "Agent Tools",
  "requiredTools": [
    "code_execute"
  ],
  "content": "# Sandbox & Code Execution\n\n## code_execute\nRun JavaScript, Python, or Bash in a sandboxed Docker container. No network access.\n\n## File I/O Contract - \"sandbox = your project\"\n- `/work/` mirrors your project files. Input paths are preserved: an `input_files` entry of `data/foo.csv` lands at `/work/data/foo.csv`.\n- Write files at **any relative path under /work/** (or the cwd, which is /work/). Anything you create or modify is written back to the project at the same path.\n- If you write to a path that already exists, the project file is **versioned** (not overwritten destructively). Users and agents can roll back with `file_version_restore`, so it's safe to transform files in place.\n- Unchanged input files are NOT round-tripped (we compare sha256 before returning them). You only pay the VFS write when you actually changed a file.\n- Python users: `os.makedirs('thumbnails', exist_ok=True)` before writing to a new subdir. `ffmpeg` and most CLI tools auto-create parent dirs.\n- Max file size: 512 KB. No network. 30s default / 600s max timeout.\n- `output_files` is an optional assertion: list paths you *expect* to produce, and you'll get a warning if any are missing. It does **not** filter - all new/modified files are returned regardless.\n\n## Pre-installed Runtimes\n- **Node.js 20** - full standard library\n- **Python 3** - pandas, numpy, matplotlib, scipy, sympy, pillow, openpyxl, xlsxwriter, xlrd, python-docx, python-pptx, reportlab, cairosvg, seaborn, qrcode, python-barcode, requests, bs4, lxml, pyyaml, Jinja2, tabulate, csvkit (+ agate-dbf, agate-excel, agate-sql, dbfread), pyfiglet, pytesseract, python-dateutil, python-slugify, Pygments, faker, wordcloud, networkx, SQLAlchemy, Markdown, babel, fonttools\n- **Perl** 5.36 - full install\n- **GCC/G++**, **mingw-w64** (cross-compile to Windows .exe via `x86_64-w64-mingw32-gcc` / `-g++` / `-windres`)\n\n## CLI Tools (prefer one-liners over scripts)\n- **FFmpeg** - transcode, trim, extract frames/audio, generate thumbnails (`ffmpeg`, `ffprobe`, `ffplay`)\n- **ImageMagick** (`convert`/`mogrify`/`identify`/`composite`) - resize, crop, composite, format-convert\n- **Graphviz** (`dot`, `neato`, `sfdp`, `fdp`, `twopi`, `circo`) - diagrams from DOT\n- **gnuplot** - CLI plotting\n- **sox** - audio processing (convert, trim, mix, effects); `play`/`rec` also available\n- **jq** - JSON query/transform\n- **sqlite3** - ad-hoc queries on .sqlite/.db\n- **PDF toolkit** - `pdftotext`, `pdfimages`, `pdfinfo`, `pdfhtml`, `pdftoppm` (PDF→PNG/PPM), `pdftocairo` (PDF→PNG/SVG), `pdfunite` (merge), `pdfseparate` (split), `pdfattach`/`pdfdetach`, `pdfsig`, `pdffonts`\n- **ghostscript** (`gs`), `ps2pdf`/`pdf2ps`/`ps2epsi`/`eps2eps`/`dvipdf` - PostScript ↔ PDF\n- **qpdf** - merge, split, encrypt, linearize PDFs\n- **pandoc** - convert markdown/HTML/docx/epub/rst/latex\n- **LibreOffice** (`soffice --headless`, `lowriter`, `localc`, `loimpress`, `lodraw`, `loweb`) - docx/xlsx/pptx → PDF or HTML\n- **wkhtmltopdf** / **wkhtmltoimage** - render HTML files to PDF or PNG\n- **exiftool**, **mediainfo** - read/write file metadata\n- **potrace**, **mkbitmap** - bitmap → SVG (`mkbitmap` preprocesses for `potrace`)\n- **optipng**, **gifsicle** - image optimization; **gifdiff**, **gifview**\n- **WebP toolkit** - `cwebp` (encode), `dwebp` (decode), `gif2webp`, `img2webp`, `webpmux`, `webpinfo`\n- **diffimg** - pixel-diff two images\n- **xmlstarlet** - query/edit XML\n- **datamash**, **miller** (`mlr`) - tabular stats and CSV/JSON transforms\n- **tesseract** - OCR (Python: `pytesseract.image_to_string`)\n- **qrencode** - generate QR code images\n- **fc-list**, **fc-match** - fontconfig: list/match fonts on the system\n- **lp_solve** - linear programming solver (LP/MIP)\n- **openssl** - hashes, x509, keygen, encrypt/decrypt\n- **gpg** (+ `gpgsm`) - sign, encrypt, verify\n- **bc** - arbitrary-precision calculator for bash\n- **tree** - recursive directory listing\n- **p7zip** (`7z`), **unzip/zip** (`zipinfo`, `zipsplit`, `zipcloak`), **unrar**\n- **hunspell**, **figlet/toilet**, **dos2unix/unix2dos**, **sed/awk/mawk/perl**\n\n## Discovering tools\nIf unsure whether a tool or package is available, probe before using it - the sandbox has no network, so a fast check is cheaper than a failed run:\n- CLI: `command -v ffmpeg` (exits 0 with path, 1 if missing)\n- Python: `python3 -c \"import foo; print(foo.__version__)\"` or `pip show foo`\n- Node: `node -e \"console.log(require.resolve('foo'))\"`\n\n## Worked Examples\n\n### 1. FFmpeg - transcode MP4 → WebM\n```\ninput_files: [\"videos/clip.mp4\"]\nlanguage: bash\ncode: ffmpeg -y -i videos/clip.mp4 -c:v libvpx-vp9 -b:v 1M -c:a libopus videos/clip.webm\n```\nReturns: project gains `videos/clip.webm`. The `.mp4` is unchanged, so it is not re-written.\n\n### 2. FFmpeg - extract 10 frames from a video\n```\ninput_files: [\"videos/clip.mp4\"]\nlanguage: bash\ncode: |\n  mkdir -p frames\n  ffmpeg -y -i videos/clip.mp4 -vf \"fps=10/$(ffprobe -v error -show_entries format=duration -of csv=p=0 videos/clip.mp4)\" frames/frame_%03d.jpg\n```\nReturns: `frames/frame_001.jpg` … `frames/frame_010.jpg`.\n\n### 3. ImageMagick - resize + convert format\n```\ninput_files: [\"images/photo.jpg\"]\nlanguage: bash\ncode: |\n  mkdir -p thumbnails\n  convert images/photo.jpg -resize 400x400 -quality 85 thumbnails/photo.webp\n```\nReturns: `thumbnails/photo.webp`.\n\n### 4. Python pandas - filter/aggregate a CSV\n```\ninput_files: [\"data/sales.csv\"]\nlanguage: python\ncode: |\n  import pandas as pd\n  df = pd.read_csv('data/sales.csv')\n  q4 = df[df['quarter'] == 'Q4'].groupby('region')['amount'].sum().reset_index()\n  q4.to_csv('data/sales_q4.csv', index=False)\n  print(q4.to_string(index=False))\n```\nReturns: `data/sales_q4.csv` plus a printed preview on stdout.\n\n### 5. Python matplotlib - chart a JSON metric series → PNG\n```\ninput_files: [\"data/metrics.json\"]\nlanguage: python\ncode: |\n  import json, os\n  import matplotlib\n  matplotlib.use('Agg')\n  import matplotlib.pyplot as plt\n  d = json.load(open('data/metrics.json'))\n  os.makedirs('charts', exist_ok=True)\n  plt.plot(d['labels'], d['values'])\n  plt.xticks(rotation=45); plt.tight_layout()\n  plt.savefig('charts/metrics.png', dpi=120)\n```\nReturns: `charts/metrics.png` (inline in the reply).\n\n### 6. Bash + poppler - PDF → plain text\n```\ninput_files: [\"docs/manual.pdf\"]\nlanguage: bash\ncode: |\n  mkdir -p docs\n  pdftotext -layout docs/manual.pdf docs/manual.txt\n  wc -l docs/manual.txt\n```\nReturns: `docs/manual.txt` plus the line count on stdout.\n\n## Audio/Music Generation - use dedicated tools\nDo NOT use code_execute with sox/ffmpeg to generate music or sound effects. Use:\n- `music_generate` - AI-generated music\n- `sound_generate` - AI-generated sound effects\n- `speech_generate` - AI-generated voice narration\n\nThese produce higher-quality results and handle file saving automatically."
}
