unslothai/unsloth/main 19M tokens More Tools
```
├── .gitattributes (omitted)
├── .github/
   ├── CODEOWNERS (3.1k tokens)
   ├── FUNDING.yml (100 tokens)
   ├── ISSUE_TEMPLATE/
      ├── bug---issue.md (600 tokens)
      ├── feature-request.md (100 tokens)
   ├── actions/
      ├── frontend-dist-restore/
         ├── action.yml (2.1k tokens)
      ├── frontend-dist-save/
         ├── action.yml (1300 tokens)
      ├── install-unsloth-local/
         ├── action.yml (1700 tokens)
      ├── pip-cache-restore/
         ├── action.yml (1600 tokens)
      ├── pip-cache-save/
         ├── action.yml (300 tokens)
      ├── uv-cache-restore/
         ├── action.yml (500 tokens)
      ├── uv-cache-save/
         ├── action.yml (600 tokens)
   ├── ci-preempt.json (900 tokens)
   ├── ci/
      ├── clean-machine-matrix.yml (1300 tokens)
      ├── interrupted-install-matrix.yml (600 tokens)
   ├── dependabot.yml (800 tokens)
   ├── scripts/
      ├── Watch-ForCompiler.ps1 (3.1k tokens)
      ├── agent-guides-drive.sh (9.1k tokens)
      ├── agent-guides-install.sh (900 tokens)
      ├── assert-bundle-signed.ps1 (700 tokens)
      ├── assert-llama-loads.sh (1000 tokens)
      ├── assert-nobuild.ps1 (700 tokens)
      ├── assert-prompt-cache.sh (2.1k tokens)
      ├── boot-studio-api-only.sh (800 tokens)
      ├── ci-connect-prompt.txt
      ├── ci-min-system-prompt.txt
      ├── clean-machine-assert.sh (3.7k tokens)
      ├── clean-machine-env.sh (2.2k tokens)
      ├── clean-machine-install-name-tool.sh (500 tokens)
      ├── ensure-docker-daemon.ps1 (300 tokens)
      ├── hf-download-with-retry.sh (800 tokens)
      ├── interrupt-install.ps1 (2.1k tokens)
      ├── interrupt-install.sh (1400 tokens)
      ├── interrupted_install_probe.py (2.8k tokens)
      ├── kaggle_prefetch.py (2.4k tokens)
      ├── kaggle_studio_ci/
         ├── build_kernel.py (5.7k tokens)
         ├── collect_evidence.py (1600 tokens)
         ├── report.py (2.2k tokens)
      ├── kaggle_t4_ci/
         ├── BUDGET.md (1600 tokens)
         ├── build_kernel.py (18.1k tokens)
         ├── check_steps.py (1800 tokens)
         ├── collect.py (6.2k tokens)
         ├── gate.py (9k tokens)
         ├── launch.py (13.5k tokens)
         ├── legs.py (10k tokens)
         ├── post_statuses.py (1500 tokens)
         ├── report.py (4.1k tokens)
      ├── lane-load-orchestrator.sh (300 tokens)
      ├── lane-lockfile-audit.sh (200 tokens)
      ├── parity-find-unsloth.sh (300 tokens)
      ├── parity-install-side.sh (500 tokens)
      ├── resolve-desktop-release.py (700 tokens)
      ├── retry-with-apt-lock.sh (1600 tokens)
      ├── run-studio-indicator-browser.sh (700 tokens)
      ├── run-studio-permission-browser.sh (900 tokens)
      ├── run-studio-ui-lane.sh (1700 tokens)
      ├── select_install_matrix.py (600 tokens)
      ├── serve-unsloth-run.sh (1400 tokens)
      ├── studio_smoke/
         ├── multi_turn_chat.py (2.5k tokens)
      ├── virgin-windows-install.ps1 (1600 tokens)
      ├── virgin-windows-probe.ps1 (1700 tokens)
      ├── wait-for-health.sh (800 tokens)
   ├── workflows/
      ├── cache-janitor.yml (4k tokens)
      ├── ci-capacity.yml (7.7k tokens)
      ├── clean-machine-install-ci.yml (17.9k tokens)
      ├── consolidated-tests-ci.yml (26.8k tokens)
      ├── cross-platform-parity-ci.yml (3.6k tokens)
      ├── desktop-app-clean-machine-ci.yml (12.5k tokens)
      ├── docker-credential-probe.yml (1100 tokens)
      ├── docker-publish.yml (7.1k tokens)
      ├── interrupted-install-ci.yml (5.1k tokens)
      ├── kaggle-collect.yml (2000 tokens)
      ├── kaggle-t4-notebook-ci.yml (15.3k tokens)
      ├── kaggle-t4-studio-gpu-ci.yml (7.1k tokens)
      ├── lint-ci.yml (6.1k tokens)
      ├── local-agent-guides-ci.yml (9.2k tokens)
      ├── lockfile-audit.yml (700 tokens)
      ├── mlx-ci.yml (6.2k tokens)
      ├── model-catalog-network-check.yml (500 tokens)
      ├── notebooks-ci.yml (7.4k tokens)
      ├── pester-guard-ci.yml (300 tokens)
      ├── publish-desktop-updater.yml (6.4k tokens)
      ├── rag-upload-compatibility.yml (300 tokens)
      ├── release-desktop.yml (21.9k tokens)
      ├── security-audit.yml (11.8k tokens)
      ├── stale.yml (300 tokens)
      ├── startup-profile-ci.yml (2.4k tokens)
      ├── studio-api-smoke.yml (2.1k tokens)
      ├── studio-backend-ci.yml (6.4k tokens)
      ├── studio-export-capability-ci.yml (1100 tokens)
      ├── studio-frontend-ci.yml (6.5k tokens)
      ├── studio-inference-smoke.yml (13.4k tokens)
      ├── studio-load-orchestrator-ci.yml (500 tokens)
      ├── studio-mac-install-matrix.yml (1600 tokens)
      ├── studio-mac-ui-smoke.yml (18.7k tokens)
      ├── studio-tauri-smoke.yml (4.4k tokens)
      ├── studio-ui-smoke.yml (12.8k tokens)
      ├── studio-update-smoke.yml (2.6k tokens)
      ├── studio-windows-api-smoke.yml (3.1k tokens)
      ├── studio-windows-inference-smoke.yml (23.4k tokens)
      ├── studio-windows-ui-smoke.yml (5.7k tokens)
      ├── studio-windows-update-smoke.yml (4.3k tokens)
      ├── studiobench-ci.yml (3.4k tokens)
      ├── studiobench-ui-parity.yml (9.3k tokens)
      ├── version-compat-ci.yml (3.6k tokens)
      ├── wheel-smoke.yml (3.1k tokens)
      ├── windows-application-control-ci.yml (4.8k tokens)
      ├── windows-no-compiler-ci.yml (2.8k tokens)
      ├── workflow-trigger-lint.yml (2.9k tokens)
├── .gitignore (1100 tokens)
├── .pre-commit-config.yaml (500 tokens)
├── CODE_OF_CONDUCT.md (1100 tokens)
├── CONTRIBUTING.md (500 tokens)
├── COPYING (6.9k tokens)
├── LICENSE (omitted)
├── MANIFEST.in (400 tokens)
├── README.md (4.6k tokens)
├── build.sh (1000 tokens)
├── cli.py (100 tokens)
├── docker/
   ├── .dockerignore (200 tokens)
   ├── DOCKERHUB.md (1400 tokens)
   ├── Dockerfile (7.5k tokens)
   ├── Dockerfile.studio (2.9k tokens)
   ├── NOTICE (400 tokens)
   ├── build.sh (1000 tokens)
   ├── entrypoint.sh (1700 tokens)
   ├── fetch_llama_prebuilt.py (1900 tokens)
   ├── install_nvidia_toolkit.sh (2.4k tokens)
   ├── jupyter/
      ├── BRANDING.md (500 tokens)
      ├── favicon.ico
      ├── install_sloth_stickers.py (500 tokens)
      ├── jupyter_server_config.d/
         ├── unsloth_branding_guard.json
      ├── login.html (1100 tokens)
      ├── logo.png
      ├── overrides.json (200 tokens)
      ├── unsloth_branding.py (1800 tokens)
      ├── unsloth_labext/
         ├── .gitignore
         ├── .yarnrc.yml
         ├── package.json (300 tokens)
         ├── src/
            ├── about.ts (700 tokens)
            ├── branding.ts (300 tokens)
            ├── cellNav.ts (800 tokens)
            ├── colabTitle.ts (900 tokens)
            ├── index.ts (500 tokens)
            ├── logo.ts (3.9k tokens)
            ├── outputSelect.ts (700 tokens)
            ├── splash.ts (500 tokens)
            ├── uiChrome.ts (300 tokens)
         ├── style/
            ├── index.css (100 tokens)
            ├── variables.css (800 tokens)
         ├── tsconfig.json (100 tokens)
   ├── run.sh (1900 tokens)
   ├── smoke_test.py (900 tokens)
   ├── studio_launch.sh (1300 tokens)
   ├── studio_password.sh (1000 tokens)
   ├── studio_run.sh (600 tokens)
   ├── supervisord.conf (600 tokens)
   ├── unsloth_colab_compat.py (400 tokens)
   ├── unsloth_ipython_startup.py (300 tokens)
   ├── unsloth_jupyter_tunnel.sh (400 tokens)
   ├── unsloth_llama_update.sh (1800 tokens)
   ├── unsloth_nb_compat.py (2.5k tokens)
   ├── unsloth_nb_content_sig.py (1700 tokens)
   ├── unsloth_nb_pip_magic.py (500 tokens)
   ├── unsloth_nb_strip_colab.py (2.2k tokens)
   ├── unsloth_nb_view.py (1700 tokens)
   ├── unsloth_pip_shim.py (10.5k tokens)
   ├── unsloth_run.py (2.2k tokens)
   ├── unsloth_studio_update.sh (1200 tokens)
   ├── unsloth_sync_notebooks.sh (7k tokens)
├── images/
   ├── Assistant.png
   ├── Colab.png
   ├── Discord button.png
   ├── Discord.png
   ├── Documentation Button.png
   ├── Free version button.png
   ├── Kaggle.png
   ├── Kofi button.png
   ├── LAION 2GPU.png
   ├── Merge.png
   ├── Run.png
   ├── STUDIO BLACK LOGO.png
   ├── STUDIO WHITE LOGO.png
   ├── Slim Orca 2GPUs.png
   ├── Terminal_Type.png
   ├── Where_Terminal.png
   ├── buy me a coffee button.png
   ├── documentation github button.png
   ├── documentation green button.png
   ├── documentation lighter.png
   ├── documentation white button.png
   ├── made with unsloth.png
   ├── ollama.png
   ├── peft x trl button.png
   ├── start free finetune button.png
   ├── unsloth end.png
   ├── unsloth loading page render.png
   ├── unsloth logo black text.png
   ├── unsloth logo only.png
   ├── unsloth logo white text.png
   ├── unsloth made with love.png
   ├── unsloth new logo.png
   ├── unsloth sticker.png
├── install.ps1 (85.5k tokens)
├── install.sh (61.3k tokens)
├── pyproject.toml (29.1k tokens)
├── scripts/
   ├── build_prequant_checkpoint.py (2.3k tokens)
   ├── build_te_prequant_checkpoint.py (1000 tokens)
   ├── build_whisper_cpp.sh (600 tokens)
   ├── check_frontend_dep_removal.py (7.2k tokens)
   ├── check_new_install_scripts.py (1600 tokens)
   ├── compare_engines.py (1400 tokens)
   ├── compile_probe.py (1300 tokens)
   ├── data/
      ├── colab_apt_list.gpu.txt (16.6k tokens)
      ├── colab_os_info.gpu.txt (100 tokens)
      ├── colab_pip_freeze.gpu.txt (2.9k tokens)
      ├── colab_to_cpu_pin.json (700 tokens)
   ├── diffusion_bench.py (4.7k tokens)
   ├── diffusion_quality.py (3.8k tokens)
   ├── enforce_kwargs_spacing.py (5.1k tokens)
   ├── exec_literals_baseline.json (3.8k tokens)
   ├── fbcache_flux_probe.py (1200 tokens)
   ├── fp8_overflow_check.py (800 tokens)
   ├── image_speedmem_bench.py (3.2k tokens)
   ├── install_gemma4_mlx.sh (1200 tokens)
   ├── install_qwen3_6_mlx.sh (1600 tokens)
   ├── install_rocm_wsl_strixhalo.sh (4k tokens)
   ├── int8_linear_probe.py (700 tokens)
   ├── leverage_probe.py (1000 tokens)
   ├── lint_backend_python_floor.py (1300 tokens)
   ├── lint_duplicate_definitions.py (7.3k tokens)
   ├── lint_exec_literals.py (2.4k tokens)
   ├── lint_no_parallel_clamp.py (1900 tokens)
   ├── lint_workflow_triggers.py (3.3k tokens)
   ├── lockfile_supply_chain_audit.py (6.3k tokens)
   ├── make_dmg_background.py (1400 tokens)
   ├── notebook_to_python.py (2.5k tokens)
   ├── notebook_validator.py (35.7k tokens)
   ├── nvfp4_probe.py (1300 tokens)
   ├── nvfp4_t211_probe.py (2.2k tokens)
   ├── online_tokenization_ab.py (1900 tokens)
   ├── p2p_integrity_probe.py (2.2k tokens)
   ├── perf_levers_probe.py (1700 tokens)
   ├── perf_verify.py (1100 tokens)
   ├── prequant_probe.py (1400 tokens)
   ├── profile_startup.py (2.8k tokens)
   ├── quant_probe.py (2.3k tokens)
   ├── run_ruff_format.py (1600 tokens)
   ├── scan_npm_packages.py (17.1k tokens)
   ├── scan_npm_packages_baseline.json (100 tokens)
   ├── scan_packages.py (24.6k tokens)
   ├── scan_packages_baseline.json (29k tokens)
   ├── sd_cpp_smoke.py (1300 tokens)
   ├── sdpa_mask_backend_probe.py (700 tokens)
   ├── sparse_accum_probe.py (1700 tokens)
   ├── stamp_studio_release.py (1800 tokens)
   ├── sync_allow_scripts_pins.py (1000 tokens)
   ├── uninstall.ps1 (13.1k tokens)
   ├── uninstall.sh (10.2k tokens)
   ├── verify_comment_only_diff.py (1700 tokens)
   ├── verify_import_hoist.py (7.8k tokens)
   ├── verify_prequant_backend.py (1500 tokens)
   ├── video_quality.py (3.8k tokens)
   ├── virustotal_scan.py (6.1k tokens)
├── studio/
   ├── LICENSE.AGPL-3.0 (6.9k tokens)
   ├── MCP.md (700 tokens)
   ├── NVLINK_P2P.md (1200 tokens)
   ├── PDF_OCR.md (500 tokens)
   ├── ROCM_RDNA2_APU.md (1100 tokens)
   ├── Unsloth_Studio_Colab.ipynb (1300 tokens)
   ├── __init__.py
   ├── backend/
      ├── __init__.py
      ├── _platform_compat.py (200 tokens)
      ├── assets/
         ├── __init__.py
         ├── chat_templates/
            ├── gemma-4-edge.jinja (3.9k tokens)
            ├── gemma-4.jinja (3.8k tokens)
         ├── configs/
            ├── __init__.py
            ├── full_finetune.yaml (200 tokens)
            ├── inference_defaults.json (2000 tokens)
            ├── lora_text.yaml (200 tokens)
            ├── model_defaults/
               ├── default.yaml (200 tokens)
               ├── embedding/
                  ├── unsloth_Qwen3-Embedding-0.6B.yaml (200 tokens)
                  ├── unsloth_all-MiniLM-L6-v2.yaml (200 tokens)
                  ├── unsloth_bge-m3.yaml (200 tokens)
                  ├── unsloth_embeddinggemma-300m.yaml (200 tokens)
                  ├── unsloth_gte-modernbert-base.yaml (200 tokens)
               ├── ernie/
                  ├── unsloth_ERNIE-4.5-21B-A3B-PT.yaml (200 tokens)
                  ├── unsloth_ERNIE-4.5-VL-28B-A3B-PT.yaml (200 tokens)
               ├── falcon/
                  ├── tiiuae_Falcon-H1-0.5B-Instruct.yaml (200 tokens)
               ├── gemma/
                  ├── unsloth_codegemma-7b-bnb-4bit.yaml (200 tokens)
                  ├── unsloth_functiongemma-270m-it.yaml (200 tokens)
                  ├── unsloth_gemma-2-27b-bnb-4bit.yaml (200 tokens)
                  ├── unsloth_gemma-2-2b.yaml (200 tokens)
                  ├── unsloth_gemma-3-270m-it.yaml (200 tokens)
                  ├── unsloth_gemma-3-27b-it.yaml (200 tokens)
                  ├── unsloth_gemma-3-4b-it.yaml (200 tokens)
                  ├── unsloth_gemma-3-4b-pt.yaml (200 tokens)
                  ├── unsloth_gemma-3n-E4B-it.yaml (200 tokens)
                  ├── unsloth_gemma-3n-E4B.yaml (200 tokens)
                  ├── unsloth_gemma-4-26B-A4B-it.yaml (200 tokens)
                  ├── unsloth_gemma-4-26B-A4B.yaml (200 tokens)
                  ├── unsloth_gemma-4-31B-it.yaml (200 tokens)
                  ├── unsloth_gemma-4-31B.yaml (200 tokens)
                  ├── unsloth_gemma-4-E2B-it.yaml (200 tokens)
                  ├── unsloth_gemma-4-E2B.yaml (200 tokens)
                  ├── unsloth_gemma-4-E4B-it.yaml (200 tokens)
                  ├── unsloth_gemma-4-E4B.yaml (200 tokens)
               ├── gpt-oss/
                  ├── unsloth_gpt-oss-120b.yaml (200 tokens)
                  ├── unsloth_gpt-oss-20b.yaml (200 tokens)
               ├── granite/
                  ├── unsloth_granite-4.0-350m-unsloth-bnb-4bit.yaml (200 tokens)
                  ├── unsloth_granite-4.0-h-micro.yaml (200 tokens)
               ├── llama/
                  ├── unsloth_Llama-3.2-11B-Vision-Instruct.yaml (200 tokens)
                  ├── unsloth_Llama-3.2-1B-Instruct.yaml (200 tokens)
                  ├── unsloth_Llama-3.2-3B-Instruct.yaml (200 tokens)
                  ├── unsloth_Llama-3.3-70B-Instruct.yaml (200 tokens)
                  ├── unsloth_Meta-Llama-3.1-70B-bnb-4bit.yaml (200 tokens)
                  ├── unsloth_Meta-Llama-3.1-8B-Instruct-bnb-4bit.yaml (200 tokens)
                  ├── unsloth_llama-3-8b-Instruct-bnb-4bit.yaml (200 tokens)
                  ├── unsloth_llama-3-8b-bnb-4bit.yaml (200 tokens)
               ├── llasa/
                  ├── unsloth_Llasa-3B.yaml (200 tokens)
               ├── mistral/
                  ├── unsloth_Magistral-Small-2509-unsloth-bnb-4bit.yaml (200 tokens)
                  ├── unsloth_Ministral-3-3B-Instruct-2512.yaml (200 tokens)
                  ├── unsloth_Mistral-Nemo-Base-2407-bnb-4bit.yaml (200 tokens)
                  ├── unsloth_Mistral-Small-Instruct-2409.yaml (200 tokens)
                  ├── unsloth_Pixtral-12B-2409.yaml (200 tokens)
                  ├── unsloth_mistral-7b-instruct-v0.3-bnb-4bit.yaml (200 tokens)
                  ├── unsloth_mistral-7b-v0.3-bnb-4bit.yaml (200 tokens)
               ├── other/
                  ├── OuteAI_Llama-OuteTTS-1.0-1B.yaml (200 tokens)
                  ├── Spark-TTS-0.5B_LLM.yaml (200 tokens)
                  ├── sesame_csm-1b.yaml (200 tokens)
                  ├── unsloth_GLM-4.7-Flash.yaml (200 tokens)
                  ├── unsloth_LFM2-1.2B.yaml (200 tokens)
                  ├── unsloth_Nemotron-3-Nano-30B-A3B.yaml (200 tokens)
                  ├── unsloth_PaddleOCR-VL.yaml (200 tokens)
                  ├── unsloth_answerdotai_ModernBERT-large.yaml (200 tokens)
                  ├── unsloth_orpheus-3b-0.1-ft.yaml (200 tokens)
                  ├── unsloth_tinyllama-bnb-4bit.yaml (200 tokens)
                  ├── unsloth_whisper-large-v3.yaml (200 tokens)
               ├── phi/
                  ├── unsloth_Phi-3-medium-4k-instruct.yaml (200 tokens)
                  ├── unsloth_Phi-3.5-mini-instruct.yaml (200 tokens)
                  ├── unsloth_Phi-4.yaml (200 tokens)
               ├── qwen/
                  ├── imdatta0_tiny_qwen3_moe_2.8B_0.7B.yaml (200 tokens)
                  ├── unsloth_Qwen2-7B.yaml (200 tokens)
                  ├── unsloth_Qwen2-VL-7B-Instruct.yaml (200 tokens)
                  ├── unsloth_Qwen2.5-1.5B-Instruct.yaml (200 tokens)
                  ├── unsloth_Qwen2.5-7B.yaml (200 tokens)
                  ├── unsloth_Qwen2.5-Coder-1.5B-Instruct.yaml (200 tokens)
                  ├── unsloth_Qwen2.5-Coder-14B-Instruct.yaml (200 tokens)
                  ├── unsloth_Qwen2.5-Coder-7B-Instruct-bnb-4bit.yaml (200 tokens)
                  ├── unsloth_Qwen2.5-VL-7B-Instruct-bnb-4bit.yaml (200 tokens)
                  ├── unsloth_Qwen3-0.6B.yaml (200 tokens)
                  ├── unsloth_Qwen3-14B-Base-unsloth-bnb-4bit.yaml (200 tokens)
                  ├── unsloth_Qwen3-14B.yaml (200 tokens)
                  ├── unsloth_Qwen3-30B-A3B-Instruct-2507.yaml (200 tokens)
                  ├── unsloth_Qwen3-32B.yaml (200 tokens)
                  ├── unsloth_Qwen3-4B-Instruct-2507.yaml (200 tokens)
                  ├── unsloth_Qwen3-4B-Thinking-2507.yaml (200 tokens)
                  ├── unsloth_Qwen3-VL-8B-Instruct-unsloth-bnb-4bit.yaml (200 tokens)
            ├── vision_lora.yaml (200 tokens)
         ├── datasets/
            ├── alpaca_unsloth.json (21.4k tokens)
         ├── docs_ui/
            ├── LICENSE.redoc (200 tokens)
            ├── LICENSE.swagger-ui (2.3k tokens)
            ├── NOTICE.swagger-ui
            ├── README.md (300 tokens)
            ├── docs_ui_manifest.json (200 tokens)
            ├── favicon-32x32.png
            ├── redoc.standalone.js (181.9k tokens)
            ├── swagger-ui-bundle.js (301.8k tokens)
            ├── swagger-ui-bundle.js.LICENSE.txt (700 tokens)
            ├── swagger-ui.css (31k tokens)
         ├── preview_page.html (3k tokens)
      ├── auth/
         ├── .gitkeep
         ├── __init__.py (300 tokens)
         ├── authentication.py (4k tokens)
         ├── bootstrap_timeout.py (1100 tokens)
         ├── hashing.py (200 tokens)
         ├── storage.py (8.4k tokens)
         ├── terminal_prompt.py (2.7k tokens)
      ├── cloudflare_tunnel.py (7.4k tokens)
      ├── colab.py (5.8k tokens)
      ├── core/
         ├── __init__.py (900 tokens)
         ├── _msvc_env.py (2.1k tokens)
         ├── _torchao_stub.py (1600 tokens)
         ├── data_recipe/
            ├── __init__.py (100 tokens)
            ├── huggingface.py (900 tokens)
            ├── jobs/
               ├── __init__.py
               ├── constants.py (200 tokens)
               ├── manager.py (4.6k tokens)
               ├── parse.py (3.4k tokens)
               ├── types.py (600 tokens)
               ├── worker.py (1700 tokens)
            ├── jsonable.py (800 tokens)
            ├── local_callable_validators.py (2.4k tokens)
            ├── oxc-validator/
               ├── package-lock.json (5.7k tokens)
               ├── package.json
               ├── validate.mjs (3.2k tokens)
            ├── service.py (2.5k tokens)
         ├── export/
            ├── __init__.py (100 tokens)
            ├── export.py (14k tokens)
            ├── orchestrator.py (6.1k tokens)
            ├── worker.py (5.6k tokens)
         ├── import_guards.py (400 tokens)
         ├── inference/
            ├── __init__.py (400 tokens)
            ├── _html_to_md.py (9.1k tokens)
            ├── _vulkan_probe.py (1400 tokens)
            ├── anthropic_compat.py (10.1k tokens)
            ├── api_monitor.py (8.3k tokens)
            ├── audio_codecs.py (3k tokens)
            ├── audio_device.py (800 tokens)
            ├── audio_errors.py (300 tokens)
            ├── audio_gallery.py (2.8k tokens)
            ├── chat_eos.py (1000 tokens)
            ├── chat_generation_runs.py (7.2k tokens)
            ├── chat_template_helpers.py (33.4k tokens)
            ├── chat_templates.py (1000 tokens)
            ├── checkpoint.py (6.4k tokens)
            ├── context_refusal.py (3.4k tokens)
            ├── context_window.py (7.3k tokens)
            ├── defaults.py (400 tokens)
            ├── diffusion.py (70.8k tokens)
            ├── diffusion_arch_patches.py (4.1k tokens)
            ├── diffusion_attention.py (9.8k tokens)
            ├── diffusion_auto_policy.py (4.5k tokens)
            ├── diffusion_batched.py (1300 tokens)
            ├── diffusion_cache.py (3.1k tokens)
            ├── diffusion_compat.py (6.6k tokens)
            ├── diffusion_compile_cache.py (3k tokens)
            ├── diffusion_cond_cache.py (1900 tokens)
            ├── diffusion_controlnet.py (2.2k tokens)
            ├── diffusion_convrot.py (3.6k tokens)
            ├── diffusion_cuda_graph.py (4.1k tokens)
            ├── diffusion_device.py (4.2k tokens)
            ├── diffusion_eager_patches.py (1500 tokens)
            ├── diffusion_engine_router.py (3.1k tokens)
            ├── diffusion_families.py (17.4k tokens)
            ├── diffusion_gguf_compile.py (900 tokens)
            ├── diffusion_hidream.py (1300 tokens)
            ├── diffusion_ideogram4.py (3.7k tokens)
            ├── diffusion_inference_info.py (400 tokens)
            ├── diffusion_krea2.py (2k tokens)
            ├── diffusion_lora.py (3.7k tokens)
            ├── diffusion_memory.py (13.5k tokens)
            ├── diffusion_patch_backend.py (1300 tokens)
            ├── diffusion_precision.py (4.5k tokens)
            ├── diffusion_prequant.py (11.8k tokens)
            ├── diffusion_quant_pad.py (3.1k tokens)
            ├── diffusion_speed.py (5.3k tokens)
            ├── diffusion_te_prequant.py (5.1k tokens)
            ├── diffusion_torchao_patches.py (1800 tokens)
            ├── diffusion_transformer_quant.py (11.8k tokens)
            ├── external_provider.py (69.8k tokens)
            ├── external_tool_transport.py (1200 tokens)
            ├── gallery_flags.py (3.5k tokens)
            ├── generation_timing.py (1100 tokens)
            ├── gpu_arbiter.py (1200 tokens)
            ├── image_gallery.py (2.3k tokens)
            ├── inference.py (26.2k tokens)
            ├── instruction_pin.py (2.3k tokens)
            ├── key_exchange.py (1200 tokens)
            ├── llama_admission.py (9.6k tokens)
            ├── llama_cpp.py (365k tokens)
            ├── llama_http.py (300 tokens)
            ├── llama_keepwarm.py (8.2k tokens)
            ├── llama_server_args.py (17.1k tokens)
            ├── llama_stats.py (2.5k tokens)
            ├── local_model_resolver.py (9.6k tokens)
            ├── mcp_client.py (15.4k tokens)
            ├── mcp_config_import.py (1400 tokens)
            ├── media_auto_switch.py (4.2k tokens)
            ├── media_keepwarm.py (3.8k tokens)
            ├── media_locality.py (5.1k tokens)
            ├── media_model_index.py (4.4k tokens)
            ├── media_switch_backends.py (1600 tokens)
            ├── media_switch_errors.py (1200 tokens)
            ├── media_switch_locks.py (700 tokens)
            ├── memory_contract.py (2.3k tokens)
            ├── message_content.py (600 tokens)
            ├── mlx_inference.py (31k tokens)
            ├── model_ids.py (900 tokens)
            ├── native_audio.py (11.3k tokens)
            ├── native_tool_tokens.py (2.3k tokens)
            ├── offload_cost_model.py (2.3k tokens)
            ├── offload_layout.py (3.1k tokens)
            ├── offload_planner.py (8.2k tokens)
            ├── openai_auto_download.py (8.2k tokens)
            ├── openai_codex_auth.py (7k tokens)
            ├── openai_codex_client.py (9.6k tokens)
            ├── openai_codex_tool_loop.py (800 tokens)
            ├── openai_responses_shared.py (800 tokens)
            ├── orchestrator.py (26.8k tokens)
            ├── passthrough_healing.py (4.6k tokens)
            ├── presence_penalty.py (400 tokens)
            ├── pricing.py (3.1k tokens)
            ├── providers.py (8.7k tokens)
            ├── repetition_guard.py (1000 tokens)
            ├── runtime_context.py (800 tokens)
            ├── safetensors_agentic.py (15.2k tokens)
            ├── sandbox_site/
               ├── __init__.py
               ├── sitecustomize.py (2.5k tokens)
            ├── sd_cpp_args.py (5k tokens)
            ├── sd_cpp_backend.py (28.7k tokens)
            ├── sd_cpp_engine.py (8k tokens)
            ├── sd_cpp_server.py (6k tokens)
            ├── search_images.py (5.2k tokens)
            ├── sse_control_frames.py (3.5k tokens)
            ├── stream_errors.py (1600 tokens)
            ├── stt_download_worker.py (1000 tokens)
            ├── stt_ggml_sidecar.py (10.3k tokens)
            ├── stt_mtmd_sidecar.py (9.8k tokens)
            ├── stt_registry.py (1300 tokens)
            ├── stt_sidecar.py (14.9k tokens)
            ├── stt_transformers_worker.py (5.9k tokens)
            ├── studio_tool_loop.py (18.4k tokens)
            ├── tensor_fallback.py (600 tokens)
            ├── tool_call_parser.py (38.1k tokens)
            ├── tool_loop_controller.py (9.3k tokens)
            ├── tool_stream_exec.py (2.5k tokens)
            ├── tools.py (142.2k tokens)
            ├── video.py (67.7k tokens)
            ├── video_families.py (8.2k tokens)
            ├── video_gallery.py (4.9k tokens)
            ├── video_ltx2.py (5.2k tokens)
            ├── video_minimax_h3.py (10.6k tokens)
            ├── video_minimax_h3_adaln.py (2.7k tokens)
            ├── video_minimax_h3_te.py (5.6k tokens)
            ├── web_access_policy.py (1700 tokens)
            ├── worker.py (12.9k tokens)
         ├── rag/
            ├── __init__.py (100 tokens)
            ├── captioner.py (2k tokens)
            ├── chunking.py (1000 tokens)
            ├── config.py (2.6k tokens)
            ├── conversation_archive.py (25.7k tokens)
            ├── embed_llama_server.py (11.2k tokens)
            ├── embeddings.py (10.3k tokens)
            ├── folder_sync.py (14.6k tokens)
            ├── ingestion.py (6.5k tokens)
            ├── job_leases.py (800 tokens)
            ├── locators.py (1300 tokens)
            ├── parsers.py (3.6k tokens)
            ├── pdf_ocr.py (600 tokens)
            ├── retrieval.py (1100 tokens)
            ├── store.py (6.8k tokens)
            ├── tool.py (2.9k tokens)
            ├── web_rank.py (1100 tokens)
         ├── research/
            ├── __init__.py
            ├── citations.py (1700 tokens)
            ├── parsing.py (2.4k tokens)
            ├── prompts.py (1900 tokens)
            ├── redaction.py (1400 tokens)
         ├── research_runs.py (26.3k tokens)
         ├── tool_healing.py (11.7k tokens)
         ├── training/
            ├── __init__.py (100 tokens)
            ├── dataset_bounds.py (3.1k tokens)
            ├── diffusion_checkpoint.py (19.6k tokens)
            ├── diffusion_clip_formats.py (300 tokens)
            ├── diffusion_dit_trainer.py (20.9k tokens)
            ├── diffusion_h3_clips.py (4.4k tokens)
            ├── diffusion_h3_trainer.py (7.6k tokens)
            ├── diffusion_lora_trainer.py (8.3k tokens)
            ├── diffusion_train_common.py (22k tokens)
            ├── diffusion_train_extras.py (4k tokens)
            ├── diffusion_training_service.py (9.9k tokens)
            ├── eval_dataset.py (300 tokens)
            ├── fsdp2_design_notes.md (1600 tokens)
            ├── lifecycle.py (100 tokens)
            ├── provenance.py (6.9k tokens)
            ├── resume.py (2.2k tokens)
            ├── s3_dataset.py (1600 tokens)
            ├── trainer.py (41.8k tokens)
            ├── training.py (31.2k tokens)
            ├── worker.py (42.5k tokens)
         ├── youtube_transcript.py (2.5k tokens)
      ├── hub/
         ├── __init__.py (100 tokens)
         ├── dependencies.py (200 tokens)
         ├── routes/
            ├── __init__.py (100 tokens)
            ├── datasets.py (1100 tokens)
            ├── inventory.py (1800 tokens)
            ├── token.py (300 tokens)
         ├── schemas/
            ├── __init__.py
            ├── datasets.py (800 tokens)
            ├── downloads.py (1700 tokens)
            ├── inventory.py (2.9k tokens)
         ├── services/
            ├── __init__.py (200 tokens)
            ├── datasets/
               ├── __init__.py
               ├── cache_inventory.py (6.7k tokens)
               ├── downloads.py (2.3k tokens)
               ├── formatting.py (4.9k tokens)
               ├── local.py (2.8k tokens)
               ├── local_options.py (5.9k tokens)
            ├── download_lifecycle.py (11.1k tokens)
            ├── models/
               ├── __init__.py
               ├── cache_inventory.py (10.5k tokens)
               ├── catalog_classification.py (4.5k tokens)
               ├── common.py (6.7k tokens)
               ├── companion_cleanup.py (2.4k tokens)
               ├── deletion.py (8.5k tokens)
               ├── downloads.py (5.8k tokens)
               ├── folder_browser.py (1100 tokens)
               ├── gguf_variants.py (15.1k tokens)
               ├── hermes.py (800 tokens)
               ├── local_inventory.py (8.3k tokens)
               ├── ollama.py (4.5k tokens)
            ├── snapshot_progress.py (6.8k tokens)
         ├── storage/
            ├── __init__.py
            ├── scan_folders.py (1500 tokens)
         ├── tests/
            ├── conftest.py (900 tokens)
            ├── test_companion_assets.py (8.5k tokens)
            ├── test_custom_gguf_discovery.py (4.6k tokens)
            ├── test_dataset_local_options.py (5.8k tokens)
            ├── test_dataset_native_drop_upload.py (800 tokens)
            ├── test_dataset_services.py (9.2k tokens)
            ├── test_download_lifecycle.py (5.2k tokens)
            ├── test_download_manifest_scoping.py (7.2k tokens)
            ├── test_empty_variant_folder.py (1500 tokens)
            ├── test_lmstudio_paths.py (300 tokens)
            ├── test_model_services.py (53.1k tokens)
            ├── test_process_unique_incomplete_repro.py (2.5k tokens)
            ├── test_resumable_partials.py (6.2k tokens)
            ├── test_sparse_partial_bytes.py (500 tokens)
            ├── test_stt_repository_ownership.py (600 tokens)
            ├── test_unresumable_partial_purge.py (6k tokens)
         ├── utils/
            ├── __init__.py
            ├── companion_assets.py (5.8k tokens)
            ├── dataset_cache.py (4.6k tokens)
            ├── dataset_format.py (5k tokens)
            ├── dataset_processed_cache.py (2.3k tokens)
            ├── download_manifest.py (12.2k tokens)
            ├── download_registry.py (16.6k tokens)
            ├── gguf.py (12.3k tokens)
            ├── gguf_plan.py (3.2k tokens)
            ├── hf_cache_state.py (6.2k tokens)
            ├── hf_errors.py (300 tokens)
            ├── hf_tokens.py (3.4k tokens)
            ├── inventory_scan.py (15.9k tokens)
            ├── llm_assist.py (3k tokens)
            ├── paths.py (2.6k tokens)
            ├── resumable_partials.py (4.9k tokens)
            ├── snapshot_filters.py (800 tokens)
            ├── state_dir.py (3.1k tokens)
         ├── workers/
            ├── __init__.py
            ├── hf_download.py (7.2k tokens)
      ├── integrations/
         ├── blender/
            ├── __init__.py (100 tokens)
            ├── launcher.py (200 tokens)
            ├── runtime.py (800 tokens)
            ├── service.py (900 tokens)
      ├── lan_access.py (3.8k tokens)
      ├── loggers/
         ├── .gitkeep
         ├── __init__.py (100 tokens)
         ├── config.py (4.5k tokens)
         ├── handlers.py (3.4k tokens)
         ├── media_progress.py (1000 tokens)
      ├── main.py (21.5k tokens)
      ├── mcp_server.py (2.2k tokens)
      ├── models/
         ├── .gitkeep
         ├── __init__.py (600 tokens)
         ├── auth.py (700 tokens)
         ├── data_recipe.py (900 tokens)
         ├── datasets.py (600 tokens)
         ├── export.py (2.1k tokens)
         ├── inference.py (45.3k tokens)
         ├── mcp_servers.py (500 tokens)
         ├── models.py (2.9k tokens)
         ├── providers.py (1600 tokens)
         ├── responses.py (500 tokens)
         ├── training.py (10.3k tokens)
         ├── users.py (200 tokens)
      ├── picker/
         ├── __init__.py
         ├── routes/
            ├── __init__.py
            ├── templates.py (400 tokens)
         ├── schemas.py (300 tokens)
         ├── service.py (3.8k tokens)
      ├── plugins/
         ├── __init__.py
         ├── data-designer-github-repo-seed/
            ├── README.md (600 tokens)
            ├── pyproject.toml (100 tokens)
            ├── src/
               ├── data_designer_github_repo_seed/
                  ├── __init__.py (100 tokens)
                  ├── config.py (400 tokens)
                  ├── impl.py (500 tokens)
                  ├── plugin.py (100 tokens)
                  ├── scraper.py (1700 tokens)
                  ├── scraper_impl/
                     ├── __init__.py
                     ├── gh_client.py (2.4k tokens)
                     ├── queries.py (5.1k tokens)
                     ├── scraper.py (5.5k tokens)
                     ├── state_store.py (2000 tokens)
         ├── data-designer-unstructured-seed/
            ├── __init__.py
            ├── pyproject.toml (200 tokens)
            ├── src/
               ├── data_designer_unstructured_seed/
                  ├── __init__.py (100 tokens)
                  ├── chunking.py (1700 tokens)
                  ├── config.py (300 tokens)
                  ├── impl.py (300 tokens)
                  ├── plugin.py (100 tokens)
      ├── requirements/
         ├── __init__.py
         ├── base.txt (100 tokens)
         ├── diffusers-pin.txt (200 tokens)
         ├── extras-no-deps.txt (500 tokens)
         ├── extras.txt (600 tokens)
         ├── no-torch-runtime.txt (1000 tokens)
         ├── overrides.txt (100 tokens)
         ├── single-env/
            ├── constraints.txt (400 tokens)
            ├── data-designer-deps.txt (100 tokens)
            ├── data-designer.txt
            ├── overrides-darwin-arm64.txt (600 tokens)
            ├── patch_metadata.py (400 tokens)
         ├── studio.txt (600 tokens)
         ├── triton-kernels.txt
      ├── routes/
         ├── .gitkeep
         ├── __init__.py (400 tokens)
         ├── auth.py (6k tokens)
         ├── chat_generation_runs.py (2.8k tokens)
         ├── chat_history.py (14.5k tokens)
         ├── data_recipe/
            ├── __init__.py (200 tokens)
            ├── jobs.py (5k tokens)
            ├── mcp.py (800 tokens)
            ├── seed.py (5.9k tokens)
            ├── validate.py (1500 tokens)
         ├── datasets.py (800 tokens)
         ├── export.py (5.1k tokens)
         ├── inference.py (337.6k tokens)
         ├── llama.py (2.4k tokens)
         ├── llama_compat.py (1900 tokens)
         ├── mcp_servers.py (4.7k tokens)
         ├── models.py (47.5k tokens)
         ├── openai_codex_auth.py (1900 tokens)
         ├── preview.py (2.2k tokens)
         ├── profile_stats.py (400 tokens)
         ├── prompts.py (600 tokens)
         ├── provider_credentials.py (600 tokens)
         ├── providers.py (7k tokens)
         ├── rag.py (8.4k tokens)
         ├── research_runs.py (4.8k tokens)
         ├── settings.py (30k tokens)
         ├── training.py (37.2k tokens)
         ├── training_history.py (3.5k tokens)
         ├── training_vram.py (5.3k tokens)
         ├── video.py (13.5k tokens)
         ├── whisper.py (600 tokens)
         ├── youtube.py (500 tokens)
      ├── run.py (26.9k tokens)
      ├── startup_banner.py (1500 tokens)
      ├── state/
         ├── .gitkeep
         ├── __init__.py
         ├── active_generations.py (1200 tokens)
         ├── tool_approvals.py (900 tokens)
         ├── tool_policy.py (600 tokens)
      ├── storage/
         ├── __init__.py
         ├── api_usage_db.py (2.2k tokens)
         ├── chat_generation_runs_db.py (6.1k tokens)
         ├── credential_secrets.py (1700 tokens)
         ├── mcp_servers_db.py (1000 tokens)
         ├── profile_stats_db.py (6k tokens)
         ├── providers_db.py (1700 tokens)
         ├── rag_db.py (3.9k tokens)
         ├── research_runs_db.py (9.9k tokens)
         ├── studio_db.py (36k tokens)
      ├── tests/
         ├── __init__.py
         ├── asgi_stream_helpers.py (500 tokens)
         ├── conftest.py (8.8k tokens)
         ├── data/
            ├── plan_vs_answer.jsonl (51.8k tokens)
            ├── refactor_guard/
               ├── ast_inventory.json (14.6k tokens)
               ├── golden_outputs.json (2.3k tokens)
               ├── idempotence_baseline.json (500 tokens)
               ├── patch_targets.json (13.9k tokens)
               ├── runtime_inventory.json (5.4k tokens)
         ├── fixtures/
            ├── access_log_records.json (800 tokens)
            ├── mcp_argument_echo_server.py (200 tokens)
         ├── llama_backend_double.py (300 tokens)
         ├── log_budget/
            ├── __init__.py
            ├── policy.py (1000 tokens)
            ├── replay.py (1300 tokens)
            ├── session.py (1700 tokens)
         ├── manual/
            ├── windows_rocm_vram_check.py (3.3k tokens)
         ├── test_active_generations.py (20.8k tokens)
         ├── test_amd_apu_unified_memory.py (5.5k tokens)
         ├── test_amd_smi_hip_index_and_coverage.py (2k tokens)
         ├── test_amd_smi_inventory_matches_hip.py (2.6k tokens)
         ├── test_anthropic_admission.py (7.1k tokens)
         ├── test_anthropic_cache_ttl.py (1200 tokens)
         ├── test_anthropic_citations.py (2k tokens)
         ├── test_anthropic_citations_edge.py (4.1k tokens)
         ├── test_anthropic_code_execution.py (2.6k tokens)
         ├── test_anthropic_compaction.py (4.3k tokens)
         ├── test_anthropic_empty_text_block.py (1600 tokens)
         ├── test_anthropic_fast_mode_and_refusal.py (2.2k tokens)
         ├── test_anthropic_fast_mode_edge.py (3.8k tokens)
         ├── test_anthropic_messages.py (40.5k tokens)
         ├── test_anthropic_native_tool_images.py (1400 tokens)
         ├── test_anthropic_passthrough_respawn.py (1500 tokens)
         ├── test_anthropic_thinking_translation.py (3.7k tokens)
         ├── test_anthropic_tool_versions.py (1200 tokens)
         ├── test_anthropic_web_fetch.py (3.8k tokens)
         ├── test_anthropic_web_search_errors.py (700 tokens)
         ├── test_api_key_expiry.py (1300 tokens)
         ├── test_api_monitor.py (12k tokens)
         ├── test_api_perf_serialization.py (600 tokens)
         ├── test_api_profile_usage_routes.py (600 tokens)
         ├── test_apple_cpu_frequency.py (2.3k tokens)
         ├── test_apple_gpu_sensors.py (500 tokens)
         ├── test_appledouble_guards.py (2.2k tokens)
         ├── test_artifact_preview_frame_csp.py (1200 tokens)
         ├── test_async_singleton_access.py (1900 tokens)
         ├── test_audio_dataset_decode.py (1900 tokens)
         ├── test_audio_decode_load_order.py (900 tokens)
         ├── test_audio_device_guards.py (3.8k tokens)
         ├── test_audio_device_preference.py (2.8k tokens)
         ├── test_audio_eval_dataset.py (2.7k tokens)
         ├── test_audio_gallery.py (4.5k tokens)
         ├── test_audio_lora_logging.py (500 tokens)
         ├── test_audio_probe_target.py (500 tokens)
         ├── test_audio_sampling_fill.py (1300 tokens)
         ├── test_audio_token_detection.py (4.9k tokens)
         ├── test_audio_tts_cancellation.py (5.1k tokens)
         ├── test_audio_type_inconclusive.py (4.3k tokens)
         ├── test_audio_unsupported_backend_error.py (500 tokens)
         ├── test_auth_lookup_off_event_loop.py (800 tokens)
         ├── test_auth_status_bootstrap_deadline.py (900 tokens)
         ├── test_auto_offload_ctx_fit_floor_coupling.py (2.2k tokens)
         ├── test_auto_offload_ctx_invariants.py (1300 tokens)
         ├── test_auto_offload_ctx_platform_matrix.py (5.6k tokens)
         ├── test_backend_tests_stub_heavy_imports.py (19.7k tokens)
         ├── test_base_model_dir_name_fallback.py (2k tokens)
         ├── test_batch_sizes_per_load.py (6.2k tokens)
         ├── test_bind_host_policy.py (2.2k tokens)
         ├── test_blender_managed.py (1400 tokens)
         ├── test_blender_runtime.py (500 tokens)
         ├── test_bootstrap_timeout.py (1400 tokens)
         ├── test_browse_denylist.py (2.9k tokens)
         ├── test_browse_folders_route.py (600 tokens)
         ├── test_build_prequant_checkpoint.py (700 tokens)
         ├── test_bypass_permissions.py (5.6k tokens)
         ├── test_cache_case_resolution.py (800 tokens)
         ├── test_cached_gguf_routes.py (54.3k tokens)
         ├── test_cached_snapshot_load_subdirs.py (1000 tokens)
         ├── test_capability_detection.py (2.8k tokens)
         ├── test_change_password_policy.py (600 tokens)
         ├── test_chat_attachments.py (5.1k tokens)
         ├── test_chat_eos_template_refresh.py (1800 tokens)
         ├── test_chat_generation_lease_compat.py (7.2k tokens)
         ├── test_chat_generation_run_lease.py (3.9k tokens)
         ├── test_chat_generation_runs.py (5.5k tokens)
         ├── test_chat_generation_supervisor.py (5.1k tokens)
         ├── test_chat_history_routes.py (10.7k tokens)
         ├── test_chat_history_storage.py (10.3k tokens)
         ├── test_chat_input_audio_part.py (3.8k tokens)
         ├── test_chat_load_during_training.py (27.5k tokens)
         ├── test_chat_message_identity.py (2.6k tokens)
         ├── test_chat_only_reason.py (1600 tokens)
         ├── test_chat_preferences_settings.py (600 tokens)
         ├── test_chat_prompt_bos.py (1200 tokens)
         ├── test_chat_settings_payload.py (2000 tokens)
         ├── test_chat_template_continuation.py (7.1k tokens)
         ├── test_chat_template_numeric_member_repair.py (1300 tokens)
         ├── test_chat_template_tool_arguments.py (2.1k tokens)
         ├── test_chat_text_encoding.py (1500 tokens)
         ├── test_chat_thread_settings.py (5.7k tokens)
         ├── test_chat_turn_end_eos.py (1200 tokens)
         ├── test_checkpoint_compaction.py (32.8k tokens)
         ├── test_checkpoints_scan.py (1600 tokens)
         ├── test_child_lifetime_boundary.py (1000 tokens)
         ├── test_cleanup_cancelled_checkpoints.py (1200 tokens)
         ├── test_cloudflare_tunnel.py (10.7k tokens)
         ├── test_code_integrity.py (1200 tokens)
         ├── test_coding_agents.py (1000 tokens)
         ├── test_colab_embed.py (4.7k tokens)
         ├── test_combined_update.py (7.1k tokens)
         ├── test_completion_masking.py (2.7k tokens)
         ├── test_compute_buffer.py (13k tokens)
         ├── test_config_mutations_on_event_loop.py (1300 tokens)
         ├── test_consent_gate.py (16.5k tokens)
         ├── test_context_overflow_truncation.py (12.5k tokens)
         ├── test_context_refusal_message.py (8.4k tokens)
         ├── test_context_refusal_units.py (1700 tokens)
         ├── test_control_markup_neutralize_7066.py (56k tokens)
         ├── test_conversation_archive.py (39.7k tokens)
         ├── test_conversation_recall_injection.py (13.7k tokens)
         ├── test_conversation_search_safetensors_loop.py (2.7k tokens)
         ├── test_cpt_modules_to_save_reaches_every_branch.py (400 tokens)
         ├── test_cpu_threads.py (1100 tokens)
         ├── test_credential_rotation_race.py (2.1k tokens)
         ├── test_credential_routes.py (10.3k tokens)
         ├── test_credential_secrets.py (2.5k tokens)
         ├── test_cuda_sm_gate.py (3.5k tokens)
         ├── test_cuda_sm_gate_os_matrix.py (2.2k tokens)
         ├── test_cuda_torch_spec.py (600 tokens)
         ├── test_current_date_prompt_settings.py (3.3k tokens)
         ├── test_custom_provider_thinking.py (900 tokens)
         ├── test_data_recipe_github_progress.py (600 tokens)
         ├── test_data_recipe_pump_resilience.py (900 tokens)
         ├── test_data_recipe_sampling_progress.py (200 tokens)
         ├── test_data_recipe_seed.py (2.7k tokens)
         ├── test_datacenter_gpu_tuning.py (9.4k tokens)
         ├── test_dataset_cache_paths.py (9.7k tokens)
         ├── test_dataset_cache_safe.py (1700 tokens)
         ├── test_dataset_cache_timestamps.py (2.3k tokens)
         ├── test_dataset_check_format_missing.py (1000 tokens)
         ├── test_dataset_custom_prompt_template.py (1800 tokens)
         ├── test_dataset_map_num_proc.py (5k tokens)
         ├── test_dataset_preview_audio_cells.py (400 tokens)
         ├── test_dataset_upload_limits.py (1700 tokens)
         ├── test_dataset_warmup_arrow_registry_repro.py (1200 tokens)
         ├── test_debug_log_reader.py (1900 tokens)
         ├── test_debug_log_redaction.py (2.6k tokens)
         ├── test_debug_log_routes.py (1900 tokens)
         ├── test_debug_log_self_feedback.py (1000 tokens)
         ├── test_debug_log_sources.py (2.9k tokens)
         ├── test_deep_research_handoff_simulation.py (3.6k tokens)
         ├── test_deepseek_v4_thinking_effort.py (1500 tokens)
         ├── test_default_output_dir_name.py (500 tokens)
         ├── test_defaults_refresh_after_redetect.py (900 tokens)
         ├── test_delete_finetuned_diffusion_guard.py (1400 tokens)
         ├── test_dense_quant_rocm_gate_9396.py (3.2k tokens)
         ├── test_desktop_auth.py (8.3k tokens)
         ├── test_detect_mmproj_file.py (3.3k tokens)
         ├── test_dgx_spark_diffusion_memory.py (3.2k tokens)
         ├── test_dgx_spark_gpu_inventory.py (3.8k tokens)
         ├── test_diffusion_arch_patches.py (2.1k tokens)
         ├── test_diffusion_attention.py (8.3k tokens)
         ├── test_diffusion_attention_trim.py (2.4k tokens)
         ├── test_diffusion_auto_policy.py (4.9k tokens)
         ├── test_diffusion_backend.py (85.4k tokens)
         ├── test_diffusion_base_precision.py (7.7k tokens)
         ├── test_diffusion_batched.py (1000 tokens)
         ├── test_diffusion_bench.py (1200 tokens)
         ├── test_diffusion_cache.py (4.1k tokens)
         ├── test_diffusion_checkpoint_resume.py (29.1k tokens)
         ├── test_diffusion_compat_preflight.py (14.8k tokens)
         ├── test_diffusion_compile_cache.py (2.6k tokens)
         ├── test_diffusion_cond_cache.py (1600 tokens)
         ├── test_diffusion_controlnet.py (3.4k tokens)
         ├── test_diffusion_convrot.py (3.4k tokens)
         ├── test_diffusion_cuda_graph.py (5.7k tokens)
         ├── test_diffusion_dataset_api.py (8.9k tokens)
         ├── test_diffusion_dataset_clips.py (4k tokens)
         ├── test_diffusion_device.py (7.3k tokens)
         ├── test_diffusion_dit_trainer.py (4.6k tokens)
         ├── test_diffusion_dit_trainer_flow_shift.py (1700 tokens)
         ├── test_diffusion_dit_trainer_ltx2.py (7.6k tokens)
         ├── test_diffusion_eager_patches.py (1400 tokens)
         ├── test_diffusion_engine_load_contract.py (3k tokens)
         ├── test_diffusion_engine_router.py (3.3k tokens)
         ├── test_diffusion_exif_orientation.py (2000 tokens)
         ├── test_diffusion_gated_base.py (9.3k tokens)
         ├── test_diffusion_gguf_compile.py (500 tokens)
         ├── test_diffusion_h3_trainer.py (16.2k tokens)
         ├── test_diffusion_hub_access.py (1300 tokens)
         ├── test_diffusion_img2img_dtype.py (900 tokens)
         ├── test_diffusion_img2img_size.py (700 tokens)
         ├── test_diffusion_inference_info.py (500 tokens)
         ├── test_diffusion_krea2.py (3.1k tokens)
         ├── test_diffusion_lora.py (3.6k tokens)
         ├── test_diffusion_lora_trainer.py (5.6k tokens)
         ├── test_diffusion_memory.py (17.3k tokens)
         ├── test_diffusion_more_families.py (5.3k tokens)
         ├── test_diffusion_offline_load.py (2000 tokens)
         ├── test_diffusion_patch_backend.py (900 tokens)
         ├── test_diffusion_precision.py (5k tokens)
         ├── test_diffusion_predownload_guard_platforms.py (3.4k tokens)
         ├── test_diffusion_predownload_memory_guard.py (5.4k tokens)
         ├── test_diffusion_prequant.py (15.8k tokens)
         ├── test_diffusion_quant_pad.py (3k tokens)
         ├── test_diffusion_routes.py (20.8k tokens)
         ├── test_diffusion_sdxl.py (2000 tokens)
         ├── test_diffusion_speed.py (8.7k tokens)
         ├── test_diffusion_te_prequant.py (6.6k tokens)
         ├── test_diffusion_train_extras.py (2.9k tokens)
         ├── test_diffusion_train_perf.py (7k tokens)
         ├── test_diffusion_train_picker_clip_families.py (2.6k tokens)
         ├── test_diffusion_training.py (22.9k tokens)
         ├── test_diffusion_transformer_quant.py (14k tokens)
         ├── test_diffusion_warmup_defaults.py (600 tokens)
         ├── test_disconnect_watcher_teardown.py (2.5k tokens)
         ├── test_docs_ui_assets.py (600 tokens)
         ├── test_download_adoption_transport.py (1000 tokens)
         ├── test_download_transport_setting.py (800 tokens)
         ├── test_edit_file_tool.py (7.8k tokens)
         ├── test_embedding_gguf_launch.py (2.3k tokens)
         ├── test_embedding_load_report_quiet.py (2.3k tokens)
         ├── test_embedding_model_resolve.py (9.9k tokens)
         ├── test_embedding_model_security_gate.py (6.3k tokens)
         ├── test_embedding_model_settings.py (3.6k tokens)
         ├── test_empty_gpu_probe_reason.py (2.9k tokens)
         ├── test_engine_stats_live_rate.py (1900 tokens)
         ├── test_estimator_flash_attn_parity.py (2.8k tokens)
         ├── test_exception_log_truncation.py (900 tokens)
         ├── test_exec_utf8.py (300 tokens)
         ├── test_export_absolute_paths.py (6.2k tokens)
         ├── test_export_capability.py (1600 tokens)
         ├── test_export_gguf_discovery.py (6k tokens)
         ├── test_export_gguf_hub_upload.py (6.7k tokens)
         ├── test_export_gguf_sharding.py (1400 tokens)
         ├── test_export_imatrix_compressed.py (2.9k tokens)
         ├── test_export_log_cursor.py (1200 tokens)
         ├── test_export_multi_gpu_device_map.py (3.6k tokens)
         ├── test_export_size_estimate.py (8.4k tokens)
         ├── test_export_wait_inactivity_timeout.py (1300 tokens)
         ├── test_external_confirm_gate_and_saved_keys.py (3.1k tokens)
         ├── test_external_hosted_tool_passthrough.py (5.4k tokens)
         ├── test_external_hosted_tool_selection.py (1500 tokens)
         ├── test_external_provider_proxy_env.py (500 tokens)
         ├── test_external_provider_route_wiring.py (600 tokens)
         ├── test_external_provider_sampling_forwarding.py (1200 tokens)
         ├── test_external_provider_sampling_over_the_wire.py (2.5k tokens)
         ├── test_external_provider_usage_chunk.py (6.7k tokens)
         ├── test_external_tool_call_id_replay.py (1300 tokens)
         ├── test_external_tool_edge_cases.py (8.2k tokens)
         ├── test_external_tool_name_and_usage.py (1800 tokens)
         ├── test_external_tool_refusal_gates.py (1300 tokens)
         ├── test_external_tool_stream_abuse.py (7.7k tokens)
         ├── test_external_tool_transport_cancel.py (700 tokens)
         ├── test_external_tool_transport_continuation.py (600 tokens)
         ├── test_external_tool_truncated_and_budget.py (3.1k tokens)
         ├── test_external_tools_compat.py (3.1k tokens)
         ├── test_file_security.py (5k tokens)
         ├── test_final_loss_not_average.py (1300 tokens)
         ├── test_frontend_resolution.py (2.6k tokens)
         ├── test_full_access_tool_prompt.py (5k tokens)
         ├── test_gallery_flags.py (3.1k tokens)
         ├── test_gemini_provider.py (35.5k tokens)
         ├── test_gemma4_chat_template_override.py (2.7k tokens)
         ├── test_gemma_tool_parse_edge_cases.py (4k tokens)
         ├── test_generation_budget.py (2.1k tokens)
         ├── test_generation_timing.py (1800 tokens)
         ├── test_gguf_bpw_variant_rows.py (2.7k tokens)
         ├── test_gguf_completion_usage.py (1000 tokens)
         ├── test_gguf_image_capability.py (700 tokens)
         ├── test_gguf_load_cache_reuse.py (9.7k tokens)
         ├── test_gguf_load_intent_slots.py (800 tokens)
         ├── test_gguf_metadata.py (6.3k tokens)
         ├── test_gguf_metadata_log_volume.py (800 tokens)
         ├── test_gguf_reload_inheritance.py (2.5k tokens)
         ├── test_gguf_route_cursor_reset.py (1600 tokens)
         ├── test_gguf_routing.py (800 tokens)
         ├── test_gguf_stream_slot_release.py (1900 tokens)
         ├── test_gguf_stream_slot_release_ordering.py (2.3k tokens)
         ├── test_gguf_tool_non_streaming.py (1500 tokens)
         ├── test_gguf_tts_audio_type.py (1400 tokens)
         ├── test_gguf_variant_dependency_key.py (900 tokens)
         ├── test_gguf_variant_preflight.py (1900 tokens)
         ├── test_gguf_variant_rows.py (10.8k tokens)
         ├── test_gguf_variants_local_resolution.py (6.1k tokens)
         ├── test_gguf_xet_fallback_integration.py (1000 tokens)
         ├── test_gpu_arbiter.py (2.5k tokens)
         ├── test_gpu_arch_gate_7624.py (4.9k tokens)
         ├── test_gpu_arch_gate_consumers_7624.py (9.6k tokens)
         ├── test_gpu_arch_gate_os_matrix_7624.py (29.4k tokens)
         ├── test_gpu_init_crash_message.py (13.1k tokens)
         ├── test_gpu_memory_mode.py (13.1k tokens)
         ├── test_gpu_selection.py (18.9k tokens)
         ├── test_gpu_selection_sandbox.py (3.9k tokens)
         ├── test_grouped_mm_rdna4_fallback.py (3.5k tokens)
         ├── test_healed_tool_call_stop.py (2.7k tokens)
         ├── test_health_answers_within_probe_budget.py (5.1k tokens)
         ├── test_health_holds_verdict_during_mlx_repair.py (5.5k tokens)
         ├── test_health_reports_unified_memory.py (1300 tokens)
         ├── test_hermes_model_scan.py (1400 tokens)
         ├── test_hf_cache_dangling_refs.py (38.1k tokens)
         ├── test_hf_cache_settings.py (2.3k tokens)
         ├── test_hf_optional_file_probe.py (1800 tokens)
         ├── test_hf_token_validation.py (1100 tokens)
         ├── test_hf_xet_fallback.py (10.8k tokens)
         ├── test_history_delete_is_atomic.py (1400 tokens)
         ├── test_host_defaults.py (700 tokens)
         ├── test_host_offload_ram_guard.py (1400 tokens)
         ├── test_hosted_code_execution_placement.py (500 tokens)
         ├── test_hosted_result_replay.py (5.9k tokens)
         ├── test_hub_download_ambient_token.py (2.2k tokens)
         ├── test_hub_download_transport_auto.py (7.5k tokens)
         ├── test_hub_token_cache_isolation.py (1500 tokens)
         ├── test_hub_token_caller_identity.py (22.2k tokens)
         ├── test_hub_write_ambient_token.py (5.2k tokens)
         ├── test_identity.py (800 tokens)
         ├── test_idle_slot_clearing_is_known.py (800 tokens)
         ├── test_igpu_carveout_advice.py (8.2k tokens)
         ├── test_igpu_carveout_notice_settings.py (1200 tokens)
         ├── test_image_gallery.py (3.8k tokens)
         ├── test_imatrix_gguf_filtering.py (2.9k tokens)
         ├── test_index_bootstrap_loopback.py (1000 tokens)
         ├── test_index_bootstrap_origin.py (1000 tokens)
         ├── test_index_bootstrap_origin_extra.py (1400 tokens)
         ├── test_inference_backend_singleton.py (1400 tokens)
         ├── test_inference_default_models_non_blocking.py (300 tokens)
         ├── test_inference_dispatcher_resilience.py (1900 tokens)
         ├── test_inference_model_validation.py (1800 tokens)
         ├── test_inference_orchestrator_crash_message.py (200 tokens)
         ├── test_inference_status_loaded_gguf.py (1900 tokens)
         ├── test_inference_status_route.py (2.3k tokens)
         ├── test_install_resolve_prebuilt.py (29.2k tokens)
         ├── test_install_whisper_prebuilt_checksums.py (1700 tokens)
         ├── test_keepwarm_tick_off_event_loop.py (400 tokens)
         ├── test_keyless_api_access.py (7.7k tokens)
         ├── test_keyless_api_access_adversarial.py (7.9k tokens)
         ├── test_keyless_tunnel_exposure.py (900 tokens)
         ├── test_kimi_k3_reasoning_defaults.py (1100 tokens)
         ├── test_kv_cache_estimate_compat.py (1100 tokens)
         ├── test_kv_cache_estimate_off_event_loop.py (600 tokens)
         ├── test_kv_cache_estimate_route.py (8.3k tokens)
         ├── test_kv_cache_estimation.py (17.5k tokens)
         ├── test_lan_access_settings.py (11.8k tokens)
         ├── test_lan_share_host_resolution.py (1700 tokens)
         ├── test_last_local_model_setting.py (2.1k tokens)
         ├── test_launch_flags_are_capability_gated.py (4.3k tokens)
         ├── test_legacy_ollama_source.py (600 tokens)
         ├── test_length_truncated_reasoning_continuation.py (6.4k tokens)
         ├── test_lifespan_restart_rewarms.py (1500 tokens)
         ├── test_lifespan_shutdown.py (900 tokens)
         ├── test_linux_external_media_paths.py (2.1k tokens)
         ├── test_liveness_reports_inference_active.py (2.2k tokens)
         ├── test_liveness_reports_warmup_state.py (2.4k tokens)
         ├── test_llama_admission.py (10.3k tokens)
         ├── test_llama_admission_compat_matrix.py (3.2k tokens)
         ├── test_llama_admission_kv_budget.py (5k tokens)
         ├── test_llama_admission_kv_budget_media_and_tools.py (8k tokens)
         ├── test_llama_admission_recost.py (4.1k tokens)
         ├── test_llama_admission_stress.py (1800 tokens)
         ├── test_llama_admission_unstated_max_tokens.py (2.2k tokens)
         ├── test_llama_audio_attachment_container.py (10.6k tokens)
         ├── test_llama_backend_double.py (600 tokens)
         ├── test_llama_backend_marker.py (1000 tokens)
         ├── test_llama_backend_selection.py (4.6k tokens)
         ├── test_llama_backend_switch.py (10.1k tokens)
         ├── test_llama_compat_routes.py (6.2k tokens)
         ├── test_llama_cpp_atexit_quiet.py (1600 tokens)
         ├── test_llama_cpp_cache_aware_disk_check.py (1700 tokens)
         ├── test_llama_cpp_changelog.py (2.9k tokens)
         ├── test_llama_cpp_context_fit.py (7.5k tokens)
         ├── test_llama_cpp_darwin_loader_env.py (7.2k tokens)
         ├── test_llama_cpp_effective_parallel_slots.py (300 tokens)
         ├── test_llama_cpp_freshness.py (5.6k tokens)
         ├── test_llama_cpp_load_progress.py (1700 tokens)
         ├── test_llama_cpp_load_progress_live.py (1400 tokens)
         ├── test_llama_cpp_load_progress_matrix.py (3.3k tokens)
         ├── test_llama_cpp_max_context_threshold.py (1700 tokens)
         ├── test_llama_cpp_mmproj_fallback.py (5.7k tokens)
         ├── test_llama_cpp_mtp_detection.py (27.4k tokens)
         ├── test_llama_cpp_no_context_shift.py (1400 tokens)
         ├── test_llama_cpp_non_chat_gguf_preflight.py (4.1k tokens)
         ├── test_llama_cpp_path_settings.py (2.6k tokens)
         ├── test_llama_cpp_placement.py (29k tokens)
         ├── test_llama_cpp_props_readback.py (2.6k tokens)
         ├── test_llama_cpp_remote_non_chat_gguf_preflight.py (8k tokens)
         ├── test_llama_cpp_reprompt_guard.py (10.8k tokens)
         ├── test_llama_cpp_single_sequence_retry.py (1200 tokens)
         ├── test_llama_cpp_slot_resume.py (4.4k tokens)
         ├── test_llama_cpp_stall_timeout.py (1700 tokens)
         ├── test_llama_cpp_start_failure_classification.py (17.9k tokens)
         ├── test_llama_cpp_stream_cancel.py (1200 tokens)
         ├── test_llama_cpp_tool_loop.py (48.9k tokens)
         ├── test_llama_cpp_update.py (12.4k tokens)
         ├── test_llama_cpp_vulkan_probe.py (2.6k tokens)
         ├── test_llama_cpp_wait_for_health.py (12.9k tokens)
         ├── test_llama_cpp_wait_for_vram_settle.py (6.9k tokens)
         ├── test_llama_cpp_windows_nvidia_path.py (2.1k tokens)
         ├── test_llama_extra_args_compatibility.py (5.3k tokens)
         ├── test_llama_extra_args_end_to_end.py (1100 tokens)
         ├── test_llama_extra_args_platforms.py (2.7k tokens)
         ├── test_llama_flag_catalog.py (2.8k tokens)
         ├── test_llama_route.py (1300 tokens)
         ├── test_llama_route_timeouts.py (1800 tokens)
         ├── test_llama_server_args.py (10.6k tokens)
         ├── test_llama_stats.py (900 tokens)
         ├── test_llama_stats_platform_matrix.py (1900 tokens)
         ├── test_llama_stats_stall.py (2.2k tokens)
         ├── test_llm_assist_startup_opt_in.py (1300 tokens)
         ├── test_load_mode_fit.py (600 tokens)
         ├── test_load_mode_fit_matrix.py (19.3k tokens)
         ├── test_load_progress_ready_fraction.py (1300 tokens)
         ├── test_load_progress_throttle.py (300 tokens)
         ├── test_load_subdirs_stay_offline.py (900 tokens)
         ├── test_local_callable_validators.py (700 tokens)
         ├── test_local_llama_cpp_link.py (1900 tokens)
         ├── test_local_model_dir_discovery.py (4.6k tokens)
         ├── test_local_model_format.py (7.5k tokens)
         ├── test_local_options_match_start_validation.py (900 tokens)
         ├── test_log_bounds.py (1400 tokens)
         ├── test_log_budget.py (1800 tokens)
         ├── test_log_filter_no_truncation.py (800 tokens)
         ├── test_log_retention.py (1000 tokens)
         ├── test_log_rule_parity.py (1000 tokens)
         ├── test_log_signal_floor.py (3k tokens)
         ├── test_logging_middleware.py (6.2k tokens)
         ├── test_login_rate_limit.py (4.4k tokens)
         ├── test_markerless_exec_tool_guard.py (22.9k tokens)
         ├── test_mcp_config_import.py (2.6k tokens)
         ├── test_mcp_flatten_result.py (3.3k tokens)
         ├── test_mcp_http_integration.py (2.6k tokens)
         ├── test_mcp_http_sessions.py (8k tokens)
         ├── test_mcp_oauth_basic_auth.py (700 tokens)
         ├── test_mcp_server.py (2.2k tokens)
         ├── test_mcp_servers.py (14.4k tokens)
         ├── test_mcp_session_platforms.py (1100 tokens)
         ├── test_mcp_session_resources.py (1600 tokens)
         ├── test_mcp_stdio_api_key_gate.py (3.7k tokens)
         ├── test_mcp_stdio_improvements.py (1800 tokens)
         ├── test_mcp_stdio_node_path.py (7.3k tokens)
         ├── test_mcp_stdio_pr5863.py (4.4k tokens)
         ├── test_mcp_stdio_real_server.py (1100 tokens)
         ├── test_mcp_stdio_sessions.py (7.6k tokens)
         ├── test_mcp_tool_read_off_event_loop.py (1700 tokens)
         ├── test_mcp_training_start_guard.py (3.3k tokens)
         ├── test_mcp_upgrade_compat.py (1200 tokens)
         ├── test_media_auto_switch.py (21.2k tokens)
         ├── test_media_family_assembler_offline.py (5.2k tokens)
         ├── test_media_generation_preset_settings.py (3.9k tokens)
         ├── test_media_generation_progress_logs.py (1300 tokens)
         ├── test_media_keepwarm.py (7k tokens)
         ├── test_media_locality_cache_layout.py (900 tokens)
         ├── test_memory_contract.py (2.6k tokens)
         ├── test_memory_contract_platforms.py (1700 tokens)
         ├── test_memory_estimate.py (29.1k tokens)
         ├── test_memory_estimate_contract_freeze.py (2.5k tokens)
         ├── test_memory_estimate_platforms.py (10.5k tokens)
         ├── test_memory_estimate_side_effects.py (8.5k tokens)
         ├── test_message_content.py (1000 tokens)
         ├── test_metal_explicit_context_guard.py (8.7k tokens)
         ├── test_metal_never_starts_at_native_context.py (5.9k tokens)
         ├── test_metal_paravirtual_guard.py (17.6k tokens)
         ├── test_middleware.py (9.1k tokens)
         ├── test_mla_kv_cache_symmetry.py (3.5k tokens)
         ├── test_mlx_autorepair_no_torch_optout.py (2.5k tokens)
         ├── test_mlx_inference_backend.py (38.7k tokens)
         ├── test_mlx_repair.py (6.1k tokens)
         ├── test_mlx_stack_blockers.py (3.2k tokens)
         ├── test_mlx_stop_checkpoint.py (1200 tokens)
         ├── test_mlx_training_worker_config.py (3.7k tokens)
         ├── test_mlx_vlm_prompt_cache.py (5.8k tokens)
         ├── test_mlx_worker_audio_commands.py (900 tokens)
         ├── test_mmproj_placement_policy.py (14.2k tokens)
         ├── test_mmproj_vram_accounting.py (200 tokens)
         ├── test_model_cache_snapshot.py (2.1k tokens)
         ├── test_model_defaults_aliases_resolve.py (800 tokens)
         ├── test_model_defaults_log_once.py (600 tokens)
         ├── test_model_defaults_none_guard.py (300 tokens)
         ├── test_model_identity.py (1700 tokens)
         ├── test_model_identity_peft_handoff.py (700 tokens)
         ├── test_model_ids.py (1000 tokens)
         ├── test_model_memory_settings.py (20.8k tokens)
         ├── test_model_override_schema_compatibility.py (3.7k tokens)
         ├── test_model_picker_regression.py (1800 tokens)
         ├── test_model_routes_snapshot_targets.py (900 tokens)
         ├── test_model_update_robustness.py (5.9k tokens)
         ├── test_models_get_model_config_case_resolution.py (2.2k tokens)
         ├── test_models_list_resident_gguf_label.py (1100 tokens)
         ├── test_msvc_env_7595.py (4.9k tokens)
         ├── test_mtp_drafter_companion.py (30.5k tokens)
         ├── test_mtp_mla_target_ctx.py (2.5k tokens)
         ├── test_mtp_partial_offload_evidence.py (4k tokens)
         ├── test_mtp_reserve_note_and_unload_log.py (1800 tokens)
         ├── test_mtp_vram_budget.py (12.9k tokens)
         ├── test_multimodal_document.py (4.1k tokens)
         ├── test_muse_glimmer_sampling_defaults.py (800 tokens)
         ├── test_namespace_shadow_guard_pr6269.py (2.1k tokens)
         ├── test_native_audio.py (5.2k tokens)
         ├── test_native_context_length.py (4.9k tokens)
         ├── test_native_gguf_companion.py (4k tokens)
         ├── test_native_template_trust_remote_code.py (1500 tokens)
         ├── test_native_tls.py (2.2k tokens)
         ├── test_native_tls_entrypoints.py (1100 tokens)
         ├── test_native_tool_token_provenance.py (2.6k tokens)
         ├── test_nextn_target_kv_policy.py (2.6k tokens)
         ├── test_no_progress_tool_results.py (4k tokens)
         ├── test_non_gguf_reload_settings.py (1700 tokens)
         ├── test_nudge_tool_calls_wiring.py (1000 tokens)
         ├── test_nvfp4_load_error_message.py (1100 tokens)
         ├── test_offline_embedding_minimal.py (12.2k tokens)
         ├── test_offline_gguf_cache_fallback.py (30.8k tokens)
         ├── test_offline_inference_parent.py (5.3k tokens)
         ├── test_offload_cost_model.py (2.9k tokens)
         ├── test_offload_planner.py (11.8k tokens)
         ├── test_offload_planner_seam.py (18.6k tokens)
         ├── test_ollama_manifest_load_resolution.py (5.5k tokens)
         ├── test_ollama_manifest_shape_guard.py (700 tokens)
         ├── test_ollama_reasoning_effort.py (700 tokens)
         ├── test_online_tokenization.py (4.1k tokens)
         ├── test_online_tokenization_runtime.py (1900 tokens)
         ├── test_online_tokenization_wiring.py (5.1k tokens)
         ├── test_openai_audio_speech_route.py (7.3k tokens)
         ├── test_openai_audio_transcriptions_route.py (6.5k tokens)
         ├── test_openai_audio_upload_bound.py (300 tokens)
         ├── test_openai_auto_download.py (17k tokens)
         ├── test_openai_auto_switch.py (90.3k tokens)
         ├── test_openai_catalog.py (4.1k tokens)
         ├── test_openai_citation_markers.py (1900 tokens)
         ├── test_openai_citation_markers_edge.py (3.3k tokens)
         ├── test_openai_code_execution.py (3.2k tokens)
         ├── test_openai_codex_subscription.py (22.3k tokens)
         ├── test_openai_compaction.py (1600 tokens)
         ├── test_openai_container_crud.py (3k tokens)
         ├── test_openai_embeddings_studio_fallback.py (11.3k tokens)
         ├── test_openai_image_generation.py (2.1k tokens)
         ├── test_openai_images_generations_route.py (6.5k tokens)
         ├── test_openai_models_media.py (5.7k tokens)
         ├── test_openai_models_path_leak.py (300 tokens)
         ├── test_openai_models_servable_cache.py (700 tokens)
         ├── test_openai_models_servable_cache_edges.py (4.5k tokens)
         ├── test_openai_passthrough_respawn.py (4k tokens)
         ├── test_openai_responses_reasoning_replay.py (2000 tokens)
         ├── test_openai_responses_translation.py (6.2k tokens)
         ├── test_openai_tool_passthrough.py (81.6k tokens)
         ├── test_openai_tool_result_fallbacks.py (4k tokens)
         ├── test_openai_videos_route.py (10.2k tokens)
         ├── test_orchestrator_idle_subprocess_teardown.py (900 tokens)
         ├── test_orchestrator_load_cancel_event.py (400 tokens)
         ├── test_orchestrator_unload_cancel.py (27.4k tokens)
         ├── test_orphaned_children.py (18.3k tokens)
         ├── test_outbound_network_guard.py (2000 tokens)
         ├── test_parallel_slots_never_clamped.py (700 tokens)
         ├── test_parallel_slots_per_load.py (4.6k tokens)
         ├── test_parallel_tool_call_arguments.py (7.4k tokens)
         ├── test_parent_watchdog.py (800 tokens)
         ├── test_partial_remaining_bytes.py (2.2k tokens)
         ├── test_partial_resume_verdict.py (2.6k tokens)
         ├── test_passthrough_healing.py (12.7k tokens)
         ├── test_password_prompt.py (3k tokens)
         ├── test_password_prompt_backstop.py (7k tokens)
         ├── test_pdf_local_ocr.py (1700 tokens)
         ├── test_pdf_ocr_regressions.py (1500 tokens)
         ├── test_permission_mode.py (34.7k tokens)
         ├── test_personalization_settings.py (4.4k tokens)
         ├── test_picker_service.py (2.3k tokens)
         ├── test_plan_classifier_accuracy.py (800 tokens)
         ├── test_pr5624_regressions.py (8.9k tokens)
         ├── test_pr7699_worker_audio_mirror.py (800 tokens)
         ├── test_presence_penalty.py (3k tokens)
         ├── test_preview.py (900 tokens)
         ├── test_preview_followups.py (1100 tokens)
         ├── test_preview_routes.py (7.3k tokens)
         ├── test_preview_sharing_settings.py (500 tokens)
         ├── test_preview_token.py (700 tokens)
         ├── test_pricing.py (4.8k tokens)
         ├── test_pricing_edge.py (3.1k tokens)
         ├── test_process_lifetime.py (3.8k tokens)
         ├── test_process_lifetime_never_signals_init.py (3.7k tokens)
         ├── test_profile_stats.py (13.4k tokens)
         ├── test_project_workspace_location.py (1100 tokens)
         ├── test_provider_base_url_validation.py (3.8k tokens)
         ├── test_provider_control_frame_spoofing.py (3k tokens)
         ├── test_provider_lookup_off_event_loop.py (1100 tokens)
         ├── test_provider_max_output_tokens_contract.py (3.3k tokens)
         ├── test_provider_model_allowlist.py (400 tokens)
         ├── test_provider_model_filter_scope.py (500 tokens)
         ├── test_provider_reasoning_normalization.py (1000 tokens)
         ├── test_provider_registry_filters.py (1800 tokens)
         ├── test_providers_api.py (4.4k tokens)
         ├── test_providers_db_models.py (700 tokens)
         ├── test_public_check_optout.py (1000 tokens)
         ├── test_pytorch_mirror.py (400 tokens)
         ├── test_quick_tunnel_streaming_routes.py (700 tokens)
         ├── test_qwen_thinking_size_gate.py (800 tokens)
         ├── test_rag_captioning.py (2.7k tokens)
         ├── test_rag_chunking.py (700 tokens)
         ├── test_rag_chunking_simulations.py (300 tokens)
         ├── test_rag_embed_llama_server.py (13.4k tokens)
         ├── test_rag_embedding_identity.py (4.4k tokens)
         ├── test_rag_embeddings.py (8.3k tokens)
         ├── test_rag_ingestion.py (4k tokens)
         ├── test_rag_job_events_queue_lifecycle.py (1400 tokens)
         ├── test_rag_linked_folders.py (18.9k tokens)
         ├── test_rag_loopback_trust_env.py (400 tokens)
         ├── test_rag_native_drop_upload.py (1500 tokens)
         ├── test_rag_nudge_roster.py (3.2k tokens)
         ├── test_rag_nudge_roster_compat.py (6k tokens)
         ├── test_rag_ocr_fallback.py (2.1k tokens)
         ├── test_rag_parsing.py (2.6k tokens)
         ├── test_rag_preview.py (1400 tokens)
         ├── test_rag_project_source_upload.py (800 tokens)
         ├── test_rag_reconcile_orphaned.py (1200 tokens)
         ├── test_rag_retrieval.py (3.7k tokens)
         ├── test_rag_store.py (5.2k tokens)
         ├── test_rag_unavailable_quiet.py (3.2k tokens)
         ├── test_rag_upload_event_loop.py (1100 tokens)
         ├── test_rag_upload_formats.py (1500 tokens)
         ├── test_rag_upload_progress.py (3.1k tokens)
         ├── test_rag_upload_simulations.py (900 tokens)
         ├── test_rag_whole_document.py (6.8k tokens)
         ├── test_readable_traceback_logging.py (2.2k tokens)
         ├── test_reasoning_effort_wide_ladder.py (1400 tokens)
         ├── test_recommended_folders_has_model.py (1400 tokens)
         ├── test_recommended_folders_permission.py (800 tokens)
         ├── test_refactor_guard.py (1600 tokens)
         ├── test_rehearsal_in_code_block.py (1300 tokens)
         ├── test_remote_access_settings.py (4.4k tokens)
         ├── test_repetition_guard.py (1400 tokens)
         ├── test_research_internal_call_tool_gate.py (1500 tokens)
         ├── test_research_internal_key_monitor.py (600 tokens)
         ├── test_research_json_fallback.py (4k tokens)
         ├── test_research_no_evidence.py (1400 tokens)
         ├── test_research_progress_events.py (2.1k tokens)
         ├── test_research_runs_hardening.py (25.8k tokens)
         ├── test_research_runs_storage.py (31.8k tokens)
         ├── test_research_synthesis_recovery.py (3.2k tokens)
         ├── test_reset_password_command.py (1200 tokens)
         ├── test_resolve_quant_gguf.py (800 tokens)
         ├── test_response_template_markers.py (1800 tokens)
         ├── test_responses_api.py (2.6k tokens)
         ├── test_responses_history_guard.py (800 tokens)
         ├── test_responses_message_attachments.py (1300 tokens)
         ├── test_responses_tool_passthrough.py (29.1k tokens)
         ├── test_resume_blocked_reason_surfaces.py (1200 tokens)
         ├── test_resume_blocker_reason.py (1000 tokens)
         ├── test_resume_pin_load_subdirs.py (1100 tokens)
         ├── test_resume_reason_matches_cause.py (1300 tokens)
         ├── test_rocm_hip_unreachable_defers_to_torch.py (1000 tokens)
         ├── test_rocm_multi_gpu_vram_system_wide.py (4.9k tokens)
         ├── test_rocm_oom_guard.py (4.6k tokens)
         ├── test_rocm_stacked_visibility_masks.py (2k tokens)
         ├── test_rocm_vram_probe_no_hip_context.py (2.6k tokens)
         ├── test_rocm_windows_mem_guards_8403.py (2.1k tokens)
         ├── test_rocm_windows_vram_7072.py (21.3k tokens)
         ├── test_rocm_windows_vram_7452.py (2.8k tokens)
         ├── test_route_import_fallbacks_agree.py (700 tokens)
         ├── test_route_strip_drift.py (500 tokens)
         ├── test_run_tools_locally_discriminator.py (2.1k tokens)
         ├── test_runtime_context_length.py (800 tokens)
         ├── test_s3_dataset.py (2000 tokens)
         ├── test_safetensors_capability_advertise.py (7.7k tokens)
         ├── test_safetensors_reasoning_stream.py (6.6k tokens)
         ├── test_safetensors_tool_loop.py (44.7k tokens)
         ├── test_safetensors_toolcall_wiring.py (1500 tokens)
         ├── test_sampling_resolution.py (2.7k tokens)
         ├── test_sandbox_files_and_storage_roots.py (49k tokens)
         ├── test_sandbox_sitecustomize.py (4.8k tokens)
         ├── test_sandbox_tools.py (21.6k tokens)
         ├── test_saved_image_metadata_precision_contract.py (5.4k tokens)
         ├── test_scan_folder_health.py (6.3k tokens)
         ├── test_scan_loras_off_event_loop.py (600 tokens)
         ├── test_scoped_download_job.py (3.1k tokens)
         ├── test_scoped_download_worker.py (600 tokens)
         ├── test_sd_cpp_args.py (6.1k tokens)
         ├── test_sd_cpp_backend.py (20.3k tokens)
         ├── test_sd_cpp_engine.py (7.8k tokens)
         ├── test_sd_cpp_h3_matrix.py (3.5k tokens)
         ├── test_sd_cpp_install.py (29.8k tokens)
         ├── test_sd_cpp_server.py (3.9k tokens)
         ├── test_search_images.py (10.1k tokens)
         ├── test_secure_tools_execute.py (1400 tokens)
         ├── test_secure_tunnel_gate.py (3k tokens)
         ├── test_security_gate_consistency.py (1100 tokens)
         ├── test_server_disk_logging.py (2.1k tokens)
         ├── test_server_disk_logging_outstream.py (2000 tokens)
         ├── test_server_tuning_flags.py (3.9k tokens)
         ├── test_session_guard_exception_paths.py (2.2k tokens)
         ├── test_settle_delay_override.py (900 tokens)
         ├── test_setup_cache_env_hf_home.py (1000 tokens)
         ├── test_setup_llama_cpp_backend.py (3.1k tokens)
         ├── test_sf_client_tools_passthrough.py (9.5k tokens)
         ├── test_sf_tool_choice_none_history.py (1200 tokens)
         ├── test_shared_memory_offload_keeps_the_prompt_cache.py (2.5k tokens)
         ├── test_shutdown_preserves_live_worker.py (1400 tokens)
         ├── test_slot_offload_fit.py (2.1k tokens)
         ├── test_slot_reduction_context_refit.py (4.4k tokens)
         ├── test_slot_refit_ctx_checkpoints.py (1800 tokens)
         ├── test_slot_refit_platform_matrix.py (2.1k tokens)
         ├── test_spec_retry_status_signals.py (2.1k tokens)
         ├── test_spec_start_after_arch_narrowing.py (900 tokens)
         ├── test_sse_streaming_headers.py (200 tokens)
         ├── test_ssm_runtime.py (6.2k tokens)
         ├── test_startup_banner_loopback.py (600 tokens)
         ├── test_startup_defers_stack_dependent_work.py (1200 tokens)
         ├── test_startup_defers_torch.py (4.9k tokens)
         ├── test_startup_llama_probe_non_blocking.py (1000 tokens)
         ├── test_status_only_progress_replay.py (900 tokens)
         ├── test_stream_errors.py (2.6k tokens)
         ├── test_streaming_stripper.py (5.9k tokens)
         ├── test_stt_broken_runtime_falls_back.py (1400 tokens)
         ├── test_stt_download_followups.py (2k tokens)
         ├── test_stt_download_validation.py (1200 tokens)
         ├── test_stt_ggml_sidecar.py (9.3k tokens)
         ├── test_stt_http_downloads.py (4.2k tokens)
         ├── test_stt_install_and_snapshot_validation.py (2.6k tokens)
         ├── test_stt_mtmd_sidecar.py (8.4k tokens)
         ├── test_stt_registry.py (3.9k tokens)
         ├── test_stt_sidecar.py (13.3k tokens)
         ├── test_stt_transcription_cancellation.py (2.1k tokens)
         ├── test_stt_transformers_worker.py (7.1k tokens)
         ├── test_studio_api.py (6.9k tokens)
         ├── test_studio_db_write_lock_contention.py (5.9k tokens)
         ├── test_studio_pid_files.py (10k tokens)
         ├── test_studio_tool_loop.py (8.1k tokens)
         ├── test_studio_train_validation.py (900 tokens)
         ├── test_subdir_pins_are_guarded.py (1200 tokens)
         ├── test_system_poll_no_cuda_context.py (13.4k tokens)
         ├── test_system_vulkan_gpu_info.py (2.7k tokens)
         ├── test_tee_progress_frames.py (1300 tokens)
         ├── test_tensor_parallel.py (16.2k tokens)
         ├── test_tensor_quant_kv_platform_matrix.py (3.6k tokens)
         ├── test_text_io_encoding.py (6.9k tokens)
         ├── test_think_prefill_reemit.py (9.4k tokens)
         ├── test_thinking_parameter.py (700 tokens)
         ├── test_third_party_progress_bars.py (3.3k tokens)
         ├── test_third_party_source.py (6.7k tokens)
         ├── test_tool_approvals.py (1700 tokens)
         ├── test_tool_call_arg_compaction.py (7k tokens)
         ├── test_tool_call_arg_healing.py (2.6k tokens)
         ├── test_tool_call_parser_strict.py (17.4k tokens)
         ├── test_tool_confirm_loop.py (1200 tokens)
         ├── test_tool_confirm_stream.py (1500 tokens)
         ├── test_tool_loop_controller.py (4.8k tokens)
         ├── test_tool_loop_exception_contracts.py (2.3k tokens)
         ├── test_tool_message_empty_content.py (500 tokens)
         ├── test_tool_output_streaming.py (10.5k tokens)
         ├── test_tool_policy_gates.py (1600 tokens)
         ├── test_tool_policy_state.py (300 tokens)
         ├── test_tool_result_fits_window.py (20.8k tokens)
         ├── test_tool_sandbox_per_thread.py (700 tokens)
         ├── test_tool_stream_generator_drain.py (500 tokens)
         ├── test_tool_strip_guard.py (600 tokens)
         ├── test_tool_xml_strip.py (8.1k tokens)
         ├── test_torch_cpu_build_on_nvidia_host.py (23.5k tokens)
         ├── test_torch_device_probe.py (4k tokens)
         ├── test_torch_step_label.py (3.2k tokens)
         ├── test_torchao_intmm_patch_wiring.py (1400 tokens)
         ├── test_torchao_select.py (4.1k tokens)
         ├── test_torchao_stub_worker_parity.py (1200 tokens)
         ├── test_tp_vision_regression.py (8.7k tokens)
         ├── test_train_precision_scheme_contract.py (3.6k tokens)
         ├── test_trained_model_scan.py (1400 tokens)
         ├── test_trainer_stdout_quiet.py (1100 tokens)
         ├── test_training_active_output_dir.py (600 tokens)
         ├── test_training_before_spawn.py (1300 tokens)
         ├── test_training_cached_start.py (24k tokens)
         ├── test_training_config_popover_source.py (900 tokens)
         ├── test_training_finalizing_phase.py (1400 tokens)
         ├── test_training_finetune_targets.py (1600 tokens)
         ├── test_training_finetune_targets_matrix.py (4.7k tokens)
         ├── test_training_gpu_arch_gate.py (4.3k tokens)
         ├── test_training_history_delete.py (5.6k tokens)
         ├── test_training_history_update.py (900 tokens)
         ├── test_training_nan_loss_handling.py (900 tokens)
         ├── test_training_preflight.py (14.5k tokens)
         ├── test_training_preflight_offline_guard.py (1100 tokens)
         ├── test_training_progress_callback.py (2.1k tokens)
         ├── test_training_progress_job_scope.py (3.7k tokens)
         ├── test_training_progress_prep_timeout.py (1000 tokens)
         ├── test_training_progress_stream_nan.py (1100 tokens)
         ├── test_training_progress_throughput.py (700 tokens)
         ├── test_training_provenance.py (10.3k tokens)
         ├── test_training_pump_resilience.py (3.7k tokens)
         ├── test_training_raw_support.py (4.3k tokens)
         ├── test_training_resume.py (3.5k tokens)
         ├── test_training_runs.py (700 tokens)
         ├── test_training_start_idempotency.py (7.1k tokens)
         ├── test_training_start_offload.py (1200 tokens)
         ├── test_training_status_terminal.py (1800 tokens)
         ├── test_training_stop_watchdog.py (10.8k tokens)
         ├── test_training_streaming.py (4.3k tokens)
         ├── test_training_streaming_mlx_warm.py (1500 tokens)
         ├── test_training_token_forwarding.py (1400 tokens)
         ├── test_training_transformers_upgrade_gate.py (3.6k tokens)
         ├── test_training_vram_coexistence.py (5.6k tokens)
         ├── test_training_worker_flash_attn.py (11.5k tokens)
         ├── test_training_worker_import_discipline.py (800 tokens)
         ├── test_training_xet_fallback.py (2.2k tokens)
         ├── test_transformers_dtype.py (500 tokens)
         ├── test_transformers_latest.py (12.5k tokens)
         ├── test_transformers_version.py (37.4k tokens)
         ├── test_trc_approval_cache.py (2.4k tokens)
         ├── test_truncated_answer_continuation.py (8.1k tokens)
         ├── test_tts_not_chattable.py (1600 tokens)
         ├── test_tunnel_safe_long_post.py (4.5k tokens)
         ├── test_ui_stream_events_gate.py (7.5k tokens)
         ├── test_unsupported_hint_reads_only_our_diagnosis.py (700 tokens)
         ├── test_update_flow_messages.py (2k tokens)
         ├── test_utils.py (5.5k tokens)
         ├── test_uvicorn_exception_dedup.py (1100 tokens)
         ├── test_uvicorn_h11_shutdown_quiet.py (2.1k tokens)
         ├── test_validate_diffusion_extra_args.py (4k tokens)
         ├── test_validate_diffusion_unknown.py (900 tokens)
         ├── test_validate_gguf_runtime_message.py (1100 tokens)
         ├── test_validate_model_error.py (2000 tokens)
         ├── test_validate_offline_guard.py (700 tokens)
         ├── test_validation_error_binary_body.py (1700 tokens)
         ├── test_vendored_truststore.py (1000 tokens)
         ├── test_video_attachment_part.py (1500 tokens)
         ├── test_video_backend.py (72.4k tokens)
         ├── test_video_capability.py (2.7k tokens)
         ├── test_video_families.py (3.8k tokens)
         ├── test_video_gallery.py (5.8k tokens)
         ├── test_video_h3_te_quant.py (7.4k tokens)
         ├── test_video_minimax_h3_adaln.py (2.6k tokens)
         ├── test_video_offline_load.py (2.7k tokens)
         ├── test_video_pr9057_simulation.py (3.2k tokens)
         ├── test_video_prequant.py (10.7k tokens)
         ├── test_video_resolution_preset_contract.py (1600 tokens)
         ├── test_video_routes.py (13.9k tokens)
         ├── test_video_shape_validation.py (5.4k tokens)
         ├── test_vision_cache.py (10.8k tokens)
         ├── test_vision_client_tools.py (9.1k tokens)
         ├── test_vision_gradient_checkpointing.py (3.6k tokens)
         ├── test_vram_budget_settings.py (7k tokens)
         ├── test_vram_estimation.py (18.2k tokens)
         ├── test_warm_window_review_fixes.py (22k tokens)
         ├── test_web_access_policy.py (2.5k tokens)
         ├── test_web_fetch_binary_guard.py (3.1k tokens)
         ├── test_web_fetch_extraction.py (19.5k tokens)
         ├── test_web_fetch_scheme_normalization.py (1400 tokens)
         ├── test_web_page_cap_fits_window.py (10.4k tokens)
         ├── test_web_rank.py (1000 tokens)
         ├── test_wheel_utils_xformers.py (3k tokens)
         ├── test_whisper_audio_vlm_eval_dataset.py (4.4k tokens)
         ├── test_whisper_cpp_freshness.py (1000 tokens)
         ├── test_wildcard_prompt_compatibility.py (1100 tokens)
         ├── test_windows_bash_shell.py (3.7k tokens)
         ├── test_windows_external_drive_paths.py (3k tokens)
         ├── test_windows_gpu_detection_mock.py (3.2k tokens)
         ├── test_worker_activates_correct_transformers.py (1600 tokens)
         ├── test_xet_notice_settings.py (800 tokens)
         ├── test_xformers_stub_diffusion_parity.py (3k tokens)
         ├── test_yaml_trust_remote_code_removed.py (1400 tokens)
         ├── test_youtube_transcript.py (1800 tokens)
         ├── tools/
            ├── refactor_guard.py (7.6k tokens)
      ├── utils/
         ├── .gitkeep
         ├── __init__.py
         ├── _studio_release_build.py (100 tokens)
         ├── api_errors.py (2.8k tokens)
         ├── audio_tokens.py (1300 tokens)
         ├── cache_cleanup.py (3.2k tokens)
         ├── chat_preferences_settings.py (500 tokens)
         ├── child_stdio.py (300 tokens)
         ├── client_ip.py (500 tokens)
         ├── code_integrity.py (1200 tokens)
         ├── coding_agents.py (900 tokens)
         ├── cpu_threads.py (300 tokens)
         ├── current_date_prompt_settings.py (800 tokens)
         ├── datasets/
            ├── __init__.py (500 tokens)
            ├── audio_decode.py (1500 tokens)
            ├── cache_safe.py (1000 tokens)
            ├── chat_templates.py (3.4k tokens)
            ├── completion_masking.py (1400 tokens)
            ├── data_collators.py (1000 tokens)
            ├── dataset_none_detect.py (6.6k tokens)
            ├── dataset_utils.py (9k tokens)
            ├── format_conversion.py (6.6k tokens)
            ├── format_detection.py (5.6k tokens)
            ├── iterable.py (100 tokens)
            ├── llm_assist.py (6.4k tokens)
            ├── model_mappings.py (4.5k tokens)
            ├── online_tokenization.py (5.7k tokens)
            ├── raw_text.py (1300 tokens)
            ├── vlm_processing.py (1500 tokens)
         ├── debug_log_reader.py (1600 tokens)
         ├── debug_log_sources.py (2k tokens)
         ├── download_transport_settings.py (400 tokens)
         ├── downsample.py (100 tokens)
         ├── embedding_model_settings.py (3k tokens)
         ├── gguf_archs.py (400 tokens)
         ├── hardware/
            ├── VRAM_ESTIMATION.md (1300 tokens)
            ├── __init__.py (800 tokens)
            ├── amd.py (4.6k tokens)
            ├── apple.py (3k tokens)
            ├── hardware.py (62.7k tokens)
            ├── nvidia.py (3.6k tokens)
            ├── vram_estimation.py (9.8k tokens)
         ├── helper_precache_settings.py (400 tokens)
         ├── hf_cache_settings.py (3k tokens)
         ├── hf_dataset_options.py (600 tokens)
         ├── hf_probe.py (400 tokens)
         ├── hf_token_validation.py (1400 tokens)
         ├── hf_xet_fallback.py (9.2k tokens)
         ├── hidden_models.py (1900 tokens)
         ├── host_policy.py (2.4k tokens)
         ├── igpu_carveout_notice_settings.py (800 tokens)
         ├── inference/
            ├── __init__.py (100 tokens)
            ├── inference_config.py (2.1k tokens)
         ├── keyless_api_access.py (5.8k tokens)
         ├── lan_access_settings.py (3.7k tokens)
         ├── lifespan_shutdown.py (600 tokens)
         ├── llama_cpp_changelog.py (2.4k tokens)
         ├── llama_cpp_freshness.py (1900 tokens)
         ├── llama_cpp_path_settings.py (1500 tokens)
         ├── llama_cpp_update.py (12.7k tokens)
         ├── log_redaction.py (1900 tokens)
         ├── log_retention.py (600 tokens)
         ├── media_generation_preset_settings.py (700 tokens)
         ├── mlx_repair.py (5.3k tokens)
         ├── model_memory_settings.py (1300 tokens)
         ├── models/
            ├── __init__.py (300 tokens)
            ├── checkpoints.py (2.3k tokens)
            ├── drafters/
               ├── __init__.py (300 tokens)
               ├── budget.py (700 tokens)
               ├── common.py (1500 tokens)
               ├── dflash.py (1700 tokens)
               ├── preference.py (900 tokens)
            ├── gguf_metadata.py (7.6k tokens)
            ├── model_config.py (36.7k tokens)
            ├── model_identity.py (700 tokens)
         ├── native_path_leases.py (4k tokens)
         ├── native_tls.py (1600 tokens)
         ├── node_runtime.py (2.3k tokens)
         ├── openai_auto_switch_settings.py (9k tokens)
         ├── parent_watchdog.py (700 tokens)
         ├── paths/
            ├── __init__.py (600 tokens)
            ├── external_media.py (1900 tokens)
            ├── path_utils.py (3k tokens)
            ├── scan_folder_health.py (1900 tokens)
            ├── sensitive.py (200 tokens)
            ├── storage_roots.py (4.6k tokens)
         ├── personalization_settings.py (100 tokens)
         ├── prebuilt/
            ├── __init__.py (100 tokens)
            ├── child_env.py (900 tokens)
            ├── freshness_flow.py (2.7k tokens)
            ├── llama_backend.py (1300 tokens)
            ├── runtime_libs.py (500 tokens)
            ├── update_flow.py (5.3k tokens)
            ├── whisper_layout.py (500 tokens)
         ├── preview_rate_limit.py (500 tokens)
         ├── preview_sharing_settings.py (400 tokens)
         ├── preview_token.py (400 tokens)
         ├── process_lifetime.py (11.1k tokens)
         ├── release_notes.py (10.1k tokens)
         ├── remote_access_settings.py (2.9k tokens)
         ├── security/
            ├── __init__.py (800 tokens)
            ├── consent.py (3k tokens)
            ├── file_security.py (5.9k tokens)
            ├── remote_code_approvals.py (1800 tokens)
            ├── remote_code_scan.py (6.1k tokens)
            ├── trusted_org.py (800 tokens)
         ├── sentencepiece_guard.py (600 tokens)
         ├── ssm_runtime.py (3.5k tokens)
         ├── studio_version.py (800 tokens)
         ├── subprocess_compat.py (200 tokens)
         ├── third_party_source.py (8.8k tokens)
         ├── torch_device_probe.py (3k tokens)
         ├── torch_warmup.py (3.1k tokens)
         ├── training_runs.py (1400 tokens)
         ├── transformers_dtype.py (500 tokens)
         ├── transformers_latest.py (6k tokens)
         ├── transformers_version.py (26.7k tokens)
         ├── update_status.py (2.5k tokens)
         ├── upload_limits.py (700 tokens)
         ├── utils.py (8k tokens)
         ├── uv_path_safety.py (600 tokens)
         ├── uvicorn_h11_shutdown.py (1100 tokens)
         ├── vram_budget_settings.py (1200 tokens)
         ├── wheel_utils.py (3.9k tokens)
         ├── whisper_cpp_freshness.py (2000 tokens)
         ├── whisper_cpp_update.py (5.4k tokens)
         ├── xet_notice_settings.py (600 tokens)
      ├── vendor/
         ├── LICENSE (200 tokens)
         ├── README.md (500 tokens)
         ├── truststore/
            ├── __init__.py (300 tokens)
            ├── _api.py (2.3k tokens)
            ├── _macos.py (4.1k tokens)
            ├── _openssl.py (500 tokens)
            ├── _ssl_constants.py (200 tokens)
            ├── _windows.py (3.6k tokens)
            ├── py.typed
         ├── truststore_manifest.json (200 tokens)
   ├── frontend/
      ├── .gitignore (100 tokens)
      ├── .gitkeep
      ├── .npmrc (400 tokens)
      ├── biome.json (700 tokens)
      ├── components.json (100 tokens)
      ├── data-designer.openapi (1).yaml (18.6k tokens)
      ├── eslint.config.js (300 tokens)
      ├── index.html (200 tokens)
      ├── package-lock.json (118.2k tokens)
      ├── package.json (900 tokens)
      ├── public/
         ├── Sloth emojis/
            ├── 241024 Sloth Drink Jus.png
            ├── 251008 Sloth Pin.png
            ├── FO2C6766BA42 Sloth Gift.png
            ├── FO71A40FA5581 Sloth and Llama.png
            ├── Large sloth Question mark.png
            ├── Sloth loca pc.png
            ├── Sloth w Gameboy Confetti no Logo.png
            ├── Sloth w PC Confetti no Logo.png
            ├── Sloth w PC no Logo.png
            ├── UnSloth Eat GPU Mouth.png
            ├── UnSloth Eat GPU.png
            ├── UnSloth GPU Front square.png
            ├── UnSloth Laptop.png
            ├── UnSloth Sparkling large.png
            ├── large sloth cheeky.png
            ├── large sloth drink.png
            ├── large sloth fire.png
            ├── large sloth glasses.png
            ├── large sloth heart.png
            ├── large sloth laugh.png
            ├── large sloth sad.png
            ├── large sloth thumbs.png
            ├── large sloth wave.png
            ├── large sloth yay.png
            ├── sloth headphones.png
            ├── sloth huglove large.png
            ├── sloth huglove large33.png
            ├── sloth magnify final.png
            ├── sloth on phone.png
            ├── sloth pc emoji.png
            ├── sloth pc square.png
            ├── sloth rounded.png
            ├── sloth shock large.png
            ├── sloth shy large.png
            ├── sloth sir large.png
            ├── sloth w pc transparent.png
            ├── sloth with gameboy.png
         ├── agent-logos/
            ├── hermes.png
            ├── openclaw.svg (200 tokens)
            ├── opencode-dark.svg (200 tokens)
            ├── opencode-light.svg (200 tokens)
         ├── circle-logo-small.png
         ├── crypto-boot.js (100 tokens)
         ├── favicon.png
         ├── fonts/
            ├── FiraCode-VariableFont_wght.ttf
            ├── Hellix-Medium.woff
            ├── Hellix-Regular.woff
            ├── Hellix-SemiBold.woff
            ├── Hellix-SemiBold.woff2
         ├── hub/
            ├── profile/
               ├── logo/
                  ├── Qwen.svg (300 tokens)
                  ├── cohere.png
                  ├── deepseek.svg (500 tokens)
                  ├── google.png
                  ├── hf.svg (7.1k tokens)
                  ├── ibm.png
                  ├── meta.svg (500 tokens)
                  ├── microsoft.svg (100 tokens)
                  ├── minimax-color.png
                  ├── mistral.svg (200 tokens)
                  ├── moonshot.jpg
                  ├── nvidia.svg (200 tokens)
                  ├── openai.svg (500 tokens)
                  ├── qwen.png
                  ├── xai.svg (100 tokens)
                  ├── zai.svg (2.2k tokens)
         ├── logotext.png
         ├── provider-logos/
            ├── anthropic.svg (1000 tokens)
            ├── gemini.svg (20k tokens)
            ├── llama_cpp.svg (200 tokens)
            ├── misc/
               ├── perplexity.png
            ├── ollama.svg (1800 tokens)
            ├── openrouter.svg (200 tokens)
            ├── vllm.svg (700 tokens)
         ├── reload-snapshot.js (6.2k tokens)
         ├── rounded-512.png
         ├── rounded.png
         ├── sticker.png
         ├── studio github landscape colab display.png
         ├── theme-boot.js (200 tokens)
         ├── unsloth-gem.png
         ├── unsloth.ico
         ├── vite.svg (300 tokens)
      ├── scripts/
         ├── build-fast-copy-bundle.mjs (400 tokens)
         ├── check-bundle-budget.ts (4.6k tokens)
         ├── coal-span-census.mjs (1700 tokens)
      ├── smoke-ansi-main.tsx (300 tokens)
      ├── smoke-ansi.html (100 tokens)
      ├── smoke-autoscroll-main.tsx (1000 tokens)
      ├── smoke-autoscroll.html (100 tokens)
      ├── smoke-code-block-flicker-main.tsx (3.7k tokens)
      ├── smoke-code-block-flicker.html (100 tokens)
      ├── smoke-collapse-layout-main.tsx (2.2k tokens)
      ├── smoke-collapse-layout.html (100 tokens)
      ├── smoke-composer-icons-main.tsx (500 tokens)
      ├── smoke-composer-icons.html (100 tokens)
      ├── smoke-find-in-page-main.tsx (2.9k tokens)
      ├── smoke-find-in-page.html (100 tokens)
      ├── smoke-heavy-thread-main.tsx (8k tokens)
      ├── smoke-heavy-thread.html (100 tokens)
      ├── smoke-link-definition-probe-main.tsx (900 tokens)
      ├── smoke-link-definition-probe.html (100 tokens)
      ├── smoke-nonmodal-menus-main.tsx (1500 tokens)
      ├── smoke-nonmodal-menus.html (100 tokens)
      ├── smoke-research-main.tsx (1400 tokens)
      ├── smoke-research.html (100 tokens)
      ├── smoke-settings-main.tsx (900 tokens)
      ├── smoke-settings.html (100 tokens)
      ├── smoke-shortcuts-main.tsx (1200 tokens)
      ├── smoke-shortcuts.html (100 tokens)
      ├── smoke-stream-pacing-main.tsx (2.6k tokens)
      ├── smoke-stream-pacing-stall.ts (400 tokens)
      ├── smoke-stream-pacing.html (100 tokens)
      ├── smoke-thread-weight-main.tsx (2.6k tokens)
      ├── smoke-thread-weight.html (100 tokens)
      ├── smoke-tool-activity-main.tsx (1900 tokens)
      ├── smoke-tool-activity.html (100 tokens)
      ├── src/
         ├── app/
            ├── app.tsx (100 tokens)
            ├── auth-guards.ts (700 tokens)
            ├── provider.tsx (6.4k tokens)
            ├── router.tsx (500 tokens)
            ├── routes/
               ├── __root.tsx (5.5k tokens)
               ├── api.tsx (100 tokens)
               ├── audio.tsx (400 tokens)
               ├── change-password.tsx (100 tokens)
               ├── chat.tsx (200 tokens)
               ├── data-recipes.$recipeId.tsx (200 tokens)
               ├── data-recipes.tsx (100 tokens)
               ├── export.tsx (200 tokens)
               ├── hub.tsx (300 tokens)
               ├── images.tsx (200 tokens)
               ├── index.tsx (100 tokens)
               ├── login.tsx (100 tokens)
               ├── projects.tsx (100 tokens)
               ├── settings.tsx (200 tokens)
               ├── studio.tsx (100 tokens)
               ├── video.tsx (200 tokens)
            ├── window-layout-lifecycle.ts (1200 tokens)
            ├── window-layout.ts (1000 tokens)
         ├── asset-queries.d.ts (omitted)
         ├── assets/
            ├── mascot-fallback.webp
            ├── react.svg (900 tokens)
         ├── components/
            ├── advanced-disclosure.tsx (400 tokens)
            ├── app-readiness.ts (400 tokens)
            ├── app-sidebar.tsx (39.7k tokens)
            ├── assistant-ui/
               ├── attachment-preview.tsx (2.5k tokens)
               ├── attachment-selection.ts (400 tokens)
               ├── attachment.tsx (2.7k tokens)
               ├── audio-player.tsx (700 tokens)
               ├── badge.tsx (400 tokens)
               ├── chat-dictation-bar.tsx (2.1k tokens)
               ├── citation-utils.ts (600 tokens)
               ├── code-fence-defer.tsx (5.9k tokens)
               ├── code-fence-mode.ts (500 tokens)
               ├── code-plugin.ts (4.1k tokens)
               ├── code-themes.ts (200 tokens)
               ├── code-toggle-icon.tsx (100 tokens)
               ├── compaction-notice.tsx (500 tokens)
               ├── generated-image-overlay-context.tsx (400 tokens)
               ├── image.tsx (2.5k tokens)
               ├── markdown-block-boundary.tsx (1200 tokens)
               ├── markdown-block-fallback.ts (1900 tokens)
               ├── markdown-text.tsx (7.3k tokens)
               ├── math-block-containment.ts (600 tokens)
               ├── math-block-marker.ts (3.2k tokens)
               ├── math-block-mode.ts (1600 tokens)
               ├── message-html-artifacts.tsx (600 tokens)
               ├── message-response-details-sheet.tsx (3.4k tokens)
               ├── message-timing.tsx (2.9k tokens)
               ├── progressive-messages.tsx (5.9k tokens)
               ├── progressive-mount-controller.ts (2.8k tokens)
               ├── python-tool-image-path.ts (100 tokens)
               ├── rag-sources.tsx (300 tokens)
               ├── reasoning-pagination.ts (2000 tokens)
               ├── reasoning.tsx (5.3k tokens)
               ├── research-reply-owners.ts (400 tokens)
               ├── sandbox-files-view.tsx (1000 tokens)
               ├── sandbox-files.ts (2.1k tokens)
               ├── sandbox-reveal.ts (400 tokens)
               ├── search-image.tsx (1200 tokens)
               ├── sources.tsx (2k tokens)
               ├── streaming-markdown.ts (800 tokens)
               ├── streaming-render-schedule.ts (11.1k tokens)
               ├── think-aria-label.ts (300 tokens)
               ├── thread-fast-copy.ts (4.5k tokens)
               ├── thread-feature-flags.ts (700 tokens)
               ├── thread-message-slot.ts (600 tokens)
               ├── thread-research-presence.ts (800 tokens)
               ├── thread.tsx (63.4k tokens)
               ├── tool-activity-open-state.ts (200 tokens)
               ├── tool-arg-text.ts (1000 tokens)
               ├── tool-code-cell.tsx (1300 tokens)
               ├── tool-confirmation-controls.tsx (1500 tokens)
               ├── tool-fallback.tsx (2.7k tokens)
               ├── tool-group.tsx (2.2k tokens)
               ├── tool-live-output.tsx (500 tokens)
               ├── tool-result-output.tsx (300 tokens)
               ├── tool-ui-code-execution.tsx (1400 tokens)
               ├── tool-ui-image-generation.tsx (3k tokens)
               ├── tool-ui-knowledge-base.tsx (1000 tokens)
               ├── tool-ui-python.tsx (1400 tokens)
               ├── tool-ui-render-html.tsx (900 tokens)
               ├── tool-ui-terminal.tsx (1000 tokens)
               ├── tool-ui-web-search.tsx (2.1k tokens)
               ├── tooltip-icon-button.tsx (300 tokens)
               ├── use-attachment-source.ts (400 tokens)
               ├── use-intent-aware-autoscroll.tsx (5.2k tokens)
               ├── use-sandbox-image.ts (700 tokens)
               ├── use-tool-activity-open.ts (200 tokens)
            ├── example.tsx (300 tokens)
            ├── floating-monitor.tsx (4.8k tokens)
            ├── gallery-item-menu.tsx (700 tokens)
            ├── image-dropzone.tsx (1200 tokens)
            ├── layout/
               ├── dashboard-grid.tsx (100 tokens)
               ├── dashboard-layout.tsx (100 tokens)
               ├── index.ts
            ├── lazy-import-boundary.tsx (400 tokens)
            ├── llama-update-banner.tsx (2.6k tokens)
            ├── markdown/
               ├── markdown-preview.tsx (800 tokens)
               ├── mermaid-error.tsx (200 tokens)
            ├── mascot-img.tsx (400 tokens)
            ├── media-page-link.tsx (500 tokens)
            ├── model-memory-bar.tsx (1400 tokens)
            ├── nav-row-state.ts (300 tokens)
            ├── navbar.tsx (400 tokens)
            ├── negative-prompt-field.tsx (400 tokens)
            ├── resource-picker/
               ├── dataset-display-name.ts (100 tokens)
               ├── device-item-match.ts (300 tokens)
               ├── hf-error.ts (100 tokens)
               ├── hub-resource-id.ts (300 tokens)
               ├── path-display-name.ts (100 tokens)
               ├── picker-focus.ts (200 tokens)
               ├── picker-pagination.tsx (300 tokens)
               ├── picker-shell.tsx (2.5k tokens)
               ├── picker-states.tsx (300 tokens)
               ├── picker-tab-policy.ts (400 tokens)
               ├── picker-tab-state.ts (200 tokens)
               ├── picker-tab-toggle.tsx (500 tokens)
               ├── selectable-picker-item.tsx (200 tokens)
               ├── use-hf-error-toast.ts (600 tokens)
               ├── use-picker-hub-pagination.ts (200 tokens)
               ├── use-picker-state.ts (700 tokens)
            ├── section-card.tsx (600 tokens)
            ├── segmented-control-styles.ts (100 tokens)
            ├── segmented-control.tsx (700 tokens)
            ├── segmented-tabs.tsx (400 tokens)
            ├── shutdown-dialog.tsx (600 tokens)
            ├── sidebar-edge-trigger.tsx (1200 tokens)
            ├── tauri/
               ├── closing-signal.ts (400 tokens)
               ├── diagnostics-copy-actions.tsx (500 tokens)
               ├── log-details.tsx (700 tokens)
               ├── log-follow.ts (200 tokens)
               ├── startup-messages.ts (500 tokens)
               ├── startup-screen.tsx (2.8k tokens)
               ├── update-banner.tsx (2.3k tokens)
               ├── update-screen.tsx (1000 tokens)
               ├── window-titlebar.tsx (3.5k tokens)
            ├── ui/
               ├── accordion.tsx (600 tokens)
               ├── alert-dialog.tsx (1300 tokens)
               ├── alert.tsx (400 tokens)
               ├── animated-shiny-text.tsx (200 tokens)
               ├── animated-theme-toggler.tsx (700 tokens)
               ├── aspect-ratio.tsx (100 tokens)
               ├── avatar.tsx (700 tokens)
               ├── badge.tsx (400 tokens)
               ├── breadcrumb.tsx (600 tokens)
               ├── button.tsx (800 tokens)
               ├── calendar.tsx (1700 tokens)
               ├── card.tsx (500 tokens)
               ├── chart.tsx (2.6k tokens)
               ├── checkbox.tsx (300 tokens)
               ├── collapsible.tsx (300 tokens)
               ├── combobox.tsx (2.5k tokens)
               ├── command.tsx (1100 tokens)
               ├── confetti.tsx (600 tokens)
               ├── context-menu.tsx (1700 tokens)
               ├── copyable-error-chip.tsx (700 tokens)
               ├── data-table.tsx (700 tokens)
               ├── dialog.tsx (1500 tokens)
               ├── dropdown-menu.tsx (2.3k tokens)
               ├── empty.tsx (500 tokens)
               ├── field.tsx (1200 tokens)
               ├── hover-card.tsx (300 tokens)
               ├── info-hint.tsx (300 tokens)
               ├── input-group.tsx (1100 tokens)
               ├── input.tsx (1100 tokens)
               ├── label.tsx (200 tokens)
               ├── light-rays.tsx (800 tokens)
               ├── menubar.tsx (1800 tokens)
               ├── navigation-menu.tsx (1400 tokens)
               ├── non-modal-dropdown-menu.tsx (700 tokens)
               ├── pagination.tsx (600 tokens)
               ├── panel-resize-handle.tsx (3.3k tokens)
               ├── panel-resize-recalc-flags.ts (1000 tokens)
               ├── popover.tsx (600 tokens)
               ├── progress.tsx (300 tokens)
               ├── radio-group.tsx (400 tokens)
               ├── resizable.tsx (500 tokens)
               ├── scroll-area.tsx (400 tokens)
               ├── select.tsx (1800 tokens)
               ├── separator.tsx (200 tokens)
               ├── sheet.tsx (1300 tokens)
               ├── shimmer-button.tsx (600 tokens)
               ├── shine-border.tsx (400 tokens)
               ├── sidebar.tsx (7.1k tokens)
               ├── skeleton.tsx (100 tokens)
               ├── slider.tsx (900 tokens)
               ├── sonner.tsx (800 tokens)
               ├── sparkles-text.tsx (900 tokens)
               ├── spinner.tsx (200 tokens)
               ├── switch.tsx (400 tokens)
               ├── table.tsx (500 tokens)
               ├── tabs.tsx (1200 tokens)
               ├── terminal.tsx (1100 tokens)
               ├── textarea.tsx (300 tokens)
               ├── toggle-group.tsx (700 tokens)
               ├── toggle.tsx (300 tokens)
               ├── tooltip-modal-layer.ts (1000 tokens)
               ├── tooltip-open-state.ts (300 tokens)
               ├── tooltip.tsx (2.3k tokens)
               ├── unmeasured-collapsible.tsx (2.3k tokens)
            ├── update/
               ├── llama-update-changelog-panel.tsx (1100 tokens)
               ├── release-notes-panel.tsx (1700 tokens)
               ├── update-notes-layout.ts (200 tokens)
            ├── web/
               ├── update-banner.tsx (1600 tokens)
         ├── config/
            ├── env.ts (2.2k tokens)
            ├── hardware-verdict.ts (800 tokens)
            ├── training.ts (1300 tokens)
         ├── features/
            ├── api-monitor/
               ├── api-monitor-overlay.tsx (3.6k tokens)
               ├── api-monitor-page.tsx (6.8k tokens)
               ├── clear-monitor.ts (300 tokens)
               ├── components/
                  ├── saved-model-settings.tsx (1600 tokens)
               ├── forget-model-override.ts (400 tokens)
               ├── index.ts (100 tokens)
               ├── lifecycle.ts (300 tokens)
               ├── new-traffic.ts (1100 tokens)
               ├── overlay-store.ts (500 tokens)
               ├── panel-placement.ts (1500 tokens)
               ├── stats.ts (700 tokens)
               ├── unload-resident.ts (500 tokens)
               ├── use-api-monitor.ts (1200 tokens)
               ├── use-panel-anchor.ts (1200 tokens)
            ├── audio/
               ├── api.ts (800 tokens)
               ├── audio-page-policy.ts (3.4k tokens)
               ├── audio-page.tsx (23.5k tokens)
               ├── catalog.ts (700 tokens)
               ├── index.ts
               ├── stt-artifacts.ts (500 tokens)
            ├── auth/
               ├── api.ts (1900 tokens)
               ├── bootstrap-deadline.ts (300 tokens)
               ├── change-password-page.tsx (200 tokens)
               ├── components/
                  ├── auth-form.tsx (3.7k tokens)
               ├── index.ts (100 tokens)
               ├── login-page.tsx (200 tokens)
               ├── session-events.ts (100 tokens)
               ├── session.ts (900 tokens)
               ├── tauri-auto-auth.ts (700 tokens)
            ├── chat/
               ├── adapters/
                  ├── dictation-level.ts (500 tokens)
                  ├── dictation-outcome.ts (300 tokens)
                  ├── pcm-recorder.ts (2.1k tokens)
                  ├── stt-errors.ts (200 tokens)
                  ├── studio-dictation-adapter.tsx (1400 tokens)
                  ├── studio-model-dictation-adapter.ts (5.7k tokens)
                  ├── studio-speech-synthesis-adapter.ts (3.6k tokens)
                  ├── studio-web-speech-dictation-adapter.ts (3.1k tokens)
               ├── api-provider-logo.tsx (300 tokens)
               ├── api/
                  ├── chat-adapter.ts (65.3k tokens)
                  ├── chat-api.ts (12.8k tokens)
                  ├── chat-generation-api.ts (3.5k tokens)
                  ├── chat-preferences.ts (400 tokens)
                  ├── chat-settings-api.ts (1300 tokens)
                  ├── code-tool-placement.ts (600 tokens)
                  ├── generation-length.ts (300 tokens)
                  ├── gguf-variants-request.ts (500 tokens)
                  ├── mcp-server-mutation-tracker.ts (600 tokens)
                  ├── mcp-servers-api.ts (1500 tokens)
                  ├── openai-containers.ts (700 tokens)
                  ├── padded-response.ts (200 tokens)
                  ├── prompts-api.ts (600 tokens)
                  ├── providers-api.ts (3k tokens)
                  ├── rag-context-length.ts (200 tokens)
                  ├── research-api.ts (2.2k tokens)
                  ├── youtube-api.ts (300 tokens)
               ├── artifacts/
                  ├── artifact-card.tsx (1100 tokens)
                  ├── artifact-surface.tsx (2.7k tokens)
                  ├── html-fences.ts (900 tokens)
                  ├── html-frame.tsx (2.6k tokens)
                  ├── store.ts (700 tokens)
                  ├── types.ts (600 tokens)
               ├── attachment-content.ts (5.6k tokens)
               ├── audio-attachment-adapter.ts (800 tokens)
               ├── blender-mcp-setup.tsx (2.4k tokens)
               ├── bypass-permissions-menu-item.tsx (600 tokens)
               ├── chat-mcp-servers-dialog.tsx (8.1k tokens)
               ├── chat-page.tsx (32.4k tokens)
               ├── chat-project-scope.ts (100 tokens)
               ├── chat-providers-dialog.tsx (17.4k tokens)
               ├── chat-settings-sheet.tsx (15k tokens)
               ├── codex-reasoning.ts (600 tokens)
               ├── components/
                  ├── chat-model-notice-switch.ts (900 tokens)
                  ├── chat-model-notice.tsx (900 tokens)
                  ├── chat-search-dialog.tsx (1800 tokens)
                  ├── context-usage-bar.tsx (1200 tokens)
                  ├── deep-research-composer-button.tsx (2.2k tokens)
                  ├── delete-chat-files-switch.tsx (300 tokens)
                  ├── model-load-status.tsx (1000 tokens)
                  ├── new-project-dialog.tsx (1200 tokens)
                  ├── openai-code-exec-section.tsx (4.9k tokens)
                  ├── project-switcher.tsx (1000 tokens)
                  ├── research-activity-panel.tsx (7.7k tokens)
                  ├── research-message.tsx (1400 tokens)
                  ├── stop-running-chats-dialog.tsx (700 tokens)
                  ├── youtube-transcript-prompt.tsx (1200 tokens)
               ├── db.ts (400 tokens)
               ├── external-providers.ts (4.6k tokens)
               ├── hooks/
                  ├── use-chat-model-runtime.ts (24k tokens)
                  ├── use-chat-projects.ts (1000 tokens)
                  ├── use-chat-search-index.ts (4k tokens)
                  ├── use-chat-sidebar-items.ts (2.5k tokens)
                  ├── use-pill-activation-order.ts (200 tokens)
                  ├── use-rag-tool-disabled.ts (300 tokens)
                  ├── use-transfer-stats.ts (400 tokens)
               ├── index.ts (2.2k tokens)
               ├── lib/
                  ├── apply-inference-status-to-store.ts (6.5k tokens)
                  ├── chat-model-loaded.ts (300 tokens)
                  ├── context-usage-bar-state.ts (1000 tokens)
                  ├── context-window-known.ts (200 tokens)
                  ├── external-model-label.ts (300 tokens)
                  ├── friendly-names.ts (700 tokens)
                  ├── gpu-placement.ts (700 tokens)
                  ├── llama-extra-args-normalize.ts (1000 tokens)
                  ├── mlx-runtime-state.ts (300 tokens)
                  ├── per-model-params.ts (1000 tokens)
                  ├── resident-config-match.ts (4.8k tokens)
                  ├── resident-model-match.ts (600 tokens)
                  ├── resolve-batch-size-seed.ts (600 tokens)
                  ├── resolve-chat-template-seed.ts (600 tokens)
                  ├── resolve-ctx-pin-seed.ts (1200 tokens)
                  ├── resolve-preserve-thinking-default.ts (100 tokens)
                  ├── resolve-vision-switch-seed.ts (400 tokens)
                  ├── server-model-wait.ts (400 tokens)
                  ├── server-tuning-fields.ts (700 tokens)
                  ├── server-wide-reload.ts (300 tokens)
                  ├── speech-only-status.ts (200 tokens)
                  ├── training-compare-handoff.ts (300 tokens)
               ├── local-model-options.ts (500 tokens)
               ├── mcp-composer-button.tsx (2.8k tokens)
               ├── mcp-server-form.ts (200 tokens)
               ├── open-document-accept.ts (200 tokens)
               ├── open-document.ts (3.8k tokens)
               ├── openai-codex-connect.tsx (1700 tokens)
               ├── permission-mode-select.tsx (2000 tokens)
               ├── presets/
                  ├── preset-load-config.ts (2.6k tokens)
                  ├── preset-policy.ts (3.4k tokens)
               ├── projects-page.tsx (6.3k tokens)
               ├── prompt-storage/
                  ├── mutation-lock.ts (400 tokens)
                  ├── prompt-storage-dialog.tsx (20.3k tokens)
                  ├── reorder.ts (500 tokens)
                  ├── sortable-prompt-items.tsx (2.6k tokens)
               ├── provider-capabilities.ts (7.8k tokens)
               ├── provider-credential-edit.ts (100 tokens)
               ├── provider-logo-path.ts (300 tokens)
               ├── research-inference-request.ts (800 tokens)
               ├── runtime-provider.tsx (25.4k tokens)
               ├── search-images/
                  ├── search-images.ts (3.7k tokens)
               ├── shared-composer.tsx (22.1k tokens)
               ├── stores/
                  ├── chat-navigation-store.ts (2.5k tokens)
                  ├── chat-preferences-store.ts (700 tokens)
                  ├── chat-runtime-keys.ts (100 tokens)
                  ├── chat-runtime-store.ts (44.3k tokens)
                  ├── chat-search-store.ts (100 tokens)
                  ├── external-providers-store.ts (200 tokens)
                  ├── mcp-servers-dialog-store.ts (100 tokens)
                  ├── pinned-chats-store.ts (400 tokens)
                  ├── pinned-projects-store.ts (300 tokens)
                  ├── plus-menu-prefs-store.ts (600 tokens)
                  ├── prompt-queue-ui-store.ts (200 tokens)
                  ├── research-run-store.ts (7.1k tokens)
                  ├── sidebar-organization-keys.ts (100 tokens)
                  ├── sidebar-organization-store.ts (1200 tokens)
                  ├── stop-running-chats-dialog-store.ts (400 tokens)
               ├── sync-external-providers.ts (2.4k tokens)
               ├── sync-model-disclaimer-preference.ts (600 tokens)
               ├── text-attachment-accept.ts (8.7k tokens)
               ├── thread-sidebar.tsx (2.9k tokens)
               ├── tool-approval.ts (100 tokens)
               ├── tool-call-arguments.ts (2.8k tokens)
               ├── tool-call-id.ts (700 tokens)
               ├── tool-output-result.ts (900 tokens)
               ├── tool-output-scope.ts (700 tokens)
               ├── tour/
                  ├── index.ts
                  ├── steps.tsx (500 tokens)
               ├── types.ts (600 tokens)
               ├── types/
                  ├── api.ts (6.2k tokens)
                  ├── research.ts (1000 tokens)
                  ├── runtime.ts (700 tokens)
               ├── utils/
                  ├── archived-chat-export.ts (400 tokens)
                  ├── auto-compaction.ts (800 tokens)
                  ├── auto-continue-run-keeper.ts (800 tokens)
                  ├── chat-attachment-events.ts (800 tokens)
                  ├── chat-generation-recovery.ts (5.6k tokens)
                  ├── chat-history-clear-boundary.ts (100 tokens)
                  ├── chat-history-revision.ts (600 tokens)
                  ├── chat-history-storage.ts (8.9k tokens)
                  ├── chat-import.ts (3k tokens)
                  ├── chat-search-history-hint.ts (500 tokens)
                  ├── chat-search-list-height.ts (200 tokens)
                  ├── chat-settings-storage.ts (3.9k tokens)
                  ├── chat-thread-creation-claim.ts (600 tokens)
                  ├── chat-thread-tombstones.ts (700 tokens)
                  ├── chat-title.ts (1300 tokens)
                  ├── clear-all-chats.ts (300 tokens)
                  ├── clipboard-files.ts (1500 tokens)
                  ├── clipboard-payload.ts (500 tokens)
                  ├── compare-pane-threads.ts (800 tokens)
                  ├── composer-draft.ts (600 tokens)
                  ├── composer-send-guard.ts (900 tokens)
                  ├── confirm-stop-running-chats.ts (1400 tokens)
                  ├── context-truncation.ts (1200 tokens)
                  ├── continuation.ts (7.5k tokens)
                  ├── conversation-markdown-export.ts (700 tokens)
                  ├── conversation-markdown.ts (5.1k tokens)
                  ├── csv-parse.ts (300 tokens)
                  ├── deep-research-handoff.ts (800 tokens)
                  ├── delete-thread-message.ts (1200 tokens)
                  ├── dictation-send.ts (600 tokens)
                  ├── document-citation-source.ts (700 tokens)
                  ├── download-json.ts (100 tokens)
                  ├── export-chat-history.ts (300 tokens)
                  ├── fork-count-store.ts (1100 tokens)
                  ├── format-transfer.ts (300 tokens)
                  ├── generation-tool-recovery.ts (3k tokens)
                  ├── google-native-parts.ts (300 tokens)
                  ├── image-input-support.ts (1100 tokens)
                  ├── incremental-assistant-content.ts (1100 tokens)
                  ├── json-record-stream.ts (2000 tokens)
                  ├── last-local-model-load.ts (1700 tokens)
                  ├── mcp-tool-name.ts (200 tokens)
                  ├── message-order.ts (700 tokens)
                  ├── mirrored-chat-settings.ts (1500 tokens)
                  ├── mmproj-fallback.ts (900 tokens)
                  ├── model-download-staging.ts (400 tokens)
                  ├── model-lifecycle-gate.ts (200 tokens)
                  ├── ndjson.ts (300 tokens)
                  ├── offer-kept-sandbox-files.ts (300 tokens)
                  ├── openapi-support.ts (400 tokens)
                  ├── openwebui-import.ts (5k tokens)
                  ├── parse-assistant-content.ts (1500 tokens)
                  ├── pasted-text.ts (2.8k tokens)
                  ├── pre-stream-run-reservation.ts (1100 tokens)
                  ├── project-attachment-target.ts (300 tokens)
                  ├── project-source-plan.ts (500 tokens)
                  ├── prompt-queue-boundary.ts (500 tokens)
                  ├── prompt-queue-events.ts (200 tokens)
                  ├── prompt-queue-input.ts (500 tokens)
                  ├── prompt-queue-model-boundary.ts (400 tokens)
                  ├── prompt-queue-reorder.ts (400 tokens)
                  ├── prompt-queue-user-stop.ts (300 tokens)
                  ├── queued-chat-run-settings.ts (900 tokens)
                  ├── queued-model-capabilities.ts (200 tokens)
                  ├── queued-settings-epoch.ts (100 tokens)
                  ├── qwen-defaults-migration.ts (1900 tokens)
                  ├── qwen-params.ts (300 tokens)
                  ├── qwen-sampling-table.ts (600 tokens)
                  ├── reasoning-duration.ts (1300 tokens)
                  ├── reasoning-visibility.ts (500 tokens)
                  ├── recorded-sandbox-session.ts (400 tokens)
                  ├── refresh-context-usage.ts (2.7k tokens)
                  ├── repair-legacy-chat-titles.ts (1000 tokens)
                  ├── reply-source-markdown.ts (200 tokens)
                  ├── research-message-sync.ts (400 tokens)
                  ├── research-run-binding.ts (200 tokens)
                  ├── retryable-shared-read.ts (200 tokens)
                  ├── row-selection.ts (200 tokens)
                  ├── run-checkpoint-scheduler.ts (1200 tokens)
                  ├── run-with-concurrency.ts (100 tokens)
                  ├── serial-queue.ts (100 tokens)
                  ├── settings-retry.ts (1000 tokens)
                  ├── stop-chat-thread.ts (600 tokens)
                  ├── stream-pacing.ts (400 tokens)
                  ├── studio-tool-history.ts (300 tokens)
                  ├── thread-ids.ts (100 tokens)
                  ├── thread-record-write-coordinator.ts (500 tokens)
                  ├── thread-scoped-settings.ts (1400 tokens)
                  ├── tool-status.ts (200 tokens)
                  ├── trailing-template-placeholder.ts (1300 tokens)
                  ├── update-thread-message.ts (1800 tokens)
                  ├── youtube-url.ts (500 tokens)
               ├── video-attachment-adapter.ts (800 tokens)
            ├── credentials/
               ├── bootstrap.ts (200 tokens)
               ├── reconciliation.ts (900 tokens)
            ├── data-recipes/
               ├── data/
                  ├── recipes-db.ts (800 tokens)
               ├── hooks/
                  ├── use-recipe-sidebar-items.ts (100 tokens)
               ├── index.ts (100 tokens)
               ├── learning-recipes/
                  ├── conversation.json (1700 tokens)
                  ├── github-support-bot.json (2.1k tokens)
                  ├── index.ts (1000 tokens)
                  ├── instruction-from-answer.json (900 tokens)
                  ├── ocr-document-extraction.json (900 tokens)
                  ├── pdf-grounded-qa.json (1400 tokens)
                  ├── structured-outputs-jinja.json (2.2k tokens)
                  ├── text-to-python.json (1500 tokens)
                  ├── text-to-sql.json (1900 tokens)
               ├── pages/
                  ├── data-recipes-page.tsx (4k tokens)
                  ├── edit-recipe-page.tsx (800 tokens)
               ├── types.ts (100 tokens)
            ├── dataset-picker/
               ├── components/
                  ├── dataset-selector-lists.tsx (1500 tokens)
                  ├── dataset-selector.tsx (2.7k tokens)
               ├── index.ts (100 tokens)
               ├── lib/
                  ├── display.ts (200 tokens)
            ├── deep-links/
               ├── deep-link-handler.tsx (500 tokens)
               ├── deep-link-intent.ts (100 tokens)
               ├── index.ts
               ├── parse-deep-link.ts (500 tokens)
            ├── export/
               ├── api/
                  ├── export-api.ts (2.9k tokens)
               ├── components/
                  ├── export-run-panel.tsx (5.5k tokens)
                  ├── method-picker.tsx (1100 tokens)
                  ├── quant-picker.tsx (800 tokens)
               ├── constants.ts (1900 tokens)
               ├── export-navigation-cache.ts (400 tokens)
               ├── export-page.tsx (14.8k tokens)
               ├── hooks/
                  ├── use-export-runtime-lifecycle.ts (1300 tokens)
                  ├── use-export-size-estimate.ts (500 tokens)
               ├── index.ts (200 tokens)
               ├── lib/
                  ├── gguf-shard-size.ts (300 tokens)
                  ├── log-style.ts (200 tokens)
               ├── stores/
                  ├── export-runtime-store.ts (4.3k tokens)
               ├── tour/
                  ├── index.ts
                  ├── steps.tsx (300 tokens)
            ├── find-in-page/
               ├── components/
                  ├── find-bar-loader.tsx (100 tokens)
                  ├── find-bar.tsx (2000 tokens)
                  ├── find-in-page.tsx (1800 tokens)
               ├── hooks/
                  ├── use-find-in-page.ts (3.2k tokens)
               ├── index.ts (100 tokens)
               ├── lib/
                  ├── find-attributes.ts (100 tokens)
                  ├── find-dom.ts (4.2k tokens)
                  ├── find-text-index.ts (8k tokens)
            ├── generation-presets/
               ├── api.ts (500 tokens)
               ├── index.ts (100 tokens)
               ├── media-generation-preset-control.tsx (1600 tokens)
               ├── preset-policy.ts (400 tokens)
               ├── types.ts (200 tokens)
               ├── use-media-generation-presets.ts (3.2k tokens)
            ├── hf-auth/
               ├── api.ts (300 tokens)
               ├── confirm-token.ts (1300 tokens)
               ├── hf-token-warning-dialog.tsx (500 tokens)
               ├── index.ts (100 tokens)
               ├── store.ts (200 tokens)
            ├── hub/
               ├── api/
                  ├── hf-token-api.ts (400 tokens)
               ├── catalog/
                  ├── card-carousel.tsx (1300 tokens)
                  ├── catalog-states.tsx (2.5k tokens)
                  ├── dataset-download-section.tsx (1100 tokens)
                  ├── delete-impact.tsx (700 tokens)
                  ├── dot-tag.tsx (200 tokens)
                  ├── download-cancel-indicator.tsx (200 tokens)
                  ├── download-card.tsx (2.2k tokens)
                  ├── download-section.tsx (500 tokens)
                  ├── external-link-confirm-dialog.tsx (500 tokens)
                  ├── free-up-space-dialog.tsx (1400 tokens)
                  ├── gguf-download-card.tsx (8.3k tokens)
                  ├── gguf-live-variant-states.ts (1100 tokens)
                  ├── gguf-status-cards.tsx (700 tokens)
                  ├── hub-detail-view.tsx (700 tokens)
                  ├── hub-feed.tsx (200 tokens)
                  ├── hub-option-menu.tsx (1700 tokens)
                  ├── hub-section-row.tsx (500 tokens)
                  ├── hub-top-bar.tsx (100 tokens)
                  ├── inventory-sort.ts (300 tokens)
                  ├── local-dataset-card.tsx (200 tokens)
                  ├── local-on-device-card.tsx (5k tokens)
                  ├── model-card.tsx (2.2k tokens)
                  ├── model-download-state.ts (100 tokens)
                  ├── model-inspector.tsx (5.6k tokens)
                  ├── model-readme.tsx (3.1k tokens)
                  ├── models-catalog-lists.tsx (3.9k tokens)
                  ├── models-catalog-rows.tsx (6.1k tokens)
                  ├── models-catalog.tsx (3.3k tokens)
                  ├── models-header.tsx (500 tokens)
                  ├── models-table.tsx (6k tokens)
                  ├── models-toolbar.tsx (3.6k tokens)
                  ├── on-device-folders-dialog.tsx (4.6k tokens)
                  ├── owner-avatar.tsx (1300 tokens)
                  ├── owner-scope-toggle.tsx (200 tokens)
                  ├── path-info-button.tsx (400 tokens)
                  ├── recent-searches.tsx (600 tokens)
                  ├── safetensors-download-card.tsx (1900 tokens)
                  ├── shared.tsx (900 tokens)
                  ├── transport-conflict-dialog.tsx (700 tokens)
                  ├── transport-toggle.tsx (800 tokens)
                  ├── use-card-delete.ts (200 tokens)
                  ├── use-delete-confirm-action.ts (400 tokens)
                  ├── use-download-card-state.ts (1100 tokens)
                  ├── use-gguf-variant-fetch-state.ts (1000 tokens)
               ├── components/
                  ├── hf-token-indicator.tsx (900 tokens)
                  ├── page-heading.tsx (200 tokens)
                  ├── train-icon.ts (100 tokens)
               ├── download-manager/
                  ├── adopt-rules.ts (1000 tokens)
                  ├── api.ts (3.2k tokens)
                  ├── constants.ts (1100 tokens)
                  ├── download-api-adapter.ts (1600 tokens)
                  ├── download-manager-config.ts (300 tokens)
                  ├── download-manager-controller.ts (600 tokens)
                  ├── download-manager-panel.tsx (1900 tokens)
                  ├── download-manager-state.ts (4.2k tokens)
                  ├── download-manager-types.ts (1200 tokens)
                  ├── download-progress-bar.tsx (500 tokens)
                  ├── external-jobs.ts (700 tokens)
                  ├── hydration.ts (2k tokens)
                  ├── index.ts (300 tokens)
                  ├── poll-loop.ts (7.1k tokens)
                  ├── progress-reconcile.ts (1600 tokens)
                  ├── runtime-registry.ts (500 tokens)
                  ├── start-toast.ts (1000 tokens)
                  ├── transport-capabilities.ts (700 tokens)
                  ├── transport-conflict.ts (2.3k tokens)
                  ├── transport-preference.ts (1500 tokens)
                  ├── types.ts (100 tokens)
                  ├── use-repo-download.ts (1500 tokens)
                  ├── use-staged-download.ts (1100 tokens)
                  ├── xet-progress-notice.ts (800 tokens)
               ├── hooks/
                  ├── hub-infinite-scroll-policy.ts (400 tokens)
                  ├── use-copy-feedback.ts (200 tokens)
                  ├── use-dataset-size.ts (300 tokens)
                  ├── use-discover-search.ts (1700 tokens)
                  ├── use-feed-write-back.ts (200 tokens)
                  ├── use-hidden-embedding-models.ts (300 tokens)
                  ├── use-hub-dataset-search.ts (2.5k tokens)
                  ├── use-hub-feed.ts (1600 tokens)
                  ├── use-hub-infinite-scroll.ts (1800 tokens)
                  ├── use-hub-model-search.ts (5.5k tokens)
                  ├── use-hub-model-vram.ts (300 tokens)
                  ├── use-hub-paginated-search.ts (2.8k tokens)
                  ├── use-latest-ref.ts (100 tokens)
                  ├── use-models-selection.ts (1900 tokens)
                  ├── use-online-status.ts (500 tokens)
                  ├── use-selected-model-metadata.ts (400 tokens)
                  ├── use-selected-model-view.ts (3.3k tokens)
               ├── hub-page.tsx (12k tokens)
               ├── hub.css (8.9k tokens)
               ├── index.ts (800 tokens)
               ├── inventory/
                  ├── api.ts (3.2k tokens)
                  ├── constants.ts (200 tokens)
                  ├── gguf-variants-cache-events.ts (300 tokens)
                  ├── index.ts (500 tokens)
                  ├── inventory-dedupe.ts (1500 tokens)
                  ├── inventory-freshness.ts (600 tokens)
                  ├── inventory-hint-store.ts (1600 tokens)
                  ├── inventory-hints.ts (1800 tokens)
                  ├── inventory-settlement.ts (200 tokens)
                  ├── inventory-timestamps.ts (100 tokens)
                  ├── resource-resolver.ts (800 tokens)
                  ├── types.ts (700 tokens)
                  ├── use-device-inventory.ts (2.7k tokens)
                  ├── use-gguf-variants-cache-version.ts (200 tokens)
                  ├── use-hub-inventory.ts (4.4k tokens)
                  ├── view-models.ts (2000 tokens)
               ├── lib/
                  ├── abort-signals.ts (600 tokens)
                  ├── adopt-inference-status.ts (800 tokens)
                  ├── avatar-theme.ts (100 tokens)
                  ├── card-accent.ts (500 tokens)
                  ├── channels.ts (500 tokens)
                  ├── dataset-size.ts (2k tokens)
                  ├── format-filters.ts (400 tokens)
                  ├── format.ts (800 tokens)
                  ├── gguf-filename.ts (200 tokens)
                  ├── gguf-variant-sort.ts (900 tokens)
                  ├── hf-cache.ts (700 tokens)
                  ├── hf-model-meta.ts (200 tokens)
                  ├── hf-owner-avatar.ts (1500 tokens)
                  ├── hf-readme.ts (1200 tokens)
                  ├── hidden-models.ts (900 tokens)
                  ├── hub-token-header.ts (100 tokens)
                  ├── inventory-search.ts (300 tokens)
                  ├── local-path.ts (200 tokens)
                  ├── lru-map.ts (400 tokens)
                  ├── merge-task-iterators.ts (600 tokens)
                  ├── model-capabilities.ts (1200 tokens)
                  ├── model-identifiers.ts (200 tokens)
                  ├── model-identity.ts (1700 tokens)
                  ├── model-run-selection.ts (900 tokens)
                  ├── model-type-filter.ts (300 tokens)
                  ├── network.ts (2.3k tokens)
                  ├── provider-logos.ts (1800 tokens)
                  ├── recent-searches.ts (600 tokens)
                  ├── resident-status-refresh.ts (300 tokens)
                  ├── scan-folder-status.ts (400 tokens)
                  ├── search-text.ts (200 tokens)
                  ├── selection-resolution.ts (2.7k tokens)
                  ├── superseded-refresh.ts (300 tokens)
                  ├── token-fingerprint.ts (100 tokens)
                  ├── unsloth-support.ts (1700 tokens)
                  ├── use-dominant-color.ts (600 tokens)
                  ├── view-models.ts (1500 tokens)
               ├── stores/
                  ├── external-link-confirm.ts (200 tokens)
                  ├── hf-token-store.ts (2.3k tokens)
                  ├── hub-feed-store.ts (900 tokens)
                  ├── inventory-events.ts (800 tokens)
                  ├── persist-storage.ts (200 tokens)
               ├── types.ts (500 tokens)
            ├── igpu-carveout/
               ├── api/
                  ├── igpu-carveout-notice.ts (200 tokens)
               ├── igpu-carveout-toast.ts (900 tokens)
               ├── index.ts (100 tokens)
               ├── types.ts (400 tokens)
            ├── images/
               ├── api.ts (6.6k tokens)
               ├── image-generation-defaults.ts (400 tokens)
               ├── image-size.ts (400 tokens)
               ├── images-page.tsx (38.3k tokens)
               ├── index.ts
               ├── lib/
                  ├── generation-stop.ts (300 tokens)
               ├── stores/
                  ├── image-workflow-store.ts (300 tokens)
               ├── train/
                  ├── dataset-files.ts (2.5k tokens)
                  ├── dataset-labeling-grid.tsx (2.4k tokens)
                  ├── dataset-showcase.tsx (1400 tokens)
                  ├── diffusion-charts.tsx (900 tokens)
                  ├── diffusion-train-deploy.ts (500 tokens)
                  ├── diffusion-train-family-facts.ts (200 tokens)
                  ├── diffusion-train-lr-schedule.ts (300 tokens)
                  ├── diffusion-train-panel.tsx (19k tokens)
                  ├── example-dataset-cards.tsx (1200 tokens)
                  ├── resume-diffusion-run.ts (600 tokens)
                  ├── train-base-selector.tsx (700 tokens)
               ├── workflows.ts (400 tokens)
            ├── loaded-models/
               ├── eject-chat-model.ts (1000 tokens)
               ├── index.ts (300 tokens)
               ├── loaded-models-api.ts (2.5k tokens)
               ├── loaded-models-indicator.tsx (3.1k tokens)
               ├── loaded-models-sources.ts (2.7k tokens)
               ├── show-loaded-models-pref.ts (700 tokens)
               ├── use-drag-position.ts (2.4k tokens)
               ├── use-loaded-models.ts (2.3k tokens)
            ├── model-picker/
               ├── api/
                  ├── llama-flags.ts (1900 tokens)
                  ├── memory-estimate.ts (2.5k tokens)
                  ├── migrate-model-overrides.ts (1000 tokens)
                  ├── model-metadata.ts (100 tokens)
                  ├── model-overrides.ts (4.8k tokens)
                  ├── templates.ts (600 tokens)
               ├── components/
                  ├── chat-template-editor-dialog.tsx (1200 tokens)
                  ├── memory-estimate-row.tsx (2.1k tokens)
                  ├── model-config-page.tsx (24.6k tokens)
                  ├── model-selector.tsx (6k tokens)
                  ├── model-selector/
                     ├── audio-picker-policy.ts (2.6k tokens)
                     ├── folder-browser.tsx (2.6k tokens)
                     ├── host-artifact-policy.ts (700 tokens)
                     ├── local-gguf-policy.ts (100 tokens)
                     ├── missing-external-model.ts (900 tokens)
                     ├── model-capabilities.ts (900 tokens)
                     ├── model-catalog.check.ts (9.1k tokens)
                     ├── model-catalog.ts (8.8k tokens)
                     ├── model-delete-action.tsx (500 tokens)
                     ├── model-load-settings-action.tsx (300 tokens)
                     ├── model-row-menu.tsx (1800 tokens)
                     ├── model-usage.ts (300 tokens)
                     ├── pickers.tsx (56.9k tokens)
                     ├── pill-tabs.tsx (800 tokens)
                     ├── pinned-models.ts (1400 tokens)
                     ├── recommended-fit.ts (2.8k tokens)
                     ├── row-identity.ts (500 tokens)
                     ├── row-meta.ts (800 tokens)
                     ├── sole-quant-cache.ts (1000 tokens)
                     ├── source-tabs.ts (100 tokens)
                     ├── types.ts (800 tokens)
                     ├── variant-listing-error.ts (300 tokens)
                     ├── variant-presentation.ts (1200 tokens)
                     ├── variant-visibility.ts (400 tokens)
                  ├── numeric-value-input.tsx (1500 tokens)
                  ├── sidebar-model-config.tsx (500 tokens)
               ├── hooks/
                  ├── use-active-model-config.ts (900 tokens)
                  ├── use-memory-estimate.ts (1200 tokens)
                  ├── use-model-defaults.ts (1100 tokens)
               ├── index.ts (500 tokens)
               ├── inventory/
                  ├── use-chat-picker-inventory.ts (1300 tokens)
               ├── model-config/
                  ├── apply-per-model-config.ts (1500 tokens)
                  ├── config-signature.ts (600 tokens)
                  ├── estimate-context.ts (700 tokens)
                  ├── llama-extra-args.ts (7.9k tokens)
                  ├── memory-fit.ts (4.2k tokens)
                  ├── model-config-handoff.ts (900 tokens)
                  ├── model-identity.ts (1300 tokens)
                  ├── per-model-config.ts (9.8k tokens)
                  ├── resident-memory-request.ts (600 tokens)
            ├── native-intents/
               ├── api.ts (600 tokens)
               ├── attachment-queue.ts (200 tokens)
               ├── attachment-target.ts (100 tokens)
               ├── components/
                  ├── native-model-chip.tsx (700 tokens)
                  ├── native-model-drop-overlay.tsx (700 tokens)
               ├── drop-paths.ts (1100 tokens)
               ├── index.ts (300 tokens)
               ├── native-attachment-file.ts (100 tokens)
               ├── native-drop-position.ts (300 tokens)
               ├── native-drop-targets.ts (700 tokens)
               ├── native-intent-drain.tsx (200 tokens)
               ├── store.ts (2.5k tokens)
               ├── types.ts (200 tokens)
               ├── use-native-drop-target.ts (200 tokens)
               ├── use-native-drop.ts (3.9k tokens)
               ├── use-native-file-drop.ts (1900 tokens)
               ├── use-native-readiness.ts (300 tokens)
            ├── profile/
               ├── api/
                  ├── profile-stats.ts (600 tokens)
               ├── components/
                  ├── profile-personalization-panel.tsx (3.3k tokens)
                  ├── stats/
                     ├── insights-card.tsx (1300 tokens)
                     ├── profile-stats-content.tsx (600 tokens)
                     ├── profile-stats-panel.tsx (100 tokens)
                     ├── stat-primitives.tsx (700 tokens)
                     ├── stats-highlights.tsx (400 tokens)
                     ├── stats-skeleton.tsx (200 tokens)
                     ├── token-activity-card.tsx (2.3k tokens)
                     ├── training-card.tsx (800 tokens)
                  ├── user-avatar.tsx (400 tokens)
               ├── hooks/
                  ├── use-effective-profile.ts (200 tokens)
                  ├── use-personalization-sync.ts (3k tokens)
                  ├── use-profile-stats.ts (400 tokens)
               ├── index.ts (100 tokens)
               ├── sloth-avatars.ts (300 tokens)
               ├── stores/
                  ├── user-profile-store.ts (300 tokens)
               ├── utils/
                  ├── avatar-initials.ts (200 tokens)
                  ├── jwt-subject.ts (100 tokens)
                  ├── resize-image-file.ts (800 tokens)
                  ├── stats-format.ts (2.7k tokens)
            ├── rag/
               ├── api/
                  ├── rag-api.ts (5.5k tokens)
                  ├── rag-availability.ts (1400 tokens)
                  ├── save-markdown-source.ts (1100 tokens)
               ├── components/
                  ├── document-preview-mount.tsx (200 tokens)
                  ├── document-preview-sheet.tsx (3k tokens)
                  ├── document-status-chip.tsx (500 tokens)
                  ├── knowledge-base-composer-button.tsx (1300 tokens)
                  ├── knowledge-base-dialog.tsx (2.9k tokens)
                  ├── linked-folders-manager.tsx (1900 tokens)
                  ├── preview-store.ts (200 tokens)
                  ├── project-source-dropzone.tsx (3.2k tokens)
                  ├── project-sources-panel.tsx (1500 tokens)
                  ├── retrieval-settings-section.tsx (1700 tokens)
                  ├── source-drop-policy.ts (200 tokens)
                  ├── staged-source.ts (600 tokens)
                  ├── thread-documents-bar.tsx (5.2k tokens)
                  ├── use-linked-folders.ts (2.8k tokens)
                  ├── use-rag-documents.ts (5.7k tokens)
                  ├── use-source-drop.ts (1100 tokens)
                  ├── vision-overrides.ts (400 tokens)
               ├── index.ts (200 tokens)
               ├── types/
                  ├── rag.ts (1000 tokens)
            ├── recipe-studio/
               ├── api/
                  ├── index.ts (2.9k tokens)
               ├── blocks/
                  ├── definitions.ts (2.4k tokens)
                  ├── registry.ts (100 tokens)
                  ├── render-dialog.tsx (1100 tokens)
               ├── components/
                  ├── block-sheet.tsx (5.1k tokens)
                  ├── chip-input.tsx (800 tokens)
                  ├── controls/
                     ├── layout-controls.tsx (400 tokens)
                     ├── run-validate-floating-controls.tsx (300 tokens)
                     ├── viewport-controls.tsx (600 tokens)
                  ├── executions/
                     ├── execution-columns-tab.tsx (400 tokens)
                     ├── execution-data-tab.tsx (2000 tokens)
                     ├── execution-overview-tab.tsx (2.5k tokens)
                     ├── execution-raw-tab.tsx (100 tokens)
                     ├── execution-sidebar.tsx (700 tokens)
                     ├── executions-view-helpers.ts (1100 tokens)
                     ├── executions-view.tsx (4.5k tokens)
                     ├── publish-execution-dialog.tsx (2.5k tokens)
                  ├── graph/
                     ├── internals-sync.tsx (200 tokens)
                  ├── inline/
                     ├── inline-category-badges.tsx (500 tokens)
                     ├── inline-expression.tsx (500 tokens)
                     ├── inline-field.tsx (100 tokens)
                     ├── inline-llm.tsx (1200 tokens)
                     ├── inline-model.tsx (1000 tokens)
                     ├── inline-policy.ts (200 tokens)
                     ├── inline-sampler.tsx (900 tokens)
                     ├── inline-seed.tsx (1000 tokens)
                  ├── recipe-floating-icon-button-class.ts (100 tokens)
                  ├── recipe-graph-aux-node.tsx (1800 tokens)
                  ├── recipe-graph-node.tsx (4.2k tokens)
                  ├── recipe-graph-semantic-edge.tsx (200 tokens)
                  ├── recipe-studio-header.tsx (1400 tokens)
                  ├── rf-ui/
                     ├── base-handle.tsx (200 tokens)
                     ├── base-node.tsx (400 tokens)
                     ├── data-edge.tsx (500 tokens)
                     ├── labeled-handle.tsx (200 tokens)
                  ├── runtime/
                     ├── execution-progress-island.tsx (1800 tokens)
                  ├── shared/
                     ├── available-references-inline.tsx (900 tokens)
                     ├── hf-dataset-combobox.tsx (700 tokens)
               ├── constants.ts (100 tokens)
               ├── data/
                  ├── executions-db.ts (200 tokens)
               ├── dialogs/
                  ├── config-dialog.tsx (900 tokens)
                  ├── expression/
                     ├── expression-dialog.tsx (700 tokens)
                  ├── import-dialog.tsx (500 tokens)
                  ├── llm/
                     ├── general-tab.tsx (3.6k tokens)
                     ├── llm-dialog.tsx (400 tokens)
                     ├── scores-tab.tsx (1200 tokens)
                  ├── markdown-note/
                     ├── markdown-note-dialog.tsx (500 tokens)
                  ├── models/
                     ├── local-recipe-model-selector.tsx (3.7k tokens)
                     ├── model-config-dialog.tsx (2.2k tokens)
                     ├── model-provider-dialog.tsx (1800 tokens)
                  ├── preview-dialog.tsx (4.7k tokens)
                  ├── processors-dialog.tsx (1000 tokens)
                  ├── samplers/
                     ├── bernoulli-dialog.tsx (300 tokens)
                     ├── category-dialog.tsx (2.2k tokens)
                     ├── datetime-dialog.tsx (600 tokens)
                     ├── gaussian-dialog.tsx (600 tokens)
                     ├── person-dialog.tsx (800 tokens)
                     ├── subcategory-dialog.tsx (1000 tokens)
                     ├── timedelta-dialog.tsx (800 tokens)
                     ├── uniform-dialog.tsx (600 tokens)
                     ├── uuid-dialog.tsx (300 tokens)
                  ├── seed/
                     ├── seed-dialog.tsx (9.9k tokens)
                     ├── unstructured-drop-zone.tsx (2.2k tokens)
                     ├── upload-limits.ts (100 tokens)
                  ├── shared/
                     ├── available-variables.tsx (700 tokens)
                     ├── collapsible-section-trigger.tsx (300 tokens)
                     ├── dialog-shell.tsx (100 tokens)
                     ├── field-label.tsx (300 tokens)
                     ├── name-field.tsx (200 tokens)
                     ├── validation-banner.tsx (100 tokens)
                  ├── tool-profile/
                     ├── helpers.ts (400 tokens)
                     ├── tool-profile-dialog.tsx (6.1k tokens)
                  ├── validators/
                     ├── validator-dialog.tsx (1800 tokens)
               ├── easy/
                  ├── github-crawler-easy-view.tsx (1700 tokens)
               ├── execution-types.ts (700 tokens)
               ├── executions/
                  ├── execution-helpers.ts (1000 tokens)
                  ├── hydration.ts (200 tokens)
                  ├── run-settings.ts (1100 tokens)
                  ├── runtime.ts (1000 tokens)
                  ├── tracker.ts (2.1k tokens)
               ├── hooks/
                  ├── use-node-connection-status.ts (300 tokens)
                  ├── use-recipe-editor-graph.ts (2.1k tokens)
                  ├── use-recipe-executions.ts (6.8k tokens)
                  ├── use-recipe-persistence.ts (2.3k tokens)
                  ├── use-recipe-runtime-visuals.ts (900 tokens)
                  ├── use-recipe-studio-actions.ts (1100 tokens)
               ├── index.ts (100 tokens)
               ├── recipe-studio-page.tsx (6.2k tokens)
               ├── stores/
                  ├── helpers/
                     ├── edge-sync.ts (1800 tokens)
                     ├── model-infra-layout.ts (2.9k tokens)
                     ├── node-updates.ts (500 tokens)
                     ├── reference-sync.ts (1200 tokens)
                     ├── removals.ts (500 tokens)
                  ├── recipe-executions.ts (900 tokens)
                  ├── recipe-studio-helpers.ts (100 tokens)
                  ├── recipe-studio.ts (5.2k tokens)
               ├── types/
                  ├── index.ts (2.4k tokens)
               ├── utils/
                  ├── config-factories.ts (2.4k tokens)
                  ├── config-labels.ts (200 tokens)
                  ├── config-type-guards.ts (300 tokens)
                  ├── graph-warnings.ts (1100 tokens)
                  ├── graph.ts
                  ├── graph/
                     ├── derive-display-graph.ts (3.4k tokens)
                     ├── fit-view.ts (400 tokens)
                     ├── recipe-graph-connection.ts (2.8k tokens)
                     ├── relations.ts (200 tokens)
                     ├── runtime-visual-state.ts (1400 tokens)
                  ├── handle-layout.ts (100 tokens)
                  ├── handles.ts (1500 tokens)
                  ├── image-preview.ts (1100 tokens)
                  ├── import/
                     ├── edges.ts (1100 tokens)
                     ├── helpers.ts (300 tokens)
                     ├── importer.ts (4k tokens)
                     ├── index.ts (100 tokens)
                     ├── parsers.ts (300 tokens)
                     ├── parsers/
                        ├── expression-parser.ts (200 tokens)
                        ├── llm-parser.ts (700 tokens)
                        ├── model-parser.ts (600 tokens)
                        ├── sampler-parser.ts (1900 tokens)
                        ├── seed-config-parser.ts (1800 tokens)
                        ├── validator-parser.ts (500 tokens)
                     ├── types.ts (100 tokens)
                     ├── ui.ts (800 tokens)
                  ├── index.ts (200 tokens)
                  ├── layout.ts (1100 tokens)
                  ├── model-provider-types.ts (100 tokens)
                  ├── naming.ts (100 tokens)
                  ├── node-data.ts (600 tokens)
                  ├── parse.ts (300 tokens)
                  ├── payload/
                     ├── build-payload.ts (3k tokens)
                     ├── builders-llm.ts (1600 tokens)
                     ├── builders-model.ts (800 tokens)
                     ├── builders-processors.ts (300 tokens)
                     ├── builders-sampler.ts (1400 tokens)
                     ├── builders-seed.ts (1400 tokens)
                     ├── builders-validator.ts (600 tokens)
                     ├── builders.ts (100 tokens)
                     ├── empty.ts (200 tokens)
                     ├── index.ts (100 tokens)
                     ├── parse.ts
                     ├── types.ts (700 tokens)
                     ├── validate.ts (1300 tokens)
                  ├── processors.ts (100 tokens)
                  ├── reactflow-changes.ts (200 tokens)
                  ├── recipe-studio-view.ts (300 tokens)
                  ├── refs.ts (500 tokens)
                  ├── rf-node-dimensions.ts (200 tokens)
                  ├── ui-tones.ts (500 tokens)
                  ├── validation.ts (2.8k tokens)
                  ├── validators/
                     ├── code-lang.ts (300 tokens)
                     ├── oxc-code-shape.ts (100 tokens)
                     ├── oxc-mode.ts (100 tokens)
                  ├── variables.ts (500 tokens)
            ├── security/
               ├── api/
                  ├── remote-code-api.ts (800 tokens)
               ├── components/
                  ├── remote-code-consent-dialog.tsx (2.2k tokens)
               ├── hooks/
                  ├── use-remote-code-consent.ts (600 tokens)
               ├── index.ts (100 tokens)
               ├── lib/
                  ├── severity-tone.ts (100 tokens)
               ├── stores/
                  ├── remote-code-consent-dialog-store.ts (200 tokens)
               ├── types.ts (400 tokens)
            ├── settings/
               ├── api/
                  ├── api-keys.ts (300 tokens)
                  ├── close-to-tray.ts (100 tokens)
                  ├── coding-agents.ts (400 tokens)
                  ├── current-date-prompt.ts (300 tokens)
                  ├── debug-logs.ts (700 tokens)
                  ├── download-transport.ts (1100 tokens)
                  ├── embedding-model.ts (1400 tokens)
                  ├── helper-precache.ts (500 tokens)
                  ├── hugging-face-cache.ts (500 tokens)
                  ├── keyless-api-access.ts (400 tokens)
                  ├── lan-access-state.ts (1600 tokens)
                  ├── lan-access.ts (300 tokens)
                  ├── launch-at-login.ts (100 tokens)
                  ├── llama-backend-payload.ts (1200 tokens)
                  ├── llama-backend.ts (400 tokens)
                  ├── llama-cpp-path.ts (400 tokens)
                  ├── microphone-permission.ts (200 tokens)
                  ├── model-memory.ts (1200 tokens)
                  ├── openai-auto-switch.ts (1600 tokens)
                  ├── openai-model-catalog.ts (200 tokens)
                  ├── openai-models.ts (100 tokens)
                  ├── personalization.ts (400 tokens)
                  ├── preview-sharing.ts (400 tokens)
                  ├── remote-access-state.ts (900 tokens)
                  ├── remote-access.ts (300 tokens)
                  ├── settings-route-absent.ts (200 tokens)
                  ├── upload-limit.ts (800 tokens)
                  ├── vram-budget.ts (2.3k tokens)
                  ├── xet-notice.ts (700 tokens)
               ├── components/
                  ├── agent-command.ts (1700 tokens)
                  ├── api-key-row.tsx (900 tokens)
                  ├── appearance-custom-controls.tsx (6k tokens)
                  ├── archived-chats-dialog.tsx (1700 tokens)
                  ├── archived-media-dialog.tsx (4.1k tokens)
                  ├── change-password-dialog.tsx (2.4k tokens)
                  ├── color-picker.tsx (2000 tokens)
                  ├── create-key-form.tsx (600 tokens)
                  ├── desktop-repair-control.tsx (700 tokens)
                  ├── desktop-update-control.tsx (700 tokens)
                  ├── dictation-dictionary-view.tsx (1000 tokens)
                  ├── documents-rag-section.tsx (3.2k tokens)
                  ├── download-transport-row.tsx (1300 tokens)
                  ├── embedding-model-picker.tsx (2k tokens)
                  ├── finetune-recipe.ts (800 tokens)
                  ├── key-reveal-card.tsx (500 tokens)
                  ├── keyless-api-access-section.tsx (1900 tokens)
                  ├── keyless-example-eligibility.ts (700 tokens)
                  ├── lan-access-section.tsx (3.3k tokens)
                  ├── language-select.tsx (600 tokens)
                  ├── llama-backend-section.tsx (2.6k tokens)
                  ├── manage-chats-view.tsx (2.9k tokens)
                  ├── model-auto-switch-section.tsx (2.5k tokens)
                  ├── model-memory-section.tsx (900 tokens)
                  ├── monitor-link.tsx (800 tokens)
                  ├── palette-cards.tsx (800 tokens)
                  ├── recent-dictations-view.tsx (4.1k tokens)
                  ├── remote-access-section.tsx (2.5k tokens)
                  ├── settings-row.tsx (700 tokens)
                  ├── settings-section.tsx (200 tokens)
                  ├── shortcut.tsx (200 tokens)
                  ├── sidebar-menu-customizer.tsx (1000 tokens)
                  ├── sidebar-nav-customizer.tsx (1100 tokens)
                  ├── stt-download-prompt.tsx (800 tokens)
                  ├── studio-version-section.tsx (800 tokens)
                  ├── theme-segmented.tsx (400 tokens)
                  ├── update-studio-instructions.tsx (2.8k tokens)
                  ├── uploaded-files-dialog.tsx (4.9k tokens)
                  ├── usage-examples.tsx (8.2k tokens)
               ├── desktop-app-version.ts (200 tokens)
               ├── hooks/
                  ├── use-desktop-boolean-setting.ts (300 tokens)
                  ├── use-llama-backend-switch.ts (1400 tokens)
                  ├── use-published-frame.ts (400 tokens)
                  ├── use-shortcut.ts (1800 tokens)
               ├── index.ts (500 tokens)
               ├── lib/
                  ├── agent-hub-model.ts (500 tokens)
                  ├── debug-log-buffer.ts (1600 tokens)
                  ├── debug-log-error.ts (200 tokens)
                  ├── keyboard-shortcuts.ts (4.4k tokens)
                  ├── llama-backend-labels.ts (200 tokens)
                  ├── stt-download-mirror.ts (1200 tokens)
                  ├── stt-download-trackers.ts (200 tokens)
               ├── settings-dialog-mount.tsx (100 tokens)
               ├── settings-dialog.tsx (4.9k tokens)
               ├── settings-search.ts (2.6k tokens)
               ├── stores/
                  ├── appearance-custom-store.ts (6.1k tokens)
                  ├── embedding-model-store.ts (1000 tokens)
                  ├── keyboard-shortcuts-store.ts (1700 tokens)
                  ├── monitor-frame-store.ts (500 tokens)
                  ├── monitor-overlay-store.ts (100 tokens)
                  ├── settings-dialog-store.ts (1200 tokens)
                  ├── settings-panel-prefs-store.ts (1100 tokens)
                  ├── stt-download-prompt-store.ts (300 tokens)
                  ├── stt-model-catalog.ts (700 tokens)
                  ├── theme-store.ts (1400 tokens)
                  ├── voice-settings-store.ts (4k tokens)
               ├── tabs/
                  ├── about-tab.tsx (2.2k tokens)
                  ├── agents-tab.tsx (12.6k tokens)
                  ├── api-keys-tab.tsx (1500 tokens)
                  ├── appearance-tab.tsx (1400 tokens)
                  ├── chat-tab.tsx (4.2k tokens)
                  ├── connections-tab.tsx (100 tokens)
                  ├── data-tab.tsx (7.4k tokens)
                  ├── debugging-tab.tsx (2.9k tokens)
                  ├── general-tab.tsx (5.9k tokens)
                  ├── keyboard-shortcuts-tab.tsx (2.8k tokens)
                  ├── profile-tab.tsx (200 tokens)
                  ├── remote-lan-tab.tsx (300 tokens)
                  ├── resources-tab.tsx (6.7k tokens)
                  ├── voice-tab.tsx (11.7k tokens)
            ├── studio/
               ├── download-state.ts (800 tokens)
               ├── historical-training-view.tsx (1500 tokens)
               ├── history-card-grid.tsx (5.3k tokens)
               ├── hooks/
                  ├── use-training-cache-reconciliation.ts (2.1k tokens)
                  ├── use-training-resource-display-names.ts (500 tokens)
               ├── live-training-view.tsx (1600 tokens)
               ├── preparation-progress.ts (1100 tokens)
               ├── sections/
                  ├── charts-content.tsx (1800 tokens)
                  ├── charts-section.tsx (400 tokens)
                  ├── charts/
                     ├── chart-preferences-store.ts (600 tokens)
                     ├── chart-settings-sheet.tsx (2.1k tokens)
                     ├── eval-loss-chart-card.tsx (1200 tokens)
                     ├── grad-norm-chart-card.tsx (800 tokens)
                     ├── learning-rate-chart-card.tsx (800 tokens)
                     ├── training-loss-chart-card.tsx (1200 tokens)
                     ├── types.ts (100 tokens)
                     ├── utils.ts (1100 tokens)
                  ├── dataset-advanced-settings-section.tsx (700 tokens)
                  ├── dataset-advanced-settings.tsx (2.1k tokens)
                  ├── dataset-panel-helpers.ts (500 tokens)
                  ├── dataset-preview-dialog-mapping-utils.ts (700 tokens)
                  ├── dataset-preview-dialog-mapping.tsx (1800 tokens)
                  ├── dataset-preview-dialog-utils.ts (400 tokens)
                  ├── dataset-preview-dialog.tsx (4.8k tokens)
                  ├── dataset-section.tsx (600 tokens)
                  ├── dataset-selection.tsx (2k tokens)
                  ├── dataset-source-toggle.tsx (500 tokens)
                  ├── dataset-upload.tsx (1400 tokens)
                  ├── document-upload-redirect-dialog.tsx (600 tokens)
                  ├── field-hint.tsx (200 tokens)
                  ├── lora-params-section.tsx (2.3k tokens)
                  ├── params-section-controls.tsx (500 tokens)
                  ├── params-section-styles.ts (100 tokens)
                  ├── params-section.tsx (3.8k tokens)
                  ├── progress-section-lib.ts (400 tokens)
                  ├── progress-section.tsx (5.2k tokens)
                  ├── run-config-override.ts (400 tokens)
                  ├── s3-config-form.tsx (900 tokens)
                  ├── training-hyperparameters-section.tsx (2.8k tokens)
                  ├── training-memory-params.tsx (1600 tokens)
                  ├── use-dataset-uploads.ts (2.8k tokens)
                  ├── use-local-dataset-inventory.ts (300 tokens)
                  ├── use-mlx-training-config-policy.ts (200 tokens)
               ├── studio-navigation.tsx (400 tokens)
               ├── studio-page.tsx (2.5k tokens)
               ├── tour/
                  ├── index.ts
                  ├── steps/
                     ├── base-model.tsx (100 tokens)
                     ├── dataset.tsx (200 tokens)
                     ├── index.tsx (100 tokens)
                     ├── method.tsx (100 tokens)
                     ├── nav.tsx (100 tokens)
                     ├── params.tsx (100 tokens)
                     ├── save.tsx (100 tokens)
                     ├── start.tsx (100 tokens)
                  ├── training/
                     ├── index.ts
                     ├── steps.tsx (400 tokens)
               ├── training-start-overlay.tsx (3.9k tokens)
               ├── use-studio-navigation.ts (1200 tokens)
               ├── wizard/
                  ├── advanced-settings-summary.ts (800 tokens)
                  ├── config-actions.tsx (1200 tokens)
                  ├── run-preview-card.tsx (3.2k tokens)
                  ├── start-training-cta-state.ts (200 tokens)
                  ├── start-training-cta.tsx (1100 tokens)
                  ├── training-config-file.ts (600 tokens)
                  ├── training-param-mode.ts (300 tokens)
                  ├── training-wizard.tsx (2k tokens)
            ├── tour/
               ├── components/
                  ├── guided-tour.tsx (3k tokens)
                  ├── read-more.tsx (100 tokens)
                  ├── spotlight-overlay.tsx (300 tokens)
               ├── hooks/
                  ├── use-guided-tour-controller.ts (400 tokens)
               ├── index.ts (100 tokens)
               ├── lib/
                  ├── confetti-fireworks.ts (700 tokens)
                  ├── dom.ts (100 tokens)
                  ├── layout.ts (400 tokens)
               ├── types.ts (100 tokens)
            ├── train-model-picker/
               ├── components/
                  ├── train-model-picker-lists.tsx (2000 tokens)
                  ├── train-model-picker-view-model.ts (1100 tokens)
                  ├── train-model-selector.tsx (4.9k tokens)
               ├── index.ts (100 tokens)
               ├── lib/
                  ├── train-model-selection-display.ts (600 tokens)
            ├── training/
               ├── api/
                  ├── datasets-api.ts (900 tokens)
                  ├── history-api.ts (700 tokens)
                  ├── mappers.ts (1500 tokens)
                  ├── models-api.ts (1000 tokens)
                  ├── train-api.ts (2.3k tokens)
               ├── components/
                  ├── hf-dataset-subset-split-selectors.tsx (4.1k tokens)
               ├── events.ts (300 tokens)
               ├── hooks/
                  ├── use-max-steps-epochs-toggle.ts (600 tokens)
                  ├── use-training-actions.ts (1200 tokens)
                  ├── use-training-completion-watch.ts (400 tokens)
                  ├── use-training-history-sidebar.ts (1100 tokens)
                  ├── use-training-readiness.ts (700 tokens)
                  ├── use-training-resource-notices.ts (800 tokens)
                  ├── use-training-runtime-lifecycle.ts (2.2k tokens)
                  ├── use-training-transformers-upgrade-notice.ts (900 tokens)
                  ├── use-training-unload-guard.ts (400 tokens)
               ├── index.ts (1000 tokens)
               ├── lib/
                  ├── cache-reference.ts (300 tokens)
                  ├── dataset-cache-rejection.ts (1200 tokens)
                  ├── dataset-recheck-budget.ts (400 tokens)
                  ├── dataset-selection.ts (300 tokens)
                  ├── dataset-split-policy.ts (100 tokens)
                  ├── freeform-model-validation.ts (500 tokens)
                  ├── fresh-dataset-check.ts (100 tokens)
                  ├── hf-dataset-option-selection.ts (200 tokens)
                  ├── local-cache-errors.ts (100 tokens)
                  ├── manual-dataset-options.ts (1100 tokens)
                  ├── model-defaults-edit-policy.ts (300 tokens)
                  ├── model-defaults.ts (1800 tokens)
                  ├── model-modality-inference.ts (400 tokens)
                  ├── model-selection.ts (100 tokens)
                  ├── model-support.ts (100 tokens)
                  ├── model-type-capabilities.ts (200 tokens)
                  ├── model-type-constraint.ts (200 tokens)
                  ├── model-type-inference.ts (300 tokens)
                  ├── native-dataset-drop.ts (500 tokens)
                  ├── resource-availability.ts (300 tokens)
                  ├── resume-remote-code-cache.ts (200 tokens)
                  ├── resume-training-run.ts (2.2k tokens)
                  ├── run-display.ts (200 tokens)
                  ├── start-fresh-training-run.ts (4.4k tokens)
                  ├── sync-runtime.ts (300 tokens)
                  ├── training-activity.ts (100 tokens)
                  ├── training-method-meta.ts (300 tokens)
                  ├── training-methods.ts (400 tokens)
                  ├── training-picker-lookups.ts (300 tokens)
                  ├── training-sse-stream.ts (1000 tokens)
                  ├── training-start-errors.ts (400 tokens)
                  ├── training-start-inputs.ts (200 tokens)
                  ├── training-start-reconciliation.ts (300 tokens)
                  ├── training-start-request-id.ts (300 tokens)
                  ├── training-start-runtime.ts (1300 tokens)
                  ├── training-status-request.ts (100 tokens)
                  ├── training-stop-scope.ts (100 tokens)
                  ├── training-stream-scope.ts (200 tokens)
                  ├── training-transformers-upgrade.ts (1900 tokens)
                  ├── training-ui-preferences.ts (100 tokens)
                  ├── training-upgrade-notice-cache.ts (600 tokens)
                  ├── validation.ts (1200 tokens)
                  ├── yaml-config.ts (800 tokens)
               ├── stores/
                  ├── dataset-preview-dialog-store.ts (200 tokens)
                  ├── training-config-persistence.ts (2.7k tokens)
                  ├── training-config-policy.ts (1100 tokens)
                  ├── training-config-store.ts (11.2k tokens)
                  ├── training-method-hardware-policy.ts (200 tokens)
                  ├── training-method-transition.ts (900 tokens)
                  ├── training-runtime-store.ts (4.2k tokens)
               ├── types/
                  ├── api.ts (700 tokens)
                  ├── config.ts (1700 tokens)
                  ├── datasets.ts (200 tokens)
                  ├── history.ts (300 tokens)
                  ├── runtime.ts (1100 tokens)
            ├── transformers-upgrade/
               ├── api/
                  ├── transformers-upgrade-api.ts (800 tokens)
               ├── components/
                  ├── transformers-upgrade-dialog.tsx (1500 tokens)
               ├── hooks/
                  ├── use-transformers-upgrade-consent.ts (300 tokens)
               ├── index.ts (100 tokens)
               ├── lib/
                  ├── upgrade-dialog-actions.ts (400 tokens)
               ├── stores/
                  ├── transformers-upgrade-dialog-store.ts (1300 tokens)
               ├── types.ts (400 tokens)
            ├── video/
               ├── api.ts (3.1k tokens)
               ├── index.ts
               ├── keyframe-canvas.ts (300 tokens)
               ├── reference-budget.ts (1100 tokens)
               ├── reference-image-crop.ts (1600 tokens)
               ├── reference-image-editor.tsx (2.8k tokens)
               ├── reference-picker.tsx (1400 tokens)
               ├── reference-trim.ts (700 tokens)
               ├── thumbnail-request-queue.ts (500 tokens)
               ├── video-page.tsx (36.1k tokens)
         ├── hooks/
            ├── backend-preflight-message.ts (500 tokens)
            ├── gpu-selection.ts (1100 tokens)
            ├── gpu-vram.ts (5.4k tokens)
            ├── hf-dataset-split-sources.ts (600 tokens)
            ├── index.ts (200 tokens)
            ├── server-stop-intent.ts (300 tokens)
            ├── system-discovery.ts (200 tokens)
            ├── tauri-repair-context.ts (300 tokens)
            ├── tauri-update-context.ts (100 tokens)
            ├── use-chat-settings-width.ts (200 tokens)
            ├── use-collapse-scroll-lock.ts (400 tokens)
            ├── use-composer-pill-fit.ts (1000 tokens)
            ├── use-debounced-value.ts (100 tokens)
            ├── use-gpu-info.ts (3.3k tokens)
            ├── use-gpu-utilization.ts (400 tokens)
            ├── use-hardware-info.ts (1400 tokens)
            ├── use-hf-dataset-splits.ts (1400 tokens)
            ├── use-hf-token-validation.ts (700 tokens)
            ├── use-host-class.ts (200 tokens)
            ├── use-llama-update-changelog.ts (1100 tokens)
            ├── use-llama-update-check.ts (3.3k tokens)
            ├── use-llama-update-pref.ts (300 tokens)
            ├── use-mobile.ts (300 tokens)
            ├── use-model-memory.ts (5.1k tokens)
            ├── use-panel-width.ts (900 tokens)
            ├── use-persisted-choice.ts (300 tokens)
            ├── use-persisted-toggle.ts (200 tokens)
            ├── use-release-notes.ts (1000 tokens)
            ├── use-scroll-fades.ts (300 tokens)
            ├── use-sidebar-pin.ts (300 tokens)
            ├── use-sidebar-width.ts (200 tokens)
            ├── use-system.ts (1500 tokens)
            ├── use-tauri-backend.ts (5.2k tokens)
            ├── use-tauri-update.ts (4.1k tokens)
            ├── use-vram-budget-fraction.ts (800 tokens)
            ├── use-web-update-check.ts (1200 tokens)
            ├── use-wheel-scroll-ref.ts (300 tokens)
         ├── i18n/
            ├── README.md (300 tokens)
            ├── check-parity.ts (1000 tokens)
            ├── index.ts (300 tokens)
            ├── locale-store.ts (3.9k tokens)
            ├── locales/
               ├── ar.ts (21.8k tokens)
               ├── de.ts (24.9k tokens)
               ├── en.ts (21.8k tokens)
               ├── es.ts (24.8k tokens)
               ├── fr.ts (25.5k tokens)
               ├── hi.ts (22.8k tokens)
               ├── it.ts (24.7k tokens)
               ├── ja.ts (17.8k tokens)
               ├── ko.ts (17.5k tokens)
               ├── pt-br.ts (24.1k tokens)
               ├── ru.ts (23.6k tokens)
               ├── zh-CN.ts (15.3k tokens)
            ├── messages.ts (1600 tokens)
            ├── relative-time.ts (300 tokens)
            ├── types.ts (200 tokens)
         ├── index.css (28.6k tokens)
         ├── lib/
            ├── api-base.ts (200 tokens)
            ├── audio-utils.ts (500 tokens)
            ├── blob-url-cache.ts (700 tokens)
            ├── bulb-icon.tsx (300 tokens)
            ├── chevron-icons.ts (200 tokens)
            ├── copy-to-clipboard.ts (800 tokens)
            ├── data-uri.ts (1400 tokens)
            ├── diffusion-gguf-filename.ts (200 tokens)
            ├── diffusion-gguf-pick.ts (600 tokens)
            ├── diffusion-route-pick.ts (400 tokens)
            ├── diffusion-route-search.ts (400 tokens)
            ├── escaped-inline-math.ts (2.8k tokens)
            ├── floating-panel-order.ts (600 tokens)
            ├── format-fastapi-error.ts (600 tokens)
            ├── gallery-flags.ts (2.3k tokens)
            ├── gguf-filename-pick.ts (500 tokens)
            ├── gguf-fit.ts (1500 tokens)
            ├── hugeicons-derived.ts (100 tokens)
            ├── latex.ts (4.7k tokens)
            ├── llama-job-events.ts (300 tokens)
            ├── llama-job-lifecycle.ts (700 tokens)
            ├── local-path.ts (100 tokens)
            ├── markdown-code-spans.ts (900 tokens)
            ├── markdown-data-images.ts (400 tokens)
            ├── markdown-inline-comments.ts (600 tokens)
            ├── markdown-list-columns.ts (2.9k tokens)
            ├── markdown-plugins.ts (400 tokens)
            ├── memory/
               ├── format.ts (600 tokens)
               ├── thresholds.ts (500 tokens)
               ├── verdict.ts (1000 tokens)
            ├── menu-dismiss-guard.tsx (100 tokens)
            ├── menu-dismiss.ts (1600 tokens)
            ├── mic-icon.tsx (200 tokens)
            ├── model-lifecycle-events.ts (1800 tokens)
            ├── model-memory.ts (4.2k tokens)
            ├── model-size.ts (200 tokens)
            ├── native-files.ts (1100 tokens)
            ├── native-notifications.ts (1300 tokens)
            ├── navigation-intents.ts
            ├── open-link.ts (200 tokens)
            ├── open-stream-response.ts (200 tokens)
            ├── overlay-scrollbar.ts (800 tokens)
            ├── release-body-links.ts (5.1k tokens)
            ├── release-notes-preview.ts (6.7k tokens)
            ├── resolved-precision.ts (2.6k tokens)
            ├── safe-markdown-url.ts (200 tokens)
            ├── schedule-idle-task.ts (300 tokens)
            ├── single-flight-request.ts (400 tokens)
            ├── sparkle-icon.ts (300 tokens)
            ├── sparkles-icon.tsx (400 tokens)
            ├── speculative-modes.ts (300 tokens)
            ├── sse-framing.ts (100 tokens)
            ├── sse-json-events.ts (500 tokens)
            ├── strip-ansi.ts (1400 tokens)
            ├── tauri-diagnostics.ts (1000 tokens)
            ├── tauri-updater.ts (600 tokens)
            ├── tick-icon.ts (100 tokens)
            ├── toast-offset.ts (200 tokens)
            ├── toast.ts (100 tokens)
            ├── transfer-stats.ts (1600 tokens)
            ├── utils.ts (200 tokens)
            ├── video-utils.ts (2.1k tokens)
            ├── vram.ts (700 tokens)
            ├── z-layers.ts (800 tokens)
         ├── main.tsx (500 tokens)
         ├── shared/
            ├── toast.ts (100 tokens)
         ├── speech-recognition.d.ts (omitted)
         ├── stores/
            ├── index.ts
         ├── types/
            ├── index.ts
            ├── training.ts (200 tokens)
         ├── utils/
            ├── index.ts
            ├── strings.ts (100 tokens)
      ├── tests/
         ├── action-menu-modal-layer.test.ts (700 tokens)
         ├── adopt-legacy-config-key.test.ts (1400 tokens)
         ├── advanced-settings-preference.test.ts (1400 tokens)
         ├── advanced-settings-summary.test.ts (600 tokens)
         ├── agent-command.test.ts (700 tokens)
         ├── agent-gguf-compatibility.test.ts (500 tokens)
         ├── agent-picker-state-space.test.ts (3.4k tokens)
         ├── agents-model-picker.test.ts (1100 tokens)
         ├── agents-reasoning-tip.test.ts (400 tokens)
         ├── anthropic-dated-model-ids-reach-the-picker.test.ts (400 tokens)
         ├── api-load-settings-refetch-sequencing.test.ts (500 tokens)
         ├── api-monitor-clear-failure.test.ts (500 tokens)
         ├── api-monitor-forget-model-override.test.ts (2.8k tokens)
         ├── api-monitor-new-traffic.test.ts (1200 tokens)
         ├── api-monitor-opt-out-rearm.test.ts (1100 tokens)
         ├── api-monitor-throughput.test.ts (400 tokens)
         ├── api-monitor-unload-resident.test.ts (900 tokens)
         ├── app-readiness.test.ts (700 tokens)
         ├── appearance-accent-vars.test.ts (1900 tokens)
         ├── archive-all-partial-failure.test.ts (500 tokens)
         ├── archived-thumbnail-budget.test.ts (500 tokens)
         ├── artifact-frame-network-access.test.ts (4.3k tokens)
         ├── artifact-source-key.test.ts (800 tokens)
         ├── assistant-ui-new-thread-contract.test.ts (800 tokens)
         ├── attachment-preview-text.test.ts (7k tokens)
         ├── attachment-source-cost.test.ts (1500 tokens)
         ├── audio-catalog-decodable.test.ts (600 tokens)
         ├── audio-community-pick-routing.test.ts (400 tokens)
         ├── audio-generation-stop.test.ts (1300 tokens)
         ├── audio-hidden-stt-seed.test.ts (300 tokens)
         ├── audio-mode-task-filter.test.ts (400 tokens)
         ├── audio-model-eject.test.ts (2.1k tokens)
         ├── audio-page-policy.test.ts (6.1k tokens)
         ├── audio-picker-policy.test.ts (4.5k tokens)
         ├── audio-recommended-mode-order.test.ts (800 tokens)
         ├── audio-stt-download-fallback.test.ts (700 tokens)
         ├── audio-stt-on-device.test.ts (600 tokens)
         ├── audio-task-picker-row-policy.test.ts (300 tokens)
         ├── audio-transcript-lifecycle.test.ts (400 tokens)
         ├── audio-tts-download-manager.test.ts (1300 tokens)
         ├── audio-utils.test.ts (200 tokens)
         ├── auth-bootstrap-deadline.test.ts (600 tokens)
         ├── auth-fetch-timezone.test.ts (300 tokens)
         ├── auto-compaction-settings.test.ts (1200 tokens)
         ├── auto-load-cpu-fallback-toast.test.ts (600 tokens)
         ├── auto-load-target-key.test.ts (500 tokens)
         ├── auto-load-validate-budget.test.ts (3.4k tokens)
         ├── auto-unload-api-only.test.ts (600 tokens)
         ├── backend-preflight-message.test.ts (800 tokens)
         ├── background-load-notice.test.ts (2.8k tokens)
         ├── batch-schema-version.test.ts (400 tokens)
         ├── batch-upgrade-downgrade-compat.test.ts (1600 tokens)
         ├── bundle-budget-cli.test.ts (1400 tokens)
         ├── bundle-budget-closure.test.ts (2.9k tokens)
         ├── bundler-resolver.mjs (200 tokens)
         ├── cancelled-turn-history-prune.test.ts (500 tokens)
         ├── chart-metric-formatting.test.ts (500 tokens)
         ├── chat-adapter-scan-cost.test.ts (4.9k tokens)
         ├── chat-autoscroll-frame-budget.test.ts (800 tokens)
         ├── chat-barrel-module-scope-reads.test.ts (20.2k tokens)
         ├── chat-continuation.test.ts (17.1k tokens)
         ├── chat-format-transfer.test.ts (400 tokens)
         ├── chat-generation-reconnect.test.ts (2.4k tokens)
         ├── chat-history-clear-boundary.test.ts (100 tokens)
         ├── chat-history-revision.test.ts (900 tokens)
         ├── chat-load-hub-token-reach.test.ts (400 tokens)
         ├── chat-local-model-options.test.ts (900 tokens)
         ├── chat-menus-nonmodal.test.ts (900 tokens)
         ├── chat-model-residency.test.ts (1400 tokens)
         ├── chat-navigation-store.test.ts (2.2k tokens)
         ├── chat-only-route-guard.test.ts (1100 tokens)
         ├── chat-remembers-its-model.test.ts (5.7k tokens)
         ├── chat-run-checkpoint-lifecycle.test.ts (6.6k tokens)
         ├── chat-run-checkpoint.test.ts (1200 tokens)
         ├── chat-runtime-reload-status.test.ts (2.1k tokens)
         ├── chat-sampling-seed.test.ts (3.3k tokens)
         ├── chat-save-conflict-detail.test.ts (1300 tokens)
         ├── chat-save-server-managed-stop.test.ts (1700 tokens)
         ├── chat-search-compact-list.test.ts (900 tokens)
         ├── chat-search-index-hint.test.ts (3k tokens)
         ├── chat-search-index-resolver.mjs (200 tokens)
         ├── chat-settings-hydration-shadows.test.ts (1100 tokens)
         ├── chat-speech-model-not-adopted.test.ts (1500 tokens)
         ├── chat-status-refresh-sequencing.test.ts (1300 tokens)
         ├── chat-stream-publish-gate.test.ts (5.3k tokens)
         ├── chat-template-status-seed.test.ts (1000 tokens)
         ├── chat-thread-tombstone-clears-owned.test.ts (700 tokens)
         ├── chat-title-clip.test.ts (2.1k tokens)
         ├── chat-transfer-hidden-tab.test.ts (500 tokens)
         ├── chat-user-turn-identity.test.ts (800 tokens)
         ├── chrome-icon-button-consistency.test.ts (600 tokens)
         ├── code-fence-defer.test.ts (5.7k tokens)
         ├── code-fence-mode.test.ts (900 tokens)
         ├── code-plugin-embedded-grammars.test.ts (2.4k tokens)
         ├── code-plugin-engine-and-cache.test.ts (2.4k tokens)
         ├── code-plugin-incremental.test.ts (4.9k tokens)
         ├── code-plugin-remount.test.ts (1100 tokens)
         ├── code-plugin-tokenization-work.test.ts (1600 tokens)
         ├── code-tool-placement.test.ts (1600 tokens)
         ├── codex-learned-capabilities-survive-sync.test.ts (400 tokens)
         ├── codex-models-endpoint-skew.test.ts (1200 tokens)
         ├── codex-picker-catalog-fallback.test.ts (1900 tokens)
         ├── codex-reasoning.test.ts (200 tokens)
         ├── codex-retired-model-sync-fallback.test.ts (400 tokens)
         ├── codex-tool-card-reconciliation.test.ts (200 tokens)
         ├── compare-pane-thread-shapes.test.ts (2.1k tokens)
         ├── composer-icon-alignment.test.ts (400 tokens)
         ├── composer-keystroke-subscription-budget.test.ts (1100 tokens)
         ├── composer-paste-draft.test.ts (600 tokens)
         ├── composer-pill-fit.test.ts (700 tokens)
         ├── composer-send-guard.test.ts (2.3k tokens)
         ├── connections-empty-opens-form.test.ts (500 tokens)
         ├── context-menu-item-radius.test.ts (200 tokens)
         ├── context-mode-ux.test.ts (400 tokens)
         ├── context-pin-survives-load.test.ts (4.4k tokens)
         ├── context-refusal-shared-floor.test.ts (2.2k tokens)
         ├── context-window-visible.test.ts (1200 tokens)
         ├── conversation-markdown-export.test.ts (1000 tokens)
         ├── conversation-markdown.test.ts (5.8k tokens)
         ├── copy-to-clipboard.test.ts (1800 tokens)
         ├── cpt-target-modules.test.ts (600 tokens)
         ├── credential-persistence.test.ts (6k tokens)
         ├── crypto-uuid-boot.test.ts (600 tokens)
         ├── current-date-context-usage.test.ts (500 tokens)
         ├── current-date-settings-accessibility.test.ts (100 tokens)
         ├── current-date-settings-errors.test.ts (300 tokens)
         ├── data-uri.test.ts (1700 tokens)
         ├── dataset-data-recipes-navigation.test.ts (1100 tokens)
         ├── dataset-display-name.test.ts (200 tokens)
         ├── dataset-file-selection.test.ts (4.1k tokens)
         ├── dataset-selection.test.ts (600 tokens)
         ├── debug-log-buffer.test.ts (2000 tokens)
         ├── debug-log-source-gone.test.ts (400 tokens)
         ├── deep-research-handoff.test.ts (1000 tokens)
         ├── delete-chat-files-preference.test.ts (1100 tokens)
         ├── delete-thread-message-cost.test.ts (1800 tokens)
         ├── delete-thread-message.test.ts (2.1k tokens)
         ├── dense-transformer-build-label.test.ts (1100 tokens)
         ├── desktop-app-version.test.ts (100 tokens)
         ├── desktop-closing-overlay.test.ts (1500 tokens)
         ├── desktop-stop-intent.test.ts (2000 tokens)
         ├── dictation-outcome.test.ts (400 tokens)
         ├── dictation-send.test.ts (1000 tokens)
         ├── diffusion-gguf-pick.test.ts (1200 tokens)
         ├── diffusion-gpu-choices.test.ts (800 tokens)
         ├── diffusion-route-model-scope.test.ts (800 tokens)
         ├── diffusion-route-search.test.ts (700 tokens)
         ├── diffusion-train-batch-cap.test.ts (400 tokens)
         ├── diffusion-train-deploy.test.ts (900 tokens)
         ├── diffusion-train-family-facts.test.ts (300 tokens)
         ├── diffusion-train-warmup-preset.test.ts (1300 tokens)
         ├── download-adopt-and-hydrate.test.ts (1500 tokens)
         ├── download-eta-invalidation.test.ts (600 tokens)
         ├── download-eta-persist-compat.test.ts (800 tokens)
         ├── download-generation-pending.test.ts (700 tokens)
         ├── download-generation-rate-reset.test.ts (600 tokens)
         ├── download-held-transfer-persistence.test.ts (700 tokens)
         ├── download-inventory-kind.test.ts (1100 tokens)
         ├── download-legacy-measured-migration.test.ts (500 tokens)
         ├── download-panel-not-permanent.test.ts (1700 tokens)
         ├── download-progress-indeterminate.test.ts (300 tokens)
         ├── download-progress-reconcile.test.ts (2.8k tokens)
         ├── download-rate-not-restored.test.ts (400 tokens)
         ├── download-scoped-delete-hint.test.ts (500 tokens)
         ├── download-scoped-kind-upgrade.test.ts (700 tokens)
         ├── download-session-boundary.test.ts (500 tokens)
         ├── download-start-lifecycle.test.ts (1300 tokens)
         ├── download-start-toast.test.ts (1300 tokens)
         ├── download-stop-mode.test.ts (600 tokens)
         ├── download-transport-after-start.test.ts (1400 tokens)
         ├── download-transport-persistence.test.ts (1100 tokens)
         ├── download-transport-probe-freshness.test.ts (700 tokens)
         ├── download-transport-setting.test.ts (2.6k tokens)
         ├── drag-costs-no-render.test.ts (700 tokens)
         ├── edit-message-keeps-metadata.test.ts (1400 tokens)
         ├── edit-reply-keeps-tool-order.test.ts (2.8k tokens)
         ├── edited-first-message-branches.test.ts (1500 tokens)
         ├── embedding-model-picker.test.ts (2.5k tokens)
         ├── embedding-model-store.test.ts (2.2k tokens)
         ├── escaped-inline-math.test.ts (1900 tokens)
         ├── export-gguf-shard-size.test.ts (600 tokens)
         ├── export-gguf-token-fallback.test.ts (700 tokens)
         ├── export-progress-percent.test.ts (700 tokens)
         ├── external-job-hidden-tab.test.ts (600 tokens)
         ├── external-model-selection-label.test.ts (3.4k tokens)
         ├── external-sampling-payload.test.ts (1000 tokens)
         ├── find-in-page.test.ts (25.6k tokens)
         ├── floating-panel-order.test.ts (600 tokens)
         ├── forced-repair-retry.test.ts (900 tokens)
         ├── fork-count-batching.test.ts (3.2k tokens)
         ├── format-fastapi-error.test.ts (700 tokens)
         ├── fresh-dataset-check.test.ts (200 tokens)
         ├── gallery-flags.test.ts (4.1k tokens)
         ├── gallery-item-menu-visibility.test.ts (300 tokens)
         ├── generation-length-cap-attribution.test.ts (900 tokens)
         ├── generation-length-toast-advice.test.ts (500 tokens)
         ├── generation-recovery-import-call-site.test.ts (700 tokens)
         ├── generation-recovery-invariants.test.ts (2000 tokens)
         ├── generation-recovery-keeps-tool-cards.test.ts (1900 tokens)
         ├── generation-recovery-monotonic.test.ts (1200 tokens)
         ├── generation-recovery-own-run.test.ts (1200 tokens)
         ├── generation-tool-recovery.test.ts (8k tokens)
         ├── gguf-filename-pick.test.ts (500 tokens)
         ├── gguf-live-remaining-label.test.ts (1600 tokens)
         ├── gguf-variant-transfer-size.test.ts (600 tokens)
         ├── gguf-variants-cache-version.test.ts (400 tokens)
         ├── gguf-variants-request-bounds.test.ts (800 tokens)
         ├── gpu-load-device.test.ts (400 tokens)
         ├── gpu-memory-aggregate.test.ts (400 tokens)
         ├── gpu-placement.test.ts (1500 tokens)
         ├── gpu-selection.test.ts (700 tokens)
         ├── gpu-torch-mismatch.test.ts (3.3k tokens)
         ├── gpu-vram-split.test.ts (700 tokens)
         ├── hardware-verdict-recovery.test.ts (1500 tokens)
         ├── helpers/
            ├── auth-stub.mjs (100 tokens)
            ├── clipboard-resolver.mjs (400 tokens)
            ├── delete-thread-message-resolver.mjs (300 tokens)
            ├── delete-thread-message-stub.mjs (200 tokens)
            ├── download-lifecycle-auth-stub.mjs (100 tokens)
            ├── download-lifecycle-resolver.mjs (200 tokens)
            ├── download-lifecycle-settings-stub.mjs (100 tokens)
            ├── export-api-stub.d.mts (200 tokens)
            ├── export-api-stub.mjs (300 tokens)
            ├── export-store-resolver.mjs (300 tokens)
            ├── hub-inventory-stub.mjs (100 tokens)
            ├── hub-stub-resolver.mjs (100 tokens)
            ├── igpu-carveout-resolver.mjs (400 tokens)
            ├── kit.ts (1300 tokens)
            ├── memory-estimate-resolver.mjs (100 tokens)
            ├── mock-timer-drain.ts (2.7k tokens)
            ├── module-stubs.ts (600 tokens)
            ├── native-path-stub.ts (200 tokens)
            ├── notification-resolver.mjs (400 tokens)
            ├── settings-api-resolver.mjs (300 tokens)
            ├── store-stubs/
               ├── auth.ts (200 tokens)
               ├── chat-history-storage.ts (400 tokens)
               ├── chat-search-auth.ts (200 tokens)
               ├── chat-search-history.ts (300 tokens)
               ├── download-manager.ts (200 tokens)
               ├── env.ts (100 tokens)
               ├── hub.ts (100 tokens)
               ├── model-picker.ts (100 tokens)
               ├── settings-http.ts (1000 tokens)
               ├── sidebar-items-deps.ts (600 tokens)
               ├── toast.ts (200 tokens)
            ├── tauri-clipboard-stub.mjs (200 tokens)
            ├── tauri-core-resolver.mjs (400 tokens)
            ├── tauri-core-stub.mjs (100 tokens)
            ├── tauri-notification-stub.mjs (300 tokens)
            ├── tauri-window-resolver.mjs (300 tokens)
            ├── tauri-window-stub.mjs (100 tokens)
            ├── thread-sampling-world.ts (2.9k tokens)
            ├── toast-resolver.mjs (300 tokens)
            ├── toast-stub.d.mts (200 tokens)
            ├── toast-stub.mjs (200 tokens)
            ├── transformers-upgrade-resolver.mjs (300 tokens)
            ├── transformers-upgrade-stub.d.mts (400 tokens)
            ├── transformers-upgrade-stub.mjs (400 tokens)
            ├── tsx-ast.ts (100 tokens)
            ├── vite-env-loader.mjs (200 tokens)
         ├── hf-dataset-option-selection.test.ts (300 tokens)
         ├── hf-dataset-split-sources.test.ts (500 tokens)
         ├── hf-token-inventory-invalidation.test.ts (200 tokens)
         ├── hf-token-preparation-bursts.test.ts (1800 tokens)
         ├── host-artifact-policy.test.ts (800 tokens)
         ├── hosted-image-tool-with-studio-tools.test.ts (500 tokens)
         ├── hub-download-rate.test.ts (2.4k tokens)
         ├── hub-failure-panel-coverage.test.ts (400 tokens)
         ├── hub-format.test.ts (400 tokens)
         ├── hub-infinite-scroll-policy.test.ts (700 tokens)
         ├── hub-inventory-hermes-source.test.ts (500 tokens)
         ├── hub-inventory-recent-sort.test.ts (2.4k tokens)
         ├── hub-local-gguf-selection.test.ts (800 tokens)
         ├── hub-media-run-gate.test.ts (600 tokens)
         ├── hub-model-run-selection.test.ts (2.5k tokens)
         ├── hub-network-availability.test.ts (2.4k tokens)
         ├── hub-progress-token-boundary.test.ts (900 tokens)
         ├── hub-provider-logo-muse-glimmer.test.ts (400 tokens)
         ├── hub-provider-logo-owner.test.ts (500 tokens)
         ├── hub-recovery-paths.test.ts (2.4k tokens)
         ├── hub-resident-status.test.ts (2.1k tokens)
         ├── hub-resource-id.test.ts (300 tokens)
         ├── hub-runtime-boundary.test.ts (2.4k tokens)
         ├── hub-selection-compat.test.ts (2.9k tokens)
         ├── hub-selection-resolution.test.ts (4.7k tokens)
         ├── hub-shared-memory-display.test.ts (200 tokens)
         ├── hub-superseded-refresh.test.ts (1100 tokens)
         ├── hydration-clears-stale-local-record.test.ts (1500 tokens)
         ├── igpu-carveout-advice.test.ts (500 tokens)
         ├── igpu-carveout-toast.test.ts (1600 tokens)
         ├── image-generation-defaults.test.ts (700 tokens)
         ├── image-generation-stop.test.ts (600 tokens)
         ├── image-restore-settings-size.test.ts (1600 tokens)
         ├── image-sentinel-tools.test.ts (400 tokens)
         ├── incognito-tagging-invariants.test.ts (600 tokens)
         ├── incremental-assistant-content.test.ts (1800 tokens)
         ├── inventory-freshness.test.ts (1000 tokens)
         ├── inventory-settlement.test.ts (400 tokens)
         ├── json-record-stream.test.ts (3.4k tokens)
         ├── keyboard-shortcuts.test.ts (15.1k tokens)
         ├── keyless-example-base-eligibility.test.ts (900 tokens)
         ├── lan-access-state.test.ts (2.9k tokens)
         ├── last-local-model-load.test.ts (1400 tokens)
         ├── latex-code-regions.test.ts (1200 tokens)
         ├── latex-list-render.test.ts (1400 tokens)
         ├── lazy-locale-loading.test.ts (6k tokens)
         ├── legacy-chat-store-timeout.test.ts (1000 tokens)
         ├── legacy-load-settings-migration.test.ts (1500 tokens)
         ├── link-definition-oracle.test.ts (1800 tokens)
         ├── linked-folders-contract.test.ts (400 tokens)
         ├── linked-folders-lease-gate.test.ts (900 tokens)
         ├── llama-backend-payload.test.ts (1700 tokens)
         ├── llama-extra-args-diagnostics.test.ts (11.5k tokens)
         ├── llama-extra-args-normalize.test.ts (800 tokens)
         ├── llama-extra-args-override-lookup.test.ts (2.3k tokens)
         ├── llama-extra-args-panel-hydration.test.ts (2.8k tokens)
         ├── llama-extra-args-status-hydration.test.ts (700 tokens)
         ├── llama-extra-args.test.ts (1900 tokens)
         ├── llama-job-events.test.ts (400 tokens)
         ├── llama-job-lifecycle.test.ts (1200 tokens)
         ├── loaded-build-panel-rows.test.ts (400 tokens)
         ├── loaded-models-backcompat.test.ts (1700 tokens)
         ├── loaded-models-barrel-order.test.ts (600 tokens)
         ├── loaded-models-dismiss.test.ts (1400 tokens)
         ├── loaded-models-drag-restore.test.ts (1800 tokens)
         ├── loaded-models-drag.test.ts (500 tokens)
         ├── loaded-models-eject-chat.test.ts (2000 tokens)
         ├── loaded-models-eject-unverified.test.ts (600 tokens)
         ├── loaded-models-pending-reset.test.ts (1400 tokens)
         ├── loaded-models-platform-matrix.test.ts (2.8k tokens)
         ├── loaded-models-q8-precision-repro.test.ts (200 tokens)
         ├── loaded-models-settled-retire.test.ts (500 tokens)
         ├── loaded-models-sources.test.ts (3.5k tokens)
         ├── loaded-models-surface.test.ts (800 tokens)
         ├── local-cache-errors.test.ts (200 tokens)
         ├── local-path.test.ts (200 tokens)
         ├── local-reasoning-replay.test.ts (400 tokens)
         ├── locale-catalog-retry.test.ts (800 tokens)
         ├── mac-titlebar-optical-alignment.test.ts (300 tokens)
         ├── manage-chats-bulk-selection.test.ts (900 tokens)
         ├── manage-chats-open-project.test.ts (300 tokens)
         ├── manual-dataset-options.test.ts (1300 tokens)
         ├── markdown-block-boundary.test.ts (3.8k tokens)
         ├── markdown-block-remount-on-complete.test.ts (700 tokens)
         ├── markdown-data-images.test.ts (400 tokens)
         ├── markdown-image-recovery.test.ts (600 tokens)
         ├── markdown-sandbox-image.test.ts (2000 tokens)
         ├── markdown-streaming-scheduling.test.ts (1200 tokens)
         ├── math-block-containment-wiring.test.ts (3.1k tokens)
         ├── math-block-marker-pipeline.test.ts (1700 tokens)
         ├── math-block-marker.test.ts (3.1k tokens)
         ├── math-block-mode.test.ts (1300 tokens)
         ├── math-block-override-reapply.test.ts (700 tokens)
         ├── mcp-server-arguments.test.ts (5.4k tokens)
         ├── mcp-tool-name.test.ts (500 tokens)
         ├── media-auto-switch-setting.test.ts (800 tokens)
         ├── media-eject-busy-state.test.ts (600 tokens)
         ├── media-generation-preset-claims.test.ts (1500 tokens)
         ├── media-generation-preset-policy.test.ts (400 tokens)
         ├── media-idle-unload-api-only.test.ts (400 tokens)
         ├── media-idle-unload-setting.test.ts (800 tokens)
         ├── media-load-cancel.test.ts (3.5k tokens)
         ├── media-status-sequencing.test.ts (400 tokens)
         ├── memory-cross-surface-matrix.test.ts (2.1k tokens)
         ├── memory-estimate-capacity.test.ts (3.1k tokens)
         ├── memory-estimate-context.test.ts (1100 tokens)
         ├── memory-estimate-free-vram.test.ts (3k tokens)
         ├── memory-estimate-identity.test.ts (1300 tokens)
         ├── memory-estimate-narrow-panel.test.ts (1300 tokens)
         ├── memory-estimate-skew.test.ts (3k tokens)
         ├── memory-estimate-standing-defaults.test.ts (700 tokens)
         ├── memory-fit.test.ts (5.1k tokens)
         ├── memory-probe-known.test.ts (600 tokens)
         ├── memory-shared-core.test.ts (3.6k tokens)
         ├── memory-unified-apu.test.ts (4.8k tokens)
         ├── merge-task-iterators.test.ts (600 tokens)
         ├── message-jsonl-import.test.ts (700 tokens)
         ├── microphone-permission-reset.test.ts (1200 tokens)
         ├── mirrored-chat-settings.test.ts (1100 tokens)
         ├── mirrored-settings-write-authority.test.ts (1100 tokens)
         ├── mlx-community-repo-detection.test.ts (500 tokens)
         ├── mlx-context-helpers.test.ts (2.6k tokens)
         ├── mlx-context-pin-record-compat.test.ts (3.3k tokens)
         ├── mmproj-fallback.test.ts (1500 tokens)
         ├── model-catalog-network-budget.test.ts (500 tokens)
         ├── model-config-handoff.test.ts (1500 tokens)
         ├── model-config-instance-key.test.ts (900 tokens)
         ├── model-config-popover-scroller.test.ts (500 tokens)
         ├── model-config-run-selection.test.ts (1200 tokens)
         ├── model-disclaimer-preference.test.ts (1100 tokens)
         ├── model-identity.test.ts (3.3k tokens)
         ├── model-lifecycle-gate.test.ts (100 tokens)
         ├── model-load-native-notifications.test.ts (2.6k tokens)
         ├── model-memory-arg-alias-parity.test.ts (1300 tokens)
         ├── model-memory-cache-policy.test.ts (1300 tokens)
         ├── model-memory-cache.test.ts (2.3k tokens)
         ├── model-memory-hardware-matrix.test.ts (1600 tokens)
         ├── model-memory-opt-in.test.ts (1200 tokens)
         ├── model-memory-round5.test.ts (1600 tokens)
         ├── model-memory.test.ts (1500 tokens)
         ├── model-modality-inference.test.ts (300 tokens)
         ├── model-picker-partial-downloads.test.ts (5k tokens)
         ├── model-picker-variant-presentation.test.ts (1400 tokens)
         ├── model-row-owner.test.ts (200 tokens)
         ├── model-selector-trigger-label.test.ts (700 tokens)
         ├── model-type-constraint.test.ts (400 tokens)
         ├── model-type-inference.test.ts (200 tokens)
         ├── module-scope-cycle-safety.test.ts (1500 tokens)
         ├── monitor-frame-ownership.test.ts (1600 tokens)
         ├── more-menu-separator-gap.test.ts (300 tokens)
         ├── native-drop-paths.test.ts (18.7k tokens)
         ├── native-drop-target-readiness.test.ts (500 tokens)
         ├── native-drop-targets.test.ts (1400 tokens)
         ├── native-dropzone-coverage.test.ts (1200 tokens)
         ├── native-training-dataset-drop.test.ts (1400 tokens)
         ├── ndjson-body.test.ts (800 tokens)
         ├── nonmodal-menu-dismiss-guard.test.ts (1100 tokens)
         ├── nonmodal-menu-second-pointer.test.ts (3.4k tokens)
         ├── on-device-dot-and-header-alignment.test.ts (6.1k tokens)
         ├── openai-codex-connect.test.ts (800 tokens)
         ├── openai-model-catalog.test.ts (300 tokens)
         ├── openapi-support.test.ts (500 tokens)
         ├── openwebui-import.test.ts (7.7k tokens)
         ├── overlay-rail-floor-gating.test.ts (2.4k tokens)
         ├── overlay-scrollbar-gutter.test.ts (1800 tokens)
         ├── overlay-shadow-gutter.test.ts (600 tokens)
         ├── padded-response.test.ts (600 tokens)
         ├── panel-placement.test.ts (1800 tokens)
         ├── parallel-tool-call-arguments.test.ts (11.4k tokens)
         ├── partial-download-affordance.test.ts (500 tokens)
         ├── pasted-text-attachment.test.ts (5.6k tokens)
         ├── pcm-recorder.test.ts (2.6k tokens)
         ├── per-model-params-hydration-max-seq-length.test.ts (400 tokens)
         ├── per-model-params-hydration-races.test.ts (1600 tokens)
         ├── per-model-params-hydration.test.ts (6.8k tokens)
         ├── per-model-params.test.ts (2.8k tokens)
         ├── per-model-spec-disable-aliases.test.ts (400 tokens)
         ├── personalization-locale-hydration.test.ts (1900 tokens)
         ├── picker-tab-policy.test.ts (800 tokens)
         ├── pinned-models-reorder.test.ts (4.5k tokens)
         ├── pr9057-video-simulation.test.ts (3k tokens)
         ├── pre-stream-run-reservation.test.ts (1000 tokens)
         ├── preserve-thinking-default.test.ts (200 tokens)
         ├── preserve-thinking-pre-hydration-toggle.test.ts (400 tokens)
         ├── preserve-thinking-user-preference.test.ts (1000 tokens)
         ├── profile-api-usage-stats.test.ts (300 tokens)
         ├── profile-stats-format.test.ts (2.6k tokens)
         ├── profile-stats-refresh.test.ts (700 tokens)
         ├── progressive-mount-controller.test.ts (3k tokens)
         ├── progressive-mount-glue.test.ts (4.6k tokens)
         ├── project-attachment-simulations.test.ts (2.2k tokens)
         ├── project-attachment-target-adoption.test.ts (2k tokens)
         ├── project-chat-run-keepalive.test.ts (4k tokens)
         ├── project-source-filename.test.ts (900 tokens)
         ├── project-source-plan.test.ts (900 tokens)
         ├── project-source-reply-destination.test.ts (700 tokens)
         ├── project-source-reply-markdown.test.ts (700 tokens)
         ├── project-source-save.test.ts (2k tokens)
         ├── prompt-list-reorder.test.ts (1400 tokens)
         ├── prompt-queue-input-edges.test.ts (2.1k tokens)
         ├── prompt-queue-input.test.ts (1200 tokens)
         ├── prompt-queue-model-boundary.test.ts (700 tokens)
         ├── prompt-queue-reorder-sweep.test.ts (1500 tokens)
         ├── prompt-queue-reorder.test.ts (600 tokens)
         ├── prompt-queue-user-stop.test.ts (500 tokens)
         ├── prompt-storage-mutation-lock.test.ts (3.2k tokens)
         ├── provider-capabilities-current-models.test.ts (3.1k tokens)
         ├── provider-capability-rollback.test.ts (600 tokens)
         ├── provider-logo-path.test.ts (400 tokens)
         ├── provider-max-output-tokens-guards.test.ts (2.6k tokens)
         ├── provider-max-output-tokens.test.ts (1000 tokens)
         ├── provider-studio-tools-capability.test.ts (500 tokens)
         ├── provisional-hardware-verdict.test.ts (4.4k tokens)
         ├── python-tool-image-path.test.ts (200 tokens)
         ├── queued-model-capabilities.test.ts (600 tokens)
         ├── queued-settings-epoch.test.ts (200 tokens)
         ├── quick-tunnel-streaming-methods.test.ts (1000 tokens)
         ├── qwen-defaults-migration-hydration.test.ts (6.1k tokens)
         ├── qwen-defaults-migration-safety.test.ts (7k tokens)
         ├── qwen-defaults-migration.test.ts (3k tokens)
         ├── qwen-migration-external-restore.test.ts (400 tokens)
         ├── qwen-migration-interactive-pick.test.ts (400 tokens)
         ├── qwen-thinking-size-gate.test.ts (800 tokens)
         ├── qwen38-sampling-defaults.test.ts (400 tokens)
         ├── rag-availability-marker.test.ts (3k tokens)
         ├── rag-job-status.test.ts (100 tokens)
         ├── rag-refresh-sequencing.test.ts (6.8k tokens)
         ├── rag-scope-context-length.test.ts (1000 tokens)
         ├── rag-source-drop-filter.test.ts (500 tokens)
         ├── rag-upload-lifecycle.test.ts (1800 tokens)
         ├── read-aloud-tts-model-row.test.ts (600 tokens)
         ├── reasoning-collapse-preference.test.ts (1100 tokens)
         ├── reasoning-document-pagination.test.ts (700 tokens)
         ├── reasoning-duration.test.ts (1300 tokens)
         ├── reasoning-grid-collapse.test.ts (2.1k tokens)
         ├── reasoning-pagination.test.ts (1200 tokens)
         ├── reasoning-selection-pagination.test.ts (200 tokens)
         ├── reasoning-source-render.test.ts (900 tokens)
         ├── recipe-selector-source-label.test.ts (500 tokens)
         ├── recipe-studio-sampler-round-trip.test.ts (700 tokens)
         ├── recommended-catalog-seeds.test.ts (3.5k tokens)
         ├── recommended-curated-row-metadata.test.ts (2.9k tokens)
         ├── recorded-sandbox-session.test.ts (1500 tokens)
         ├── relative-time.test.ts (600 tokens)
         ├── reload-snapshot.test.ts (11.8k tokens)
         ├── remend-complete-markdown.test.ts (2.8k tokens)
         ├── remote-access-state.test.ts (2.2k tokens)
         ├── research-activity-follow-loop.test.ts (600 tokens)
         ├── research-activity-progress.test.ts (3.3k tokens)
         ├── research-activity-visuals.test.ts (400 tokens)
         ├── research-inference-request.test.ts (1200 tokens)
         ├── research-message-sync.test.ts (800 tokens)
         ├── research-model-timeout-bounds.test.ts (1100 tokens)
         ├── research-render-budget.test.ts (1200 tokens)
         ├── research-reoffered-after-stop.test.ts (600 tokens)
         ├── research-reply-owners.test.ts (600 tokens)
         ├── research-run-binding.test.ts (200 tokens)
         ├── research-run-identity.test.ts (1000 tokens)
         ├── research-thread-claim-release.test.ts (600 tokens)
         ├── resident-config-match-accelerator-matrix.test.ts (3k tokens)
         ├── resident-config-match.test.ts (12.5k tokens)
         ├── resident-memory-credit.test.ts (1400 tokens)
         ├── resident-memory-refresh.test.ts (600 tokens)
         ├── resident-memory-request.test.ts (800 tokens)
         ├── resident-model-match-legacy-status.test.ts (1200 tokens)
         ├── resident-model-match-matrix.test.ts (2.7k tokens)
         ├── resident-model-match.test.ts (1000 tokens)
         ├── resident-remembered-config.test.ts (900 tokens)
         ├── resident-status-baselines.test.ts (1300 tokens)
         ├── resolve-batch-size-seed.test.ts (800 tokens)
         ├── resolved-precision.test.ts (2.4k tokens)
         ├── resources-shared-memory-display.test.ts (200 tokens)
         ├── resume-diffusion-run.test.ts (700 tokens)
         ├── retryable-shared-read.test.ts (600 tokens)
         ├── rocm-windows-vram-aggregate.test.ts (600 tokens)
         ├── rolling-context-window.test.ts (3.3k tokens)
         ├── route-loading-fallback.test.ts (100 tokens)
         ├── run-with-concurrency.test.ts (300 tokens)
         ├── sandbox-image-lifecycle.test.ts (800 tokens)
         ├── sandbox-reveal-path.test.ts (2.2k tokens)
         ├── scan-folder-status.test.ts (600 tokens)
         ├── search-images.test.ts (8.5k tokens)
         ├── serial-queue.test.ts (300 tokens)
         ├── server-managed-autosave-write.test.ts (600 tokens)
         ├── server-tuning-settings.test.ts (1600 tokens)
         ├── server-tuning-upgrade-downgrade-compat.test.ts (5.6k tokens)
         ├── server-wide-reload.test.ts (500 tokens)
         ├── settings-deep-open-requests.test.ts (1200 tokens)
         ├── settings-finetune-action-loading.test.ts (600 tokens)
         ├── settings-panel-prefs.test.ts (1800 tokens)
         ├── settings-retry.test.ts (1200 tokens)
         ├── settings-row-text-width.test.ts (100 tokens)
         ├── settings-search.test.ts (800 tokens)
         ├── settings-tab-panel-loading.test.ts (1200 tokens)
         ├── shiki-tokenization-counter.mts (200 tokens)
         ├── shiki-tokenization-resolver.mjs (200 tokens)
         ├── shortcut-dispatch-guards.test.ts (4.7k tokens)
         ├── shortcut-text-field-gate.test.ts (700 tokens)
         ├── sidebar-action-rows-inert.test.ts (1500 tokens)
         ├── sidebar-collapse-to-zero.test.ts (500 tokens)
         ├── sidebar-items-resolver.mjs (200 tokens)
         ├── sidebar-more-menu-interaction.test.ts (200 tokens)
         ├── sidebar-nav-backend-parity.test.ts (700 tokens)
         ├── sidebar-nav-migration.test.ts (1100 tokens)
         ├── sidebar-organization-store.test.ts (1300 tokens)
         ├── sidebar-row-selection.test.ts (400 tokens)
         ├── sidebar-scroll-fade-deps.test.ts (300 tokens)
         ├── sidebar-selection-coverage.test.ts (1300 tokens)
         ├── sidebar-spinner-column.test.ts (1800 tokens)
         ├── sidebar-touch-reorder.test.ts (500 tokens)
         ├── sidebar-unread-dot.test.ts (200 tokens)
         ├── sidebar-width.test.ts (500 tokens)
         ├── single-flight-request.test.ts (700 tokens)
         ├── slider-thumb-accessible-value.test.ts (600 tokens)
         ├── sole-quant-cache.test.ts (2.1k tokens)
         ├── sole-quant-row-state.test.ts (500 tokens)
         ├── spec-fallback-partial-offload-copy.test.ts (700 tokens)
         ├── sse-framing.test.ts (200 tokens)
         ├── sse-json-events.test.ts (500 tokens)
         ├── staged-source-dedup.test.ts (600 tokens)
         ├── start-training-cta-state.test.ts (300 tokens)
         ├── startup-handoff.test.ts (400 tokens)
         ├── startup-messages.test.ts (500 tokens)
         ├── store-settings-resolver.mjs (200 tokens)
         ├── store-stub-resolver.mjs (200 tokens)
         ├── stream-pacing-stall.test.ts (500 tokens)
         ├── streaming-crlf-retention.test.ts (1100 tokens)
         ├── streaming-has-prefix.test.ts (1000 tokens)
         ├── streaming-horizontal-rule.test.ts (2000 tokens)
         ├── streaming-latex-corpus.test.ts (2.7k tokens)
         ├── streaming-latex-retro-edit.test.ts (2.9k tokens)
         ├── streaming-open-fence-repair.test.ts (2.1k tokens)
         ├── streaming-render-schedule.test.ts (4.8k tokens)
         ├── strip-ansi.test.ts (1300 tokens)
         ├── stt-download-mirror-policy.test.ts (400 tokens)
         ├── stt-download-trackers.test.ts (400 tokens)
         ├── stt-request-error.test.ts (300 tokens)
         ├── stuck-generation-run.test.ts (7.3k tokens)
         ├── studio-tool-history.test.ts (800 tokens)
         ├── system-discovery.test.ts (300 tokens)
         ├── system-status-verdict.test.ts (1900 tokens)
         ├── tauri-details-toggle.test.ts (400 tokens)
         ├── tauri-log-follow.test.ts (600 tokens)
         ├── tauri-update-schedule.test.ts (3.5k tokens)
         ├── tensor-parallel-row-gating.test.ts (400 tokens)
         ├── think-tag-tracker.test.ts (2.1k tokens)
         ├── thread-ancestor-has-scope.test.ts (2.1k tokens)
         ├── thread-delete-render-budget.test.ts (700 tokens)
         ├── thread-fast-copy.test.ts (12.9k tokens)
         ├── thread-message-slot.test.ts (500 tokens)
         ├── thread-part-components-stable.test.ts (800 tokens)
         ├── thread-record-write-coordinator.test.ts (700 tokens)
         ├── thread-research-presence.test.ts (600 tokens)
         ├── thread-sampling-resolver.mjs (400 tokens)
         ├── thread-scoped-commit-restores-defaults.test.ts (1100 tokens)
         ├── thread-scoped-held-edit-model-memory.test.ts (900 tokens)
         ├── thread-scoped-pairing-composition.test.ts (1200 tokens)
         ├── thread-scoped-pairing-default-refresh.test.ts (1000 tokens)
         ├── thread-scoped-pairing-invariants.test.ts (8.4k tokens)
         ├── thread-scoped-params-pre-hydration.test.ts (800 tokens)
         ├── thread-scoped-sampling-compat.test.ts (4.7k tokens)
         ├── thread-scoped-sampling-simulation.test.ts (4.6k tokens)
         ├── thread-scoped-settings.test.ts (1400 tokens)
         ├── timeout-card-keeps-its-status.test.ts (1200 tokens)
         ├── titlebar-modal-layering.test.ts (500 tokens)
         ├── toast-offset.test.ts (800 tokens)
         ├── tool-activity-preference.test.ts (4.5k tokens)
         ├── tool-call-arguments-precision.test.ts (1100 tokens)
         ├── tool-call-delta-index.test.ts (1000 tokens)
         ├── tool-card-arg-coercion.test.ts (2.3k tokens)
         ├── tool-fallback-label.test.ts (600 tokens)
         ├── tool-status.test.ts (300 tokens)
         ├── tooltip-modal-layer-store.test.ts (1500 tokens)
         ├── tooltip-modal-layer.test.ts (400 tokens)
         ├── tooltip-open-state.test.ts (400 tokens)
         ├── trailing-placeholder-prefix-safety.test.ts (2.9k tokens)
         ├── trailing-placeholder-reseed.test.ts (1000 tokens)
         ├── trailing-placeholder-watch.test.ts (1100 tokens)
         ├── trailing-template-placeholder.test.ts (1500 tokens)
         ├── train-configure-preview-column.test.ts (1500 tokens)
         ├── training-cache-reconciliation.test.ts (2.5k tokens)
         ├── training-config-import.test.ts (200 tokens)
         ├── training-config-persistence.test.ts (2.6k tokens)
         ├── training-config-platforms.test.ts (1500 tokens)
         ├── training-config-policy.test.ts (600 tokens)
         ├── training-config-roundtrip.test.ts (1700 tokens)
         ├── training-config-wizard-state-retirement.test.ts (800 tokens)
         ├── training-cpt-model-switch.test.ts (5k tokens)
         ├── training-dataset-recheck-bound.test.ts (1100 tokens)
         ├── training-dataset-source-transitions.test.ts (2.1k tokens)
         ├── training-method-provenance.test.ts (800 tokens)
         ├── training-model-defaults-race.test.ts (200 tokens)
         ├── training-model-defaults-warmup-ratio.test.ts (800 tokens)
         ├── training-model-support.test.ts (200 tokens)
         ├── training-progress-pin.test.ts (1000 tokens)
         ├── training-resume-remote-code.test.ts (500 tokens)
         ├── training-run-display.test.ts (300 tokens)
         ├── training-runtime-store.test.ts (4.1k tokens)
         ├── training-sse-stream.test.ts (1400 tokens)
         ├── training-start-cached-progress.test.ts (2.2k tokens)
         ├── training-start-errors.test.ts (200 tokens)
         ├── training-start-inputs.test.ts (600 tokens)
         ├── training-start-payload-grad-norm.test.ts (700 tokens)
         ├── training-start-preparation.test.ts (2.5k tokens)
         ├── training-start-reconciliation.test.ts (500 tokens)
         ├── training-start-request-id.test.ts (200 tokens)
         ├── training-status-request.test.ts (300 tokens)
         ├── training-stop-scope.test.ts (300 tokens)
         ├── training-stream-scope.test.ts (300 tokens)
         ├── training-transformers-upgrade.test.ts (3.1k tokens)
         ├── training-ui-preferences.test.ts (300 tokens)
         ├── training-unload-guard.test.ts (500 tokens)
         ├── training-upgrade-gate-contract.test.ts (1300 tokens)
         ├── training-upgrade-notice-cache.test.ts (1000 tokens)
         ├── training-upgrade-notice-precision.test.ts (900 tokens)
         ├── training-validation.test.ts (1700 tokens)
         ├── transfer-stats-hook-hidden.test.ts (600 tokens)
         ├── transformers-upgrade-dialog-actions.test.ts (700 tokens)
         ├── transport-capabilities.test.ts (500 tokens)
         ├── transport-mode-auto.test.ts (400 tokens)
         ├── tray-server-status.test.ts (1300 tokens)
         ├── tts-custom-connections-disabled.test.ts (2.2k tokens)
         ├── uncaptioned-image-empty-text-block.test.ts (800 tokens)
         ├── unsloth-support-companion-mirror.test.ts (500 tokens)
         ├── update-banner-flex-priority.test.ts (3.3k tokens)
         ├── variant-listing-error.test.ts (400 tokens)
         ├── variant-visibility.test.ts (1000 tokens)
         ├── verdict-poll-stall-guard.test.ts (1400 tokens)
         ├── video-capability-plumbing.test.ts (600 tokens)
         ├── video-download-plan-payload.test.ts (1100 tokens)
         ├── video-gallery-clear-confirmation.test.ts (700 tokens)
         ├── video-gallery-thumbnail-load.test.ts (2k tokens)
         ├── video-generate-refusal-resync.test.ts (800 tokens)
         ├── video-h3-task-dialog.test.ts (600 tokens)
         ├── video-keyframe-canvas.test.ts (400 tokens)
         ├── video-mime-normalisation.test.ts (500 tokens)
         ├── video-reference-budget.test.ts (100 tokens)
         ├── video-reference-file-size.test.ts (1000 tokens)
         ├── video-reference-image-crop.test.ts (1700 tokens)
         ├── video-reference-selection-gate.test.ts (300 tokens)
         ├── video-reference-trim.test.ts (800 tokens)
         ├── vision-switch-seed.test.ts (900 tokens)
         ├── vision-toggle-config.test.ts (1000 tokens)
         ├── vision-toggle-gating.test.ts (2.5k tokens)
         ├── voice-download-model-switch.test.ts (600 tokens)
         ├── voice-settings-stt-migration.test.ts (700 tokens)
         ├── voice-stt-device-control.test.ts (300 tokens)
         ├── vram-budget.test.ts (3.9k tokens)
         ├── vram-total-gib-suffix.test.ts (1400 tokens)
         ├── web-search-action-variants.test.ts (1300 tokens)
         ├── window-layout.test.ts (3k tokens)
         ├── windows-path-portability.test.ts (6.1k tokens)
         ├── xet-notice-reservation.test.ts (1200 tokens)
         ├── xet-progress-notice.test.ts (1300 tokens)
         ├── youtube-url.test.ts (500 tokens)
         ├── z-layers.test.ts (500 tokens)
      ├── tsconfig.app.json (200 tokens)
      ├── tsconfig.json
      ├── tsconfig.node.json (100 tokens)
      ├── tsconfig.test.json (200 tokens)
      ├── vite.config.ts (500 tokens)
   ├── install_llama_prebuilt.py (79.6k tokens)
   ├── install_manifest.py (6.8k tokens)
   ├── install_node_prebuilt.py (7.3k tokens)
   ├── install_python_stack.py (76.8k tokens)
   ├── install_sd_cpp_prebuilt.py (9.5k tokens)
   ├── install_whisper_prebuilt.py (13.1k tokens)
   ├── node_prebuilt_pins.json (200 tokens)
   ├── package-lock.json (1500 tokens)
   ├── package.json (100 tokens)
   ├── prebuilt_core.py (19.1k tokens)
   ├── scripts/
      ├── unsloth_freeze_report.py (8.1k tokens)
   ├── setup.bat
   ├── setup.ps1 (76.4k tokens)
   ├── setup.sh (37.6k tokens)
   ├── src-tauri/
      ├── Cargo.lock (omitted)
      ├── Cargo.toml (500 tokens)
      ├── Entitlements.plist (100 tokens)
      ├── Info.plist (100 tokens)
      ├── build.rs
      ├── capabilities/
         ├── default.json (300 tokens)
      ├── dmg/
         ├── background.tiff
      ├── icons/
         ├── 128x128.png
         ├── 32x32.png
         ├── icon.icns
         ├── icon.ico
         ├── icon.png
      ├── linux/
         ├── appimage-apprun.sh (500 tokens)
         ├── appimage-fonts.conf (500 tokens)
         ├── finalize-complete-appimage.sh (600 tokens)
         ├── postremove.sh (100 tokens)
         ├── prepare-complete-appimage-tools.sh (1000 tokens)
         ├── unsloth.desktop
         ├── verify-complete-appimage.sh (2.3k tokens)
      ├── src/
         ├── app_layout.rs (1800 tokens)
         ├── commands.rs (19.8k tokens)
         ├── desktop_auth.rs (3.1k tokens)
         ├── desktop_backend_owner.rs (15.3k tokens)
         ├── desktop_update_policy.rs (3.1k tokens)
         ├── desktop_updater.rs (2.6k tokens)
         ├── diagnostics/
            ├── mod.rs (1100 tokens)
            ├── phase_log.rs (5.3k tokens)
            ├── redaction.rs (1700 tokens)
            ├── report.rs (7.9k tokens)
            ├── state.rs (5k tokens)
         ├── install.rs (15.4k tokens)
         ├── install_watchdog.rs (2.4k tokens)
         ├── linux_webkit.rs (11.7k tokens)
         ├── loopback_http.rs (1000 tokens)
         ├── main.rs (22.2k tokens)
         ├── native_backend_lease.rs (1700 tokens)
         ├── native_clipboard.rs (5.1k tokens)
         ├── native_file_dialogs.rs (8.3k tokens)
         ├── native_intents.rs (9.9k tokens)
         ├── native_path_policy.rs (9.5k tokens)
         ├── preflight.rs (10k tokens)
         ├── preflight/
            ├── backend.rs (3.5k tokens)
            ├── managed.rs (7.5k tokens)
            ├── pid_records.rs (4.7k tokens)
            ├── types.rs (300 tokens)
            ├── version.rs (1500 tokens)
         ├── process.rs (47.3k tokens)
         ├── process_identity.rs (5.6k tokens)
         ├── staged_update.rs (7k tokens)
         ├── update.rs (5k tokens)
         ├── webview_permissions.rs (1200 tokens)
         ├── windows_job.rs (1900 tokens)
         ├── x11_threads.rs (500 tokens)
      ├── tauri.conf.json (600 tokens)
      ├── tauri.linux.conf.json
      ├── tauri.macos.conf.json (100 tokens)
      ├── tauri.windows.conf.json (100 tokens)
      ├── windows/
         ├── branding/
            ├── nsis-header.bmp
            ├── nsis-sidebar.bmp
         ├── hooks.nsh (300 tokens)
         ├── installer.nsi (7k tokens)
         ├── sign-with-trusted-signing.ps1 (300 tokens)
├── tests/
   ├── __init__.py
   ├── _grpo_dispatch_source.py (600 tokens)
   ├── _rl_source.py (500 tokens)
   ├── _shared/
      ├── compile_cache_isolation.py (600 tokens)
      ├── installer_venv_root.py (800 tokens)
      ├── unsloth_pwsh_runner.py (2.7k tokens)
   ├── _zoo_aggressive_cuda_spoof.py (1600 tokens)
   ├── _zoo_rocm_spoof.py (700 tokens)
   ├── conftest.py (1800 tokens)
   ├── fast_inference/
      ├── test_fast_inference.py (1600 tokens)
   ├── kaggle/
      ├── conftest.py (400 tokens)
      ├── studio_gpu/
         ├── gpu_assert.py (2.8k tokens)
         ├── run_studio_gpu.py (26.7k tokens)
         ├── studio_client.py (3.1k tokens)
         ├── train_canary.jsonl (300 tokens)
      ├── t4_smoke/
         ├── canary_dataset.jsonl (100 tokens)
         ├── determinism.py (2k tokens)
         ├── gguf_export.py (2.3k tokens)
         ├── kernel_provenance.py (1500 tokens)
         ├── measured_vram.json (100 tokens)
         ├── naive_trl_compare.py (2.6k tokens)
         ├── phase_timers.py (1500 tokens)
         ├── pins/
            ├── control.txt (600 tokens)
         ├── references/
            ├── README.md (3.2k tokens)
            ├── t4_qwen2.5-0.5b.json (500 tokens)
         ├── run_gptoss_t4.py (9.1k tokens)
         ├── run_grpo_t4.py (6.3k tokens)
         ├── run_t4_smoke.py (23.1k tokens)
         ├── run_vision_t4.py (4.1k tokens)
         ├── training_evidence.py (1700 tokens)
         ├── versions.py (1400 tokens)
      ├── test_adapter_config_regex.py (700 tokens)
      ├── test_directive_leg_set.py (1500 tokens)
      ├── test_fire_and_forget.py (15.1k tokens)
      ├── test_gptoss_completions_and_gguf.py (2.8k tokens)
      ├── test_grpo_nightly.py (3.4k tokens)
      ├── test_harness_dependencies.py (1400 tokens)
      ├── test_kernel_provenance.py (1500 tokens)
      ├── test_known_upstream_breakage.py (900 tokens)
      ├── test_launch_cleanup.py (9.2k tokens)
      ├── test_multi_gpu_leg.py (4.4k tokens)
      ├── test_naive_trl_compare.py (1500 tokens)
      ├── test_phase_timers.py (2.1k tokens)
      ├── test_prefetch_covers_the_wired_legs.py (1800 tokens)
      ├── test_studio_api_key.py (900 tokens)
      ├── test_studio_cli_run.py (2000 tokens)
      ├── test_studio_cloudflare.py (1300 tokens)
      ├── test_studio_code_execution.py (1300 tokens)
      ├── test_studio_compaction.py (2000 tokens)
      ├── test_studio_gpu_harness.py (19.6k tokens)
      ├── test_studio_image_generation.py (1600 tokens)
      ├── test_studio_lora_vs_base.py (1400 tokens)
      ├── test_studio_mtp_engages.py (800 tokens)
      ├── test_studio_password_path.py (1000 tokens)
      ├── test_studio_server_flags.py (2.3k tokens)
      ├── test_studio_tabs.py (1100 tokens)
      ├── test_studio_web_search.py (1700 tokens)
      ├── test_t4_ci_transport.py (28.3k tokens)
      ├── test_t4_payload_assertions.py (19.1k tokens)
      ├── test_t4_smoke_harness.py (39.1k tokens)
      ├── test_two_account_selection.py (6.3k tokens)
      ├── test_venv_interpreter_and_overlay_path.py (1700 tokens)
      ├── test_vision_run.py (2.8k tokens)
   ├── notebooks/
      ├── __init__.py
      ├── test_colab_oracle_drift.py (4.5k tokens)
      ├── test_notebook_validator_shell_parsing.py (45.7k tokens)
      ├── test_smoke_install_contract.py (1500 tokens)
      ├── test_validator_fixtures.py (2.1k tokens)
   ├── python/
      ├── __init__.py
      ├── conftest.py (100 tokens)
      ├── test_bitsandbytes_kernel_readiness.py (1400 tokens)
      ├── test_change_system_message.py (600 tokens)
      ├── test_conftest_bitsandbytes_preimport.py (800 tokens)
      ├── test_construct_chat_template_validation.py (2.7k tokens)
      ├── test_cpo_processor_text_tokenizer.py (800 tokens)
      ├── test_cross_platform_parity.py (14.2k tokens)
      ├── test_docker_build_ref_resolution.py (900 tokens)
      ├── test_docker_cpu_fallback.py (1700 tokens)
      ├── test_docker_credential_probe.py (700 tokens)
      ├── test_docker_hub_readme.py (1300 tokens)
      ├── test_docker_labext_cell_nav.py (400 tokens)
      ├── test_docker_llama_cuda_backend.py (1300 tokens)
      ├── test_docker_llama_prebuilt_probe.py (700 tokens)
      ├── test_docker_nb_compat_pre_run_cell.py (2.8k tokens)
      ├── test_docker_nb_install_cell_sig.py (2.9k tokens)
      ├── test_docker_nb_ipython_profile_writable.py (1300 tokens)
      ├── test_docker_nb_populate_retry.py (4.9k tokens)
      ├── test_docker_nb_refresh_state_durability.py (4.6k tokens)
      ├── test_docker_nb_strip_colab_durability.py (2k tokens)
      ├── test_docker_nb_strip_colab_race.py (1600 tokens)
      ├── test_docker_nb_strip_colab_scope.py (900 tokens)
      ├── test_docker_nb_sync_publish_ownership.py (3.7k tokens)
      ├── test_docker_nb_sync_race.py (2.8k tokens)
      ├── test_docker_nb_sync_upstream_removal.py (3.2k tokens)
      ├── test_docker_nb_view_ownership.py (1200 tokens)
      ├── test_docker_nvidia_toolkit_install.py (6.1k tokens)
      ├── test_docker_pip_shim_training_stack.py (2.3k tokens)
      ├── test_docker_ppa_retry.py (500 tokens)
      ├── test_docker_publish_ref_freeze.py (3.5k tokens)
      ├── test_docker_publish_tag_scheme.py (3.1k tokens)
      ├── test_docker_run_kernel_cwd.py (800 tokens)
      ├── test_docker_run_output_publish.py (1600 tokens)
      ├── test_docker_run_pin_scan.py (2.5k tokens)
      ├── test_docker_single_compile_worker_options.py (1300 tokens)
      ├── test_docker_studio_launch_view_config.py (1100 tokens)
      ├── test_docker_studio_password_banner.py (3.7k tokens)
      ├── test_docker_tf_sidecar_vllm_floor.py (1300 tokens)
      ├── test_docker_update_helpers.py (2.9k tokens)
      ├── test_dpo_vision_processor_passthrough.py (800 tokens)
      ├── test_e2e_no_torch_sandbox.py (8.5k tokens)
      ├── test_embed_lm_head_target_modules_redirect.py (2000 tokens)
      ├── test_fast_language_model_text_only.py (3k tokens)
      ├── test_fast_model_config_passthrough.py (1300 tokens)
      ├── test_fast_sentence_transformer_embedding_parity.py (1100 tokens)
      ├── test_fast_sentence_transformer_redirect_lifecycle.py (1700 tokens)
      ├── test_flash_attn_install_python_stack.py (4.8k tokens)
      ├── test_gemma4_base_bos_token.py (3.6k tokens)
      ├── test_get_chat_template_escaping.py (800 tokens)
      ├── test_get_lora_parameters_bias_fp8_block_size.py (600 tokens)
      ├── test_get_lora_parameters_fp8_block_size.py (600 tokens)
      ├── test_gpu_init_ldconfig_guard.py (300 tokens)
      ├── test_grpo_ddp_model_config.py (800 tokens)
      ├── test_grpo_logit_transform_families.py (900 tokens)
      ├── test_import_without_bitsandbytes.py (2.4k tokens)
      ├── test_install_python_stack.py (25.4k tokens)
      ├── test_install_uv_override_space.py (200 tokens)
      ├── test_mlx_public_trainer_api.py (9.8k tokens)
      ├── test_module_entry_point.py (3.6k tokens)
      ├── test_no_torch_filtering.py (6.8k tokens)
      ├── test_orpo_processor_text_tokenizer.py (1600 tokens)
      ├── test_pad_token_fix.py (700 tokens)
      ├── test_patch_trl_rl_trainers_defensive.py (500 tokens)
      ├── test_pwsh_runner_encoding.py (1500 tokens)
      ├── test_remove_special_tokens_no_bos.py (300 tokens)
      ├── test_revision_forwarding.py (7.4k tokens)
      ├── test_rl_config_pickling.py (2.7k tokens)
      ├── test_rocm_bf16_capability.py (1500 tokens)
      ├── test_studio_import_no_torch.py (4.8k tokens)
      ├── test_studio_runtime_gate.py (3.6k tokens)
      ├── test_to_sharegpt_optional_none.py (1400 tokens)
      ├── test_tokenizers_and_torch_constraint.py (5.9k tokens)
      ├── test_torchcodec_torch_compat.py (14.7k tokens)
      ├── test_unsloth_nb_pip_magic.py (600 tokens)
      ├── test_unsloth_pip_shim.py (16.7k tokens)
      ├── test_unsloth_run_tool_policy_resolver.py (800 tokens)
      ├── test_v100_fullft_precision.py (1800 tokens)
      ├── test_virustotal_scan.py (9.7k tokens)
      ├── test_vision_lora_targeting.py (3.4k tokens)
      ├── test_whisper_source_build_root.py (400 tokens)
      ├── test_windows_arm64_python_choice.py (1200 tokens)
      ├── test_windows_git_gate.py (1000 tokens)
      ├── test_windows_installer_concurrency_guard.py (9.4k tokens)
      ├── test_windows_installer_native_type_fallback.py (19.5k tokens)
      ├── test_windows_no_torch_setup.py (1400 tokens)
      ├── test_windows_python_313_8_screen.py (2.7k tokens)
      ├── test_windows_python_venv_hardening.py (9.9k tokens)
      ├── test_windows_setup_output_encoding.py (7.5k tokens)
      ├── test_windows_studio_update_launcher.py (8.7k tokens)
      ├── test_windows_vcredist_download_tls.py (800 tokens)
      ├── test_windows_xformers_installer.py (3.4k tokens)
      ├── test_windows_xformers_wheel_match.py (2000 tokens)
   ├── qlora/
      ├── README.md (500 tokens)
      ├── test_hf_qlora_train_and_merge.py (1000 tokens)
      ├── test_unsloth_qlora_train_and_merge.py (1200 tokens)
   ├── run_all.sh (300 tokens)
   ├── saving/
      ├── gpt-oss-merge/
         ├── run_test.sh (200 tokens)
         ├── test_merged_model.py (400 tokens)
         ├── train_and_merge.py (500 tokens)
      ├── language_models/
         ├── test_merge_4bit_validation.py (1400 tokens)
         ├── test_merge_model_perplexity_llama_3_2.py (1500 tokens)
         ├── test_merge_model_perplexity_mistral.py (1800 tokens)
         ├── test_merge_model_perplexity_phi_4.py (1500 tokens)
         ├── test_merged_model_perplexity_llama_3_1_8b.py (1500 tokens)
         ├── test_merged_model_perplexity_qwen_2_5.py (1700 tokens)
         ├── test_push_to_hub_merged.py (1200 tokens)
         ├── test_push_to_hub_merged_sharded_index_file.py (1300 tokens)
         ├── test_save_merged_grpo_model.py (4.8k tokens)
      ├── non_peft/
         ├── test_mistral_non_peft.py (500 tokens)
         ├── test_whisper_non_peft.py (500 tokens)
      ├── run_offline_gguf_integration.py (400 tokens)
      ├── test_compressed_export_schemes.py (600 tokens)
      ├── test_export_api_surface.py (1400 tokens)
      ├── test_export_dispatch.py (3.7k tokens)
      ├── test_fix_sentencepiece_gguf_robustness.py (1000 tokens)
      ├── test_fix_sentencepiece_tokenizer_guard.py (2.3k tokens)
      ├── test_gguf_disk_preflight.py (33.6k tokens)
      ├── test_gguf_export_and_inference.py (2.3k tokens)
      ├── test_gguf_shard_size.py (1400 tokens)
      ├── test_gguf_single_pass_export.py (2.4k tokens)
      ├── test_imatrix_export.py (1800 tokens)
      ├── test_is_gpt_oss_detection.py (400 tokens)
      ├── test_is_vlm_detection.py (500 tokens)
      ├── test_llm_compressor_install_pin.py (1000 tokens)
      ├── test_normalize_tied_weights_keys.py (800 tokens)
      ├── test_offline_gguf_real_cache_integration.py (800 tokens)
      ├── test_offline_gguf_vlm_tokenizer_7481.py (2.6k tokens)
      ├── test_patch_saving_none_tokenizer.py (200 tokens)
      ├── test_preserve_tokenizer_eos_token.py (700 tokens)
      ├── test_prewarm_base_model_hub_cache.py (3.6k tokens)
      ├── test_quant_method_none_normalization.py (700 tokens)
      ├── test_qwen3_5_vlm_full_finetune_key_remap.py (500 tokens)
      ├── test_save_shell_injection.py (700 tokens)
      ├── test_save_subprocess_utf8_encoding.py (900 tokens)
      ├── test_sentence_transformer_gguf_shards.py (500 tokens)
      ├── test_torchao_remote_code_consent.py (1200 tokens)
      ├── test_unsloth_save.py (2.5k tokens)
      ├── text_to_speech_models/
         ├── test_csm.py (900 tokens)
         ├── test_lasa.py (1200 tokens)
         ├── test_orpheus.py (1600 tokens)
         ├── test_whisper.py (1200 tokens)
      ├── vision_models/
         ├── test_index_file_sharded_model.py (1900 tokens)
         ├── test_push_to_hub_merged.py (1700 tokens)
         ├── test_save_merge_qwen2_5vl32B_model_ocr_benchmark.py (1500 tokens)
         ├── test_save_merge_vision_model_ocr_benchmark.py (1500 tokens)
   ├── security/
      ├── __init__.py
      ├── conftest.py (600 tokens)
      ├── fixtures/
         ├── __init__.py
         ├── _build.py (1100 tokens)
         ├── clean_lockfile.json (100 tokens)
         ├── clean_wheel.whl
         ├── malicious_lockfile.json (200 tokens)
         ├── malicious_sdist.tar.gz
         ├── malicious_wheel.whl
         ├── structural_only_lockfile.json (100 tokens)
      ├── test_custom_dtype_no_eval.py (1000 tokens)
      ├── test_custom_dtype_wire_format.py (1200 tokens)
      ├── test_desktop_release_resolver.py (800 tokens)
      ├── test_desktop_updater_pointer.py (5.2k tokens)
      ├── test_inherited_custom_dtype_is_neutralized.py (1700 tokens)
      ├── test_lint_exec_literals.py (1800 tokens)
      ├── test_lint_workflow_triggers.py (6.8k tokens)
      ├── test_lockfile_supply_chain_audit.py (4.6k tokens)
      ├── test_mapper_probe_no_exec.py (7k tokens)
      ├── test_network_blocker_does_not_leak.py (1200 tokens)
      ├── test_new_install_scripts.py (1300 tokens)
      ├── test_release_desktop_appimage.py (5.6k tokens)
      ├── test_release_desktop_integrity.py (5.1k tokens)
      ├── test_release_desktop_notarization.py (2000 tokens)
      ├── test_release_desktop_permissions.py (3.1k tokens)
      ├── test_release_desktop_signing.py (900 tokens)
      ├── test_release_desktop_signing_simulation.py (3.4k tokens)
      ├── test_scan_npm_packages.py (7.5k tokens)
      ├── test_scan_packages.py (23.2k tokens)
      ├── test_security_suite_stays_import_light.py (6.2k tokens)
   ├── sh/
      ├── _harness.sh (300 tokens)
      ├── _ps1_source.sh (500 tokens)
      ├── test_agent_guides_timeout_classification.sh (3.6k tokens)
      ├── test_apt_distro_prompt.sh (2.3k tokens)
      ├── test_clean_machine_install_name_tool_assert.sh (1200 tokens)
      ├── test_get_torch_index_url.sh (4.8k tokens)
      ├── test_install_gpu_summary_probe_sources.sh (2.8k tokens)
      ├── test_install_host_defaults.sh (5.2k tokens)
      ├── test_install_pipe_safety.sh (600 tokens)
      ├── test_install_python_guard.sh (2000 tokens)
      ├── test_install_rollback_lifecycle.sh (4.7k tokens)
      ├── test_install_sh_xpu_flavor_probe.sh (900 tokens)
      ├── test_install_uv_cache_root.sh (4.2k tokens)
      ├── test_install_uv_override_space.sh (2000 tokens)
      ├── test_linux_deps_gate.sh (1800 tokens)
      ├── test_linux_uv_python_downloads_manual.sh (3k tokens)
      ├── test_llama_build_jobs.sh (7.3k tokens)
      ├── test_llama_degraded_tauri_mode.sh (1500 tokens)
      ├── test_mac_intel_compat.sh (4.4k tokens)
      ├── test_macos_clt_gate.sh (1800 tokens)
      ├── test_macos_uv_install_name_tool_guard.sh (2k tokens)
      ├── test_macos_venv_python_preference.sh (900 tokens)
      ├── test_node_decision.sh (500 tokens)
      ├── test_nvcc_meets_llama_minimum.sh (700 tokens)
      ├── test_packaged_frontend_skip.sh (600 tokens)
      ├── test_previous_torch_pin.sh (2.3k tokens)
      ├── test_ps1_code_view.sh (800 tokens)
      ├── test_redact_install_output.sh (700 tokens)
      ├── test_resolve_cuda_archs.sh (400 tokens)
      ├── test_rocm_bad_arch_gate.sh (4.6k tokens)
      ├── test_rocm_no_version_arch_route.sh (2.9k tokens)
      ├── test_rocm_no_version_arch_route_e2e.sh (4.5k tokens)
      ├── test_rocm_version_source_disagreement.sh (5.3k tokens)
      ├── test_rocminfo_gpu_name_7307.sh (2.4k tokens)
      ├── test_select_cuda_jit_tools.sh (900 tokens)
      ├── test_setup_amd_fastpath_escape.sh (700 tokens)
      ├── test_setup_desktop_backend_version_fastpath.sh (1300 tokens)
      ├── test_setup_gpu_summary_probe_sources.sh (3.6k tokens)
      ├── test_setup_http_get.sh (800 tokens)
      ├── test_setup_sh_denied_install_tree.sh (3.4k tokens)
      ├── test_setup_staged_root.sh (1300 tokens)
      ├── test_setup_webview_cache_clear.sh (2.6k tokens)
      ├── test_setup_xpu_fastpath_escape.sh (2.4k tokens)
      ├── test_setup_xpu_posix_summary.sh (2.5k tokens)
      ├── test_shell_rc_path_append.sh (1600 tokens)
      ├── test_staged_validation_enabled.sh (800 tokens)
      ├── test_strixhalo_wsl_reroute.sh (3k tokens)
      ├── test_studio_home_node_dir.sh (900 tokens)
      ├── test_system_node_readonly.sh (700 tokens)
      ├── test_tauri_install_exit_order.sh (800 tokens)
      ├── test_tauri_retry_failure_context.sh (3.2k tokens)
      ├── test_torch_constraint.sh (3.5k tokens)
      ├── test_torch_flavor.sh (2.2k tokens)
      ├── test_uninstall_arg_guard.sh (2.1k tokens)
      ├── test_uninstall_legacy_layout_gate.sh (4k tokens)
      ├── test_uninstall_prebuilt_artifacts.sh (1300 tokens)
      ├── test_uninstall_sd_cpp_custom_root.sh (3.3k tokens)
      ├── test_uninstall_shared_icon.sh (900 tokens)
      ├── test_uninstall_webview_data.sh (6.6k tokens)
      ├── test_unsloth_torch_override.sh (2.1k tokens)
      ├── test_uv_cache_colocation.sh (1600 tokens)
      ├── test_uv_pinned_release.sh (9.8k tokens)
      ├── test_with_llama_cpp_dir_flag.sh (1400 tokens)
      ├── test_with_llama_cpp_dir_link_behavior.sh (1300 tokens)
      ├── test_xpu_bitsandbytes_reachable.sh (800 tokens)
      ├── test_xpu_torch_spec_parity.sh (600 tokens)
   ├── studio/
      ├── _code_block_flicker_analysis.py (1400 tokens)
      ├── _js_source.py (1700 tokens)
      ├── _node_harness.py (800 tokens)
      ├── _playwright_robust.py (6.6k tokens)
      ├── _thread_fast_copy_constructs.py (1100 tokens)
      ├── _ts_deps.py (4.5k tokens)
      ├── appimage_media_pipeline_probe.py (1200 tokens)
      ├── appimage_model_download_webdriver.py (7.7k tokens)
      ├── appimage_portability_smoke.py (2.8k tokens)
      ├── appimage_test_support.py (600 tokens)
      ├── fixtures/
         ├── ansi-smoke-screenshots/
            ├── smoke-ansi.png
         ├── release_bodies/
            ├── v0.1.43-beta.md (1500 tokens)
            ├── v0.1.471-beta.md (5k tokens)
            ├── v0.1.501-beta.md (5k tokens)
            ├── v0.1.526-beta.md (4.5k tokens)
            ├── v0.1.527-beta.md (8.5k tokens)
            ├── v0.1.60-beta.md (10k tokens)
      ├── install/
         ├── conftest.py (100 tokens)
         ├── smoke_test_llama_prebuilt.py (1000 tokens)
         ├── smoke_test_parallel_studio_home.py (2.7k tokens)
         ├── test_amd_fastpath_probe.py (6.3k tokens)
         ├── test_base_requirements_reach_install.py (1700 tokens)
         ├── test_cuda_repair.py (19.5k tokens)
         ├── test_denied_llama_cpp_preflight.py (2.9k tokens)
         ├── test_diffusers_pin.py (1600 tokens)
         ├── test_docker_studio_keep_cuda_prebuilt.py (3.3k tokens)
         ├── test_download_host_resolve.py (2.2k tokens)
         ├── test_gpu_detection_followups.py (4.7k tokens)
         ├── test_hf_auth.py (800 tokens)
         ├── test_install_llama_prebuilt_logic.py (45.8k tokens)
         ├── test_install_manifest.py (5k tokens)
         ├── test_install_manifest_damage.py (6k tokens)
         ├── test_install_node_prebuilt_logic.py (7.1k tokens)
         ├── test_install_whisper_prebuilt_logic.py (17.8k tokens)
         ├── test_installed_family_hermeticity.py (1800 tokens)
         ├── test_installed_release_backend_line.py (5.2k tokens)
         ├── test_keep_install_backcompat_9979.py (6.1k tokens)
         ├── test_launch_studio_launcher.py (600 tokens)
         ├── test_llama_pr_force_and_source.py (4.6k tokens)
         ├── test_llama_prebuilt_no_space.py (2.9k tokens)
         ├── test_macos_version_compat.py (3.8k tokens)
         ├── test_managed_node_runtime.py (1500 tokens)
         ├── test_missing_kernel_arch_routing_9396.py (14.9k tokens)
         ├── test_mlx_install.py (1900 tokens)
         ├── test_no_torch_skips_mlx_stack.py (1000 tokens)
         ├── test_nvidia_smi_candidate_probing.py (800 tokens)
         ├── test_package_discovery.py (1800 tokens)
         ├── test_pr4562_bugfixes.py (9.8k tokens)
         ├── test_pr5940_followups.py (8.2k tokens)
         ├── test_prebuilt_core.py (7k tokens)
         ├── test_probe_timeouts.py (2.4k tokens)
         ├── test_rdna1_unsupported_message_8529.py (14k tokens)
         ├── test_rocm_arch_table_parity.py (6.9k tokens)
         ├── test_rocm_gfx_spoof_7331.py (9.6k tokens)
         ├── test_rocm_native_linux_lib_dirs.py (4.4k tokens)
         ├── test_rocm_rdna_routing.py (800 tokens)
         ├── test_rocm_support.py (73k tokens)
         ├── test_selection_logic.py (36.2k tokens)
         ├── test_setup_denied_install_tree.py (4.1k tokens)
         ├── test_setup_fast_path_guard.py (1300 tokens)
         ├── test_setup_whisper_status.py (300 tokens)
         ├── test_studio_deps_cli.py (5.3k tokens)
         ├── test_studio_extra_matches_requirements.py (1100 tokens)
         ├── test_torch_probe_classification_parity.py (2.3k tokens)
         ├── test_torch_probe_memoization.py (4k tokens)
         ├── test_transformers_tokenizers_pair.py (3.1k tokens)
         ├── test_unsupported_arch_routing_guards_8529.py (9.2k tokens)
         ├── test_windows_torch_flavor_invariant.py (5.8k tokens)
      ├── load_freeze/
         ├── __init__.py
         ├── llama_server_shim.py (1800 tokens)
         ├── test_load_orchestrator.py (6.2k tokens)
      ├── mac_capability_verdict_smoke.py (8k tokens)
      ├── playwright_chat_autoscroll.py (3k tokens)
      ├── playwright_chat_ime_i18n.py (7.3k tokens)
      ├── playwright_chat_ui.py (20.8k tokens)
      ├── playwright_code_block_flicker.py (3.5k tokens)
      ├── playwright_collapse_layout.py (7.5k tokens)
      ├── playwright_composer_icons.py (1300 tokens)
      ├── playwright_declared_polls.py (2.3k tokens)
      ├── playwright_extra_ui.py (8.6k tokens)
      ├── playwright_find_in_page.py (7.5k tokens)
      ├── playwright_heavy_thread.py (20.6k tokens)
      ├── playwright_image_download_cancel_retry.py (3.5k tokens)
      ├── playwright_image_model_footprint.py (2.2k tokens)
      ├── playwright_keyboard_shortcuts.py (4.4k tokens)
      ├── playwright_link_definition_probe.py (1200 tokens)
      ├── playwright_loaded_models_indicator.py (5.9k tokens)
      ├── playwright_mac_tab_capabilities.py (10.2k tokens)
      ├── playwright_mcp_arguments.py (4.1k tokens)
      ├── playwright_memory_estimate.py (9.4k tokens)
      ├── playwright_model_config.py (11.7k tokens)
      ├── playwright_nonmodal_menus.py (3.5k tokens)
      ├── playwright_research_freeze.py (4.5k tokens)
      ├── playwright_settings_tabs.py (5.4k tokens)
      ├── playwright_stream_pacing.py (2.3k tokens)
      ├── playwright_strip_ansi_smoke.py (800 tokens)
      ├── playwright_tauri_python_tool_images.py (1600 tokens)
      ├── playwright_thread_fast_copy.py (4.1k tokens)
      ├── playwright_thread_scoped_settings.py (4.3k tokens)
      ├── playwright_thread_weight.py (8.4k tokens)
      ├── playwright_tool_activity.py (4k tokens)
      ├── playwright_train_pickers.py (5.7k tokens)
      ├── playwright_ui_font_scale.py (2.7k tokens)
      ├── playwright_update_banner_layout.py (11.5k tokens)
      ├── probe_compact_tail_gap.py (1800 tokens)
      ├── probe_dismiss_guard.py (6.5k tokens)
      ├── probe_progressive_anchor.py (2.4k tokens)
      ├── probe_progressive_reflow.py (1500 tokens)
      ├── rag_upload_browser_server.mjs (1900 tokens)
      ├── rag_upload_browser_tests.py (2.3k tokens)
      ├── rag_upload_ci.py (1600 tokens)
      ├── rag_upload_pytest.py (200 tokens)
      ├── rag_upload_requirements.txt (200 tokens)
      ├── rag_upload_safari.py (600 tokens)
      ├── run_real_mlx_smoke.py (4.9k tokens)
      ├── sim_thread_settings_portability.py (2000 tokens)
      ├── studio_api_smoke.py (4.3k tokens)
      ├── studiobench/
         ├── CONTRIBUTING-perf.md (9k tokens)
         ├── INTERFACES.md (9.9k tokens)
         ├── README.md (3.7k tokens)
         ├── __init__.py (100 tokens)
         ├── __main__.py (26.2k tokens)
         ├── analysis/
            ├── __init__.py (900 tokens)
            ├── behaviour.py (5.9k tokens)
            ├── bridge_build.py (3k tokens)
            ├── classify.py (3.8k tokens)
            ├── cpuprofile.py (3.8k tokens)
            ├── fit.py (2k tokens)
            ├── oracles.py (4.1k tokens)
            ├── parity.py (14.9k tokens)
            ├── selftest/
               ├── test_studiobench_scroll_bounds.py (3.2k tokens)
               ├── test_studiobench_visible_parity.py (3.4k tokens)
            ├── symbols.py (4.2k tokens)
            ├── test_analysis.py (4.8k tokens)
            ├── test_instruments_live.py (2.5k tokens)
            ├── testdata/
               ├── probe_msgchan_timer_raf.json.gz
            ├── traceparse.py (2.7k tokens)
         ├── arms/
            ├── __init__.py (500 tokens)
            ├── batch.py (1700 tokens)
            ├── bundle.py (2.6k tokens)
            ├── calibration.py (3.6k tokens)
            ├── content_visibility_probe.js (3k tokens)
            ├── dose.py (2.4k tokens)
            ├── knobs.js (15.3k tokens)
            ├── knobs.py (3.2k tokens)
            ├── ladder.py (5k tokens)
            ├── layoutcost.py (2.2k tokens)
            ├── manifest.py (2.8k tokens)
            ├── recovery.py (1700 tokens)
            ├── selftest/
               ├── test_studiobench_arms.py (4.7k tokens)
               ├── test_studiobench_end_to_end.py (2.7k tokens)
               ├── test_studiobench_knobs_contract.py (900 tokens)
               ├── test_studiobench_probe_hooks.py (4.2k tokens)
               ├── test_studiobench_selfcheck.py (1900 tokens)
         ├── attribution/
            ├── vite.studiobench.config.ts (1500 tokens)
         ├── build.py (1000 tokens)
         ├── fixture/
            ├── __init__.py
            ├── corpus.py (10.7k tokens)
            ├── corpus/
               ├── frozen/
                  ├── manifest.json (1000 tokens)
                  ├── units.jsonl (112.7k tokens)
            ├── selftest/
               ├── test_studiobench_corpus_distinctness.py (1600 tokens)
               ├── test_studiobench_corpus_math.py (1600 tokens)
               ├── test_studiobench_parity_digest.py (5k tokens)
               ├── test_studiobench_parity_streamed.py (7.6k tokens)
               ├── test_studiobench_parity_text_runs.py (1000 tokens)
               ├── test_studiobench_reply_axis.py (3k tokens)
               ├── test_studiobench_rung_plan.py (1900 tokens)
               ├── test_studiobench_surfaces.py (4.4k tokens)
               ├── test_studiobench_tail_deliverable.py (1800 tokens)
         ├── instruments/
            ├── __init__.py (700 tokens)
            ├── coverage.py (3.2k tokens)
            ├── cpuprofile.py (2.8k tokens)
            ├── frames.js (2.1k tokens)
            ├── glass.js (1100 tokens)
            ├── heap.py (3k tokens)
            ├── input.js (1900 tokens)
            ├── layoutcost.js (5.4k tokens)
            ├── layoutcost.py (200 tokens)
            ├── pagejs.py (2.7k tokens)
            ├── rss.py (1600 tokens)
            ├── selfcheck.py (5.3k tokens)
            ├── selftest/
               ├── test_studiobench_input_coverage.py (2.1k tokens)
               ├── test_studiobench_input_latency.py (1100 tokens)
               ├── test_studiobench_streamcost.py (4.1k tokens)
               ├── test_studiobench_streamcost_bias.py (2.3k tokens)
               ├── test_studiobench_streamcost_integrity.py (6.2k tokens)
               ├── test_studiobench_tracing_window.py (1300 tokens)
            ├── streamcost.js (5.1k tokens)
            ├── streamcost.py (3k tokens)
            ├── tracing.py (7.1k tokens)
         ├── pacer.py (7.1k tokens)
         ├── report/
            ├── __init__.py (300 tokens)
            ├── ablation.py (1800 tokens)
            ├── build.py (1300 tokens)
            ├── overhead.py (1600 tokens)
            ├── payload.py (3.1k tokens)
            ├── render.py (3.4k tokens)
            ├── selftest/
               ├── test_studiobench_ab_report_resume.py (1300 tokens)
               ├── test_studiobench_cli_contracts.py (4.8k tokens)
               ├── test_studiobench_liveness.py (3.9k tokens)
               ├── test_studiobench_overhead_layoutcost.py (1200 tokens)
               ├── test_studiobench_report.py (3.2k tokens)
         ├── runtime/
            ├── __init__.py
            ├── ab.py (5.6k tokens)
            ├── browser.py (1700 tokens)
            ├── bundle_guard.py (2000 tokens)
            ├── lifecycle.py (7k tokens)
            ├── readiness.py (9.1k tokens)
            ├── resources.py (500 tokens)
            ├── seeder.py (3.1k tokens)
            ├── selftest/
               ├── test_studiobench_ab.py (1000 tokens)
               ├── test_studiobench_ab_failed_cell_verdict.py (1800 tokens)
               ├── test_studiobench_ab_home_collision.py (1100 tokens)
               ├── test_studiobench_ab_pair_resume.py (2.5k tokens)
               ├── test_studiobench_ab_pairing.py (1800 tokens)
               ├── test_studiobench_cell_aborted_emitter.py (1300 tokens)
               ├── test_studiobench_completeness_gate_rows.py (2.7k tokens)
               ├── test_studiobench_composer_click.py (1000 tokens)
               ├── test_studiobench_copy_from_store_live.py (1900 tokens)
               ├── test_studiobench_equivalence_mirror.py (600 tokens)
               ├── test_studiobench_follow_coverage_carveout.py (3.2k tokens)
               ├── test_studiobench_instrument_lifecycle.py (700 tokens)
               ├── test_studiobench_ladder_ratio.py (900 tokens)
               ├── test_studiobench_ladder_ratio_identity.py (2.3k tokens)
               ├── test_studiobench_launch_cleanup.py (1800 tokens)
               ├── test_studiobench_lifecycle_refs.py (900 tokens)
               ├── test_studiobench_live_marker_race.py (2.5k tokens)
               ├── test_studiobench_payload_identity.py (10k tokens)
               ├── test_studiobench_probe_survives_failure.py (1700 tokens)
               ├── test_studiobench_readiness_live.py (7.8k tokens)
               ├── test_studiobench_resume_commit.py (2k tokens)
               ├── test_studiobench_resume_latest_attempt.py (1500 tokens)
               ├── test_studiobench_resume_supersedes.py (1300 tokens)
               ├── test_studiobench_run_acquisition.py (7.2k tokens)
               ├── test_studiobench_stream_drain.py (2.7k tokens)
               ├── test_studiobench_stream_stats.py (5.9k tokens)
               ├── test_studiobench_token_refresh.py (3.8k tokens)
               ├── test_studiobench_watchdog_budget.py (1300 tokens)
               ├── test_studiobench_windowed_arm_names.py (800 tokens)
               ├── thread_fixture.js (2.6k tokens)
            ├── session.py (14.1k tokens)
            ├── types.py (6.3k tokens)
         ├── scene/
            ├── __init__.py (300 tokens)
            ├── actions.py (22.5k tokens)
            ├── dom.js (6.4k tokens)
            ├── parity.js (7.4k tokens)
            ├── schedule.py (5.2k tokens)
            ├── selftest/
               ├── test_studiobench_action_bar_wait.py (2.6k tokens)
               ├── test_studiobench_copy_confirmed_live.py (2k tokens)
               ├── test_studiobench_follow_coverage_live.py (2.7k tokens)
               ├── test_studiobench_hover_reveal_live.py (1900 tokens)
               ├── test_studiobench_observation_cost.py (2.3k tokens)
               ├── test_studiobench_parity_shot_hook.py (1000 tokens)
               ├── test_studiobench_queued_idle_live.py (6.9k tokens)
               ├── test_studiobench_reasoning_one_live.py (1500 tokens)
               ├── test_studiobench_reasoning_settle_js.py (3.5k tokens)
               ├── test_studiobench_reasoning_settling.py (1400 tokens)
               ├── test_studiobench_stop_slot_budget.py (6k tokens)
               ├── test_studiobench_thread_reopen_gate.py (4.5k tokens)
               ├── test_studiobench_visible_blind_probe_live.py (3.7k tokens)
               ├── test_studiobench_visible_capture_live.py (7.4k tokens)
            ├── surface_sweep.py (4k tokens)
            ├── surfaces.js (2.2k tokens)
            ├── surfaces.py (7.7k tokens)
         ├── scoring/
            ├── __init__.py (500 tokens)
            ├── ab.py (4.8k tokens)
            ├── anchors.py (1400 tokens)
            ├── frames.py (2.2k tokens)
            ├── from_payload.py (7.2k tokens)
            ├── payload_rules.py (3.9k tokens)
            ├── schema.py (3.9k tokens)
            ├── score.py (2.6k tokens)
            ├── selftest/
               ├── test_studiobench_from_payload.py (4.4k tokens)
               ├── test_studiobench_payload_rules.py (5.8k tokens)
               ├── test_studiobench_scoring.py (6.7k tokens)
               ├── test_studiobench_stream_metrics.py (4.8k tokens)
         ├── sweep/
            ├── __init__.py (200 tokens)
            ├── floor_table.py (9.8k tokens)
            ├── parity_null_control.py (1800 tokens)
            ├── parity_shots.py (3.5k tokens)
            ├── selftest/
               ├── test_studiobench_floor_applicability.py (3.8k tokens)
               ├── test_studiobench_null_audit.py (14.4k tokens)
               ├── test_studiobench_parity_shots.py (5.5k tokens)
               ├── test_studiobench_partial_censoring.py (4.2k tokens)
               ├── test_studiobench_resumed_collision.py (3.9k tokens)
               ├── test_studiobench_session_isolation.py (2.2k tokens)
               ├── test_studiobench_sweep.py (14.9k tokens)
               ├── test_studiobench_windowed_parity.py (20.2k tokens)
            ├── ui_parity.py (25.4k tokens)
         ├── symbols/
            ├── README.md (600 tokens)
      ├── test_about_tab_xpu_runtime_contract.py (700 tokens)
      ├── test_absorbed_lanes_still_run.py (1500 tokens)
      ├── test_agent_guides_verdicts.py (1300 tokens)
      ├── test_amd_name_arch_r9700.ps1 (1200 tokens)
      ├── test_amd_no_rocm_vulkan_routing.py (2.3k tokens)
      ├── test_amd_venv_repair_loop.ps1 (12.3k tokens)
      ├── test_appimage_fixture_cors.py (1200 tokens)
      ├── test_appimage_toolchain_contract.py (500 tokens)
      ├── test_application_control_cli_fallback.ps1 (7.8k tokens)
      ├── test_apt_steps_are_bounded.py (3.1k tokens)
      ├── test_audio_snapshot_download_targets.py (800 tokens)
      ├── test_auth_form_input_count.py (3.4k tokens)
      ├── test_autoload_hf_token_preflight.py (1300 tokens)
      ├── test_autoscroll_harness_contract.py (3.5k tokens)
      ├── test_backend_ci_matrix.py (3.9k tokens)
      ├── test_backend_ci_parallel_isolation.py (5.9k tokens)
      ├── test_banner_update_delay_override.py (800 tokens)
      ├── test_branding_guard.py (1600 tokens)
      ├── test_cache_budget_discipline.py (8.5k tokens)
      ├── test_cached_model_path_selection.py (1600 tokens)
      ├── test_cancel_atomicity.py (1900 tokens)
      ├── test_cancel_id_wiring.py (1200 tokens)
      ├── test_cancelled_turn_history_prune.py (3.8k tokens)
      ├── test_chat_autoload_failure_gate.py (15.9k tokens)
      ├── test_chat_mount_cli_load_adoption.py (5k tokens)
      ├── test_chat_preset_builtin_invariants.py (2.1k tokens)
      ├── test_chat_preset_load_config.py (1100 tokens)
      ├── test_chat_prompt_variables.py (300 tokens)
      ├── test_chat_response_details_ui_contract.py (1700 tokens)
      ├── test_chat_thinking_compact_layout.py (300 tokens)
      ├── test_chat_thread_read_consolidation.py (400 tokens)
      ├── test_chat_thread_title_cas.py (1200 tokens)
      ├── test_chat_title_generation.py (1100 tokens)
      ├── test_chat_ui_driver_cpu_throttle.py (1100 tokens)
      ├── test_chat_ui_shards_cover_everything.py (1600 tokens)
      ├── test_ci_shell_suite_coverage.py (2.8k tokens)
      ├── test_cli_attach_load_knobs.py (7.5k tokens)
      ├── test_cli_hsa_spoof_launch_7331.py (3.5k tokens)
      ├── test_cli_repo_variant.py (700 tokens)
      ├── test_cli_run_alias.py (500 tokens)
      ├── test_cli_share_host_lines.py (700 tokens)
      ├── test_cli_start_download_liveness.py (3k tokens)
      ├── test_cli_studio_defaults.py (600 tokens)
      ├── test_cli_studio_stop_windows.py (1400 tokens)
      ├── test_click_forced.py (900 tokens)
      ├── test_code_block_flicker_contract.py (2.7k tokens)
      ├── test_compact_dropdown_submenus.py (300 tokens)
      ├── test_compile_caches_are_per_worker.py (1000 tokens)
      ├── test_composer_rtl_bidi_attribute.py (1700 tokens)
      ├── test_deep_research_frontend_contract.py (4.7k tokens)
      ├── test_desktop_reliability_frontend_contract.py (9.4k tokens)
      ├── test_diffusion_gpu_layers_contract.py (3.4k tokens)
      ├── test_diffusion_train_settings_layout_contract.py (400 tokens)
      ├── test_export_output_path_contract.py (900 tokens)
      ├── test_first_turn_thread_identity.py (600 tokens)
      ├── test_freeze_report_verdicts.py (7.7k tokens)
      ├── test_frontend_dep_removal.py (9.2k tokens)
      ├── test_frontend_dist_cache.py (9.3k tokens)
      ├── test_generation_length_ui_contract.py (200 tokens)
      ├── test_gguf_smoke_phases_stay_independent.py (1500 tokens)
      ├── test_gpu_inference_smoke.py (600 tokens)
      ├── test_hardware_dispatch_matrix.py (3.8k tokens)
      ├── test_heavy_thread_gap_contract.py (600 tokens)
      ├── test_heavy_thread_harness_contract.py (2.8k tokens)
      ├── test_heavy_thread_measurement_integrity.py (12k tokens)
      ├── test_hf_token_validation_tick_contract.py (5.6k tokens)
      ├── test_indicator_browsers_run_in_parallel.py (2.1k tokens)
      ├── test_inference_smoke_http_diagnostics.py (1600 tokens)
      ├── test_inference_status_runtime_fields_contract.py (800 tokens)
      ├── test_install_matrix_selection.py (2.2k tokens)
      ├── test_install_phase_timing.py (3.9k tokens)
      ├── test_install_rollback_lifecycle.ps1 (1900 tokens)
      ├── test_installer_av_shapes.py (4.6k tokens)
      ├── test_intel_registry_fallback.ps1 (1900 tokens)
      ├── test_is_mlx_dispatch_gate.py (1500 tokens)
      ├── test_legacy_chat_title_repair.py (1200 tokens)
      ├── test_llama_cpp_wall_clock_cap.py (200 tokens)
      ├── test_locale_root_direction_contract.py (200 tokens)
      ├── test_loggers_package_not_shadowed.py (400 tokens)
      ├── test_mac_bundled_job_phases.py (2.2k tokens)
      ├── test_mac_host_offload_optin.py (1100 tokens)
      ├── test_mac_tab_capability_warm_window.py (9.8k tokens)
      ├── test_macos_slots_per_commit.py (3.4k tokens)
      ├── test_main_runs_survive_merge_bursts.py (2.4k tokens)
      ├── test_mlx_context_platform_matrix.py (5.5k tokens)
      ├── test_mlx_training_worker_behaviors.py (1300 tokens)
      ├── test_model_picker_catalog_first_paint.py (600 tokens)
      ├── test_model_picker_contracts.py (43.2k tokens)
      ├── test_multi_chat_prompt_queue_contract.py (10.8k tokens)
      ├── test_native_path_resolver_degrades.ps1 (3k tokens)
      ├── test_new_chat_context_recount.py (16.6k tokens)
      ├── test_no_test_shadows_another.py (600 tokens)
      ├── test_node_decision.ps1 (1400 tokens)
      ├── test_node_harness_dependency_resolution.py (1400 tokens)
      ├── test_node_probe_guard.ps1 (900 tokens)
      ├── test_nonce_chat_resume_restore.py (2k tokens)
      ├── test_nsis_signed_plugins_contract.py (600 tokens)
      ├── test_overlay_layering.py (1200 tokens)
      ├── test_path_probe_access_denied.ps1 (8k tokens)
      ├── test_pdf_qa_recipe_contract.py (1900 tokens)
      ├── test_pester_bootstrap_hardening.py (1400 tokens)
      ├── test_pip_cache_naming.py (1200 tokens)
      ├── test_playwright_install_avoids_with_deps.py (1000 tokens)
      ├── test_playwright_server_lifecycle.py (2.5k tokens)
      ├── test_playwright_suites_run_in_ci.py (3.6k tokens)
      ├── test_pre_turing_cap.ps1 (1400 tokens)
      ├── test_previous_torch_pin.ps1 (1500 tokens)
      ├── test_project_chat_view_switch.py (21.6k tokens)
      ├── test_prompt_queue_pause_side_effects.py (400 tokens)
      ├── test_prompt_queue_user_stop.py (200 tokens)
      ├── test_provider_backfill_awaits_batch.py (1000 tokens)
      ├── test_psmodulepath_normalization.ps1 (800 tokens)
      ├── test_pwsh_interpreter_crash_attribution.py (1200 tokens)
      ├── test_rdna1_unsupported_message_8529.ps1 (5.3k tokens)
      ├── test_recipe_context_intent.py (600 tokens)
      ├── test_remote_connection_models_contract.py (1100 tokens)
      ├── test_resolve_cuda_toolkit.ps1 (1800 tokens)
      ├── test_reveal_file_manager.py (800 tokens)
      ├── test_reveal_file_manager_matrix.py (2.8k tokens)
      ├── test_run_windows_entry_point.py (2.3k tokens)
      ├── test_sdk_installs_are_major_bounded.py (3.6k tokens)
      ├── test_settings_compact_overflow_contract.py (700 tokens)
      ├── test_settings_smoke_covers_every_tab.py (1100 tokens)
      ├── test_setup_pin_stale.ps1 (1500 tokens)
      ├── test_setup_xpu_runtime_prereport.ps1 (3.8k tokens)
      ├── test_short_job_absorption.py (1500 tokens)
      ├── test_smoke_workflows_share_one_script.py (2.6k tokens)
      ├── test_spark_tts_tokenizer_subfolder.py (500 tokens)
      ├── test_stop_running_chats_prompt_contract.py (600 tokens)
      ├── test_stream_cancel_registration_timing.py (7.2k tokens)
      ├── test_stt_model_search_locator_contract.py (1300 tokens)
      ├── test_studio_gguf_export_script_pin.py (1700 tokens)
      ├── test_studio_pid_file_contract.py (600 tokens)
      ├── test_studio_smokes_do_not_trigger_on_the_training_library.py (2.5k tokens)
      ├── test_studio_text_descender_clipping.py (600 tokens)
      ├── test_sync_allow_scripts_pins.py (900 tokens)
      ├── test_tauri_branding_contract.py (2.7k tokens)
      ├── test_tauri_deep_link_contract.py (1500 tokens)
      ├── test_tauri_installer_resource_contract.py (600 tokens)
      ├── test_tauri_python_tool_images.py (600 tokens)
      ├── test_tee_stream_none_guard.py (1000 tokens)
      ├── test_token_count_prompt_parity.py (3.5k tokens)
      ├── test_torch_flavor.ps1 (1000 tokens)
      ├── test_torch_index_pin_hardening.ps1 (1200 tokens)
      ├── test_torch_overrides_merge.ps1 (1800 tokens)
      ├── test_training_config_filename_contract.py (500 tokens)
      ├── test_training_worker_contracts.py (400 tokens)
      ├── test_ui_font_scale_contract.py (1900 tokens)
      ├── test_ui_scripts_report_signals.py (900 tokens)
      ├── test_ui_shard_engines.py (1300 tokens)
      ├── test_uninstall_arg_guard.ps1 (1100 tokens)
      ├── test_uninstall_dual_install_icon.ps1 (1000 tokens)
      ├── test_uninstall_legacy_layout_gate.ps1 (4.4k tokens)
      ├── test_uninstall_prebuilt_parity.ps1 (700 tokens)
      ├── test_uninstall_reparse_stop_roots.ps1 (1800 tokens)
      ├── test_unsloth_torch_override.ps1 (1300 tokens)
      ├── test_update_release_notes.py (26.8k tokens)
      ├── test_usage_examples_agent_detection_contract.py (200 tokens)
      ├── test_usage_examples_model_source_contract.py (2.4k tokens)
      ├── test_uv_cache_discipline.py (3.8k tokens)
      ├── test_version_compat_bundle.py (1700 tokens)
      ├── test_voice_settings_select_width.py (100 tokens)
      ├── test_wait_for_first.py (1000 tokens)
      ├── test_whisper_binary_probe_denied.py (600 tokens)
      ├── test_windows_small_checks_stay_on_their_image.py (1200 tokens)
      ├── test_windows_ui_lanes_are_isolated.py (1700 tokens)
      ├── test_workflow_guards_run_unfiltered.py (1300 tokens)
      ├── test_xpu_arm64_torchaudio.ps1 (1000 tokens)
      ├── test_xpu_spoof_pipeline.py (4k tokens)
      ├── test_xpu_triton_swap.py (6.1k tokens)
      ├── test_zoo_suite_parallel_isolation.py (1700 tokens)
   ├── studio_setup_ps1/
      ├── Get-FunctionSource.ps1 (400 tokens)
      ├── Studio.Setup.FastWrapperFlags.Tests.ps1 (1300 tokens)
      ├── Studio.Setup.Output.Tests.ps1 (2.7k tokens)
      ├── Studio.Setup.Vs2026.Tests.ps1 (3.7k tokens)
   ├── test_accelerator_distributed_type_patch.py (700 tokens)
   ├── test_allow_cpu_import_driverless.py (2.3k tokens)
   ├── test_amp_helpers_every_device.py (600 tokens)
   ├── test_apertus_instruct_mapping.py (700 tokens)
   ├── test_attention_implementation.py (1400 tokens)
   ├── test_attn_dtype_custom_datatype.py (1100 tokens)
   ├── test_attn_impl_honor_explicit.py (1400 tokens)
   ├── test_bad_mappings_redirect.py (400 tokens)
   ├── test_bf16_quant_disabled_message.py (1400 tokens)
   ├── test_bnb_checkpoint_skip_modules.py (1500 tokens)
   ├── test_broken_tf_does_not_break_import.py (5.1k tokens)
   ├── test_broken_torchvision_probe.py (2.8k tokens)
   ├── test_callback_signature_drift.py (2.3k tokens)
   ├── test_cli_export_unpacking.py (1300 tokens)
   ├── test_collection_hygiene.py (700 tokens)
   ├── test_compressed_export_gpu_release.py (5.1k tokens)
   ├── test_construct_chat_template_processor.py (800 tokens)
   ├── test_cross_entropy_softcap_padding.py (1000 tokens)
   ├── test_cuda_spoof_reports_free_memory.py (600 tokens)
   ├── test_dataclass_default_backfill.py (1200 tokens)
   ├── test_deliberate_crashes_suppress_cores.py (11.9k tokens)
   ├── test_device_helpers.py (1400 tokens)
   ├── test_dill_module_by_value_fix.py (7.2k tokens)
   ├── test_dispatch_hook_repair.py (6.5k tokens)
   ├── test_enforce_kwargs_spacing.py (3.2k tokens)
   ├── test_enforce_kwargs_spacing_mode.py (300 tokens)
   ├── test_fa2_fast_generate_bypass.py (2.4k tokens)
   ├── test_fast_gemv_dispatch.py (500 tokens)
   ├── test_fast_generate_slow_guard.py (700 tokens)
   ├── test_finetune_last_n_layers.py (500 tokens)
   ├── test_flash_attn_4_namespace_shadow.py (2.3k tokens)
   ├── test_flex_attention_needs_ampere.py (900 tokens)
   ├── test_float32_generate_autocast.py (900 tokens)
   ├── test_float32_no_fp16_autocast.py (2.5k tokens)
   ├── test_for_training_generation_flag.py (600 tokens)
   ├── test_formatter_fixed_point.py (2.4k tokens)
   ├── test_fp8_device_context.py (1800 tokens)
   ├── test_fp8_fbgemm_block_shapes.py (2k tokens)
   ├── test_fp8_restore_dropped_scale.py (2.7k tokens)
   ├── test_fp8_tiny_e8m0.py (1000 tokens)
   ├── test_fused_ce_not_return_dict_logits.py (500 tokens)
   ├── test_gemma4_chat_template.py (1200 tokens)
   ├── test_gemma_2b_mapper_key.py (400 tokens)
   ├── test_generate_kwarg_gate.py (1200 tokens)
   ├── test_generation_failure_is_visible.py (600 tokens)
   ├── test_get_chat_template_processor.py (1300 tokens)
   ├── test_get_model_name.py (1400 tokens)
   ├── test_gguf_basename_platform_matrix.py (1100 tokens)
   ├── test_gguf_disk_headroom.py (7.9k tokens)
   ├── test_gguf_model_basename.py (2.1k tokens)
   ├── test_gguf_windows_export_routing.py (1600 tokens)
   ├── test_gguf_windows_native.py (900 tokens)
   ├── test_gradient_checkpointing_restore.py (1600 tokens)
   ├── test_grouped_gemm_optional_gather_indices.py (1200 tokens)
   ├── test_grpo_accumulated_loss_hidden_states_signal.py (1800 tokens)
   ├── test_grpo_autocast_disabled.py (2.1k tokens)
   ├── test_grpo_autocast_per_trainer.py (5.8k tokens)
   ├── test_grpo_hidden_states_logits_cost.py (3.7k tokens)
   ├── test_grpo_hidden_states_per_call_degradation.py (1400 tokens)
   ├── test_grpo_hidden_states_signal.py (2.9k tokens)
   ├── test_grpo_hidden_states_wrap_target.py (1000 tokens)
   ├── test_grpo_packed_raw_logits_nograd.py (3.7k tokens)
   ├── test_grpo_padded_raw_logits.py (3.5k tokens)
   ├── test_grpo_width_dispatch_sites.py (2.2k tokens)
   ├── test_heterogeneous_config_probes.py (1600 tokens)
   ├── test_ignored_tokenizer_casing.py (400 tokens)
   ├── test_import_fixes_drift.py (8.3k tokens)
   ├── test_installer_elevation_report.py (4.1k tokens)
   ├── test_installer_interactive_prompts.py (9.1k tokens)
   ├── test_installer_profile_hardening.py (17k tokens)
   ├── test_installer_shortcut_icons.py (900 tokens)
   ├── test_installer_skip_autostart.py (1100 tokens)
   ├── test_installer_system32_guard.py (13.4k tokens)
   ├── test_installer_unsloth_version.py (600 tokens)
   ├── test_kaggle_gguf_error_message.py (2.3k tokens)
   ├── test_lint_duplicate_definitions.py (1800 tokens)
   ├── test_lint_no_parallel_clamp.py (700 tokens)
   ├── test_loader_glob_skip.py (1000 tokens)
   ├── test_map_eos_token.py (2.7k tokens)
   ├── test_mapper_no_duplicate_keys.py (400 tokens)
   ├── test_merged_hub_destination.py (3.5k tokens)
   ├── test_missing_optional_dep_skips.py (600 tokens)
   ├── test_missing_torchvision_vlm.py (200 tokens)
   ├── test_model_registry.py (1900 tokens)
   ├── test_moe_lora_targets.py (1700 tokens)
   ├── test_multi_image_grpo_chunking.py (1200 tokens)
   ├── test_new_mapper_fetched_fp8.py (2.2k tokens)
   ├── test_new_mapper_no_global_leak.py (1900 tokens)
   ├── test_nvfp4_quant_load.py (900 tokens)
   ├── test_offline_loading_helpers.py (7.7k tokens)
   ├── test_offload_device_property.py (800 tokens)
   ├── test_offload_embedding_hooks.py (900 tokens)
   ├── test_offload_frozen_module_device.py (1900 tokens)
   ├── test_offload_tied_autodisable.py (2.8k tokens)
   ├── test_offload_tied_guard.py (400 tokens)
   ├── test_offloaded_parameter_hint.py (1100 tokens)
   ├── test_ollama_eos_token_order.py (600 tokens)
   ├── test_optimized_precision_conflicts.py (1700 tokens)
   ├── test_peft_stale_torchao.py (1700 tokens)
   ├── test_peft_symbol_backfill.py (1200 tokens)
   ├── test_peft_tensor_parallel_compat.py (1600 tokens)
   ├── test_peft_weight_converter_compat.py (1600 tokens)
   ├── test_prefetch_snapshot_scope.py (7.8k tokens)
   ├── test_pretrain_compile_reset.py (1200 tokens)
   ├── test_profile_startup_gate.py (2000 tokens)
   ├── test_psutil_apple_cpu_freq.py (3.4k tokens)
   ├── test_public_api_surface.py (1300 tokens)
   ├── test_push_to_ollama_modelfile_args.py (1300 tokens)
   ├── test_python39_compatibility.py (4.1k tokens)
   ├── test_pythonpath_empty_components.py (1400 tokens)
   ├── test_raw_text.py (5.7k tokens)
   ├── test_raw_text_json_loading.py (1100 tokens)
   ├── test_resolve_model_class.py (700 tokens)
   ├── test_rl_config_compat.py (3.9k tokens)
   ├── test_rmsnorm_gradient_layout.py (1000 tokens)
   ├── test_run_ruff_format_pin.py (3.1k tokens)
   ├── test_runtime_text_encoding.py (3.5k tokens)
   ├── test_save_entrypoints_reach_converter.py (1100 tokens)
   ├── test_save_lora_without_vllm.py (1800 tokens)
   ├── test_sdpa_fully_masked_rows.py (2.6k tokens)
   ├── test_settle_eager_fallbacks_between_steps.py (600 tokens)
   ├── test_sft_vision_dataset_gate.py (900 tokens)
   ├── test_source_read_encoding.py (10.6k tokens)
   ├── test_st_save_merged_signature.py (2.1k tokens)
   ├── test_st_subfolder_weights_are_fetched.py (2.7k tokens)
   ├── test_studio_install_workspace_guard.py (16.6k tokens)
   ├── test_studio_root_resilience.py (1500 tokens)
   ├── test_studio_shutdown_thread_wait.py (800 tokens)
   ├── test_synthetic_chunk_data.py (1300 tokens)
   ├── test_synthetic_vllm_startup_failure.py (3.1k tokens)
   ├── test_tool_mask_zoo_compat.py (700 tokens)
   ├── test_torch2110_cuda_extras.py (1600 tokens)
   ├── test_torchao_aten_grouped_mm.py (1500 tokens)
   ├── test_torchao_nf4tensor_move.py (2.2k tokens)
   ├── test_torchao_subprocess_fix.py (6.5k tokens)
   ├── test_torchao_torch_symbol_skew.py (2.5k tokens)
   ├── test_torchaudio_cuda_mismatch.py (2.1k tokens)
   ├── test_transformers5_bare_annotation_live.py (1300 tokens)
   ├── test_transformers_dependency_floor.py (3.2k tokens)
   ├── test_uma_safetensors_load.py (1600 tokens)
   ├── test_uninitialized_position_ids.py (500 tokens)
   ├── test_unsloth_device_map_leaks.py (2.1k tokens)
   ├── test_unsloth_device_map_optin.py (9k tokens)
   ├── test_unsloth_device_map_platform_matrix.py (3.6k tokens)
   ├── test_unsloth_device_map_review_fixes.py (4.2k tokens)
   ├── test_version_single_source.py (1700 tokens)
   ├── test_video_path_validation.py (4.6k tokens)
   ├── test_vllm_broken_detection.py (1200 tokens)
   ├── test_vllm_cuda_mismatch_wheel_url.py (2.5k tokens)
   ├── test_warnings_issued_guard.py (4.6k tokens)
   ├── test_wheel_smoke_publish_guard.py (2.5k tokens)
   ├── test_windows_amd_gpu_scan_fallback.py (9k tokens)
   ├── test_windows_no_sentencepiece.py (2.9k tokens)
   ├── test_windows_rocm_bnb_version.py (2.1k tokens)
   ├── utils/
      ├── __init__.py (200 tokens)
      ├── aime_eval.md (1300 tokens)
      ├── aime_eval.py (3.6k tokens)
      ├── cleanup_utils.py (1200 tokens)
      ├── data_utils.py (800 tokens)
      ├── generate_dataset_with_none.py (1300 tokens)
      ├── hf_utils.py (1600 tokens)
      ├── ocr_eval.md (600 tokens)
      ├── ocr_eval.py (2.2k tokens)
      ├── os_utils.py (1100 tokens)
      ├── perplexity_eval.md (100 tokens)
      ├── perplexity_eval.py (500 tokens)
      ├── run_none_detect_tests.py (4.8k tokens)
      ├── test_attention_dispatch_dora_dtype.py (1000 tokens)
      ├── test_attention_masks.py (4.8k tokens)
      ├── test_attn_mask_compat.py (2.1k tokens)
      ├── test_attn_mask_upstream_drift.py (2k tokens)
      ├── test_batched_leftpad_generation_gpu.py (800 tokens)
      ├── test_dataset_num_proc.py (14.3k tokens)
      ├── test_packing.py (11.3k tokens)
      ├── test_prepare_inputs_leftpad.py (2.9k tokens)
      ├── test_q_galore.py (3.9k tokens)
      ├── test_qat.py (1400 tokens)
      ├── test_rope_scaling_drift.py (4.3k tokens)
      ├── test_train_on_responses_only_num_proc.py (2.4k tokens)
      ├── test_trunc_normal_patch.py (900 tokens)
      ├── test_truncation_attestation.py (1800 tokens)
      ├── test_varlen_int32_overflow_guard.py (2k tokens)
      ├── test_xformers_capability_gate.py (900 tokens)
   ├── validate_studio_features.py (1900 tokens)
   ├── version_compat/
      ├── __init__.py
      ├── _fetch.py (400 tokens)
      ├── test_bitsandbytes_pinned_symbols.py (1800 tokens)
      ├── test_import_leaves_torch_globals_alone.py (1000 tokens)
      ├── test_peft_conversion_symbol_backfill.py (11.5k tokens)
      ├── test_peft_pinned_symbols.py (2.3k tokens)
      ├── test_sentence_transformers_pinned_symbols.py (1700 tokens)
      ├── test_transformers_pinned_symbols.py (2.7k tokens)
      ├── test_trl_fake_train_cpu.py (2.7k tokens)
      ├── test_trl_grpo_fake_run.py (2k tokens)
      ├── test_trl_grpo_pinned_symbols.py (5.3k tokens)
      ├── test_trl_loss_normalization_contract.py (2.6k tokens)
      ├── test_trl_padding_free_max_length.py (27.7k tokens)
      ├── test_trl_vllm_generation_lora_patch.py (4.2k tokens)
      ├── test_unsloth_zoo_save_merged_pinned_symbols.py (800 tokens)
   ├── vllm_compat/
      ├── __init__.py
      ├── test_extended_module_imports.py (2.1k tokens)
      ├── test_unsloth_zoo_imports.py (1200 tokens)
      ├── test_vllm_pinned_symbols.py (1800 tokens)
├── unsloth-cli.py (3.6k tokens)
├── unsloth/
   ├── __init__.py (13.4k tokens)
   ├── _auto_install.py (600 tokens)
   ├── _compressed_quantize.py (3.1k tokens)
   ├── _gpu_init.py (4.4k tokens)
   ├── _version.py (200 tokens)
   ├── bnb_availability.py (800 tokens)
   ├── chat_templates.py (26.9k tokens)
   ├── dataprep/
      ├── __init__.py (100 tokens)
      ├── raw_text.py (3.5k tokens)
      ├── synthetic.py (4.1k tokens)
      ├── synthetic_configs.py (800 tokens)
   ├── dataset_num_proc.py (5.7k tokens)
   ├── device_type.py (2k tokens)
   ├── disk_utils.py (800 tokens)
   ├── import_fixes.py (50.2k tokens)
   ├── kernels/
      ├── __init__.py (400 tokens)
      ├── cross_entropy_loss.py (3.1k tokens)
      ├── fast_lora.py (3.8k tokens)
      ├── flex_attention.py (1300 tokens)
      ├── fp8.py (5.9k tokens)
      ├── geglu.py (1700 tokens)
      ├── layernorm.py (1400 tokens)
      ├── moe/
         ├── LICENSE (6.9k tokens)
         ├── README.md (1200 tokens)
         ├── __init__.py
         ├── autotune_cache.py (3.2k tokens)
         ├── benchmark/
            ├── benchmark_fused_moe.py (2.7k tokens)
            ├── utils.py (1400 tokens)
         ├── grouped_gemm/
            ├── LICENSE (6.9k tokens)
            ├── __init__.py
            ├── interface.py (6.4k tokens)
            ├── kernels/
               ├── __init__.py
               ├── autotuning.py (2.2k tokens)
               ├── backward.py (3.9k tokens)
               ├── forward.py (1800 tokens)
               ├── tuning.py (1700 tokens)
            ├── reference/
               ├── __init__.py
               ├── layers/
                  ├── llama4_moe.py (3.4k tokens)
                  ├── qwen3_moe.py (2.6k tokens)
               ├── moe_block.py (1200 tokens)
               ├── moe_ops.py (800 tokens)
         ├── requirements.txt
         ├── tests/
            ├── __init__.py
            ├── common.py (2000 tokens)
            ├── moe_utils.py (3.6k tokens)
            ├── run_qwen3_moe_tests.sh (300 tokens)
            ├── test_grouped_gemm.py (8.6k tokens)
            ├── test_llama4_moe.py (1600 tokens)
            ├── test_qwen3_moe.py (2000 tokens)
      ├── rms_layernorm.py (2k tokens)
      ├── rope_embedding.py (2.8k tokens)
      ├── swiglu.py (800 tokens)
      ├── utils.py (7.2k tokens)
   ├── models/
      ├── __init__.py (300 tokens)
      ├── _attn_mask_compat.py (2.4k tokens)
      ├── _custom_dtype.py (900 tokens)
      ├── _uma_safetensors.py (1200 tokens)
      ├── _utils.py (35k tokens)
      ├── cohere.py (3.8k tokens)
      ├── diffusion.py (3.2k tokens)
      ├── dpo.py (200 tokens)
      ├── falcon_h1.py (5.5k tokens)
      ├── gemma.py (3.5k tokens)
      ├── gemma2.py (4.6k tokens)
      ├── glm4_moe.py (2.7k tokens)
      ├── granite.py (4.5k tokens)
      ├── llama.py (33.6k tokens)
      ├── llama4.py (100 tokens)
      ├── loader.py (21.1k tokens)
      ├── loader_utils.py (18.9k tokens)
      ├── mapper.py (10.4k tokens)
      ├── mistral.py (3.8k tokens)
      ├── qwen2.py (700 tokens)
      ├── qwen3.py (3.1k tokens)
      ├── qwen3_moe.py (1700 tokens)
      ├── rl.py (36.4k tokens)
      ├── rl_config_compat.py (3.4k tokens)
      ├── rl_replacements.py (31.7k tokens)
      ├── sentence_transformer.py (20.1k tokens)
      ├── vision.py (24.9k tokens)
   ├── ollama_template_mappers.py (16.7k tokens)
   ├── optimizers/
      ├── __init__.py (200 tokens)
      ├── q_galore_adamw.py (2.9k tokens)
      ├── q_galore_projector.py (2.5k tokens)
   ├── registry/
      ├── REGISTRY.md (700 tokens)
      ├── __init__.py (400 tokens)
      ├── _deepseek.py (1300 tokens)
      ├── _gemma.py (500 tokens)
      ├── _llama.py (800 tokens)
      ├── _mistral.py (600 tokens)
      ├── _phi.py (500 tokens)
      ├── _qwen.py (900 tokens)
      ├── registry.py (1200 tokens)
   ├── save.py (63.5k tokens)
   ├── tokenizer_utils.py (14.7k tokens)
   ├── trainer.py (8.6k tokens)
   ├── utils/
      ├── __init__.py (300 tokens)
      ├── attention_dispatch.py (5.1k tokens)
      ├── hf_hub.py (400 tokens)
      ├── packing.py (6k tokens)
      ├── prefix_grouper.py (2.9k tokens)
      ├── prefix_grouper_kernel.py (3.4k tokens)
├── unsloth_cli/
   ├── __init__.py (1700 tokens)
   ├── __main__.py (500 tokens)
   ├── _inference.py (7.1k tokens)
   ├── _model_catalog.py (5.8k tokens)
   ├── _studio_deps.py (6.1k tokens)
   ├── _studio_runtime_gate.py (2.9k tokens)
   ├── _studio_stage.py (1200 tokens)
   ├── _system_dir_guard.py (6k tokens)
   ├── _tool_policy.py (1200 tokens)
   ├── claude_subagent_mcp.py (3.4k tokens)
   ├── codex_fallback_prompt.md (4.1k tokens)
   ├── codex_subagent_mcp.py (1200 tokens)
   ├── commands/
      ├── __init__.py
      ├── _password_prompt.py (2.2k tokens)
      ├── chat.py (3.7k tokens)
      ├── export.py (1000 tokens)
      ├── inference.py (1100 tokens)
      ├── start.py (50.9k tokens)
      ├── studio.py (36k tokens)
      ├── train.py (1300 tokens)
   ├── config.py (1800 tokens)
   ├── options.py (1200 tokens)
   ├── pi_subagent.ts (2.6k tokens)
   ├── tests/
      ├── conftest.py (400 tokens)
      ├── test_claude_plan_gate.py (1300 tokens)
      ├── test_claude_subagent_mcp.py (4.1k tokens)
      ├── test_codex_subagent_mcp.py (2000 tokens)
      ├── test_inference_chat.py (21.7k tokens)
      ├── test_installer_download_markers.py (2.3k tokens)
      ├── test_pi_subagent.py (2.9k tokens)
      ├── test_start.py (73.7k tokens)
      ├── test_studio_cli_api_key.py (1300 tokens)
      ├── test_studio_cloudflare_flag.py (4.1k tokens)
      ├── test_studio_password_prompt.py (18.5k tokens)
      ├── test_studio_refresh_shortcuts_installer_source.py (3.3k tokens)
      ├── test_studio_run_parallel_flag.py (7.2k tokens)
      ├── test_studio_run_short_alias_clashes.py (3.7k tokens)
      ├── test_studio_runtime_gate_powershell.py (1800 tokens)
      ├── test_studio_secure_flag.py (3.4k tokens)
      ├── test_studio_stop.py (4.1k tokens)
      ├── test_studio_update_local_repo.py (2k tokens)
      ├── test_studio_update_stage.py (2.5k tokens)
      ├── test_studio_update_uv_cache.py (7.3k tokens)
      ├── test_studio_update_verify.py (7.1k tokens)
      ├── test_studio_verbose_flag.py (1000 tokens)
      ├── test_train_config_unknown_keys.py (1500 tokens)
```


## /.github/CODEOWNERS

```github/CODEOWNERS path="/.github/CODEOWNERS" 
# Inspired from https://github.com/vllm-project/vllm/blob/main/.github/CODEOWNERS
#
# Ordering matters: GitHub applies the LAST matching rule for a path, so the
# broad per-area rules come first and the narrow per-file overrides come last.
#
# Area owners:
#   @danielhanchen    training, RL, kernels, diffusion training
#   @Imagineer99      Studio UI / frontend
#   @wasimysaid       Tauri and the desktop app
#   @oobabooga        Studio packaging, install, compilation, inference,
#                     video / image diffusion serving
#   @Lyxot            macOS and MLX
#   @NilayYadav       MCP, `unsloth start`, the API surface
#   @LeoBorcherding   AMD / ROCm and Windows
#   @alkinun          Deep Research and RAG
#   @Etherll          Windows, image models, audio models
#   @shimmyshimmer    Studio UI


# ---------------------------------------------------------------------------
# Core library: training, kernels, model patching
# ---------------------------------------------------------------------------
/unsloth/ @danielhanchen
/unsloth/kernels/ @danielhanchen
/unsloth/kernels/moe/ @danielhanchen
/unsloth/models/ @danielhanchen
/unsloth/optimizers/ @danielhanchen
/unsloth/dataprep/ @danielhanchen
/unsloth/registry/ @danielhanchen
/unsloth/utils/ @danielhanchen
/unsloth/trainer.py @danielhanchen
/unsloth/save.py @danielhanchen
/unsloth/tokenizer_utils.py @danielhanchen
/unsloth/chat_templates.py @danielhanchen
/unsloth/ollama_template_mappers.py @danielhanchen
/unsloth/models/loader.py @danielhanchen
/unsloth/models/llama.py @danielhanchen
/unsloth/models/vision.py @danielhanchen
/unsloth/models/rl.py @danielhanchen
/unsloth/models/rl_replacements.py @danielhanchen
/unsloth/models/rl_config_compat.py @danielhanchen
/unsloth/models/mapper.py @danielhanchen
/unsloth/models/sentence_transformer.py @danielhanchen

# Diffusion / image model training lives in the core library.
/unsloth/models/diffusion.py @danielhanchen

# Device + install probing: AMD/ROCm and Windows behaviour is decided here.
/unsloth/device_type.py @danielhanchen
/unsloth/_gpu_init.py @danielhanchen
/unsloth/_auto_install.py @danielhanchen
/unsloth/import_fixes.py @danielhanchen


# ---------------------------------------------------------------------------
# CLI: `unsloth start`, `unsloth studio`, MCP subagents, local inference
# ---------------------------------------------------------------------------
/unsloth_cli/ @danielhanchen
/unsloth_cli/commands/start.py @danielhanchen
/unsloth_cli/commands/studio.py @danielhanchen
/unsloth_cli/commands/inference.py @danielhanchen
/unsloth_cli/commands/chat.py @danielhanchen
/unsloth_cli/commands/train.py @danielhanchen
/unsloth_cli/commands/export.py @danielhanchen
/unsloth_cli/_inference.py @danielhanchen
/unsloth_cli/_studio_deps.py @danielhanchen
/unsloth_cli/_studio_stage.py @danielhanchen
/unsloth_cli/_studio_runtime_gate.py @danielhanchen
/unsloth_cli/claude_subagent_mcp.py @danielhanchen
/unsloth_cli/codex_subagent_mcp.py @danielhanchen
/unsloth_cli/pi_subagent.ts @danielhanchen
/unsloth_cli/_model_catalog.py @danielhanchen
/cli.py @danielhanchen
/unsloth-cli.py @danielhanchen


# ---------------------------------------------------------------------------
# Studio backend
# ---------------------------------------------------------------------------
/studio/backend/ @danielhanchen
/studio/backend/main.py @danielhanchen
/studio/backend/run.py @danielhanchen
/studio/backend/mcp_server.py @danielhanchen
/studio/backend/cloudflare_tunnel.py @danielhanchen
/studio/backend/colab.py @danielhanchen
/studio/backend/startup_banner.py @danielhanchen
/studio/backend/auth/ @danielhanchen
/studio/backend/hub/ @danielhanchen
/studio/backend/picker/ @danielhanchen
/studio/backend/loggers/ @danielhanchen
/studio/backend/models/ @danielhanchen
/studio/backend/plugins/ @danielhanchen
/studio/backend/state/ @danielhanchen
/studio/backend/storage/ @danielhanchen
/studio/backend/vendor/ @danielhanchen
/studio/backend/assets/ @danielhanchen
/studio/backend/requirements/ @danielhanchen

# Backend API surface. Every route is part of the public API.
/studio/backend/routes/ @danielhanchen
/studio/backend/routes/inference.py @danielhanchen
/studio/backend/routes/llama.py @danielhanchen
/studio/backend/routes/models.py @danielhanchen
/studio/backend/routes/datasets.py @danielhanchen
/studio/backend/routes/training.py @danielhanchen
/studio/backend/routes/training_history.py @danielhanchen
/studio/backend/routes/training_vram.py @danielhanchen
/studio/backend/routes/export.py @danielhanchen
/studio/backend/routes/data_recipe/ @danielhanchen
/studio/backend/routes/chat_history.py @danielhanchen
/studio/backend/routes/settings.py @danielhanchen
/studio/backend/routes/rag.py @danielhanchen
/studio/backend/routes/research_runs.py @danielhanchen
/studio/backend/routes/mcp_servers.py @danielhanchen
/studio/backend/routes/providers.py @danielhanchen
/studio/backend/routes/provider_credentials.py @danielhanchen
/studio/backend/routes/video.py @danielhanchen
/studio/backend/routes/preview.py @danielhanchen
/studio/backend/routes/profile_stats.py @danielhanchen
/studio/backend/routes/auth.py @danielhanchen

# Inference engines: loading, compiling and serving models.
/studio/backend/core/ @danielhanchen
/studio/backend/core/inference/ @danielhanchen
/studio/backend/core/inference/llama_cpp.py @danielhanchen
/studio/backend/core/inference/sd_cpp_*.py @danielhanchen
/studio/backend/core/inference/diffusion*.py @danielhanchen
/studio/backend/core/inference/image_gallery.py @danielhanchen
/studio/backend/core/inference/search_images.py @danielhanchen
/studio/backend/core/inference/video*.py @danielhanchen
/studio/backend/core/inference/audio_*.py @danielhanchen
/studio/backend/core/inference/native_audio.py @danielhanchen
/studio/backend/core/inference/mlx_inference.py @danielhanchen
/studio/backend/core/inference/context_window.py @danielhanchen

# Training pipeline.
/studio/backend/core/training/ @danielhanchen
/studio/backend/core/training/diffusion_*.py @danielhanchen
/studio/backend/core/export/ @danielhanchen
/studio/backend/core/data_recipe/ @danielhanchen

# Deep Research and RAG.
/studio/backend/core/rag/ @danielhanchen
/studio/backend/core/research/ @danielhanchen
/studio/backend/core/research_runs.py @danielhanchen
/studio/backend/core/tool_healing.py @danielhanchen
/studio/backend/core/youtube_transcript.py @danielhanchen

# Backend utils.
/studio/backend/utils/ @danielhanchen
/studio/backend/utils/datasets/ @danielhanchen
/studio/backend/utils/models/ @danielhanchen
/studio/backend/utils/inference/ @danielhanchen
/studio/backend/utils/paths/ @danielhanchen
/studio/backend/utils/prebuilt/ @danielhanchen
/studio/backend/utils/security/ @danielhanchen
/studio/backend/utils/hardware/ @danielhanchen
/studio/backend/utils/hardware/amd.py @danielhanchen
/studio/backend/utils/llama_cpp_update.py @danielhanchen
/studio/backend/utils/llama_cpp_freshness.py @danielhanchen
/studio/backend/utils/whisper_cpp_update.py @danielhanchen
/studio/backend/utils/audio_tokens.py @danielhanchen
/studio/backend/utils/mlx_repair.py @danielhanchen
/studio/backend/utils/host_policy.py @danielhanchen
/studio/backend/utils/lan_access_settings.py @danielhanchen
/studio/backend/utils/remote_access_settings.py @danielhanchen
/studio/backend/utils/keyless_api_access.py @danielhanchen
/studio/backend/utils/node_runtime.py @danielhanchen
/studio/backend/utils/api_errors.py @danielhanchen
/studio/backend/utils/openai_auto_switch_settings.py @danielhanchen
/studio/backend/utils/transformers_version.py @danielhanchen
/studio/backend/utils/transformers_latest.py @danielhanchen
/studio/backend/utils/wheel_utils.py @danielhanchen
/studio/backend/utils/hf_xet_fallback.py @danielhanchen
/studio/backend/utils/hf_cache_settings.py @danielhanchen
/studio/backend/utils/hidden_models.py @danielhanchen
/studio/backend/utils/upload_limits.py @danielhanchen
/studio/backend/utils/studio_version.py @danielhanchen
/studio/backend/utils/update_status.py @danielhanchen
/studio/backend/utils/native_path_leases.py @danielhanchen
/studio/backend/utils/process_lifetime.py @danielhanchen
/studio/backend/utils/subprocess_compat.py @danielhanchen
/studio/backend/utils/torch_warmup.py @danielhanchen
/studio/backend/utils/cpu_threads.py @danielhanchen
/studio/backend/utils/cache_cleanup.py @danielhanchen
/studio/backend/utils/ssm_runtime.py @danielhanchen
/studio/backend/utils/training_runs.py @danielhanchen

/studio/backend/tests/ @danielhanchen


# ---------------------------------------------------------------------------
# Studio frontend: everything the user actually sees
# ---------------------------------------------------------------------------
/studio/frontend/ @danielhanchen
/studio/frontend/public/ @danielhanchen
/studio/frontend/src/app/ @danielhanchen
/studio/frontend/src/components/ @danielhanchen
/studio/frontend/src/components/ui/ @danielhanchen
/studio/frontend/src/components/assistant-ui/ @danielhanchen
/studio/frontend/src/components/tauri/ @danielhanchen
/studio/frontend/src/components/update/ @danielhanchen
/studio/frontend/src/hooks/ @danielhanchen
/studio/frontend/src/lib/ @danielhanchen
/studio/frontend/src/stores/ @danielhanchen
/studio/frontend/src/types/ @danielhanchen
/studio/frontend/src/utils/ @danielhanchen
/studio/frontend/src/config/ @danielhanchen
/studio/frontend/src/i18n/ @danielhanchen

/studio/frontend/src/features/ @danielhanchen
/studio/frontend/src/features/chat/ @danielhanchen
/studio/frontend/src/features/settings/ @danielhanchen
/studio/frontend/src/features/hub/ @danielhanchen
/studio/frontend/src/features/model-picker/ @danielhanchen
/studio/frontend/src/features/training/ @danielhanchen
/studio/frontend/src/features/images/ @danielhanchen
/studio/frontend/src/features/video/ @danielhanchen
/studio/frontend/src/features/audio/ @danielhanchen
/studio/frontend/src/features/rag/ @danielhanchen
/studio/frontend/src/features/export/ @danielhanchen
/studio/frontend/src/features/recipe-studio/ @danielhanchen
/studio/frontend/src/features/data-recipes/ @danielhanchen
/studio/frontend/src/features/native-intents/ @danielhanchen
/studio/frontend/src/features/deep-links/ @danielhanchen
/studio/frontend/src/features/api-monitor/ @danielhanchen
/studio/frontend/src/features/credentials/ @danielhanchen
/studio/frontend/src/features/auth/ @danielhanchen
/studio/frontend/src/features/hf-auth/ @danielhanchen
/studio/frontend/src/features/security/ @danielhanchen
/studio/frontend/src/features/generation-presets/ @danielhanchen
/studio/frontend/src/features/loaded-models/ @danielhanchen
/studio/frontend/src/features/transformers-upgrade/ @danielhanchen
/studio/frontend/src/features/chat/lib/mlx-runtime-state.ts @danielhanchen
/studio/frontend/src/features/studio/sections/use-mlx-training-config-policy.ts @danielhanchen


# ---------------------------------------------------------------------------
# Desktop app (Tauri)
# ---------------------------------------------------------------------------
/studio/src-tauri/ @danielhanchen
/studio/src-tauri/src/ @danielhanchen
/studio/src-tauri/capabilities/ @danielhanchen
/studio/src-tauri/tauri.macos.conf.json @danielhanchen
/studio/src-tauri/Entitlements.plist @danielhanchen
/studio/src-tauri/Info.plist @danielhanchen
/studio/src-tauri/dmg/ @danielhanchen
/studio/src-tauri/tauri.windows.conf.json @danielhanchen
/studio/src-tauri/windows/ @danielhanchen
/studio/src-tauri/src/windows_job.rs @danielhanchen
/studio/src-tauri/linux/ @danielhanchen
/studio/src-tauri/tauri.linux.conf.json @danielhanchen
/studio/src-tauri/src/linux_webkit.rs @danielhanchen
/studio/src-tauri/src/x11_threads.rs @danielhanchen


# ---------------------------------------------------------------------------
# Packaging, installation and compilation
# ---------------------------------------------------------------------------
/build.sh @danielhanchen
/pyproject.toml @danielhanchen
/install.sh @danielhanchen
/install.ps1 @danielhanchen
/studio/setup.sh @danielhanchen
/studio/setup.ps1 @danielhanchen
/studio/setup.bat @danielhanchen
/studio/install_manifest.py @danielhanchen
/studio/install_python_stack.py @danielhanchen
/studio/install_llama_prebuilt.py @danielhanchen
/studio/install_node_prebuilt.py @danielhanchen
/studio/install_sd_cpp_prebuilt.py @danielhanchen
/studio/install_whisper_prebuilt.py @danielhanchen
/studio/prebuilt_core.py @danielhanchen
/studio/Unsloth_Studio_Colab.ipynb @danielhanchen


# ---------------------------------------------------------------------------
# Scripts
# ---------------------------------------------------------------------------
/scripts/ @danielhanchen
/scripts/uninstall.ps1 @danielhanchen
/scripts/install_rocm_wsl_strixhalo.sh @danielhanchen
/scripts/install_gemma4_mlx.sh @danielhanchen
/scripts/install_qwen3_6_mlx.sh @danielhanchen
/scripts/make_dmg_background.py @danielhanchen
/scripts/build_whisper_cpp.sh @danielhanchen
/scripts/sd_cpp_smoke.py @danielhanchen
/scripts/diffusion_bench.py @danielhanchen
/scripts/diffusion_quality.py @danielhanchen
/scripts/video_quality.py @danielhanchen
/scripts/image_speedmem_bench.py @danielhanchen
/scripts/fbcache_flux_probe.py @danielhanchen
/scripts/notebook_to_python.py @danielhanchen
/scripts/notebook_validator.py @danielhanchen


# ---------------------------------------------------------------------------
# Tests
# ---------------------------------------------------------------------------
/tests/ @danielhanchen
/tests/studio/ @danielhanchen
/tests/studio_setup_ps1/ @danielhanchen
/tests/sh/ @danielhanchen


# ---------------------------------------------------------------------------
# CI definitions. A workflow change can hand a fork PR the base repo's
# secrets, or skip the very lint that would have caught it, and no CI gate
# can stop a PR that disables its own gate. Owner review is the control.
# ---------------------------------------------------------------------------
/.github/ @danielhanchen
/.github/workflows/ @danielhanchen
/.github/scripts/ @danielhanchen
/.github/CODEOWNERS @danielhanchen

# Platform-specific CI still needs its platform owner alongside @danielhanchen
/.github/workflows/mlx-ci.yml @danielhanchen
/.github/workflows/studio-mac-*.yml @danielhanchen
/.github/workflows/studio-windows-*.yml @danielhanchen
/.github/workflows/windows-application-control-ci.yml @danielhanchen
/.github/workflows/studio-tauri-smoke.yml @danielhanchen
/.github/workflows/release-desktop.yml @danielhanchen
/.github/workflows/publish-desktop-updater.yml @danielhanchen
/.github/workflows/desktop-app-clean-machine-ci.yml @danielhanchen
/.github/workflows/clean-machine-install-ci.yml @danielhanchen
/.github/workflows/interrupted-install-ci.yml @danielhanchen
/.github/workflows/studio-inference-smoke.yml @danielhanchen
/.github/workflows/studio-ui-smoke.yml @danielhanchen
/.github/workflows/studio-frontend-ci.yml @danielhanchen
/.github/workflows/studio-api-smoke.yml @danielhanchen
/.github/scripts/virgin-windows-*.ps1 @danielhanchen
/.github/scripts/assert-bundle-signed.ps1 @danielhanchen

# Snapshot data for the notebook linter / Colab oracle. Drift in these
# files changes the pin floor for every Unsloth notebook, so refreshes
# must be reviewed by the repo owner directly. CODEOWNERS later
# wins, so this overrides the broader /scripts/ rule above.
/scripts/data/colab_*.txt  @danielhanchen
/scripts/data/colab_*.json @danielhanchen

```

## /.github/FUNDING.yml

```yml path="/.github/FUNDING.yml" 
# These are supported funding model platforms

github: unslothai
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # unsloth
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

```

## /.github/ISSUE_TEMPLATE/bug---issue.md

---
name: Bug / Issue
about: Bug / Issue
title: "[Bug] Please fill in your issue title here."
labels: bug, feature request
assignees: ''

---

---
name: Unsloth Studio Bug
about: Report a problem with the Unsloth Studio desktop app or web UI
title: "[Unsloth Bug] "
labels: bug
assignees: ""
---

<!--
Search existing issues before submitting. Please do not remove the questions.
Never post API keys, Hugging Face tokens, passwords, cookies, private prompts,
datasets, or other sensitive information.
-->

## Environment

**Where are you using Unsloth?**

- [ ] Unsloth desktop application
- [ ] Unsloth web UI (`unsloth studio`)
- [ ] Unsloth CLI
- [ ] Python package or notebook
- [ ] Colab or Kaggle

**Operating system and version:**

**GPU model(s) and accelerator backend:**
<!-- Examples: NVIDIA CUDA, AMD ROCm, Intel XPU, Apple MLX, CPU. -->

**Versions:**
<!--
For Unsloth, copy the Unsloth, package, desktop, and llama.cpp versions from
Settings → About when available.
-->

## What happened?

**Steps to reproduce:**

1.
2.
3.

**Expected behavior:**

**Actual behavior:**

**Model and operation involved:**
<!--
Include the model ID or filename and whether this involved installation,
startup, download, training, inference, GGUF, diffusion, or export.
-->

## Diagnostics and logs

<!--
Remove API keys, Hugging Face tokens, passwords, cookies, private prompts,
local paths you do not want to disclose, and other sensitive information.
Do not upload your entire ~/.unsloth/studio directory: it can contain auth
state, databases, chats, datasets, and models.
-->

### Desktop application

Click **Copy Diagnostics** on the error, startup, or update screen and paste the
result below:

```text
PASTE COPY DIAGNOSTICS HERE
```

If **Copy Diagnostics** is unavailable, attach the newest relevant files from:

- Windows: `%USERPROFILE%\.unsloth\studio\`
- Linux/macOS: `~/.unsloth/studio/`

Useful files include:

- `tauri.log` and, if relevant, `tauri.log.1`
- `logs/install-*.log`, `logs/update-*.log`, `logs/repair-*.log`, or `logs/backend-*.log`
- The newest `logs/server/server-*.log`

### Unsloth web UI

Attach the newest relevant items:

- Linux/macOS/Windows: `~/.unsloth/studio/logs/server/server-*.log`
  (use `%USERPROFILE%\.unsloth\studio\logs\server\` on Windows)
- Linux/macOS shortcut launches only: `~/.local/share/unsloth/studio.log`
- Terminal output if Unsloth was launched from a terminal
- Browser Console errors for browser-only problems

If you configured `UNSLOTH_STUDIO_HOME` or `STUDIO_HOME`, look under
`<CUSTOM_STUDIO_HOME>/logs/` instead.

### Model-specific logs, if applicable

- GGUF/llama.cpp: newest `~/.unsloth/studio/logs/llama-server/*.log`
- Diffusion GGUF: newest `~/.unsloth/studio/logs/diffusion-server/*.log`
- Training resume/checkpoint bug: relevant `trainer_state.json`

### Python package or notebook, if applicable

Paste the complete traceback and minimal reproduction:

```python
# Remove all tokens and private data.
```

Also include Python, Unsloth, unsloth_zoo, PyTorch, Transformers, and TRL
versions, plus `nvidia-smi` output when applicable.

## Additional context

<!-- Add screenshots or anything else that may help. -->


## /.github/ISSUE_TEMPLATE/feature-request.md

---
name: Feature Request
about: New features, model support, ideas
title: "[Feature]"
labels: feature request
assignees: ''

---

For new models, have you tried:
```python
from unsloth import FastModel
model, tokenizer = FastModel.from_pretrained(
    "microsoft/Phi-4-multimodal-instruct",
    trust_remote_code = True,
)
from transformers import AutoModelForSequenceClassification
model, tokenizer = FastModel.from_pretrained(
    auto_model = AutoModelForSequenceClassification,
)
```


## /.github/actions/frontend-dist-restore/action.yml

```yml path="/.github/actions/frontend-dist-restore/action.yml" 
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.

# Restore half of the built-frontend cache. Pair it with frontend-dist-save AFTER
# the install, passing the outputs below.
#
# WHY THIS IS AN ACTION AND NOT FOUR STEPS IN A WORKFLOW
# ---------------------------------------------------------------------------
# The cache is correct only because two independent places agree:
#
#   studio/setup.sh    rebuilds when anything under frontend/ (maxdepth 1, minus
#                      bun.lock), frontend/src or frontend/public is NEWER than
#                      frontend/dist
#   studio/setup.ps1   the same predicate, over the same three groups, against
#                      `(Get-Item $DistDir).LastWriteTime`
#   the key below      hashes exactly those three path groups
#
# A hit therefore means the build inputs are byte-identical, which is strictly
# stronger than the mtime test it rides on, and it makes a restored dist correct
# by construction rather than by luck.
#
# Break that agreement and NOTHING GOES RED. The cache keeps hitting and quietly
# starts serving a dist built from inputs the key no longer covers. So the key
# gets exactly one definition -- this one. `install-unsloth-local` delegates
# here rather than carrying its own copy, because two copies of a key whose drift
# is silent will drift, and the twelve workflows that now share it would drift twelve
# ways. tests/studio/test_frontend_dist_cache.py holds the agreement together and
# is where the reasoning lives.
#
# Measured: 36s median of a 74s install on Linux (13 jobs), and 96s of a ~257s
# install on Windows (`[72s] building frontend...` -> `[168s] frontend built`),
# every job, every commit, producing byte-identical output.

name: Restore the built frontend
description: >-
  Restore studio/frontend/dist for this runner, keyed on exactly the sources
  setup.sh and setup.ps1 check before rebuilding, and make the restored directory
  outrank the checkout that just wrote those sources. Read-only: the save is a
  separate action and runs on the default branch only.

inputs:
  path-prefix:
    description: >-
      Where actions/checkout put THIS repo, WITH a trailing slash ("unsloth/"),
      or the empty string when it is at the workspace root.

      Not cosmetic. `hashFiles()` resolves from GITHUB_WORKSPACE, not from the
      workflow file, so a job that checks the repo out into a subdirectory and
      leaves this empty gets globs that match nothing -- and hashFiles returns
      the EMPTY STRING for that rather than failing, which collapses every commit
      onto one key and serves an arbitrary dist. The degenerate-key step below
      refuses that outright, and a prefix missing its trailing slash lands in the
      same place (loudly), so both mistakes fail at the first step rather than
      silently.
    required: false
    default: ''

outputs:
  cache-hit:
    description: "'true' when the exact key was restored."
    value: ${{ steps.restore.outputs.cache-hit }}
  key:
    description: The full cache key, to hand to frontend-dist-save.
    value: ${{ steps.restore.outputs.cache-primary-key }}
  dist-path:
    description: The dist directory this action restored, prefix included.
    value: ${{ inputs.path-prefix }}studio/frontend/dist

runs:
  using: composite
  steps:
    # Before the restore, not after: an empty key would otherwise be used to look
    # something up first, and on a repo where some other branch once saved under
    # the same empty key that lookup HITS.
    - name: Refuse a frontend cache key that hashes nothing
      shell: bash
      env:
        FE_KEY: ${{ hashFiles(format('{0}studio/frontend/*', inputs.path-prefix), format('{0}studio/frontend/src/**', inputs.path-prefix), format('{0}studio/frontend/public/**', inputs.path-prefix), format('!{0}studio/frontend/tests/**', inputs.path-prefix), format('!{0}studio/frontend/scripts/**', inputs.path-prefix)) }}
        FE_PREFIX: ${{ inputs.path-prefix }}
      run: |
        # hashFiles returns "" when a glob matches no file, which would collapse
        # every commit onto one key and serve an arbitrary dist. That is the one
        # way this cache can be actively WRONG rather than merely useless, and it
        # is invisible: the restore succeeds and the build is skipped.
        if [ -z "$FE_KEY" ]; then
          echo "::error::hashFiles matched no frontend sources under '${FE_PREFIX}studio/frontend', so the dist cache key is degenerate. Either this job checks the repo out into a subdirectory and did not pass path-prefix (which must end in '/'), or the frontend layout moved -- in which case update this action and tests/studio/test_frontend_dist_cache.py together."
          exit 1
        fi

    - name: Restore the built frontend
      id: restore
      uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9  # v6.1.0
      # A cache is an optimisation; a cache service blip must not fail the job.
      continue-on-error: true
      with:
        path: ${{ inputs.path-prefix }}studio/frontend/dist
        # NO restore-keys, deliberately, and the opposite of the uv download cache
        # in install-unsloth-local. A near-miss download cache still supplies most
        # of the wheels, which is most of the win. A near-miss dist is a bundle
        # built from DIFFERENT source: wrong, not partial. Only an exact match may
        # be served.
        key: fe-dist-${{ runner.os }}-${{ hashFiles(format('{0}studio/frontend/*', inputs.path-prefix), format('{0}studio/frontend/src/**', inputs.path-prefix), format('{0}studio/frontend/public/**', inputs.path-prefix), format('!{0}studio/frontend/tests/**', inputs.path-prefix), format('!{0}studio/frontend/scripts/**', inputs.path-prefix)) }}

    # THE STEP THE WHOLE CACHE RESTS ON, and the one that is silent when wrong.
    #
    # actions/cache restores through tar, which preserves the ORIGINAL mtimes. A
    # dist restored that way is older than the checkout that just wrote every
    # source file, so the staleness check sees the whole tree as newer and rebuilds
    # anyway. The cache would report a hit, cost a download, and save nothing --
    # green job, healthy-looking hit rate, 96s still spent.
    #
    # Touching the DIRECTORY is what makes the hit count, and it is honest because
    # the key already proved the inputs are byte-identical. The directory only:
    # both scripts compare against `frontend/dist` itself, not its contents.
    - name: Make the restored frontend outrank its sources (POSIX)
      if: steps.restore.outputs.cache-hit == 'true' && runner.os != 'Windows'
      shell: bash
      env:
        DIST: ${{ inputs.path-prefix }}studio/frontend/dist
        FE: ${{ inputs.path-prefix }}studio/frontend
      run: |
        if [ ! -d "$DIST" ]; then
          echo "::error::the frontend dist cache reported a hit but restored no directory at $DIST"
          exit 1
        fi
        touch "$DIST"
        # Read it back and evaluate setup.sh's own predicate here, where it can be
        # reported. `touch` succeeding is not the same claim as `find -newer dist`
        # coming back empty, and only the second one stops the rebuild.
        newer=$(find "$FE" -maxdepth 1 -type f ! -name 'bun.lock' -newer "$DIST" -print -quit 2> /dev/null)
        if [ -z "$newer" ]; then
          newer=$(find "$FE/src" "$FE/public" -type f -newer "$DIST" -print -quit 2> /dev/null) || true
        fi
        if [ -n "$newer" ]; then
          echo "::error::$DIST was touched but $newer is still newer, so setup.sh will rebuild the frontend it just restored"
          exit 1
        fi
        echo "restored a prebuilt frontend; setup.sh will report it up to date"

    # pwsh rather than `shell: bash` + `touch`, even though Git Bash is present on
    # windows-latest and these workflows already use it as their default shell.
    #
    # setup.ps1 reads `(Get-Item $DistDir).LastWriteTime`. This writes that exact
    # property, by name, through the same API -- so no inference is required about
    # whether MSYS `utimensat` on a DIRECTORY handle lands in the field NTFS
    # reports there. `touch` may well work; it just cannot be checked from the
    # Linux box where this was written, and the cost of it silently not working is
    # a cache that hits and rebuilds anyway, which is the failure this whole action
    # exists to prevent. The POSIX branch keeps the `touch` that is measured
    # working on main rather than churning a proven path.
    - name: Make the restored frontend outrank its sources (Windows)
      if: steps.restore.outputs.cache-hit == 'true' && runner.os == 'Windows'
      shell: pwsh
      env:
        DIST: ${{ inputs.path-prefix }}studio/frontend/dist
        FE: ${{ inputs.path-prefix }}studio/frontend
      run: |
        $ErrorActionPreference = 'Stop'
        $dist = $env:DIST
        $fe = $env:FE
        if (-not (Test-Path -LiteralPath $dist -PathType Container)) {
          Write-Host "::error::the frontend dist cache reported a hit but restored no directory at $dist"
          exit 1
        }
        (Get-Item -LiteralPath $dist).LastWriteTime = Get-Date

        # Read it back and evaluate setup.ps1:3526-3549's own predicate here, over
        # the same three groups, so a touch that did not take is reported instead of
        # showing up as 96s nobody attributes.
        $distTime = (Get-Item -LiteralPath $dist).LastWriteTime
        $newer = $null
        foreach ($subDir in @('src', 'public')) {
          $subPath = Join-Path $fe $subDir
          if (Test-Path -LiteralPath $subPath) {
            $newer = Get-ChildItem -LiteralPath $subPath -Recurse -File -ErrorAction SilentlyContinue |
              Where-Object { $_.LastWriteTime -gt $distTime } | Select-Object -First 1
            if ($newer) { break }
          }
        }
        if (-not $newer) {
          $newer = Get-ChildItem -LiteralPath $fe -File -ErrorAction SilentlyContinue |
            Where-Object { $_.Name -ne 'bun.lock' -and $_.LastWriteTime -gt $distTime } |
            Select-Object -First 1
        }
        if ($newer) {
          Write-Host "::error::$dist was stamped $distTime but $($newer.FullName) is still newer, so setup.ps1 will rebuild the frontend it just restored"
          exit 1
        }
        Write-Host "restored a prebuilt frontend; setup.ps1 will report it up to date"

```

## /.github/actions/frontend-dist-save/action.yml

```yml path="/.github/actions/frontend-dist-save/action.yml" 
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.

# Save half of the built-frontend cache, plus the one assertion that stops this
# cache from failing silently. See frontend-dist-restore for why the pair is split
# and where the key's reasoning lives. Run this AFTER the install step.
#
# THE ASSERTION IS THE POINT
# ---------------------------------------------------------------------------
# Every other way this cache goes wrong is loud. This one is not: if the restored
# dist does not end up NEWER than the checked-out sources, setup.sh / setup.ps1
# rebuild it anyway. The job goes green, `Cache hit for: fe-dist-...` still appears
# in the log, the cache dashboard shows a healthy hit rate, and the only trace is
# the 36s (Linux) / 96s (Windows) that the cache was supposed to remove and that
# nobody attributes to anything. That state is indistinguishable from success
# unless something looks.
#
# So something looks. The install already tees its output to a log; a hit that was
# followed by a rebuild marker fails the job here, once, in one place, for every
# call site. tests/studio/test_frontend_dist_cache.py pins the markers against the
# two installer scripts, so a rename goes red in pytest rather than quietly
# disarming this.

name: Save the built frontend
description: >-
  Prove a restored frontend was actually reused rather than rebuilt, then save
  studio/frontend/dist under the restore step's key, on the default branch only.

inputs:
  path-prefix:
    description: >-
      The same value passed to frontend-dist-restore: where actions/checkout put
      this repo, WITH a trailing slash, or the empty string.
    required: false
    default: ''
  cache-hit:
    description: >-
      frontend-dist-restore's `cache-hit` output. Drives both halves: 'true' means
      assert the restore was reused and skip the save (the key is already present,
      re-uploading it is pure cost); anything else means the build really ran and
      is worth saving.
    required: true
  key:
    description: frontend-dist-restore's `key` output.
    required: true
  save:
    description: >-
      'false' to run the reuse assertion but skip the upload. For a workflow whose
      triggers cannot routinely put github.ref on refs/heads/main -- no `push`, no
      `schedule` -- where the save below could only fire if a human dispatched the
      workflow from main by hand. A cache that fills only when somebody remembers to
      press a button is not a cache, and leaving the step in place would be config that
      reads as a caching decision which is not in force.

      The assertion half still runs, deliberately: it is the only check on the one
      failure mode this cache has that nothing else reveals, and a consumer-only lane is
      as good a place to catch it as a producer.
    required: false
    default: 'true'
  install-log:
    description: >-
      Path to the installer log this job teed, used for the reuse assertion. Every
      call site writes logs/install.log, which is why that is the default; a job
      that writes somewhere else must say so rather than have the assertion quietly
      find no file and pass.
    required: false
    default: logs/install.log

runs:
  using: composite
  steps:
    - name: Prove the restored frontend was reused and not rebuilt
      if: inputs.cache-hit == 'true'
      shell: bash
      env:
        INSTALL_LOG: ${{ inputs.install-log }}
        DIST: ${{ inputs.path-prefix }}studio/frontend/dist
      run: |
        # A missing log is a failure, not a skip. "The assertion found nothing to
        # read" and "the assertion passed" must not look the same, or this guard
        # disarms itself the first time a call site moves its log.
        if [ ! -f "$INSTALL_LOG" ]; then
          echo "::error::the frontend dist cache hit, but $INSTALL_LOG does not exist, so whether the restored dist was reused or rebuilt cannot be checked. Pass install-log pointing at the log this job actually writes."
          exit 1
        fi
        if [ ! -d "$DIST" ]; then
          echo "::error::the frontend dist cache hit, but $DIST is gone after the install"
          exit 1
        fi
        # setup.sh:1265 and setup.ps1:3633 both emit this immediately before running
        # the bundler. Seeing it after a HIT means the restored dist did not outrank
        # its sources and the cache cost a download and saved nothing.
        if grep -qi 'building frontend' "$INSTALL_LOG"; then
          echo "::error::the frontend dist cache reported a hit and the installer rebuilt the frontend anyway, so the cache cost a download and saved nothing. The restored dist did not end up newer than the checked-out sources -- check the touch step in frontend-dist-restore for this runner's OS."
          grep -n -i -E 'frontend' "$INSTALL_LOG" | tail -20
          exit 1
        fi
        # The same fact from the other side. Either marker being renamed would
        # otherwise disarm the check above without anything going red;
        # tests/studio/test_frontend_dist_cache.py pins both against the scripts.
        if ! grep -qi 'frontend.*up to date' "$INSTALL_LOG"; then
          echo "::error::the frontend dist cache hit and the installer did not report the frontend up to date. Either the staleness check no longer prints that, or it took a branch nobody expected here."
          grep -n -i -E 'frontend' "$INSTALL_LOG" | tail -20
          exit 1
        fi
        echo "the restored frontend was reused; no rebuild happened"

    # Main only, the rule every cache in this repo follows: a PR-scoped entry can
    # only be restored by re-runs of that same PR while still counting against the
    # shared 50 GiB budget -- measured 99.3% full once already -- evicting the copy
    # on main that every PR can read.
    #
    # Deliberately NOT `always()`. A save whose payload was produced by an earlier
    # step must not run when that step failed, or a half-built dist gets stored
    # under an immutable key and served to every later run
    # (tests/studio/test_cache_budget_discipline.py has the Playwright version of
    # that story). Leaving the condition off `always()` means a failed install
    # simply skips this step, which is the behaviour wanted.
    - name: Save the built frontend
      if: >-
        github.ref == 'refs/heads/main' && inputs.cache-hit != 'true'
        && inputs.save != 'false'
      uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9  # v6.1.0
      continue-on-error: true
      with:
        path: ${{ inputs.path-prefix }}studio/frontend/dist
        key: ${{ inputs.key }}

```

## /.github/actions/install-unsloth-local/action.yml

```yml path="/.github/actions/install-unsloth-local/action.yml" 
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.

# The POSIX `install.sh --local --no-torch` bootstrap, which 13 jobs across 8
# workflows ran with a byte-identical body. Extracted so the invocation has one
# definition: the `set -o pipefail` + `tee` idiom is easy to get subtly wrong
# (without pipefail the step reports the exit status of `tee`, not of
# install.sh, and a failed install passes), and a flag or log-path change
# previously had to be applied to 13 places consistently.
#
# Deliberately NOT parameterised beyond the two tokens. This action is "the
# standard local no-torch install", not a general installer wrapper: giving it
# an `args` input would let call sites drift apart again, which is the thing it
# exists to prevent. The Windows `install.ps1` path is a different script with a
# different body and stays separate.
#
# Composite actions cannot read the `secrets` context, so both tokens are
# explicit inputs that each caller passes. That is not boilerplate for its own
# sake: it keeps the PR-withholding decision visible at the call site, where it
# belongs, rather than hidden behind a default.
#
# Keep `id`, `if`, `timeout-minutes` and `continue-on-error` on the CALLER's
# step. They are step-level keys on the `uses:` step, so `steps.<id>.outcome`
# gating in the caller keeps working unchanged; the caller sees this action as a
# single step and cannot inspect the steps inside it.

name: Install Unsloth (--local, --no-torch)
description: >-
  Run the checked-out install.sh in --local --no-torch mode, teeing the
  installer output to logs/install.log. Requires actions/checkout to have run.

inputs:
  gh-token:
    description: >-
      Token for installer calls that hit the GitHub API (release lookups for the
      llama.cpp prebuilt). Normally secrets.GITHUB_TOKEN.
    required: true
  hf-token:
    description: >-
      Hugging Face token, or the empty string to run unauthenticated. Callers
      that can reach this step on a pull_request event should withhold it,
      because this step executes checked-out PR code; public models still
      download without it. The idiom every such caller uses is a conditional on
      github.event_name that yields secrets.HF_TOKEN off pull_request and an
      empty string on it (see any call site). Callers whose job cannot run on
      pull_request, such as a workflow_dispatch-only job, may pass it
      unconditionally.

      Do not write that conditional out as a literal template expression here.
      GitHub evaluates expression syntax inside an action manifest, including
      inside these description strings, and neither the github nor the secrets
      context exists at manifest-parse time, so an example written out in full
      fails the whole action with "Unrecognized named-value: 'github'".
    required: false
    default: ''

runs:
  using: composite
  steps:
    # The uv download cache. Delegated, like the frontend dist below, so the key has
    # exactly one definition: the Windows jobs run install.ps1 from a hand-written pwsh
    # step and never come through here, and a second copy would drift silently. The
    # reasoning lives in .github/actions/uv-cache-restore, which folds the UV_CACHE_DIR
    # setter and the restore into this one step; tests/studio/test_uv_cache_discipline.py
    # inlines them again and still checks their order against the install.
    - name: Restore the uv download cache
      id: uv-cache
      uses: ./.github/actions/uv-cache-restore

    # The frontend build is the other half of this step, and unlike the wheels it is
    # not a download at all. Measured over 13 distinct Linux jobs on main, using the
    # elapsed-second prefix below: a median 36s of a 74s install, 49% of it, and
    # 468s per commit spent producing byte-identical output. The uv cache above
    # already hits exactly (`Cache hit for: uv-Linux-<hash>`, one 31 kB straggler),
    # so what is left is compute, and the only way to stop paying it 13 times is to
    # not do it 13 times.
    #
    # Delegated rather than written out here, since #9375, because the Windows jobs
    # need the identical cache and do not go through this action: they run
    # `install.ps1` from a hand-written `shell: pwsh` step. Two copies of a key whose
    # drift is SILENT will drift -- the cache keeps hitting and starts serving a dist
    # built from inputs the key no longer covers -- so the key has exactly one
    # definition, in frontend-dist-restore, and that is where its reasoning lives.
    #
    # This action is therefore ROOT-CHECKOUT ONLY, and more explicitly than before.
    # `uses: ./...` resolves from GITHUB_WORKSPACE and does not accept expressions,
    # so the two references below cannot be prefixed for a job that checks this repo
    # out into a subdirectory; such a job fails outright with "Can't find
    # 'action.yml'". No caller does that today -- every call site is
    # `./.github/actions/install-unsloth-local` -- and
    # tests/studio/test_frontend_dist_cache.py asserts it stays true, so the next
    # person meets a named rule instead of that error message. A nested-checkout job
    # that wants the dist cache calls frontend-dist-restore/-save directly and passes
    # their `path-prefix`, which is exactly what the Windows call sites do.
    #
    # (The runner resolves `./X` as `$GITHUB_WORKSPACE/X` unconditionally -- there is
    # no branch that consults the referencing action's own directory, and `uses:`
    # takes no expressions, so this cannot be parameterised. actions/runner#1348 is
    # the open bug. If the constraint ever needs lifting, the fix is the
    # self-repository `uses:` syntax that went GA on 2026-07-30, which resolves
    # against the repo at the running commit rather than the workspace; it needs
    # runner >= 2.336.0, is unavailable on GHES, and nothing in this repo uses it
    # yet, so adopting it is a separate decision from this one.)
    - name: Restore the built frontend
      id: fe-dist
      uses: ./.github/actions/frontend-dist-restore

    - name: Install Unsloth (--local, --no-torch)
      shell: bash
      env:
        GH_TOKEN: ${{ inputs.gh-token }}
        HF_TOKEN: ${{ inputs.hf-token }}
      run: |
        mkdir -p logs
        set -o pipefail
        # Elapsed-seconds prefix, added to the STEP LOG only.
        #
        # This is the largest step in most jobs that run it -- ~90s median on Linux,
        # 268-292s on Windows, ~118s on macOS, across 40 jobs -- and its output carries
        # no timestamps anywhere, so which phase spends that time cannot be read off a
        # CI log. Guessing has already been misleading: a no-op `unsloth studio update`
        # over a complete install costs MORE than the full install it follows, which is
        # the opposite of what a download-bound install does.
        #
        # Done here rather than in install.sh on purpose. install.sh, install.ps1 and
        # studio/setup.* are user-facing scripts and stay untouched; this is a display
        # filter over a stream CI already pipes, so it adds no switch to maintain, no
        # environment variable for the installers to interpret, and nothing that can
        # behave differently for a real user than it does here.
        #
        # Downstream of `tee` deliberately: logs/install.log keeps byte-for-byte what
        # install.sh wrote, so the ~30 places that read or grep that artifact see no
        # change at all. $SECONDS is the step's own clock and survives into the pipeline
        # subshell. The `|| [ -n "$line" ]` tail emits a final unterminated line, which
        # a bare `read` loop would swallow.
        bash install.sh --local --no-torch 2>&1 \
          | tee logs/install.log \
          | while IFS= read -r line || [ -n "$line" ]; do
              printf '[%4ds] %s\n' "$SECONDS" "$line"
            done

    # Same pair as the restore above, and the other half of the reason to delegate:
    # this action gets the post-install reuse assertion (a hit followed by a
    # `building frontend` line fails the job) for free, in the same place the eight
    # five Windows job-legs get it.
    #
    # The uv save is delegated the same way, `uv cache prune --ci` included.
    - name: Save the built frontend
      uses: ./.github/actions/frontend-dist-save
      with:
        cache-hit: ${{ steps.fe-dist.outputs.cache-hit }}
        key: ${{ steps.fe-dist.outputs.key }}

    - name: Save the uv download cache
      uses: ./.github/actions/uv-cache-save
      with:
        cache-hit: ${{ steps.uv-cache.outputs.cache-hit }}
        key: ${{ steps.uv-cache.outputs.key }}

```

## /.github/actions/pip-cache-restore/action.yml

```yml path="/.github/actions/pip-cache-restore/action.yml" 
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.

# Restore half of the pip cache, replacing `actions/setup-python`'s built-in
# `cache: 'pip'`.
#
# The built-in cache is read-write and saves from its own post-step on WHATEVER
# REF the job ran on. A cache written on a pull_request ref can only be restored
# by re-runs of that same pull request ("caches created on the base branch are
# available to the topic branch, but not the other way round"), so every PR
# writes a ~700MB copy that nobody else can ever read, and that copy competes for
# the shared 50 GiB budget against main's copy, which every PR CAN read. Measured
# on this repo: setup-python entries were 19.45 GiB across 40 entries, 15.49 GiB
# of it on PR refs, with four interpreter keys duplicated 4-6 times each.
#
# Nothing about that is visible as a failure. Over quota, GitHub evicts
# least-recently-used, so main's copy goes, the next PR misses, downloads, and
# writes its own copy. CI just gets slower and everyone assumes that is the cost.
# The repo had already diagnosed and fixed this exact loop for the GGUF caches
# (see the save step in studio-inference-smoke.yml) and for the Playwright
# browsers; setup-python was left doing it because its built-in cache has no
# save-gating knob. Splitting restore from save is how you get one.
#
# Pair this with pip-cache-save AFTER the install, passing the outputs below.

name: Restore the pip cache
description: >-
  Restore pip's HTTP cache for this runner and interpreter, keyed on the files
  the job actually installs from. Read-only: the save is a separate action and
  runs on the default branch only.

inputs:
  name:
    description: >-
      Short, stable identifier for the INSTALLING JOB (`consolidated`,
      `notebooks-colab`, ...). Two things depend on it.

      Jobs that install different things must not share a key. Five jobs here
      passed the same key-files and so resolved to the same key; the save is
      gated on `cache-hit != 'true'`, so whichever finished first on main wrote
      the cache and the other four restored it exactly, installed their own
      extra wheels, and never saved them. Those extras were re-downloaded on
      every run of main, forever, and nothing about it was visible.

      It also makes each family its own key prefix. Without that, generations of
      five different jobs sit under `pip-<os>-<arch>-py<ver>-` and cannot be told
      apart from five generations of one, so cache-janitor.yml cannot prune any
      of them. 14 GiB of unreachable pip entries had accumulated by 2026-08-26
      for exactly that reason.

      Lowercase, digits and dashes; it goes into the cache key verbatim.
    required: true
  key-files:
    description: >-
      Newline-separated glob(s) whose hash keys the cache. Pass the files this
      job installs from, NOT a repo-wide pattern: the built-in cache hashed
      dependency files across the whole repo, so an unrelated requirements edit
      invalidated every interpreter's entry at once and orphaned the old ones.
      Paths resolve from the workspace root, so a job that checks out into a
      subdirectory must include it.
    required: true

outputs:
  dir:
    description: pip's cache directory on this runner.
    value: ${{ steps.probe.outputs.dir }}
  key:
    description: The full cache key, to hand to pip-cache-save.
    value: ${{ steps.probe.outputs.key }}
  prefix:
    description: The cache key without the dependency hash, i.e. the restore-key.
    value: ${{ steps.probe.outputs.prefix }}
  cache-hit:
    description: 'true when the exact key was restored.'
    value: ${{ steps.restore.outputs.cache-hit }}

runs:
  using: composite
  steps:
    # `pip cache dir` rather than a hardcoded path per OS: it differs on Linux,
    # macOS and Windows, and pip itself is the authority on where it put things.
    - name: Resolve the pip cache directory and key
      id: probe
      shell: bash
      run: |
        set -euo pipefail
        dir="$(python -m pip cache dir)"
        echo "dir=$dir" >> "$GITHUB_OUTPUT"
        # Minor, deliberately not patch. Nothing in this repo pins a patch version:
        # 53 steps ask for '3.12' and the one matrix offers '3.11' and '3.13', so the
        # patch is whatever the hosted image happens to ship that week. Carrying it in
        # the key duplicated the WHOLE cache every time GitHub bumped it, which is not
        # a hypothetical -- measured 2026-08-20, two entries differing in nothing but
        # 3.12.13 vs 3.12.14 held 10.85 and 11.21 GiB, 44% of the repo's 50 GiB budget
        # between them, against a total that had climbed back to 99.1% full. The same
        # pairing showed up in 10 of the 12 pip entries.
        #
        # Safe because of WHAT is cached, the same argument the uv cache rests on: pip
        # stores downloaded wheels, tagged cp312 and so ABI-compatible across every
        # 3.12.x, behind an HTTP cache addressed by URL and hash. A stale entry cannot
        # serve wrong content; the worst it can do is miss.
        pyver="$(python -c 'import sys; print("%d.%d" % sys.version_info[:2])')"
        hash="${{ hashFiles(inputs.key-files) }}"
        # Empty means the globs matched nothing, which would silently collapse
        # every job onto one key. Loud here, where the cause is one line away.
        if [ -z "$hash" ]; then
          echo "::error::pip-cache: key-files matched no file, so the cache key would not distinguish anything. Given: ${{ inputs.key-files }}"
          exit 1
        fi
        name="${{ inputs.name }}"
        # An empty or surprising segment collapses distinct jobs onto one key, or
        # breaks the janitor's prefix grouping. Both fail silently, so check here.
        case "$name" in
          ''|*[!a-z0-9-]*)
            echo "::error::pip-cache: name must be lowercase letters, digits and dashes. Given: '$name'"
            exit 1 ;;
        esac

        # `v2` is a real load-bearing segment, not decoration. Keys minted before
        # `name` existed look like `pip-Linux-X64-py3.12-<hash>`, and `Linux` is a
        # valid name, so nothing distinguishes an old key from a new one whose job
        # happens to be called `linux`. The janitor matches `pip-v2-` only, which
        # leaves every legacy entry untouched to expire on its own 7-day idle
        # timer rather than being ranked against keys it has nothing to do with.
        #
        # Emitted separately so the restore-key fallback and the janitor's
        # grouping are built from the same string as the key, not a copy that
        # can drift.
        prefix="pip-v2-${name}-${{ runner.os }}-${{ runner.arch }}-py${pyver}-"
        echo "prefix=$prefix" >> "$GITHUB_OUTPUT"
        echo "key=${prefix}${hash}" >> "$GITHUB_OUTPUT"

    - name: Restore the pip cache
      id: restore
      uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9  # v6.1.0
      # A cache is an optimisation; a cache service blip must not fail the job.
      continue-on-error: true
      with:
        path: ${{ steps.probe.outputs.dir }}
        key: ${{ steps.probe.outputs.key }}
        # WITH a prefix fallback, unlike the frontend-dist cache. A dist cache is
        # a build output: the wrong generation is wrong, so only an exact key will
        # do. This is pip's HTTP cache, addressed by URL and content hash, where
        # the previous generation is the current one minus whatever moved. A
        # dependency bump then costs the changed wheels instead of all of them,
        # and a stale entry cannot serve wrong content -- the worst it can do is
        # miss. Same argument that lets the key carry 3.12 rather than 3.12.14.
        #
        # `name` is inside the prefix, so the fallback stays inside this job's own
        # family and never hands one job the wheels another downloaded.
        restore-keys: |
          ${{ steps.probe.outputs.prefix }}

```

## /.github/actions/pip-cache-save/action.yml

```yml path="/.github/actions/pip-cache-save/action.yml" 
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.

# Save half of the pip cache. See pip-cache-restore for why this is split out.
#
# Runs on the default branch ONLY. That is the whole point: an entry written on a
# pull_request ref is restorable only by re-runs of that same PR, so it buys no
# hit rate and evicts the copy on main that every PR can read.

name: Save the pip cache
description: Save pip's cache under the restore step's key, on the default branch only.

inputs:
  dir:
    description: pip's cache directory, from pip-cache-restore's `dir` output.
    required: true
  key:
    description: The cache key, from pip-cache-restore's `key` output.
    required: true
  cache-hit:
    description: >-
      pip-cache-restore's `cache-hit`. Skipped when it is 'true', because the key
      is already present and re-uploading it would be pure cost.
    required: true

runs:
  using: composite
  steps:
    - name: Save the pip cache
      # always(), so a cache earned by a successful install is not thrown away
      # because a LATER step in the job failed. The install itself is what fills
      # this directory, and a failed test does not make its downloads wrong.
      if: >-
        always() && github.ref == 'refs/heads/main'
        && inputs.cache-hit != 'true'
      uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9  # v6.1.0
      continue-on-error: true
      with:
        path: ${{ inputs.dir }}
        key: ${{ inputs.key }}

```

## /.github/actions/uv-cache-restore/action.yml

```yml path="/.github/actions/uv-cache-restore/action.yml" 
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.

# The uv download cache, restore half. One definition of the key, for the same reason
# frontend-dist-restore has one: the Windows jobs run install.ps1 from a hand-written pwsh
# step and never go through install-unsloth-local, so a pasted copy would drift silently.
# A download cache is the safest kind: uv's is content-addressed by URL and hash, so a
# stale entry cannot serve wrong content, only miss. Caching the VENV instead would have to
# reason about an editable overlay, a moving `unsloth-zoo @ git+main` and absolute paths
# baked into console scripts; tests/studio/test_uv_cache_discipline.py pins that
# distinction and the cold-install lanes that must never adopt this.
# UV_CACHE_DIR is set explicitly so one config covers Linux, macOS and Windows, and
# exported so install.sh, install.ps1 and studio/setup.* inherit it; install.ps1 preserves
# a custom value. ROOT-CHECKOUT ONLY: the path below is workspace-relative.

name: Restore the uv download cache
description: >-
  Point UV_CACHE_DIR at a workspace directory and restore uv's download cache
  into it, keyed on what decides the resolution. Read-only: the save is a
  separate action and runs on the default branch only.

outputs:
  cache-hit:
    description: "'true' when the exact key was restored."
    value: ${{ steps.restore.outputs.cache-hit }}
  key:
    description: The full cache key, to hand to uv-cache-save.
    value: ${{ steps.restore.outputs.cache-primary-key }}

runs:
  using: composite
  steps:
    - name: Point uv's cache somewhere cacheable
      shell: bash
      run: |
        echo "UV_CACHE_DIR=${{ github.workspace }}/.uv-cache" >> "$GITHUB_ENV"
        mkdir -p "${{ github.workspace }}/.uv-cache"

    # Keyed on what decides the resolution, with a prefix fallback: a near-miss still
    # supplies almost every wheel. A download cache wants restore-keys for exactly that
    # reason, where a venv cache must not have them. runner.os: wheels differ per platform.
    - name: Restore the uv download cache
      id: restore
      uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9  # v6.1.0
      continue-on-error: true
      with:
        path: ${{ github.workspace }}/.uv-cache
        key: uv-${{ runner.os }}-${{ hashFiles('studio/backend/requirements/**', 'pyproject.toml') }}
        restore-keys: |
          uv-${{ runner.os }}-

```

## /.github/actions/uv-cache-save/action.yml

```yml path="/.github/actions/uv-cache-save/action.yml" 
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.

# The uv download cache, save half. Paired with uv-cache-restore, which owns the key.
# Default branch only: a PR-scoped entry is restorable only by re-runs of that same PR,
# while every PR can restore from main, so saving on PRs spends a near-full budget to evict
# main's copy, the one everyone reads. A hit is not re-uploaded either.
# `uv cache prune --ci` first: uv keeps built wheels AND unpacked source artifacts, only the
# former worth carrying, so without it the entry grows without bound and re-opens the
# eviction thrash the GGUF caches were fixed for. Best effort: an older uv without `--ci`,
# or a uv off this step's PATH, must not fail an install that already succeeded.

name: Save the uv download cache
description: >-
  Prune uv's download cache to what is worth carrying, then save it under the
  restore step's key, on the default branch only.

inputs:
  cache-hit:
    description: >-
      uv-cache-restore's `cache-hit` output. 'true' skips the save: the key is
      already present and re-uploading it is pure cost.
    required: true
  key:
    description: uv-cache-restore's `key` output.
    required: true
  save:
    description: >-
      'false' to skip the upload. For a workflow whose triggers cannot routinely
      put github.ref on refs/heads/main (no `push`, no `schedule`), where the save
      below could only fire if a human dispatched the workflow from main by hand.
      Such a workflow consumes the cache the producers fill and declares here that
      it is not one of them, rather than carrying a save that never runs.
    required: false
    default: 'true'

runs:
  using: composite
  steps:
    - name: Prune the uv download cache to what is worth carrying
      if: >-
        github.ref == 'refs/heads/main' && inputs.cache-hit != 'true'
        && inputs.save != 'false'
      shell: bash
      run: |
        uv_bin="$(command -v uv 2> /dev/null || true)"
        for candidate in "$HOME/.local/bin/uv" "$HOME/.local/bin/uv.exe" "$HOME/.cargo/bin/uv" "$HOME/.cargo/bin/uv.exe"; do
          [ -n "$uv_bin" ] && break
          [ -x "$candidate" ] && uv_bin="$candidate"
        done
        if [ -n "$uv_bin" ]; then
          "$uv_bin" cache prune --ci 2> /dev/null || true
        else
          echo "uv is not on PATH in this step; saving the cache unpruned"
        fi
        du -sh "${{ github.workspace }}/.uv-cache" 2> /dev/null || true

    - name: Save the uv download cache
      if: >-
        github.ref == 'refs/heads/main' && inputs.cache-hit != 'true'
        && inputs.save != 'false'
      uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9  # v6.1.0
      continue-on-error: true
      with:
        path: ${{ github.workspace }}/.uv-cache
        key: ${{ inputs.key }}

```

## /.github/ci-preempt.json

```json path="/.github/ci-preempt.json" 
{
  "$comment": [
    "Allowlist for .github/workflows/ci-capacity.yml. Nothing outside this file",
    "is ever cancelled or disabled, so the blast radius is reviewable in a diff",
    "rather than inferred from a filter expression at runtime.",
    "",
    "'heavy' is the set a release pipeline is allowed to preempt, split by the",
    "runner class each one actually consumes. Pick workflows by what they cost",
    "the shared pool, not by how important they are: preempting a one-job lint",
    "run frees nothing while still showing up as a cancelled check.",
    "",
    "A workflow is listed under EVERY class it consumes, not just its headline",
    "one. Both actions the sweeper takes are whole-workflow: disable stops the",
    "workflow, and a cancelled run takes all of its jobs with it. There is no",
    "way to reach one leg of a matrix. So a mixed-platform workflow filed under",
    "one class only is invisible to a pause naming the others, and its jobs on",
    "the class being held keep refilling the pool the pause is paying for.",
    "clean-machine-install-ci.yml alone is 6 linux and 7 windows legs on its nightly",
    "(a PR runs 2 linux and 1 windows; see .github/ci/clean-machine-matrix.yml).",
    "",
    "The cost of the rule is the converse: a linux pause now also takes that",
    "workflow's 7 macOS legs down. That is the right way round. Losing coverage",
    "is bounded by the guard at MAX_DISABLED_MINUTES and a cancelled run keeps",
    "its re-run button, whereas a pause that silently does not hold fails at the",
    "only thing it was for. The file already made this trade in the worse",
    "direction: a macos pause disables 9 linux and 10 windows legs today. The",
    "sweeper de-duplicates, so a file under two classes is still disabled once.",
    "",
    "Read the macos list before you use it. Measured across every clean",
    "attempt-1 release run in the org, macOS is the FASTEST class to get a",
    "runner, not the slowest: llama.cpp's two macOS jobs on 08-03 waited 6",
    "seconds while its Linux and Windows jobs each accumulated ~5h48m of queue,",
    "and release-desktop's macOS leg waited 1m54s against 2h54m for Windows.",
    "The 5-macOS cap is real but it is not on the critical path of any of the",
    "three release pipelines. Freeing it buys almost nothing. The leverage is in",
    "linux and windows, which is also where the blast radius is worst, and that",
    "tension is the whole reason this ships switched off.",
    "",
    "'never' is belt and braces. The sweeper already refuses to touch releases,",
    "pull_request runs and itself; listing them again means a careless edit to",
    "'heavy' cannot reach them.",
    "",
    "kaggle-t4-notebook-ci.yml is in 'never' rather than under heavy.linux,",
    "which its 90-minute ubuntu job would otherwise qualify for. Cancelling",
    "that run does not stop the Kaggle kernel it has already pushed, and an",
    "orphaned kernel bills the account's weekly GPU quota to its own 45-minute",
    "ceiling with nobody left to read the result. It holds one ubuntu runner",
    "that spends almost all of its time asleep on a poll loop, so preempting it",
    "frees close to nothing and costs quota that is not the pool's to spend.",
    "",
    "kaggle-t4-studio-gpu-ci.yml is in 'never' for exactly the same reason, and",
    "more so: its kernel ceiling is 70 minutes rather than 45, so an orphaned",
    "one wastes correspondingly more of the account's weekly quota."
  ],
  "heavy": {
    "macos": [
      "clean-machine-install-ci.yml",
      "interrupted-install-ci.yml",
      "studio-mac-install-matrix.yml",
      "studio-mac-inference-smoke.yml",
      "studio-mac-ui-smoke.yml",
      "mlx-ci.yml",
      "startup-profile-ci.yml"
    ],
    "linux": [
      "version-compat-ci.yml",
      "local-agent-guides-ci.yml",
      "notebooks-ci.yml",
      "security-audit.yml",
      "cross-platform-parity-ci.yml",
      "clean-machine-install-ci.yml",
      "interrupted-install-ci.yml",
      "startup-profile-ci.yml"
    ],
    "windows": [
      "studio-windows-inference-smoke.yml",
      "cross-platform-parity-ci.yml",
      "clean-machine-install-ci.yml",
      "interrupted-install-ci.yml",
      "startup-profile-ci.yml"
    ]
  },
  "never": [
    "release-desktop.yml",
    "publish-desktop-updater.yml",
    "ci-capacity.yml",
    "ossf.yml",
    "stale.yml",
    "kaggle-t4-notebook-ci.yml",
    "kaggle-t4-studio-gpu-ci.yml"
  ]
}

```

## /.github/ci/clean-machine-matrix.yml

```yml path="/.github/ci/clean-machine-matrix.yml" 
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.

# The legs of .github/workflows/clean-machine-install-ci.yml, one list per matrix job.
# `pr: true` legs run on pull_request; everything runs nightly, on push to main and on
# workflow_dispatch. The `select` job strips `pr`, so a leg's other keys are exactly what
# the steps read as `matrix.<key>`. macOS is capped at five concurrent jobs account-wide
# and the full set (20 jobs, 7 macOS) never once finished on a PR before the next push
# cancelled it, so the subset keeps one leg per claim and defers OS/arch-only legs.
# tests/studio/test_install_matrix_selection.py pins the counts and the keys.

macos:
  # `overlay` decides whether this ref's Python is under test; the pipe legs stay on the
  # released package on purpose.
  # The reported failure, in the `curl | sh` shape users run, with torch as a consumer
  # gets: the only leg that can see a truncated script or a curl: (56) from an early exit.
  - {os: macos-15, mode: mask,  delivery: pipe,  flags: '',           experimental: false, overlay: false, pr: true}
  - {os: macos-15, mode: mask,  delivery: file,  flags: '',           experimental: false, overlay: true,  pr: true}
  # What the desktop app runs: no tty, stdin closed, TAURI markers on, legacy ~/.unsloth.
  - {os: macos-15, mode: mask,  delivery: tauri, flags: '',           experimental: false, overlay: true,  pr: false}
  # Toolchain present but logged: uv's managed-libpython self-ID patch is the one call
  # allowed. No overlay: setuptools-scm's editable build would call git itself.
  - {os: macos-15, mode: trace, delivery: file,  flags: '',           experimental: false, overlay: false, pr: true}
  # --no-torch is the one macOS path that can still want a compiler (no guaranteed cp313
  # arm64 sentencepiece wheel), so probe it apart from the default path.
  - {os: macos-15, mode: mask,  delivery: file,  flags: '--no-torch', experimental: true,  overlay: true,  pr: false}
  # The next macOS image, same asserts as the macos-15 file leg.
  - {os: macos-26, mode: mask,  delivery: file,  flags: '',           experimental: true,  overlay: true,  pr: false}
  # Intel pins python 3.12 and its /usr/bin/git is not CLT-provided, so it survives
  # masking. Informational only.
  - {os: macos-15-intel, mode: mask, delivery: file, flags: '',       experimental: true,  overlay: true, allow_working: 'git', pr: false}

linux:
  # Root + apt: _smart_apt_install self-heals from an image with no curl, git, gcc or
  # cmake. Nightly only: the nonroot leg below proves everything this one does and more.
  - label: ubuntu2404-root
    image: ubuntu:24.04
    runner: ubuntu-latest
    experimental: false
    overlay: true
    pr: false
  # The arm64 dimension of the root leg.
  - label: ubuntu2404-arm-root
    image: ubuntu:24.04
    runner: ubuntu-24.04-arm
    experimental: false
    overlay: true
    pr: false
  # No elevation, but WITH the transport the one-liner needs: no elevation path anywhere
  # on the image, no toolchain, ca-certificates + curl and nothing else. Since #7547 the
  # optional set never escalates, so this must install end to end off prebuilt llama.cpp.
  # overlay: true because the RELEASED install_python_stack.py has no "skip triton kernels
  # when git is missing" guard and would die at the final step on release lag alone.
  - label: ubuntu2404-nonroot
    image: ubuntu:24.04
    runner: ubuntu-latest
    experimental: false
    overlay: true
    nonroot: true
    pr: true
  # The same premise with the OTHER transport. install.sh falls back to wget everywhere it
  # prefers curl (729-738, 1019-1027, 3064-3067) and calls the transport missing only when
  # BOTH are gone (2077-2079), so a wget-only box (Debian netinst default) is supported on
  # paper and had never been run: the row above provisions curl, which won every probe.
  - label: ubuntu2404-nonroot-wget
    image: ubuntu:24.04
    runner: ubuntu-latest
    experimental: false
    overlay: true
    nonroot: true
    wget_only: true
    pr: false
  # No elevation AND no transport, so failing is correct: pin the exact message and prove
  # it actionable rather than a bare `curl: (56)`. No overlay: it never reaches a venv.
  - label: ubuntu2404-nonroot-notransport
    image: ubuntu:24.04
    runner: ubuntu-latest
    experimental: false
    overlay: false
    nonroot: true
    no_transport: true
    pr: true
  # Non-apt: hard-fails at install.sh:2034 today. Tolerate the install STEP, not the job:
  # job-level continue-on-error would swallow the outcome assertion too.
  - label: fedora41
    image: fedora:41
    runner: ubuntu-latest
    experimental: false
    overlay: true
    tolerate_install_failure: true
    pr: false

windows:
  - os: windows-latest
    winget: 'visible'
    experimental: false
    overlay: true
    pr: true
  # The no-winget path (LTSC / Server / managed corporate) falls back to python.org +
  # astral.sh and is where Ensure-VCRedist silently does not run, leaving torch unable to
  # load: hence the explicit `import torch` assert below. #7549 relaxed setup.ps1's
  # unconditional git gate (1750-1759), and the assert proves it took the relaxed branch
  # rather than passing on git leaking back onto PATH.
  - os: windows-latest
    winget: 'masked'
    experimental: false
    overlay: true
    pr: false
  # Windows on ARM gets a native ARM64 CPython and torchaudio publishes no win_arm64 wheel
  # (nor do pyarrow and hf-transfer), so PyTorch could not resolve until #7549 made the
  # installer prefer an emulated x64 interpreter (install.ps1:1160-1253, 1335-1353). The
  # assert below checks that outcome, not the log line announcing it.
  - os: windows-11-arm
    winget: 'visible'
    experimental: false
    overlay: true
    pr: false

windows_container_install:
  # The consumer path: install.ps1 from this ref, unsloth from PyPI, so studio/setup.ps1
  # comes out of the RELEASED wheel rather than this ref's. Both rows gate.
  - overlay: false
    pr: false
  # This ref's studio/setup.ps1 and install_python_stack.py, via UNSLOTH_CI_SOURCE_OVERLAY
  # (install.ps1:2643); without it a branch changing setup.ps1 proves nothing. On PRs too:
  # the only environment with no preinstalled VC++ runtime.
  - overlay: true
    pr: true

```

## /.github/ci/interrupted-install-matrix.yml

```yml path="/.github/ci/interrupted-install-matrix.yml" 
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.

# The legs of .github/workflows/interrupted-install-ci.yml, one list per matrix job.
# `pr: true` legs run on pull_request; everything runs nightly and on workflow_dispatch.
# Every leg is a hard gate, with no continue-on-error cell: a leg allowed to fail is a
# warning wearing a red icon, and the claim here is that a killed install cannot report
# itself healthy. The PR subset (10 legs, 6 macOS, five concurrent macOS jobs account-wide)
# takes one leg per verdict family on different operating systems: `studio-deps`, a partial
# venv that reports HEALTHY, and `torch`, a complete venv with nothing in it where the
# re-run must repair rather than short-circuit on the version fast path.
# tests/studio/test_install_matrix_selection.py pins the counts and the keys.

interrupt:
  # A marker, never a delay: every label prints BEFORE its work, so the kill lands inside
  # the phase, while a timed wait bets on phase duration and twice turned a leg into a
  # duplicate of the next one. This one is the reported case, killed installing structlog.
  - {os: macos-15, label: studio-deps, marker: 'studio deps', pr: true}
  # Coarse phases, earliest to latest, each leaving a different partial venv. No venv leg:
  # "Creating virtual environment" runs ~0.1s, shorter than any poll, so its kill always
  # landed in the NEXT phase and the leg duplicated this one.
  - {os: macos-15, label: torch,       marker: '\[TAURI:STEP\] Installing PyTorch', pr: false}
  - {os: macos-15, label: unsloth,     marker: '\[TAURI:STEP\] Installing Unsloth', pr: false}
  # The latest phase, the closest to a complete-looking install.
  - {os: macos-15, label: setup,       marker: '\[TAURI:STEP\] Running Unsloth setup', pr: false}
  # Other dependency-pass sub-steps around the named one. No pip-bootstrap leg (over before
  # a poll can see it) and no base-packages leg (--local sets skip_base, so it never prints
  # and the leg ran to completion, proving nothing).
  - {os: macos-15, label: unsloth-extras, marker: 'unsloth extras', pr: false}
  # Killed before install_python_stack.py writes the manifest.
  - {os: macos-15, label: data-designer,  marker: 'data designer deps', pr: false}
  # Linux: same teardown path, different package manager and process semantics.
  - {os: ubuntu-latest, label: studio-deps, marker: 'studio deps', pr: false}
  - {os: ubuntu-latest, label: torch, marker: '\[TAURI:STEP\] Installing PyTorch', pr: true}

# Windows has no process groups, so the kill path differs. Both legs are nightly only:
# the verdict families are covered on PRs by the POSIX legs.
interrupt_windows:
  # install.ps1:121 parses `--no-torch`; `-SkipTorch` matches no case there and is
  # silently dropped. The torch leg must NOT skip torch or its marker never appears.
  - {label: studio-deps, marker: 'studio deps', installArgs: '--tauri --no-torch --local', pr: false}
  - {label: torch, marker: 'Installing PyTorch', installArgs: '--tauri --local', pr: false}

```

## /.github/dependabot.yml

```yml path="/.github/dependabot.yml" 
---
version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    cooldown:
      # github-actions refs are git tags / SHAs, not semver -- the
      # `semver-minor-days` / `semver-patch-days` knobs are rejected
      # by Dependabot's validator for this ecosystem. Only the
      # `default-days` floor applies.
      default-days: 7
    groups:
      actions:
        patterns: ["*"]
      actions-security:
        applies-to: security-updates
        patterns: ["*"]

  # Removed a stray `package-ecosystem: "bun"` entry for
  # /studio/frontend: that path has no bun.lock / bun.lockb, so
  # Dependabot's bun ecosystem silently no-ops on it. The actual
  # lockfile committed at /studio/frontend is package-lock.json
  # (npm), and the npm entry further below already catches
  # npm_and_yarn security advisories for that directory. Version
  # updates for /studio/frontend stay suppressed (open-pull-
  # requests-limit: 0 in that entry) -- security PRs flow through
  # regardless. Add a real bun entry IF and WHEN bun.lock lands.

  - package-ecosystem: "npm"
    directory: "/studio/backend/core/data_recipe/oxc-validator"
    schedule:
      interval: "weekly"
    cooldown:
      default-days: 7
      semver-minor-days: 3
      semver-patch-days: 3
    groups:
      npm-oxc-validator:
        patterns: ["*"]
      npm-oxc-validator-security:
        applies-to: security-updates
        patterns: ["*"]

  # pip + cargo grouped weekly; the *-security siblings batch
  # advisories that would otherwise each open their own PR.
  - package-ecosystem: "pip"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 5
    cooldown:
      default-days: 7
    groups:
      python:
        patterns: ["*"]
      python-security:
        applies-to: security-updates
        patterns: ["*"]

  - package-ecosystem: "cargo"
    directory: "/studio/src-tauri"
    schedule:
      interval: "weekly"
    cooldown:
      default-days: 7
      semver-minor-days: 3
      semver-patch-days: 3
    # Tauri renders Unsloth on Linux through GTK3 and the gtk-rs GTK3
    # bindings are archived at 0.18.2, so `gtk`/`gdk` will never ship
    # 0.19+. Moving `glib`/`gdk-pixbuf` past 0.18 puts two
    # incompatible copies in the tree and native_clipboard.rs stops
    # compiling: `gtk::Clipboard::wait_for_image` returns a 0.18
    # `Pixbuf` our `gdk_pixbuf` no longer accepts. This also
    # suppresses security PRs above 0.18, leaving alerts only.
    ignore:
      - dependency-name: "glib"
        versions: [">= 0.19"]
      - dependency-name: "gdk-pixbuf"
        versions: [">= 0.19"]
    groups:
      cargo-tauri:
        patterns: ["*"]
      cargo-tauri-security:
        applies-to: security-updates
        patterns: ["*"]

  # /studio/frontend npm dependencies. Version-update PRs are
  # deliberately suppressed (open-pull-requests-limit: 0) -- the
  # frontend dep tree is large, the lockfile is the authoritative
  # pin, and `min-release-age=7` in studio/frontend/.npmrc already
  # blocks fresh tarballs at install time. Security advisories
  # arrive via GitHub's npm_and_yarn channel and are NOT capped by
  # `open-pull-requests-limit` per Dependabot's documented
  # behaviour; they flow through this entry, group together, and
  # still respect the cooldown below so we never ingest a tarball
  # that was hot-published less than 3 days ago.
  - package-ecosystem: "npm"
    directory: "/studio/frontend"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 0
    cooldown:
      default-days: 7
      semver-minor-days: 3
      semver-patch-days: 3
    groups:
      npm-frontend-security:
        applies-to: security-updates
        patterns: ["*"]
...

```

## /.github/scripts/Watch-ForCompiler.ps1

```ps1 path="/.github/scripts/Watch-ForCompiler.ps1" 
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.

<#
.SYNOPSIS
Run a script block and report whether a C# compiler ran, or a DLL landed in a
temporary directory, while it did.

.DESCRIPTION
Two independent detectors, because either alone can be defeated by something that
is not the code under test:

  1. Security log event 4688, process creation. Authoritative about what ran, and
     it sees a compiler spawned through any depth of child process, which a text
     search of our own scripts cannot reach. Needs auditing enabled by the caller;
     the workflow does that and verifies it took.

  2. New *.dll, *.cmdline, *.rsp and *.?.cs files under every temporary directory
     in play. The artefact half of the same shape, and it survives auditing being
     silently overridden by machine policy. csc.exe writes the source and the
     response file next to the assembly, so those names are watched too.

     Watched live, with a FileSystemWatcher, and not only by comparing a listing
     taken before the action against one taken after. CodeDom deletes its whole
     intermediate directory once the assembly is loaded, so on a hosted runner the
     before-and-after diff saw nothing at all while 4688 recorded

         csc.exe /noconfig /fullpaths @"...\Temp\vpmyd5eq\vpmyd5eq.cmdline"

     which is a compile this half missed entirely. The two are unioned: the listing
     catches what was left behind, the watcher catches what was cleaned up.

Both are reported. The positive control requires both to fire, and the real
measurement requires neither to.

TEMP is read from the environment rather than assumed, and the machine-wide
C:\Windows\Temp is watched alongside it, because a compile launched from a
service or an elevated child does not write where this process would.
#>

Set-StrictMode -Version Latest

$script:CompilerNames = @('csc.exe', 'vbc.exe', 'cvtres.exe', 'jsc.exe')

function Get-StudioTempRoots {
    <#
    .SYNOPSIS
    Every directory a compile could write its intermediates to, de-duplicated.
    #>
    $roots = @($env:TEMP, $env:TMP, "$env:SystemRoot\Temp", "$env:LOCALAPPDATA\Temp")
    $seen = New-Object 'System.Collections.Generic.HashSet[string]' ([StringComparer]::OrdinalIgnoreCase)
    $result = @()
    foreach ($root in $roots) {
        if ([string]::IsNullOrWhiteSpace($root)) { continue }
        if (-not (Test-Path -LiteralPath $root)) { continue }
        $full = (Resolve-Path -LiteralPath $root).ProviderPath
        if ($seen.Add($full)) { $result += $full }
    }
    return $result
}

function Get-StudioTempArtifacts {
    <#
    .SYNOPSIS
    Compiler intermediates and assemblies currently sitting in the temp roots.
    #>
    $patterns = @('*.dll', '*.cmdline', '*.rsp', '*.cs', '*.err', '*.out')
    $found = @()
    foreach ($root in (Get-StudioTempRoots)) {
        foreach ($pattern in $patterns) {
            # Recurse: PowerShell compiles into a per-invocation subdirectory, not
            # into the root, so a non-recursive listing sees none of this.
            $found += Get-ChildItem -LiteralPath $root -Filter $pattern -File -Recurse `
                -Force -ErrorAction SilentlyContinue |
                Select-Object -ExpandProperty FullName
        }
    }
    # Comma-wrapped: PowerShell unrolls an empty array to nothing on return, and the
    # caller casts this into a HashSet whose two-argument constructor rejects null.
    # On a clean runner that killed the watcher before the positive control ran.
    return ,[string[]]$found
}

$script:ArtifactPattern = '\.(dll|cmdline|rsp|cs|err|out){{contextString}}#39;
$script:LibraryPattern = '\.(dll|cmdline|rsp){{contextString}}#39;

function Start-StudioTempWatch {
    <#
    .SYNOPSIS
    Begin recording file creations under every temp root, and return the handles.
    .DESCRIPTION
    Register-ObjectEvent without an -Action: the events queue in the session's event
    manager as they are raised, and Stop-StudioTempWatch drains them afterwards. An
    -Action block would have to run for anything to be recorded, and there is nothing
    to run it while a synchronous installer holds the pipeline.

    A root that cannot be watched is skipped rather than fatal. The listing half still
    covers it, and on a machine where none of them can be watched the positive control
    is what says so.
    #>
    $handles = @()
    foreach ($root in (Get-StudioTempRoots)) {
        try {
            $watcher = New-Object System.IO.FileSystemWatcher
            $watcher.Path = $root
            $watcher.IncludeSubdirectories = $true
            $watcher.NotifyFilter = [System.IO.NotifyFilters]::FileName
            # The default 8 KB buffer overflows on a busy temp directory, and an
            # overflow drops events silently, which here reads as a clean run.
            $watcher.InternalBufferSize = 65536
            $identifier = "StudioTempWatch-" + [guid]::NewGuid().ToString('N')
            $null = Register-ObjectEvent -InputObject $watcher -EventName Created `
                -SourceIdentifier $identifier
            $watcher.EnableRaisingEvents = $true
            $handles += [pscustomobject]@{
                Watcher          = $watcher
                SourceIdentifier = $identifier
                Root             = $root
            }
        } catch {
            continue
        }
    }
    return ,[object[]]$handles
}

function Stop-StudioTempWatch {
    <#
    .SYNOPSIS
    Stop recording and return every path created while the handles were live.
    .DESCRIPTION
    Always unregisters and disposes, including on a path that saw nothing: a leaked
    subscription keeps firing into the next measurement's queue.
    #>
    param([Parameter(Mandatory = $true)][AllowEmptyCollection()][object[]]$Handle)

    # Delivery is asynchronous, so the last few creations before the action returned may
    # still be in flight. Settle first, then stop raising: draining immediately dropped
    # exactly the events that matter, the ones from the end of a compile.
    Start-Sleep -Milliseconds 750

    $seen = @()
    foreach ($entry in $Handle) {
        try { $entry.Watcher.EnableRaisingEvents = $false } catch { }
        try {
            foreach ($record in @(Get-Event -SourceIdentifier $entry.SourceIdentifier `
                    -ErrorAction SilentlyContinue)) {
                $path = ''
                try { $path = [string]$record.SourceEventArgs.FullPath } catch { }
                if (-not [string]::IsNullOrWhiteSpace($path)) { $seen += $path }
                Remove-Event -EventIdentifier $record.EventIdentifier -ErrorAction SilentlyContinue
            }
        } catch { }
        Unregister-Event -SourceIdentifier $entry.SourceIdentifier -ErrorAction SilentlyContinue
        try { $entry.Watcher.Dispose() } catch { }
    }
    return ,[string[]]$seen
}

function Get-StudioProcessImageName {
    <#
    .SYNOPSIS
    The image a 4688 record says was created, from the record's own field.
    .DESCRIPTION
    NewProcessName, read out of the event XML by name rather than by position, so a
    schema that gains a field still means the same thing. Nothing else is consulted:
    the rendered message also carries the command line, so matching it would score
    `cmd.exe /c echo csc.exe` as a compiler.
    #>
    param([Parameter(Mandatory = $true)]$Event)

    try {
        $xml = [xml]$Event.ToXml()
        foreach ($field in $xml.Event.EventData.Data) {
            if ($field.Name -eq 'NewProcessName') { return [string]$field.'#text' }
        }
    } catch { }
    return ''
}

function Select-StudioCompilerHits {
    <#
    .SYNOPSIS
    The records among $Events whose created image is a compiler.
    .DESCRIPTION
    Separate from the query so the classification can be exercised without a
    Security log, which is the only way to test it off a Windows runner.
    #>
    param([Parameter(Mandatory = $true)][AllowEmptyCollection()][array]$Events)

    $hits = @()
    foreach ($record in $Events) {
        $image = Get-StudioProcessImageName -Event $record
        if ([string]::IsNullOrEmpty($image)) { continue }
        # Split explicitly, not via [System.IO.Path]::GetFileName, which splits on the
        # HOST's separators: under the Linux pwsh where this is tested a backslash is an
        # ordinary character and the whole path came back as the leaf. The records are
        # always Windows paths whatever reads them.
        $leaf = ($image -split '[\\/]')[-1]
        foreach ($name in $script:CompilerNames) {
            if ($leaf -eq $name) {
                $rendered = ''
                try { $rendered = [string]$record.Message } catch { }
                $hits += ("{0:o} {1} :: {2}" -f $record.TimeCreated, $image,
                    ($rendered -replace '\s+', ' '))
                break
            }
        }
    }
    return ,[string[]]$hits
}

function Get-StudioCompilerEvents {
    <#
    .SYNOPSIS
    4688 records naming a compiler image, created at or after $Since.
    .PARAMETER Since
    The instant the measured action began. Taken before the action rather than
    filtering afterwards by a fixed window, so a slow installer cannot outrun it.
    .PARAMETER Until
    The instant it ended. Both ends are needed: a runner is a shared machine, and an
    unrelated service starting a compiler after the action would be scored against it.

    A window, not the process tree the workflow prose describes. 4688 carries the
    creator's pid, but a compile can be several processes deep and the intermediate
    pids have exited by the time this reads the log, so ancestry is not
    reconstructable after the fact. The positive control proves the window measures
    anything.
    #>
    param(
        [Parameter(Mandatory = $true)][datetime]$Since,
        [Parameter(Mandatory = $true)][datetime]$Until
    )

    $events = @()
    try {
        # Bounded at both ends. Open-ended, a compiler started by something else during
        # the recursive temp scan counted against the action that had already finished.
        $events = Get-WinEvent -FilterHashtable @{
            LogName   = 'Security'
            Id        = 4688
            StartTime = $Since
            EndTime   = $Until
        } -ErrorAction Stop
    } catch [System.Exception] {
        # No matching events is an exception from Get-WinEvent, not an empty set, and on
        # a clean run that is expected. A log this cannot READ throws the same way, so
        # swallowing both would print "no compiler" having seen nothing at all. The
        # positive control runs in an earlier step and says nothing about whether the log
        # was readable during the measurements.
        #
        # Separate them structurally rather than by the localised message text: ask the
        # log for any one record. If that succeeds the filter genuinely matched nothing;
        # if it fails too, this measurement is void, not clean.
        # Bound before the probe below, whose own catch rebinds $_.
        $reason = $_.Exception.Message
        $readable = $false
        try {
            $null = Get-WinEvent -LogName 'Security' -MaxEvents 1 -ErrorAction Stop
            $readable = $true
        } catch { }
        if (-not $readable) {
            throw ("the Security log could not be read, so this run measured nothing. " +
                   "Treat it as void rather than as clean. Underlying error: $reason")
        }
        return ,[string[]]@()
    }

    return Select-StudioCompilerHits -Events @($events)
}

function Invoke-WithCompilerWatch {
    <#
    .SYNOPSIS
    Run $Action and return what the two detectors saw while it ran.
    .OUTPUTS
    A hashtable with Compilers and TempLibraries, each an array of strings, plus
    the exit state of the action. Evidence is written under $EvidenceRoot even when
    the action fails, which is exactly when the trace is wanted.
    #>
    param(
        [Parameter(Mandatory = $true)][string]$Name,
        [Parameter(Mandatory = $true)][scriptblock]$Action,
        [Parameter(Mandatory = $true)][string]$EvidenceRoot
    )

    New-Item -ItemType Directory -Force -Path $EvidenceRoot | Out-Null

    # Baseline first, THEN open the window. The sweep walks every temp root
    # recursively and can take seconds, and a csc.exe the machine started during that
    # walk predates the action, so counting it fails a measurement for something it
    # did not do. Same reasoning as the $until below.
    $before = New-Object 'System.Collections.Generic.HashSet[string]' (
        [string[]](Get-StudioTempArtifacts), [StringComparer]::OrdinalIgnoreCase)
    # A second back, so a process created in the same tick as the timestamp survives
    # Get-WinEvent's strictly-later comparison. That reaches one second into the tail
    # of the sweep above, so a compiler started in that second is counted: a deliberate
    # trade towards a loud false alarm rather than a dropped real compile.
    $since = (Get-Date).AddSeconds(-1)
    # Opened here, with the 4688 window, and not before the baseline: a file the
    # machine creates during that recursive sweep predates the action.
    $watch = Start-StudioTempWatch

    $failure = $null
    $live = @()
    try {
        # Out-Host, not the success stream. The installer action tees its log, and those
        # lines would be emitted as function output ahead of the result hashtable, making
        # the caller's $seen an object array whose $seen.Compilers fails under
        # Set-StrictMode instead of reporting the measurement.
        & $Action | Out-Host
    } catch {
        # Recorded and re-thrown below. The detectors still report, because "the
        # installer died AND spawned a compiler" beats either half alone.
        $failure = $_
    } finally {
        # In the finally, so an action that threw still closes its subscriptions.
        $live = @(Stop-StudioTempWatch -Handle $watch)
    }

    # Closed before the temp sweep, which can take seconds: anything the machine
    # starts during that walk belongs to nobody's measurement.
    $until = Get-Date
    $compilers = @(Get-StudioCompilerEvents -Since $since -Until $until)

    $after = Get-StudioTempArtifacts
    $left = @($after | Where-Object { -not $before.Contains($_) })
    # Only the names the compiler writes, because the watcher reports every creation
    # under temp and most of them are nobody's business.
    $transient = @($live | Where-Object { $_ -match $script:ArtifactPattern })
    $union = New-Object 'System.Collections.Generic.HashSet[string]' ([StringComparer]::OrdinalIgnoreCase)
    $newArtifacts = @()
    foreach ($path in ($left + $transient)) {
        if ($union.Add($path)) { $newArtifacts += $path }
    }
    $newLibraries = @($newArtifacts | Where-Object { $_ -match $script:LibraryPattern })

    $stem = Join-Path $EvidenceRoot $Name
    $compilers | Out-File -FilePath "$stem-compilers.txt" -Encoding utf8
    $newArtifacts | Out-File -FilePath "$stem-temp-artifacts.txt" -Encoding utf8
    if ($failure) {
        $failure | Out-String | Out-File -FilePath "$stem-error.txt" -Encoding utf8
    }

    if ($failure) { throw $failure }

    return @{
        Compilers     = $compilers
        TempLibraries = $newLibraries
        TempArtifacts = $newArtifacts
    }
}

```

## /.github/scripts/agent-guides-drive.sh

```sh path="/.github/scripts/agent-guides-drive.sh" 
#!/usr/bin/env bash
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.
# Drive one coding agent against the running `unsloth run` server for the
# Local Agent Guides CI. All failures from here are failure class (c)
# "guide drift": the server preflight already passed and the agent CLI
# already installed, so a failure here means the documented recipe in
# unsloth_cli/commands/start.py no longer produces a working flow.
# Self-updating: for all seven agents (claude, codex, hermes, openclaw,
# opencode, pi, dsh) we obtain the exact env + command from
# `unsloth start <agent> --no-launch` and run THAT, so a recipe change is
# exercised automatically.
# Every agent invocation is wrapped in `timeout` so a headless-TTY prompt
# can never hang the runner -- a timeout is reported as guide drift with a
# distinct message.
# Usage:
#   agent-guides-drive.sh connection     <agent>
#   agent-guides-drive.sh file-edit      <agent>
#   agent-guides-drive.sh attribution-ab claude
# Required env (exported by serve-unsloth-run.sh):
#   UNSLOTH_BASE_URL UNSLOTH_API_KEY UNSLOTH_MODEL_ID
#   UNSLOTH_LLAMA_LOG_DIR  AGENT_INVOKE_TIMEOUT  UNSLOTH_SEED
set -uo pipefail

MODE="${1:?usage: agent-guides-drive.sh <mode> <agent>}"
AGENT="${2:?usage: agent-guides-drive.sh <mode> <agent>}"

: "${UNSLOTH_BASE_URL:?serve step did not export UNSLOTH_BASE_URL}"
: "${UNSLOTH_API_KEY:?serve step did not export UNSLOTH_API_KEY}"
: "${UNSLOTH_MODEL_ID:?serve step did not export UNSLOTH_MODEL_ID}"
# Determinism (seed/temp) is applied at the server level by
# serve-unsloth-run.sh --extra; agents inherit it through the API.
TIMEOUT="${AGENT_INVOKE_TIMEOUT:-180}"
# opencode is the slow outlier. Unlike the print-mode agents (claude -p, codex
# exec) it runs a full turn AND a separate small_model call to name the session,
# so one connection reply takes ~8 min on a CPU-served 4B -- right at the shared
# 600s cap, so the cell flaked when a run drifted past a ~480s success. Give it
# headroom (still well under the 40-min job budget); the fast agents keep the
# tight cap that still catches a real headless-TTY hang.
case "$AGENT" in
  opencode)
    # Double it, but only for a bare-integer seconds value. A GNU timeout(1)
    # duration suffix (s/m/h/d, including floats like 0.5s) is left unchanged so
    # the arithmetic never sees a non-number; timeout(1) parses it directly.
    case "$TIMEOUT" in
      *[!0-9]*) ;;
      *) TIMEOUT=$(( TIMEOUT * 2 )) ;;
    esac
    ;;
esac

# Claude refuses --dangerously-skip-permissions outside a sandbox; the CI runner
# IS the sandbox, so declare it (mirrors unslothai/scripts launcher.sh). Harmless
# to the other agents, which ignore it.
export IS_SANDBOX=1

# Absolute paths anchored at the repo root (this script lives in
# .github/scripts/). Everything writes here regardless of the current working
# directory, so the file-edit mode can `cd` into a scratch work dir without
# breaking log/redaction writes.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
LOGS_DIR="$REPO_ROOT/logs"
REDACTED_DIR="$REPO_ROOT/redacted-configs"
WORKDIR_BASE="$REPO_ROOT/agent-workdir"
CACHE_HELPER="$SCRIPT_DIR/assert-prompt-cache.sh"
mkdir -p "$LOGS_DIR" "$REDACTED_DIR"
CONNECT_REF="unsloth_cli/commands/start.py"

# Prefill-shrinking flags for Claude Code. The heavyweight agents send
# multi-thousand-token system prompts + full tool schemas, which on a CPU-only
# runner is minutes of prefill per model round-trip (~16 tok/s for a 4B model).
# Replacing the ~5.7k default system prompt with a tiny one (--system-prompt-file)
# and restricting tools cuts the prefill to a few hundred tokens so it completes
# quickly on CPU. These only shape the request size; the start.py recipe
# (endpoint, auth, model) is still exercised end to end.
# The bulk of Claude Code's prompt is the built-in tool JSON schemas: measured
# via `claude -p /context`, the default prompt is ~28k tokens of which ~18k is
# "System tools" alone. --allowedTools/--disallowedTools only gate PERMISSION to
# call a tool; they do NOT remove its schema from what is sent to the model, so
# the earlier whitelist left the full ~18k in the prompt and CPU prefill
# (~16 tok/s) overran claude's own request timeout into a retry loop. --tools is
# the flag that restricts which schemas are sent. (The ~8k "Memory files" chunk
# is auto-loaded CLAUDE.md; the unsloth repo ships none, so it is 0 in CI.)
# Connection probe: --tools "" sends ZERO tool schemas, leaving ~20 tokens total
# (a one-line --system-prompt-file + the user turn), which prefills instantly.
CLAUDE_CONNECT_FLAGS=(
  --system-prompt-file "$SCRIPT_DIR/ci-connect-prompt.txt"
  --tools ""
)
# File-edit: the task needs the file/shell tools, so send only those schemas
# (~2.3k tokens vs ~18k for the full set).
CLAUDE_EDIT_FLAGS=(
  --system-prompt-file "$SCRIPT_DIR/ci-min-system-prompt.txt"
  --tools "Bash,Edit,Write,Read"
)

guide_fail() {
  echo "::error::[guide drift] agent=${AGENT}: $* (preflight passed + install OK, so the documented flow in ${CONNECT_REF} drifted)." >&2
  exit 1
}

# Redact the API key from any file we are about to keep as an artifact.
# Portable across GNU sed (Linux runners) and BSD sed (macOS), so the
# redaction is never silently skipped.
redact() {
  local f
  for f in "$@"; do
    [ -f "$f" ] || continue
    if sed --version >/dev/null 2>&1; then
      sed -i "s#${UNSLOTH_API_KEY}#<REDACTED>#g" "$f" 2>/dev/null || true
    else
      sed -i '' "s#${UNSLOTH_API_KEY}#<REDACTED>#g" "$f" 2>/dev/null || true
    fi
  done
}

# Print a file to the log with the key scrubbed, without mutating it (the raw file is
# still needed to parse the real env). Use this instead of `cat` for any transcript that
# carries an `export UNSLOTH_API_KEY=...` line, so a live key never reaches Actions logs.
cat_redacted() {
  sed "s#${UNSLOTH_API_KEY}#<REDACTED>#g" "$1"
}

# A reply must be non-empty and free of connection/auth errors.
assert_reply() {
  local out="$1"
  if [ ! -s "$out" ]; then
    guide_fail "agent produced an EMPTY reply"
  fi
  if grep -qiE 'connection refused|connection error|econnrefused|fetch failed|http 4[0-9][0-9]|unauthorized|invalid api key|authentication failed' "$out"; then
    guide_fail "agent reply contained a connection/auth error: $(grep -iE 'connection|unauthorized|auth|http 4' "$out" | head -1)"
  fi
  echo "[$AGENT] reply (first 20 lines):"
  head -20 "$out"
}

# Run a command under a hard timeout. Two unrelated things hit the cap and only
# one of them is guide drift:
#   * nothing was ever printed -> the recipe blocked on a headless TTY prompt,
#     which is exactly the class-(c) failure this script exists to catch.
#   * a transcript was printed -> the CLI did the work and then failed to exit.
#     opencode did this on 2026-08-03: it ran the tool, printed 'Hello', and sat
#     there for the remaining 18 min with llama-server serving nothing. It is
#     intermittent, not a one-way regression -- the same two turns took 635s the
#     week before and 633s the day after.
# Blaming start.py for the second is wrong, so flag it and let the caller judge
# the turn on its assertions. TIMED_OUT is global: callers with no assertion that
# can rescue a partial turn (connection, resume, attribution-ab) treat it as fatal.
# Deciding that the cap was hit needs care. timeout(1) reports 124 when the
# command dies on the TERM it sends, but a CLI that catches or ignores TERM is
# not bounded at all without --kill-after (measured: a TERM-ignoring loop under
# `timeout 2` was still alive 8s later). --kill-after makes that case exit 137
# -- and so does an unrelated SIGKILL, e.g. the OOM killer, which must NOT be
# waived as a timeout. The two are indistinguishable by status, so read the wall
# clock instead of the exit code: only a 137 that arrives at or after the
# deadline is an expiry (measured: kill-after fired at 5s on a 3s cap, an
# external kill -9 landed at 1s on a 30s cap).
run_timed() {  # $1=outfile, rest=command
  local out="$1"; shift
  TIMED_OUT=0
  TURN_DONE=0
  local t0=$SECONDS
  local rc
  if [ -z "${TURN_DONE_RE:-}" ]; then
    timeout --kill-after=30 "$TIMEOUT" "$@" > "$out" 2>&1
    rc=$?
  else
    # An agent that prints an end-of-run marker does not have to exit before its
    # turn can be judged. openclaw finishes and then holds its session write lock
    # for the rest of the cap: on 2026-09-06 it answered `pong` and logged
    # `ended with stopReason=stop` 39ms after the model replied, then sat there
    # for the remaining 1200s, costing a 20 minute job and a "never completed a
    # turn" verdict its own transcript contradicted. Give the CLI EXIT_GRACE
    # seconds to leave on its own once the marker lands, then take it down, so
    # the caller judges a finished turn instead of a cap. Only agents with such a
    # marker opt in; for everyone else this is the same blocking call as before.
    : > "$out"
    timeout --kill-after=30 "$TIMEOUT" "$@" > "$out" 2>&1 &
    local tpid=$! seen=""
    while kill -0 "$tpid" 2>/dev/null; do
      if [ -z "$seen" ]; then
        grep -qF -- "$TURN_DONE_RE" "$out" 2>/dev/null && seen=$SECONDS
      elif [ $(( SECONDS - seen )) -ge "${EXIT_GRACE:-30}" ]; then
        TURN_DONE=1
        # The whole group, not timeout(1) and not its direct child. The command
        # is a bash wrapper that runs the agent, so signalling either one leaves
        # the CLI orphaned and unbounded -- the state this is here to end.
        # timeout(1) gives its child a group of its own, so that group is exactly
        # the invocation; refuse to fire if it ever resolves to ours.
        local kid pg
        kid="$(pgrep -P "$tpid" 2>/dev/null | head -1)"
        pg="$(ps -o pgid= -p "${kid:-0}" 2>/dev/null | tr -d ' ')"
        if [ -n "$pg" ] && [ "$pg" != "$(ps -o pgid= -p $ | tr -d ' ')" ]; then
          kill -TERM "-$pg" 2>/dev/null || true
          sleep 10
          kill -KILL "-$pg" 2>/dev/null || true
        else
          pkill -TERM -P "$tpid" 2>/dev/null || true
          sleep 10
          pkill -KILL -P "$tpid" 2>/dev/null || true
        fi
        break
      fi
      sleep 2
    done
    wait "$tpid"
    rc=$?
  fi
  local elapsed=$(( SECONDS - t0 ))
  # Neither status proves expiry on its own. 137 is also an unrelated SIGKILL,
  # and 124 is also whatever the CLI itself chose to exit with -- timeout(1)
  # otherwise returns "the exit status of COMMAND", and an agent that hit its
  # own internal request timeout can exit 124 early, after leaving hello.py
  # behind. So both statuses have to agree with the clock. SECONDS is
  # truncated to whole seconds at both ends, so allow one second of slack;
  # a CLI-originated 124 returns nowhere near the cap.
  local expired=0
  case "$TIMEOUT" in
    # A timeout(1) duration suffix (600s / 10m) is not a number we can compare,
    # so fall back to trusting 124 alone rather than parsing it.
    *[!0-9]*) [ "$rc" -eq 124 ] && expired=1 ;;
    *)
      if [ "$rc" -eq 124 ] || [ "$rc" -eq 137 ]; then
        [ "$elapsed" -ge $(( TIMEOUT - 1 )) ] && expired=1
      fi
      ;;
  esac
  if [ "$expired" -eq 1 ]; then
    redact "$out"  # guide_fail may exit below, so scrub the transcript here too
    echo "[$AGENT] last 40 lines before timeout:"; tail -40 "$out" 2>/dev/null || true
    [ -s "$out" ] || guide_fail "invoke timed out after ${TIMEOUT}s having printed nothing (headless-TTY hang -- the recipe likely needs a non-interactive/print flag)"
    TIMED_OUT=1
    # State the fact, not the verdict. Three callers (connection, resume,
    # attribution-ab) have no assertion that can rescue a partial turn and treat
    # a cap as fatal on purpose, so promising that the turn will be judged on its
    # assertions was wrong for exactly the cases most likely to hit it -- and it
    # is what a reader sees immediately above the error that contradicts it.
    echo "::warning::[$AGENT] the CLI printed a transcript but did not exit within ${TIMEOUT}s; whether that is fatal is the caller's call."
    # The marker can land inside the last poll interval, or after a cap reached
    # without the watcher. Either way the turn is over, and the caller may say so.
    if [ -n "${TURN_DONE_RE:-}" ] && grep -qF -- "$TURN_DONE_RE" "$out" 2>/dev/null; then
      TURN_DONE=1
    fi
  fi
  if [ "${TURN_DONE:-0}" = 1 ]; then
    # The fact, not the verdict, for the same reason the cap warning states one:
    # what a finished-but-hung run means is the caller's to say, and a promise
    # made here is read directly above whatever the caller decides.
    echo "::warning::[$AGENT] the CLI logged the end of its run (${TURN_DONE_RE}) and then would not exit."
  fi
  return "$rc"
}

# Read a value from an `export VAR=...` line in the connect --no-launch output.
# `unsloth start` writes each agent's session config off the user's ~ and points
# at it through a relocation env var (CODEX_HOME / OPENCODE_CONFIG /
# OPENCLAW_CONFIG_PATH), so the contract checks read the path from here.
raw_env() {  # $1 = var name -> value (one shlex-quote layer stripped)
  local raw="$LOGS_DIR/connect-${AGENT}.txt"
  local v; v="$(sed -n "s/^export $1=//p" "$raw" | tail -1)"
  v="${v#\'}"; v="${v%\'}"; printf '%s' "$v"
}

# ── 5-agent start.py path: parse env + command from --no-launch ─────────
# Populates globals CONNECT_ENV (export/unset lines) and CONNECT_CMD (the
# launch command on the last printed line), and runs start.py's config
# writers as a side effect (it writes each agent's relocated session config).
parse_connect() {
  local raw="$LOGS_DIR/connect-${AGENT}.txt"
  # CONNECT_YOLO=1 adds --yolo. opencode/openclaw gate tool approval through their
  # config (which now prompts by default), so the file-edit test opts into auto-approval
  # here, the same intent as claude/codex's per-call bypass flags.
  local yolo=()
  [ -n "${CONNECT_YOLO:-}" ] && yolo=(--yolo)
  # dsh's `--profile headless`: its default recipe opens the browser UI instead.
  # shellcheck disable=SC2206
  local passthrough=(${CONNECT_START_ARGS:-})
  if ! unsloth start "$AGENT" --no-launch "${yolo[@]}" --api-key "$UNSLOTH_API_KEY" \
      "${passthrough[@]}" > "$raw" 2>&1; then
    cat_redacted "$raw"
    guide_fail "'unsloth start ${AGENT} --no-launch' exited non-zero"
  fi
  echo "[$AGENT] connect --no-launch printed:"; cat_redacted "$raw"
  CONNECT_ENV="$(grep -E '^(export |unset )' "$raw" || true)"
  # The launch command is the last non-export, non-status line. start.py
  # prints "Unsloth <url> · model <id>" and "Updated ..." status lines first.
  CONNECT_CMD="$(grep -vE '^(export |unset |Unsloth |Updated |Disabled |Warning|Loading)' "$raw" \
    | grep -E '[^[:space:]]' | tail -1)"
  [ -n "$CONNECT_CMD" ] || guide_fail "could not parse a launch command from connect --no-launch output"
  redact "$raw"
}

# Cross-check the documented contract knobs so silent start.py changes
# (env-var rename, wire_api flip, attribution setting drop) also fail/flag.
crosscheck_contract() {
  local raw="$LOGS_DIR/connect-${AGENT}.txt"
  local cfg home
  case "$AGENT" in
    codex)
      grep -q 'UNSLOTH_STUDIO_AUTH_TOKEN' "$raw" \
        || guide_fail "Codex env key is no longer UNSLOTH_STUDIO_AUTH_TOKEN (start.py _CODEX_ENV_KEY)"
      home="$(raw_env CODEX_HOME)"
      # An empty relocation var would make cfg "/config.toml" and silently
      # skip the [ -f ] contract check below; fail loudly instead.
      [ -n "$home" ] || guide_fail "CODEX_HOME missing from connect output (start.py codex())"
      cfg="$home/config.toml"
      if [ -f "$cfg" ]; then
        grep -q 'wire_api = "responses"' "$cfg" \
          || guide_fail "Codex wire_api is no longer \"responses\" in \$CODEX_HOME/config.toml"
        cp "$cfg" "$REDACTED_DIR/codex-config.toml"
      fi
      grep -q 'codex --oss --profile unsloth_api' "$raw" \
        || echo "::warning::Codex launch command changed from 'codex --oss --profile unsloth_api'"
      ;;
    claude)
      grep -q 'ANTHROPIC_AUTH_TOKEN' "$raw" \
        || guide_fail "Claude no longer exports ANTHROPIC_AUTH_TOKEN (start.py claude())"
      grep -q 'CLAUDE_CODE_ATTRIBUTION_HEADER' "$raw" \
        || echo "::warning::CLAUDE_CODE_ATTRIBUTION_HEADER no longer set for the session (start.py claude())"
      ;;
    hermes)
      grep -q 'UNSLOTH_API_KEY' "$raw" \
        || guide_fail "Hermes env key is no longer UNSLOTH_API_KEY (start.py _HERMES_ENV_KEY)"
      home="$(raw_env HERMES_HOME)"
      [ -n "$home" ] || guide_fail "HERMES_HOME missing from connect output (start.py hermes())"
      cfg="$home/config.yaml"
      [ -f "$cfg" ] && cp "$cfg" "$REDACTED_DIR/hermes-config.yaml"
      ;;
    openclaw)
      cfg="$(raw_env OPENCLAW_CONFIG_PATH)"
      if [ -n "$cfg" ] && [ -f "$cfg" ]; then
        grep -q '"openai-completions"' "$cfg" \
          || echo "::warning::OpenClaw provider api is no longer 'openai-completions' (write_openclaw_config)"
        cp "$cfg" "$REDACTED_DIR/openclaw.json"
      fi
      ;;
    opencode)
      cfg="$(raw_env OPENCODE_CONFIG)"
      [ -n "$cfg" ] && [ -f "$cfg" ] && cp "$cfg" "$REDACTED_DIR/opencode.json"
      ;;
    pi)
      # Pi has no config-dir env var; the session is HOME-relocated, and the
      # provider config lives at $HOME/.pi/agent/models.json.
      cfg="$(raw_env HOME)/.pi/agent/models.json"
      if [ -f "$cfg" ]; then
        grep -q '"openai-completions"' "$cfg" \
          || echo "::warning::Pi provider api is no longer 'openai-completions' (write_pi_config)"
        cp "$cfg" "$REDACTED_DIR/pi-models.json"
      fi
      ;;
    dsh)
      grep -q 'UNSLOTH_API_KEY' "$raw" \
        || guide_fail "dsh env key is no longer UNSLOTH_API_KEY (start.py _DSH_ENV_KEY)"
      home="$(raw_env DSH_HOME)"
      [ -n "$home" ] || guide_fail "DSH_HOME missing from connect output (start.py dsh())"
      cfg="$home/settings.yaml"
      if [ -f "$cfg" ]; then
        grep -q 'openai-completions' "$cfg" \
          || echo "::warning::dsh provider api is no longer 'openai-completions' (write_dsh_config)"
        cp "$cfg" "$REDACTED_DIR/dsh-settings.yaml"
      fi
      ;;
  esac
  redact "$REDACTED_DIR"/* 2>/dev/null || true
}

# Heavyweight agents (hermes, openclaw) bake a large system prompt + tool JSON
# schemas into every request, which a CPU runner cannot prefill before the invoke
# timeout. As with claude's --tools, we shrink the request from the agent's own
# config: zero tools for the connection probe collapses the prompt to a few
# hundred tokens, since both CLIs gate the bulk of their prompt on having tools.

# Hermes: an explicit empty cli toolset disables all tools (and drops the
# tool-gated guidance blocks), so -z sends ~300 tokens instead of thousands.
# Hermes enables its default cli toolset when the session config does not pin one,
# so we must set platform_toolsets.cli explicitly to [] (not just append) to get
# zero tools. That needs a YAML parser, and the runner's bare python3 has no
# PyYAML -- but the venv that ships `unsloth` does (start.py imports yaml), so run
# the patch with that interpreter. We patch the relocated $HERMES_HOME/config.yaml
# that `unsloth start` printed, not the user's ~/.hermes.
# (-z reads platform_toolsets.cli; --ignore-rules is a no-op under -z.)
patch_hermes_tools() {  # $1 = none|default
  # Check the raw var BEFORE appending /config.yaml: the joined path is never
  # empty, so the old guard could not fire and the patcher would die on
  # "/config.yaml" with a bare traceback instead of this clear failure.
  local home; home="$(raw_env HERMES_HOME)"
  [ -n "$home" ] || guide_fail "Hermes HERMES_HOME missing from connect output (start.py hermes())"
  local cfg; cfg="$home/config.yaml"
  # Find a python that can import yaml. The runner's bare python3 cannot, but the
  # interpreter in the `unsloth` console-script shebang provably can (it runs
  # start.py's write_hermes_config, which imports yaml). Try that first, then
  # any python on PATH, then the venv sibling, picking the first with PyYAML.
  local cand py="" shebang
  shebang="$(head -1 "$(command -v unsloth)" 2>/dev/null | sed -n 's/^#![[:space:]]*//p' | awk '{print $1}')"
  for cand in "$shebang" python3 python "$(dirname "$(command -v unsloth)")/python"; do
    [ -n "$cand" ] || continue
    { [ -x "$cand" ] || command -v "$cand" >/dev/null 2>&1; } || continue
    if "$cand" -c 'import yaml' 2>/dev/null; then py="$cand"; break; fi
  done
  [ -n "$py" ] || guide_fail "could not find a python with PyYAML to patch the hermes session config"
  echo "[hermes] patching $cfg with $py"
  "$py" - "$1" "$cfg" <<'PY'
import os, sys
import yaml
mode = sys.argv[1]
p = sys.argv[2]
cfg = (yaml.safe_load(open(p)) or {}) if os.path.exists(p) else {}
ts = cfg.get("platform_toolsets")
if not isinstance(ts, dict):
    ts = cfg["platform_toolsets"] = {}
if mode == "none":
    ts["cli"] = []          # explicit empty list -> zero tools (not "defaults")
else:
    ts.pop("cli", None)     # file-edit needs real tools -> restore defaults
with open(p, "w") as fh:
    yaml.safe_dump(cfg, fh, sort_keys=False)
print(f"[hermes] platform_toolsets.cli = {ts.get('cli', 'default')}")
PY
}

# OpenClaw: 'openclaw agent' has no tool/prompt flags, so we define a 'ci' agent
# in openclaw.json. tools.deny ["*"] sends zero tool schemas (deny always wins)
# for the connection probe; contextInjection "never" + defaults.skipBootstrap
# drop the auto-injected AGENTS.md/SOUL.md bootstrap (the bulk of the prompt) for
# both modes. --agent must reference a defined agent, so write it before invoking.
patch_openclaw_agent() {  # $1 = notools|tools
  # OpenClaw reads its config from the relocated OPENCLAW_CONFIG_PATH that
  # `unsloth start` printed, so patch THAT file (not the user's ~/.openclaw).
  local cfg; cfg="$(raw_env OPENCLAW_CONFIG_PATH)"
  [ -n "$cfg" ] || guide_fail "OpenClaw OPENCLAW_CONFIG_PATH missing from connect output (start.py openclaw())"
  python3 - "$1" "$cfg" <<'PY'
import os, sys, json
mode = sys.argv[1]
p = sys.argv[2]
cfg = json.load(open(p)) if os.path.exists(p) else {}
agents = cfg.setdefault("agents", {})
agents.setdefault("defaults", {})["skipBootstrap"] = True
lst = [a for a in agents.get("list", []) if a.get("id") != "ci"]
agent = {"id": "ci", "contextInjection": "never"}
if mode == "notools":
    agent["tools"] = {"deny": ["*"]}
lst.append(agent)
agents["list"] = lst
with open(p, "w") as fh:
    json.dump(cfg, fh, indent=2)
print(f"[openclaw] agent ci tools = {agent.get('tools', 'default')}")
PY
}

# Build an invoke script that applies start.py's env then runs the launch
# command (with extra args appended) under bash. We do NOT eval connect's env
# into this shell; we write it into a one-shot script so the export/unset
# semantics are exactly what start.py printed. The script path is absolute
# so it is valid even when the caller has cd'd into a scratch work dir.
invoke_via_connect() {  # $1=outfile, rest=extra args appended to the command
  local out="$1"; shift
  local script="$LOGS_DIR/invoke-${AGENT}.sh"
  local real; real="$(mktemp)"
  # CONNECT_ENV_EXTRA / CONNECT_CMD_OVERRIDE let a caller (attribution-ab) flip a
  # session knob without editing the user's config; empty -> use what start.py emitted.
  local cmd="${CONNECT_CMD_OVERRIDE:-$CONNECT_CMD}"
  # A bare V2 recipe ends in --standalone for the TUI. Once this driver adds the
  # run subcommand, V2 requires that option after run instead of before it.
  if [ "$AGENT" = opencode ] && [[ "$cmd" == *" --standalone" ]] && [ "${1:-}" = run ]; then
    cmd="${cmd% --standalone}"
    set -- run --standalone "${@:2}"
  fi
  {
    echo "set -uo pipefail"
    echo "$CONNECT_ENV"
    [ -n "${CONNECT_ENV_EXTRA:-}" ] && echo "$CONNECT_ENV_EXTRA"
    # Append extra args (the prompt / flags) to the launch command verbatim.
    printf '%s' "$cmd"
    local a
    for a in "$@"; do printf ' %q' "$a"; done
    printf '\n'
  } > "$real"
  # Upload a REDACTED copy of the script, but EXECUTE the un-redacted one from a
  # temp path outside the artifact dir. Redacting the script we run would turn
  # the real `export TOKEN=sk-...` line into `export TOKEN=<REDACTED>`, which is
  # invalid bash (the `<`/`>` are redirections) and silently breaks every agent.
  # Writing the redacted copy up front keeps the key out of the artifact even if
  # the run times out (run_timed exits before returning here).
  cp "$real" "$script"; redact "$script"
  # The connect one-liner now carries the key as an inline env assignment; scrub it on
  # the way to the log (the executed $real keeps the live value).
  echo "[$AGENT] invoking (timeout ${TIMEOUT}s): ${cmd//${UNSLOTH_API_KEY}/<REDACTED>} $*"
  run_timed "$out" bash "$real"
  local rc=$?
  rm -f "$real"
  redact "$out"  # the transcript can echo the token; scrub before upload
  return "$rc"
}

case "$MODE" in
  # ── connection: trivial prompt, assert a non-empty, error-free reply ────
  connection)
    PROMPT='Reply with exactly the single word: pong'
    OUT="$LOGS_DIR/${AGENT}-connection.txt"
    case "$AGENT" in dsh) CONNECT_START_ARGS='--profile headless' ;; esac
    parse_connect
    crosscheck_contract
    # claude/codex run in print mode via the flags start.py emits
    # (claude -p / codex exec). For agents whose default subcommand prints
    # to stdout we pass the prompt through ctx.args.
    case "$AGENT" in
      claude)   invoke_via_connect "$OUT" "${CLAUDE_CONNECT_FLAGS[@]}" -p "$PROMPT" ;;
      codex)    invoke_via_connect "$OUT" exec --dangerously-bypass-approvals-and-sandbox "$PROMPT" ;;
      opencode) invoke_via_connect "$OUT" run "$PROMPT" ;;
      pi)       invoke_via_connect "$OUT" -p "$PROMPT" ;;
      hermes)   patch_hermes_tools none
                invoke_via_connect "$OUT" -z "$PROMPT" ;;
      openclaw) patch_openclaw_agent notools
                # openclaw logs this once per run, and only when the run is over
                # ("run <uuid> ended with stopReason=stop"). It is the one signal
                # here that a banner cannot forge, so it is what lets a hung exit
                # be told apart from a turn that never came back.
                TURN_DONE_RE='ended with stopReason='
                CONNECT_CMD_OVERRIDE=openclaw invoke_via_connect "$OUT" agent --local --agent ci \
                  --model "unsloth/${UNSLOTH_MODEL_ID}" --message "$PROMPT" ;;
      *)        invoke_via_connect "$OUT" "$PROMPT" ;;
    esac
    # A non-zero exit from the documented launch command is drift even if it
    # printed something: a benign-looking "command not found" / usage dump would
    # otherwise slip past assert_reply (which only flags empty/error-keyword text).
    # A timeout is no exception here. assert_reply cannot tell a completed reply
    # from a startup banner (it checks for non-empty text without the connection
    # /auth error strings, not for the requested "pong"), so waiving a cap would
    # report "connection OK" for a recipe that printed a banner and then blocked
    # on a headless prompt -- the exact failure this job exists to catch.
    rc=$?
    # Two different failures, and pointing both at start.py costs an
    # investigation. A cap means the launch command was fine and the turn never
    # came back: on 2026-08-19 codex printed a correct banner (right provider,
    # right model) and then sat on `ERROR: Reconnecting... 1/5` for the whole
    # 600s. Nothing about the documented flow had drifted, and guide_fail said it
    # had. It is still fatal -- see the note above on why a cap cannot be waived
    # here -- but it is reported as what it is.
    if [ "${TIMED_OUT:-0}" = 1 ] && [ "${TURN_DONE:-0}" != 1 ]; then
      echo "::error::[$AGENT] the documented launch command started but never completed a turn within ${TIMEOUT}s. The recipe in ${CONNECT_REF} is not implicated: the transcript above shows what the CLI was doing when the cap hit. A connection or model-server failure looks like this; so does a headless prompt, which prints nothing at all." >&2
      exit 1
    fi
    # TURN_DONE is not a waiver of the cap, it is the assertion the cap was
    # missing. The reason connection could never rescue a hang is that
    # assert_reply cannot tell a completed reply from a startup banner; an
    # end-of-run line the agent prints only when a run terminates can. A banner
    # still carries no marker and still fails above. The rc check is skipped only
    # here, because the non-zero status is the one run_timed produced itself when
    # it stopped a CLI that had already finished.
    if [ "${TURN_DONE:-0}" != 1 ]; then
      [ "$rc" -eq 0 ] || guide_fail "the documented launch command exited non-zero (rc=$rc) -- see the transcript above"
    fi
    assert_reply "$OUT"
    echo "[$AGENT] connection OK"
    ;;

  # ── file-edit: deterministic 2-turn hello.py test (gemma-4-E4B-it) ──────
  file-edit)
    WORK="$WORKDIR_BASE/${AGENT}"
    rm -rf "$WORK"; mkdir -p "$WORK"
    OUT1="$LOGS_DIR/${AGENT}-fileedit-turn1.txt"
    OUT2="$LOGS_DIR/${AGENT}-fileedit-turn2.txt"
    T1='Create a file named hello.py in the current directory whose entire contents are a single line: print("Hello"). Do not run it.'
    # One instruction only. Also asking for a ran.txt copy (#7838) made opencode
    # narrate the tool call and create no file, where the one-part prompt had run
    # for real in ~90s every time.
    T2='Run hello.py with python and show me the exact output.'

    # The start.py recipe writers + crosscheck must see the repo; run them
    # from the repo root BEFORE cd-ing into the scratch work dir. opencode/openclaw
    # gate tool approval through their config (prompting by default), so file-edit
    # opts them into auto-approval to run edits/commands headlessly.
    case "$AGENT" in
      opencode|openclaw) CONNECT_YOLO=1 ;;
      # A headless run has nobody to answer dsh's approval asks.
      dsh) CONNECT_YOLO=1; CONNECT_START_ARGS='--profile headless' ;;
    esac
    parse_connect
    crosscheck_contract
    # File-edit needs real tools, so we cannot zero them as in connection.
    # hermes keeps default tools; openclaw still strips its AGENTS.md/SOUL.md
    # bootstrap (the largest prompt chunk) via the 'ci' agent. The scratch work
    # dir is empty, so no project context files are auto-loaded either.
    case "$AGENT" in
      hermes)   patch_hermes_tools default ;;
      openclaw) patch_openclaw_agent tools ;;
    esac

    # Drive from inside the work dir so the agent edits files there. All log
    # writes use absolute $LOGS_DIR, so cwd does not matter for them.
    cd "$WORK" || guide_fail "could not enter work dir $WORK"

    invoke_turn() {  # $1=outfile $2=continue? $3=prompt
      local out="$1" cont="$2" prompt="$3"
      case "$AGENT" in
        pi)
          # Pi continues the previous session with -c; provider/model come from
          # the parsed `unsloth start pi` recipe (CONNECT_CMD), not hardcoded here.
          if [ "$cont" = "continue" ]; then
            invoke_via_connect "$out" -p --continue "$prompt"
          else
            invoke_via_connect "$out" -p "$prompt"
          fi ;;
        claude)
          # --dangerously-skip-permissions lets headless claude actually use the
          # Write/Bash tools (otherwise it blocks on an approval prompt and emits
          # nothing). IS_SANDBOX=1 (exported above) authorizes it.
          if [ "$cont" = "continue" ]; then
            invoke_via_connect "$out" "${CLAUDE_EDIT_FLAGS[@]}" --dangerously-skip-permissions -p --continue "$prompt"
          else
            invoke_via_connect "$out" "${CLAUDE_EDIT_FLAGS[@]}" --dangerously-skip-permissions -p "$prompt"
          fi ;;
        codex)
          # --dangerously-bypass-approvals-and-sandbox gives codex exec
          # workspace-write (default is read-only -> cannot create hello.py) and
          # skips the bubblewrap sandbox that the runner lacks.
          if [ "$cont" = "continue" ]; then
            invoke_via_connect "$out" exec --dangerously-bypass-approvals-and-sandbox resume --last "$prompt"
          else
            invoke_via_connect "$out" exec --dangerously-bypass-approvals-and-sandbox "$prompt"
          fi ;;
        opencode) invoke_via_connect "$out" run "$prompt" ;;
        hermes)   invoke_via_connect "$out" -z "$prompt" ;;
        openclaw) CONNECT_CMD_OVERRIDE=openclaw invoke_via_connect "$out" agent --local --agent ci \
                    --model "unsloth/${UNSLOTH_MODEL_ID}" --message "$prompt" ;;
        *)        invoke_via_connect "$out" "$prompt" ;;
      esac
    }

    # Turn 1: create hello.py.
    invoke_turn "$OUT1" fresh "$T1"
    # Fail on a non-zero agent exit before trusting side effects: an agent can
    # error out (API/tool failure) yet leave a plausible file/transcript behind,
    # which would otherwise slip past the assertions below (mirrors connection).
    rc=$?
    [ "$rc" -eq 0 ] || [ "${TIMED_OUT:-0}" = 1 ] \
      || { echo "[$AGENT] turn-1 transcript:"; tail -40 "$OUT1" 2>/dev/null || true; \
      guide_fail "turn 1 (create hello.py) exited non-zero (rc=$rc)"; }

    # Hard assertions on the side effect (the real test): file + content + run.
    if [ ! -f hello.py ]; then
      echo "[$AGENT] turn-1 transcript:"; tail -40 "$OUT1" 2>/dev/null || true
      guide_fail "turn 1 did not create hello.py"
    fi
    grep -q 'Hello' hello.py || guide_fail "hello.py does not contain 'Hello'"
    RUN_OUT="$(python3 hello.py 2>&1 || true)"
    [ "$RUN_OUT" = "Hello" ] || guide_fail "python3 hello.py printed '$RUN_OUT', expected exactly 'Hello'"
    echo "[$AGENT] turn 1 OK (file created, prints 'Hello')"

    # Turn 2: same cwd + session continuation; assert the agent's run output
    # contains Hello. Narration drift is WARN-only, missing output is a hard fail.
    # No cap waiver here, unlike turn 1, whose side effect the harness re-runs
    # itself: turn 1's assertions all ran before this started, so a cap leaves
    # only the transcript, and 'Hello' is hello.py's source, its stdout and a
    # narration of it alike. Fatal, as for connection, resume, attribution-ab.
    invoke_turn "$OUT2" continue "$T2"
    rc=$?
    [ "$rc" -eq 0 ] \
      || { echo "[$AGENT] turn-2 transcript:"; tail -60 "$OUT2" 2>/dev/null || true; \
      guide_fail "turn 2 (run hello.py) exited non-zero (rc=$rc)"; }
    if grep -q 'Hello' "$OUT2"; then
      echo "[$AGENT] turn 2 OK (run output contains 'Hello')"
    else
      echo "[$AGENT] turn-2 transcript:"; tail -60 "$OUT2" 2>/dev/null || true
      guide_fail "turn 2 run/bash output did not contain 'Hello'"
    fi
    cd "$REPO_ROOT" || true
    echo "[$AGENT] file-edit OK"
    ;;

  # ── attribution-ab: Claude Code KV-cache HIT vs MISS ────────────────────
  attribution-ab)
    [ "$AGENT" = "claude" ] || guide_fail "attribution-ab only applies to claude"
    # The llama-server log filename uses the INTERNAL random llama.cpp port,
    # not STUDIO_PORT, so we never glob by port: assert-prompt-cache.sh picks
    # the newest llama-*.log and we slice it by a byte offset (`mark`) captured
    # right before the measured turn, so an earlier turn's reuse can't leak in.
    LLAMA_LOG_DIR="${UNSLOTH_LLAMA_LOG_DIR:-$HOME/.unsloth/studio/logs/llama-server}"
    export LLAMA_LOG_DIR
    parse_connect          # prints session env + suppression flags (no ~/.claude write)
    crosscheck_contract
    PROMPT='Reply with exactly the single word: pong'

    # The four invokes below never check rc, so run_timed's cap was their only
    # hang guard. Nothing here can adjudicate a partial turn either -- the
    # verdict is a llama-server log slice -- so a cap stays fatal, as it does
    # for connection and resume.
    # --tools "" and nothing else: gemma-3-270m declares no tools, so /v1/messages now 400s
    # the default 25 schemas. The system prompt stays -- the attribution line lives in it.
    ab_invoke() {
      invoke_via_connect "$1" --tools "" "${@:2}"
      [ "${TIMED_OUT:-0}" = 1 ] && guide_fail "attribution-ab invoke timed out after ${TIMEOUT}s; the A/B cannot be judged from a partial turn"
      return 0
    }

    # Phase A: the suppression start.py ships (CLAUDE_CODE_ATTRIBUTION_HEADER=0 +
    # --exclude-dynamic-system-prompt-sections + --settings overlay) -> expect a
    # HIT on the continued turn, since the system-prompt prefix is stable.
    ab_invoke "$LOGS_DIR/claude-ab-hit-1.txt" -p "$PROMPT"        # turn 1 primes
    FROM_HIT="$(bash "$CACHE_HELPER" mark)"                                # offset before turn 2
    ab_invoke "$LOGS_DIR/claude-ab-hit-2.txt" -p --continue "$PROMPT again"
    CACHE_LOG_FROM="$FROM_HIT" bash "$CACHE_HELPER" log HIT

    # Phase B: vanilla Claude with the header ENABLED -> expect a MISS. We flip
    # the env var to 1 and strip the suppression flags from the launch command
    # (without them the dynamic attribution line is included and changes every
    # turn, so the shared prefix moves and the KV cache is invalidated, ~90%
    # slower). This is session-only: nothing is written to ~/.claude.
    CONNECT_ENV_EXTRA='export CLAUDE_CODE_ATTRIBUTION_HEADER=1'
    CONNECT_CMD_OVERRIDE="$(printf '%s' "$CONNECT_CMD" \
      | sed -E "s/ --exclude-dynamic-system-prompt-sections//; s/ --settings '[^']*'//")"
    ab_invoke "$LOGS_DIR/claude-ab-miss-1.txt" -p "$PROMPT"
    FROM_MISS="$(bash "$CACHE_HELPER" mark)"
    ab_invoke "$LOGS_DIR/claude-ab-miss-2.txt" -p --continue "$PROMPT again"
    CACHE_LOG_FROM="$FROM_MISS" bash "$CACHE_HELPER" log MISS
    unset CONNECT_ENV_EXTRA CONNECT_CMD_OVERRIDE
    echo "[claude] attribution A/B OK (suppressed HIT, header=1 MISS)"
    ;;

  # ── resume: does a launched agent's session survive exit and resume? ────
  # Unlike the other modes, this drives the real LAUNCH path (`unsloth start
  # <agent> ...`, the interactive default), not the --no-launch recipe. That
  # path relocates each agent's home to a throwaway temp dir wiped on exit, so
  # a session cannot be resumed -- unless --persist routes it to the stable
  # Unsloth agents dir instead. We run one headless turn per pass and check
  # whether the turn left a session in a persistent store (deterministic, no
  # reliance on the model recalling anything), for a baseline pass and a
  # --persist pass, and assert the expected split for this agent.
  resume)
    CODEWORD="PLATYPUS7"
    T1="Remember this codeword for later: ${CODEWORD}. Reply with just the word OK."
    T2="What codeword did I ask you to remember? Reply with just that word."
    WORK="$WORKDIR_BASE/${AGENT}-resume"

    # STABLE_HOME: the stable dir that --no-launch (and --persist) relocate to.
    # Read it from a --no-launch probe (which also writes the agent's config
    # there). codex/pi relocate their whole home/HOME here; opencode/claude keep
    # their session data in a fixed user dir, so STABLE_HOME stays empty for them.
    parse_connect
    case "$AGENT" in
      codex)    STABLE_HOME="$(raw_env CODEX_HOME)" ;;
      pi)       STABLE_HOME="$(raw_env HOME)" ;;
      *)        STABLE_HOME="" ;;
    esac

    # The persistent stores a session would land in if it were NOT wiped. We
    # count files here before/after each turn; a positive delta means the
    # session persisted (is resumable), zero means it went to a wiped temp dir.
    resume_tracked_dirs() {
      case "$AGENT" in
        codex)    printf '%s\n' "$HOME/.codex" ;;
        opencode) printf '%s\n' "$HOME/.local/share/opencode" "$HOME/.config/opencode" ;;
        claude)   printf '%s\n' "$HOME/.claude" ;;
        pi)       printf '%s\n' "$HOME/.pi" ;;
        *)        : ;;
      esac
      [ -n "$STABLE_HOME" ] && printf '%s\n' "$STABLE_HOME"
    }
    count_session_files() {
      local total=0 d n
      while IFS= read -r d; do
        [ -n "$d" ] && [ -d "$d" ] || continue
        n="$(find "$d" -type f 2>/dev/null | wc -l)"; total=$((total + n))
      done < <(resume_tracked_dirs)
      echo "$total"
    }

    # The headless first-turn subcommand per agent (mirrors file-edit's map),
    # forwarded verbatim through the launch path as passthrough args.
    set_t1_cmd() {
      case "$AGENT" in
        claude)   T1_CMD=("${CLAUDE_CONNECT_FLAGS[@]}" -p "$T1") ;;
        codex)    T1_CMD=(exec "$T1") ;;
        opencode) T1_CMD=(run "$T1") ;;
        pi)       T1_CMD=(-p "$T1") ;;
        *)        guide_fail "resume mode does not cover agent '$AGENT'" ;;
      esac
    }

    # Run one headless turn through the launch path. $1=outfile, $2="" or
    # "--persist", rest = the agent subcommand. --yolo auto-approves so no tool
    # prompt can hang; --api-key attaches to the already-served CI model.
    launch_turn() {
      local out="$1" rflag="$2"; shift 2
      local flag=(); [ -n "$rflag" ] && flag=("$rflag")
      run_timed "$out" unsloth start "$AGENT" "${flag[@]}" --yolo \
        --api-key "$UNSLOTH_API_KEY" "$@"
      local rc=$?
      redact "$out"
      # Unlike connection/file-edit there is no assertion that can rescue a
      # partial turn here: RESULT is a session-store delta, and a half-written
      # store would read as a bogus PERSISTED/WIPED. Keep a hang fatal.
      [ "${TIMED_OUT:-0}" = 1 ] && guide_fail "invoke timed out after ${TIMEOUT}s; a resume pass cannot be judged from a partial turn"
      return "$rc"
    }

    # One pass: fresh work dir, one planting turn, set RESULT to PERSISTED/WIPED
    # from the session-store delta. Runs in the main shell (not a command
    # substitution) so a hang's guide_fail actually fails the job and the
    # progress lines reach the CI log. $1 = "" (baseline) or "--persist".
    RESULT=""
    run_pass() {
      local rflag="$1" label="baseline"
      [ -n "$rflag" ] && label="resume"
      rm -rf "$WORK"; mkdir -p "$WORK"
      set_t1_cmd
      local out="$LOGS_DIR/${AGENT}-resume-${label}.txt"
      local before after rc
      before="$(count_session_files)"
      pushd "$WORK" >/dev/null || guide_fail "could not enter work dir $WORK"
      launch_turn "$out" "$rflag" "${T1_CMD[@]}"; rc=$?
      popd >/dev/null || true
      after="$(count_session_files)"
      echo "[$AGENT] ${label}: session files ${before} -> ${after} (rc=${rc})"
      # The turn must succeed for the delta to mean anything: an agent that writes a
      # session file then errors would otherwise be misread as PERSISTED. Mirror the
      # file-edit mode and fail the pass on a non-zero launch (the flagship codex recall
      # below stays WARN-only, driven by its own launch_turn calls).
      [ "$rc" -eq 0 ] || { echo "[$AGENT] ${label} transcript (tail):"; tail -30 "$out" 2>/dev/null || true; \
        guide_fail "resume ${label} turn for ${AGENT} exited non-zero (rc=${rc})"; }
      if [ "$after" -gt "$before" ]; then RESULT="PERSISTED"; else RESULT="WIPED"; fi
    }

    run_pass ""; BASELINE="$RESULT"
    # Only the temp-dir agents (codex/pi) need the --persist pass to prove the fix.
    # opencode/claude persist either way, so the baseline already proves it and a
    # second full CPU turn only risks a timeout; skip it for them.
    case "$AGENT" in
      codex|pi) run_pass "--persist"; RESUME="$RESULT" ;;
      *)        RESUME="n/a (persists either way)" ;;
    esac

    # Expected: codex/pi relocate their whole home to the temp dir, so a plain
    # launch is WIPED and only --persist PERSISTS. opencode/claude keep their
    # session data in a fixed user dir, so the baseline already PERSISTS.
    case "$AGENT" in
      codex|pi)        EXPECT_BASELINE="WIPED" ;;
      opencode|claude) EXPECT_BASELINE="PERSISTED" ;;
    esac

    echo "──────────────────────────────────────────────"
    echo "[$AGENT] RESUME EXPERIMENT"
    echo "  baseline (unsloth start ${AGENT}):                 ${BASELINE}  (expected ${EXPECT_BASELINE})"
    echo "  with --persist (unsloth start ${AGENT} --persist): ${RESUME}"
    echo "──────────────────────────────────────────────"

    [ "$BASELINE" = "$EXPECT_BASELINE" ] \
      || guide_fail "baseline resume behavior for ${AGENT} was ${BASELINE}, expected ${EXPECT_BASELINE}"
    case "$AGENT" in
      codex|pi)
        [ "$RESUME" = "PERSISTED" ] \
          || guide_fail "--persist did not persist ${AGENT}'s session (got ${RESUME}); the session dir is still not stable" ;;
    esac

    # Flagship behavioral proof (codex only, WARN-only): after a --persist plant,
    # resume the session and check the model actually recalls the codeword. A
    # miss is not a failure (the CI model is small); the mechanism gate above is
    # the real assertion.
    if [ "$AGENT" = "codex" ]; then
      rm -rf "$WORK"; mkdir -p "$WORK"
      ( cd "$WORK" && launch_turn "$LOGS_DIR/codex-resume-plant.txt" "--persist" exec "$T1" ) || true
      ( cd "$WORK" && launch_turn "$LOGS_DIR/codex-resume-recall.txt" "--persist" exec resume --last "$T2" ) || true
      if grep -q "$CODEWORD" "$LOGS_DIR/codex-resume-recall.txt" 2>/dev/null; then
        echo "[codex] behavioral recall HIT: resumed session remembered ${CODEWORD}"
      else
        echo "::warning::[codex] behavioral recall MISS (small CI model); mechanism gate still passed"
      fi
    fi
    echo "[$AGENT] resume OK"
    ;;

  *)
    echo "agent-guides-drive.sh: unknown mode '$MODE'" >&2
    exit 2
    ;;
esac

```

## /.github/scripts/agent-guides-install.sh

```sh path="/.github/scripts/agent-guides-install.sh" 
#!/usr/bin/env bash
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.
# Install one coding-agent CLI for the Local Agent Guides CI. Isolated as
# failure class (b) "agent package install failed": npm/curl flakiness here
# is the single biggest source of false reds, so installs retry with
# backoff and the only ::error:: this script can emit is class (b). The
# install recipes mirror the install_hint strings in
# unsloth_cli/commands/start.py at HEAD.
# Usage: agent-guides-install.sh <agent>
#   agent in: claude codex hermes openclaw opencode pi dsh
set -uo pipefail

AGENT="${1:?usage: agent-guides-install.sh <agent>}"
mkdir -p logs
LOG="logs/install-${AGENT}.log"

install_fail() {
  echo "::error::[agent install failed] agent=${AGENT}: $* (class (b): the agent CLI did not install; not a server or guide problem)." >&2
  echo "---- tail $LOG ----" >&2
  tail -60 "$LOG" 2>/dev/null || true
  exit 1
}

# npm registry flakiness is common in CI; retry 3x with linear backoff.
# Extra npm flags may precede the package (e.g. npm_retry --ignore-scripts pkg).
npm_retry() {
  local i
  for i in 1 2 3; do
    if npm install -g "$@" >> "$LOG" 2>&1; then
      return 0
    fi
    echo "[install] npm install -g $* attempt $i failed; backing off $((i * 10))s" | tee -a "$LOG"
    sleep "$((i * 10))"
  done
  return 1
}

# curl|bash installers, retried at the curl layer. We download to a temp file
# first and only execute on a fully successful fetch, so a truncated download
# (network hiccup mid-stream) can never run a half-written installer.
curl_bash() {
  local url="$1"; shift
  local i tmp
  tmp="$(mktemp)"
  for i in 1 2 3; do
    if curl -fsSL --retry 3 --retry-delay 5 "$url" -o "$tmp" 2>>"$LOG" \
        && bash "$tmp" "$@" >> "$LOG" 2>&1; then
      rm -f "$tmp"
      return 0
    fi
    echo "[install] curl|bash $url attempt $i failed; backing off $((i * 10))s" | tee -a "$LOG"
    sleep "$((i * 10))"
  done
  rm -f "$tmp"
  return 1
}

echo "[install] agent=$AGENT (log=$LOG)"
case "$AGENT" in
  claude)
    # start.py install_hint: curl -fsSL https://claude.ai/install.sh | bash
    curl_bash "https://claude.ai/install.sh" || install_fail "claude installer failed"
    # The installer drops the binary under ~/.local/bin.
    echo "$HOME/.local/bin" >> "$GITHUB_PATH"
    ;;
  codex)
    # start.py install_hint: npm install -g @openai/codex
    npm_retry "@openai/codex" || install_fail "npm install -g @openai/codex failed"
    ;;
  opencode)
    case "${OPENCODE_CHANNEL:-stable}" in
      stable) package="opencode-ai" ;;
      v2)
        package="@opencode-ai/cli@beta"
        if latest_bin="$(npm view @opencode-ai/cli@latest bin --json 2>>"$LOG")" \
            && grep -q '"opencode2"' <<<"$latest_bin"; then
          package="@opencode-ai/cli@latest"
        fi
        ;;
      *) install_fail "unknown OpenCode channel '${OPENCODE_CHANNEL}'" ;;
    esac
    npm_retry "$package" || install_fail "npm install -g $package failed"
    ;;
  openclaw)
    # start.py install_hint: curl -fsSL https://openclaw.ai/install.sh | bash
    # npm is the more deterministic path in CI and matches the agent's docs;
    # fall back to the start.py curl installer if the npm tag is missing.
    if ! npm_retry "openclaw@latest"; then
      curl_bash "https://openclaw.ai/install.sh" || install_fail "openclaw install failed (npm + curl)"
      echo "$HOME/.local/bin" >> "$GITHUB_PATH"
    fi
    ;;
  hermes)
    # start.py install_hint:
    #   curl -fsSL .../NousResearch/hermes-agent/main/scripts/install.sh | bash
    curl_bash "https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh" \
      --non-interactive --skip-setup --skip-browser --no-skills \
      || install_fail "hermes installer failed"
    echo "$HOME/.local/bin" >> "$GITHUB_PATH"
    ;;
  pi)
    # start.py install_hint: npm install -g --ignore-scripts @earendil-works/pi-coding-agent
    # (--ignore-scripts matches Pi's documented recipe; exercising the exact hint
    # catches guide drift). The CLI moved from the now-deprecated @mariozechner
    # scope to @earendil-works (the old scope is frozen, so installing it would
    # test a stale Pi against the API).
    npm_retry --ignore-scripts "@earendil-works/pi-coding-agent" \
      || install_fail "npm install -g --ignore-scripts @earendil-works/pi-coding-agent failed"
    ;;
  dsh)
    # start.py install_hint: npm install -g @deepseek-ai/dsh
    npm_retry "@deepseek-ai/dsh" || install_fail "npm install -g @deepseek-ai/dsh failed"
    ;;
  *)
    install_fail "unknown agent '$AGENT'"
    ;;
esac

echo "[install] OK for $AGENT"

```

## /.github/scripts/assert-bundle-signed.ps1

```ps1 path="/.github/scripts/assert-bundle-signed.ps1" 
# Fail if any executable inside a Windows bundle is unsigned. NSIS runs its
# plugin DLLs from $PLUGINSDIR, so a signed installer proves nothing about them.

param(
    # Bundles to unpack; every PE inside is verified.
    [Parameter(Mandatory = $true)][string[]] $Path,
    # 7-Zip, preinstalled on windows-latest.
    [string] $SevenZip = '7z',
    # Known-unsigned leaf names to accept. Keep empty where possible.
    [string[]] $Allow = @()
)

$ErrorActionPreference = 'Continue'
# .ps1/.psm1 included: install.ps1 ships as a bundle resource and runs on first
# launch. Authenticode covers scripts, and Smart App Control checks them.
$exeExtensions = @('.exe', '.dll', '.sys', '.ocx', '.cpl', '.scr', '.ps1', '.psm1')

$unsigned = @()
$checked = 0

foreach ($bundle in $Path) {
    if (-not (Test-Path $bundle -PathType Leaf)) {
        Write-Host "::error::bundle not found: $bundle"
        exit 1
    }
    $name = Split-Path $bundle -Leaf
    Write-Host ''
    Write-Host "=== $name ==="

    $sig = Get-AuthenticodeSignature $bundle
    $checked++
    if ($sig.Status -ne 'Valid') {
        Write-Host "  UNSIGNED  $name  ($($sig.Status))"
        $unsigned += [pscustomobject]@{ Bundle = $name; File = $name; Status = [string]$sig.Status }
    } else {
        Write-Host "  signed    $name  <- $($sig.SignerCertificate.Subject)"
    }

    $dest = Join-Path $env:RUNNER_TEMP ("sigcheck-" + [System.IO.Path]::GetFileNameWithoutExtension($name))
    Remove-Item $dest -Recurse -Force -ErrorAction SilentlyContinue
    & $SevenZip x -y "-o$dest" $bundle | Out-Null
    # 7-Zip leaves a partial tree behind on error, so a created dir proves nothing.
    if ($LASTEXITCODE -ne 0) {
        Write-Host "::error::7-Zip exited $LASTEXITCODE unpacking $name; contents not verified"
        exit 1
    }
    if (-not (Test-Path $dest)) {
        Write-Host "::error::could not unpack $name; cannot verify its contents"
        exit 1
    }

    $inner = Get-ChildItem $dest -Recurse -File |
        Where-Object { $exeExtensions -contains $_.Extension.ToLower() }
    # No hits means 7-Zip dumped PE sections, not that the payload is clean.
    if (-not $inner) {
        Write-Host "::error::no executable payload found inside $name; contents not verified"
        exit 1
    }

    foreach ($f in ($inner | Sort-Object Name)) {
        $checked++
        $s = Get-AuthenticodeSignature $f.FullName
        if ($s.Status -eq 'Valid') {
            Write-Host ("  signed    {0}" -f $f.Name)
        } elseif ($Allow -contains $f.Name) {
            Write-Host ("  ALLOWED   {0}  ({1}) - explicitly accepted as unsigned" -f $f.Name, $s.Status)
        } else {
            # UnknownError = no signature or unbuilt chain; StatusMessage tells which.
            Write-Host ("  UNSIGNED  {0}  ({1})  {2}" -f $f.Name, $s.Status, $s.StatusMessage)
            $unsigned += [pscustomobject]@{ Bundle = $name; File = $f.Name; Status = [string]$s.Status }
        }
    }
    Remove-Item $dest -Recurse -Force -ErrorAction SilentlyContinue
}

Write-Host ''
Write-Host "checked $checked file(s) across $($Path.Count) bundle(s)"

if (-not $unsigned) {
    Write-Host 'Every executable in every bundle is validly signed.'
    exit 0
}

Write-Host ''
Write-Host '================ UNSIGNED FILES ================'
$unsigned | Format-Table Bundle, File, Status -AutoSize | Out-String | Write-Host
foreach ($u in $unsigned) {
    Write-Host "::error file=$($u.File)::$($u.File) in $($u.Bundle) is $($u.Status) and needs signing"
}
Write-Host ''
Write-Host 'These ship inside the installer and land on the user machine.'
Write-Host 'For NSIS plugin DLLs see the NSISPLUGINS note in windows/installer.nsi.'
exit 1

```

## /.github/scripts/assert-llama-loads.sh

```sh path="/.github/scripts/assert-llama-loads.sh" 
#!/usr/bin/env bash
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.
# Assert Unsloth installed a llama.cpp that loads and runs on THIS macOS. Tests
# the contract that matters (binaries load and their minimum-OS is <= this host)
# instead of the old "did install.sh fall back to a source build?" grep, since a
# source build with a correct deployment target is a valid outcome.
set -uo pipefail

UNSLOTH_HOME="${STUDIO_HOME:-$HOME/.unsloth}"
LLAMA_DIR="${LLAMA_CPP_DIR:-$UNSLOTH_HOME/llama.cpp}"
BIN_DIR="$LLAMA_DIR/build/bin"

fail() {
  echo "::error::$*"
  if [ -f logs/install.log ]; then
    echo "---- install.log (llama.cpp lines) ----"
    grep -E "llama-prebuilt|llama\.cpp|macos prebuilt|falling back" logs/install.log | tail -80 || true
  fi
  exit 1
}

SERVER="$(find "$LLAMA_DIR" -type f -name 'llama-server' 2>/dev/null | head -1)"
QUANT="$(find "$LLAMA_DIR" -type f -name 'llama-quantize' 2>/dev/null | head -1)"
[ -n "$SERVER" ] || fail "llama-server not found under $LLAMA_DIR after install"
[ -n "$QUANT" ]  || fail "llama-quantize not found under $LLAMA_DIR after install"

HOST_VER="$(sw_vers -productVersion 2>/dev/null || echo '0')"
HOST_MAJOR="${HOST_VER%%.*}"

# Static minimum-OS check on every Mach-O we ship. vtool ships with the Xcode
# command line tools, which GitHub macOS runners always have; if it is somehow
# missing we skip the static check and rely on the runtime launch below.
if command -v vtool >/dev/null 2>&1; then
  while IFS= read -r macho; do
    [ -n "$macho" ] || continue
    minos="$(vtool -show-build "$macho" 2>/dev/null | awk '/minos/{print $2; exit}')"
    [ -n "$minos" ] || continue
    min_major="${minos%%.*}"
    if [ "$min_major" -gt "$HOST_MAJOR" ] 2>/dev/null; then
      fail "$(basename "$macho") is built for macOS $minos but this runner is macOS $HOST_VER (prebuilt is newer than the host)"
    fi
  done < <(find "$BIN_DIR" -type f \( -name '*.dylib' -o -name 'llama-server' -o -name 'llama-quantize' \) 2>/dev/null)
fi

# Runtime launch: --version forces dyld to load every linked dylib (including
# libggml-metal.dylib). A missing Metal symbol or too-new binary fails here.
if ! "$SERVER" --version >/tmp/llama-server-version.txt 2>&1; then
  echo "---- llama-server --version output ----"
  cat /tmp/llama-server-version.txt || true
  fail "llama-server failed to launch on macOS $HOST_VER (dyld load / symbol error)"
fi

# The launch above uses this shell's environment, not the one Unsloth builds for
# its child. That one was Linux-shaped on macOS (LD_LIBRARY_PATH, which dyld
# ignores) while the installer's own validation set DYLD_LIBRARY_PATH, so the
# defect could not show up at install time (#8566). A unit test with a
# monkeypatched sys.platform cannot prove the real thing; this can.
# Resolve the interpreter from STUDIO_HOME first, not from PATH. The
# clean-machine lane scrubs PATH down to system directories and puts the shim
# under its own UNSLOTH_STUDIO_HOME, so `command -v unsloth` is empty there and
# a PATH-only lookup would skip this assertion in the one lane whose whole
# point is a clean install, while CI still reported success. The tauri delivery
# nests its venv one level deeper (clean-machine-install-ci.yml checks
# $HOME_DIR/studio/unsloth_studio), so both layouts are candidates.
STUDIO_PY=""
for candidate in \
  "$UNSLOTH_HOME/unsloth_studio/bin/python" \
  "$UNSLOTH_HOME/studio/unsloth_studio/bin/python" \
  "$UNSLOTH_HOME/.venv/bin/python" \
  "$HOME/.unsloth/unsloth_studio/bin/python"; do
  [ -x "$candidate" ] && { STUDIO_PY="$candidate"; break; }
done
if [ -z "$STUDIO_PY" ]; then
  for shim in "$UNSLOTH_HOME/bin/unsloth" "$(command -v unsloth || true)"; do
    [ -n "$shim" ] && [ -x "$shim" ] || continue
    candidate="$(head -1 "$shim" | sed 's/^#!//' | awk '{print $1}')"
    [ -n "$candidate" ] && [ -x "$candidate" ] && { STUDIO_PY="$candidate"; break; }
  done
fi
# Fail rather than skip: an install that produced a llama-server but no
# reachable interpreter is itself a broken install, and a skip here is
# indistinguishable from a pass.
[ -n "$STUDIO_PY" ] || fail "no Unsloth interpreter found under $UNSLOTH_HOME or on PATH; cannot check the launch environment"
if [ -n "$STUDIO_PY" ]; then
  if ! PYTHONPATH=studio/backend "$STUDIO_PY" - "$SERVER" <<'PY'
import os, sys
from core.inference.llama_cpp import LlamaCppBackend, _llama_lib_dir

binary = sys.argv[1]
lib_dir = str(_llama_lib_dir(binary))
env = LlamaCppBackend._llama_server_env_for_binary(binary)
got = env.get("DYLD_LIBRARY_PATH", "")
print(f"DYLD_LIBRARY_PATH: {got or '<unset>'}")
if not got:
    sys.exit("Unsloth would launch llama-server with no DYLD_LIBRARY_PATH; dyld ignores LD_LIBRARY_PATH")
if got.split(os.pathsep)[0] != lib_dir:
    sys.exit(f"expected {lib_dir} first on DYLD_LIBRARY_PATH, got {got}")
print("child launch environment is correct for dyld")
PY
  then
    fail "Unsloth's llama-server launch environment is wrong for macOS (see above)"
  fi
fi

echo "llama.cpp load validation passed on macOS $HOST_VER"
echo "  server: $SERVER"
sed -n '1,4p' /tmp/llama-server-version.txt 2>/dev/null || true

```

## /.github/scripts/assert-nobuild.ps1

```ps1 path="/.github/scripts/assert-nobuild.ps1" 
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.

# The `nobuild` contract from clean-machine-assert.sh, for Windows. A port, not
# `shell: bash`: the scrub drops every `*\Git\*` PATH entry the bash version needs
# sed/grep/tr/sort from, and it also runs inside the servercore container, which has no
# bash. Both Windows lanes call this one file so the sdist allowlist cannot drift.
# Usage: assert-nobuild.ps1 -LogPath logs/install.log   (exit 1 = a source build)
[CmdletBinding()]
param([Parameter(Mandatory = $true)][string] $LogPath)

if (-not (Test-Path -LiteralPath $LogPath)) {
    Write-Host "::error::nobuild requested but $LogPath is missing"
    exit 1
}

# "Built an sdist" is NOT "needed a compiler": each name was verified against its own
# sdist (setuptools.build_meta, no ext_modules, no .c/.cpp/.pyx/.rs), so its PEP 517
# build is a pure-Python copy step. clean-machine-assert.sh carries the per-name detail.
# diffusers is here only for the `overlay: false` legs, which install the released wheel
# and its pre-0.40.0 GitHub-archive pin; remove it once a release carries the wheel pin.
$allow = @('openai-whisper', 'argbind', 'randomname', 'antlr4-python3-runtime', 'triton-kernels', 'diffusers')
if ($env:UNSLOTH_ALLOW_SDIST) {
    $allow += ($env:UNSLOTH_ALLOW_SDIST -split '\s+' | Where-Object { $_ })
}
# Lowercased and underscore-folded on both sides: the distribution name and the name uv
# prints can differ on the separator (triton_kernels vs triton-kernels).
$allow = @($allow | ForEach-Object { $_.ToLowerInvariant() -replace '_', '-' })

# [char]27, not "`e": that escape is PowerShell 6+ and degrades to a literal "e" under
# 5.1, so the strip would eat real text instead of ANSI codes.
$esc = [char]27
$text = (Get-Content -LiteralPath $LogPath -Raw) -replace "$esc\[[0-9;]*[A-Za-z]", ''
$built = @()
foreach ($line in ($text -split "`r?`n")) {
    # A local-path build is one the caller pointed at (the overlay), never one
    # resolution chose; index deps always print `==<version>`.
    if ($line -imatch 'building [a-z0-9._-]+ @ file://') { continue }
    # pip prints `Building wheel for <pkg>`, uv `Building <pkg>==<ver>`
    # (astral-sh/uv#11165); the `==` / ` @ ` keeps this off the installer's own
    # "building frontend..." text.
    foreach ($m in [regex]::Matches($line, '(?i)building wheel for ([a-z0-9._-]+)|building ([a-z0-9._-]+)(==| @ )')) {
        $name = if ($m.Groups[1].Success) { $m.Groups[1].Value } else { $m.Groups[2].Value }
        $built += ($name.ToLowerInvariant() -replace '_', '-')
    }
}
$built = @($built | Sort-Object -Unique)
$bad = @($built | Where-Object { $allow -notcontains $_ })

$rc = 0
if ($bad.Count -gt 0) {
    Write-Host "::error::built from source: $($bad -join ' ') -- these must resolve to wheels on a clean machine"
    $rc = 1
} else {
    Write-Host "[assert] OK  no non-allowlisted source build (built: $(if ($built) { $built -join ' ' } else { 'none' }))"
}
# Independent of package names: a compiler error means a toolchain was needed.
$compilerErr = Select-String -Path $LogPath -Pattern "error: command '(cc|gcc|clang|cl)' failed", 'clang: error', 'cargo: not found', 'Microsoft Visual C\+\+ 14.0 or greater is required'
if ($compilerErr) {
    Write-Host '::error::compiler invocation appears in the install log'
    $compilerErr | Select-Object -First 10 | ForEach-Object { Write-Host "  $($_.Line)" }
    $rc = 1
}
exit $rc

```

## /.github/scripts/assert-prompt-cache.sh

```sh path="/.github/scripts/assert-prompt-cache.sh" 
#!/usr/bin/env bash
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.
# Prompt-cache (KV-cache prefix reuse) detection, two strategies in one helper:
#   mode=api     A 2-turn /v1/chat/completions probe. Turn 2 prepends turn 1 +
#                its reply, so the shared prefix must be served from llama.cpp's
#                KV cache. Asserts usage.prompt_tokens_details.cached_tokens > 0
#                on turn 2. This is the OpenAI-dialect server cache sanity.
#                WHY this works on chat completions: the chat path forwards
#                llama-server's real cached_tokens through
#                studio/backend/routes/inference.py:482-489 (_prompt_tokens_details)
#                into prompt_tokens_details (inference.py:519).
#   mode=log     Read the llama-server log and decide HIT vs MISS from the
#                prompt-reprocessing trace. WHY the log (not the API field):
#                the Anthropic /v1/messages path builds AnthropicUsage(
#                input_tokens=..., output_tokens=...) at inference.py:8787-8790
#                / :8829-8832 and NEVER sets cache_read_input_tokens, which
#                therefore stays at its model default of 0
#                (studio/backend/models/inference.py:1655). So an Anthropic-path
#                client (Claude Code, OpenClaw is openai-completions but Claude
#                Code is the canonical Anthropic agent) can get a real KV-cache
#                hit that the API usage field reports as 0. The only ground
#                truth for the Anthropic path is the llama-server log.
# Log location (verified): studio/backend/core/inference/llama_cpp.py:4363-4365
#   _swa_cache_path().parent/"logs"/"llama-server"/llama-<ts>[label]-port-<P>[-try<N>].log
#   _swa_cache_path() => $UNSLOTH_STUDIO_HOME|$STUDIO_HOME or ~/.unsloth/studio
#   (llama_cpp.py:337-340). So default: ~/.unsloth/studio/logs/llama-server/.
#   <P> is the INTERNAL llama-server port (self._find_free_port(),
#   llama_cpp.py:3489 / :4641) -- a RANDOM port, NOT the Unsloth port. So we must
#   NOT filter the log glob by STUDIO_PORT (the brief's `port-<STUDIO_PORT>`
#   glob would never match). We pick the newest llama-*.log instead.
# Usage:
#   assert-prompt-cache.sh api  BASE_URL API_KEY
#   assert-prompt-cache.sh log  EXPECT          # EXPECT = HIT | MISS
#                                               # reads MARKER_BEFORE/MARKER_AFTER
#                                               # byte offsets from env (see below)
#   assert-prompt-cache.sh mark                 # print current log size to stdout
#                                               # (use to bracket a turn)
# Env for mode=log:
#   LLAMA_LOG_DIR    override the log dir (default ~/.unsloth/studio/logs/llama-server)
#   CACHE_LOG_FROM   byte offset to start scanning the newest log from (so we
#                    only look at the trace produced by THIS turn). Default 0.
# Exit codes: 0 = assertion held; 1 = assertion failed (::error:: emitted).

set -uo pipefail

MODE="${1:?usage: assert-prompt-cache.sh api|log|mark ...}"

# Locate the newest llama-server log. Shared by mark + log modes.
_default_log_dir() {
  local home="${UNSLOTH_STUDIO_HOME:-${STUDIO_HOME:-}}"
  if [ -n "$home" ]; then
    echo "${home%/}/logs/llama-server"
  else
    echo "${HOME}/.unsloth/studio/logs/llama-server"
  fi
}

_newest_log() {
  local dir="${LLAMA_LOG_DIR:-$(_default_log_dir)}"
  [ -d "$dir" ] || return 1
  # Newest by mtime among llama-*.log (covers both `llama-<ts>-port-<P>.log`
  # and the retry form `llama-<ts><label>-port-<P>-try<N>.log`). Filenames are
  # tool-generated timestamps, so ls -t is safe here.
  # shellcheck disable=SC2012
  ls -1t "$dir"/llama-*.log 2>/dev/null | head -1
}

case "$MODE" in
  # mark: emit the current byte size of the newest llama log so a caller can
  # scan only the slice a single turn produced (set CACHE_LOG_FROM to it).
  mark)
    log="$(_newest_log || true)"
    if [ -n "$log" ] && [ -f "$log" ]; then
      wc -c < "$log" | tr -d ' '
    else
      echo 0
    fi
    exit 0
    ;;

  # api: 2-turn /v1/chat/completions, assert turn-2 cached_tokens > 0.
  api)
    BASE_URL="${2:?usage: assert-prompt-cache.sh api BASE_URL API_KEY}"
    API_KEY="${3:?usage: assert-prompt-cache.sh api BASE_URL API_KEY}"

    # A deliberately long, fixed system prompt makes the shared prefix big so a
    # KV-cache hit is unambiguous (cached_tokens grows with the reused prefix).
    # Do not set a request seed: fixed seeds disable prompt caching for reproducibility.
    # This probe measures cache reuse; the server already uses --seed/--temp 0.
    SYS='You are a meticulous assistant. Always answer concisely and correctly. This is a fixed system preamble that exists only to create a large, identical prompt prefix across both turns so the KV cache has something substantial to reuse on the second request. Do not mention this preamble.'

    turn1_body() {
      jq -n --arg sys "$SYS" '{
        model: "default",
        messages: [
          {role:"system", content:$sys},
          {role:"user",   content:"What is the capital of France?"}
        ],
        temperature: 0.0, max_tokens: 40, stream: false,
        enable_thinking: false
      }'
    }

    echo "[cache/api] turn 1 (prime the KV cache)"
    R1="$(curl -fs -X POST "${BASE_URL}/v1/chat/completions" \
          -H "Authorization: Bearer ${API_KEY}" -H 'content-type: application/json' \
          --max-time 240 -d "$(turn1_body)")" || {
      echo "::error::[cache/api] turn-1 /v1/chat/completions request failed. Unsloth server/API regression."
      exit 1
    }
    A1="$(echo "$R1" | jq -r '.choices[0].message.content // ""')"

    turn2_body() {
      jq -n --arg sys "$SYS" --arg a1 "$A1" '{
        model: "default",
        messages: [
          {role:"system",    content:$sys},
          {role:"user",      content:"What is the capital of France?"},
          {role:"assistant", content:$a1},
          {role:"user",      content:"And the capital of Germany?"}
        ],
        temperature: 0.0, max_tokens: 40, stream: false,
        enable_thinking: false
      }'
    }

    echo "[cache/api] turn 2 (expect cached_tokens > 0)"
    R2="$(curl -fs -X POST "${BASE_URL}/v1/chat/completions" \
          -H "Authorization: Bearer ${API_KEY}" -H 'content-type: application/json' \
          --max-time 240 -d "$(turn2_body)")" || {
      echo "::error::[cache/api] turn-2 /v1/chat/completions request failed. Unsloth server/API regression."
      exit 1
    }

    CACHED="$(echo "$R2" | jq -r '.usage.prompt_tokens_details.cached_tokens // 0')"
    PROMPT_TOK="$(echo "$R2" | jq -r '.usage.prompt_tokens // 0')"
    echo "[cache/api] turn-2 usage: prompt_tokens=${PROMPT_TOK} cached_tokens=${CACHED}"

    if [ -z "$CACHED" ] || ! [ "$CACHED" -gt 0 ] 2>/dev/null; then
      echo "::error::[cache/api] turn-2 usage.prompt_tokens_details.cached_tokens=${CACHED}, expected > 0. The server is not surfacing llama.cpp KV-cache hits on /v1/chat/completions. Check studio/backend/routes/inference.py:482-489 (_prompt_tokens_details) and :519. Full turn-2 usage:"
      echo "$R2" | jq -c '.usage' 2>/dev/null || echo "$R2"
      exit 1
    fi
    echo "[cache/api] PASS server cache sanity (cached_tokens=${CACHED} > 0)"
    exit 0
    ;;

  # log: classify the newest llama-server log (from CACHE_LOG_FROM bytes on)
  # as HIT or MISS and compare to EXPECT.
  log)
    EXPECT="${2:?usage: assert-prompt-cache.sh log HIT|MISS}"
    FROM="${CACHE_LOG_FROM:-0}"

    log="$(_newest_log || true)"
    if [ -z "$log" ] || [ ! -f "$log" ]; then
      echo "::error::[cache/log] no llama-server log under ${LLAMA_LOG_DIR:-$(_default_log_dir)}. Cannot read KV-cache trace. (Path contract: studio/backend/core/inference/llama_cpp.py:4363-4365.)"
      exit 1
    fi
    echo "[cache/log] reading $log from byte $FROM"

    # Scan only the slice produced after FROM.
    slice="$(tail -c "+$((FROM + 1))" "$log" 2>/dev/null || cat "$log")"

    # 1. Modern + legacy "re-used N tokens" / "reused N" (N>0). Primary signal
    #    per the design brief.
    reused_n="$(printf '%s\n' "$slice" \
      | grep -aoiE 're-?used[^0-9]*([0-9]+)' \
      | grep -aoE '[0-9]+' | sort -rn | head -1 || true)"
    # 2. "kv cache rm [START, end)" with START>0 => prefix [0,START) reused.
    cache_rm_start="$(printf '%s\n' "$slice" \
      | grep -aoiE 'kv cache rm \[[0-9]+' \
      | grep -aoE '[0-9]+' | sort -rn | head -1 || true)"
    # 3. "n_past = N" with N>0 after a prompt-processing line (prefix kept).
    n_past_n="$(printf '%s\n' "$slice" \
      | grep -aoiE 'n_past[^0-9]*([0-9]+)' \
      | grep -aoE '[0-9]+' | sort -rn | head -1 || true)"
    # 4. tokens_cached / tokens from cache (some builds).
    tok_cached="$(printf '%s\n' "$slice" \
      | grep -aoiE 'tokens_cached[^0-9]*([0-9]+)' \
      | grep -aoE '[0-9]+' | sort -rn | head -1 || true)"

    # Explicit forced full re-processing (SWA / recurrent) or kv cache rm [0,.
    forced_full=0
    if printf '%s\n' "$slice" | grep -aqiE 'forcing full prompt re-?processing|kv cache rm \[0,'; then
      forced_full=1
    fi

    HIT=0
    why=""
    if [ -n "$reused_n" ] && [ "$reused_n" -gt 0 ] 2>/dev/null; then
      HIT=1; why="re-used=$reused_n"
    elif [ -n "$cache_rm_start" ] && [ "$cache_rm_start" -gt 0 ] 2>/dev/null; then
      HIT=1; why="kv-cache-rm-start=$cache_rm_start"
    elif [ -n "$tok_cached" ] && [ "$tok_cached" -gt 0 ] 2>/dev/null; then
      HIT=1; why="tokens_cached=$tok_cached"
    elif [ "$forced_full" = "0" ] && [ -n "$n_past_n" ] && [ "$n_past_n" -gt 0 ] 2>/dev/null; then
      # n_past>0 is the weakest signal; only trust it if nothing forced a full
      # reprocess. (On a cold slot n_past tracks total processed, so it is a
      # last-resort fallback per the brief.)
      HIT=1; why="n_past=$n_past_n(fallback)"
    fi
    [ "$HIT" = "1" ] || why="${why:-no-reuse-markers (forced_full=$forced_full)}"

    OBSERVED="MISS"; [ "$HIT" = "1" ] && OBSERVED="HIT"
    echo "[cache/log] observed=$OBSERVED expected=$EXPECT ($why)"

    if [ "$OBSERVED" != "$EXPECT" ]; then
      echo "::error::[cache/log] KV-cache observed=$OBSERVED but expected=$EXPECT ($why). See the attribution A/B note in the workflow."
      echo "---- llama-server log slice (last 60 lines) ----"
      printf '%s\n' "$slice" | tail -60
      exit 1
    fi
    echo "[cache/log] PASS ($OBSERVED == $EXPECT)"
    exit 0
    ;;

  *)
    echo "::error::unknown mode '$MODE' (want api|log|mark)"
    exit 1
    ;;
esac

```

## /.github/scripts/boot-studio-api-only.sh

```sh path="/.github/scripts/boot-studio-api-only.sh" 
#!/usr/bin/env bash
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.
# Wipe Unsloth's auth state and boot `unsloth studio` in the background, exporting
# the pid so a later step can stop it.
# Usage:
#   boot-studio-api-only.sh --port 18888 [--log logs/studio.log] [--pid-var STUDIO_PID]
#                           [--api-only]
# On the name, and on --api-only being a flag rather than the default. The
# UNSLOTH_API_ONLY=1 below reads like the switch and is not: nothing in unsloth_cli
# takes it as input. Whether the web UI is served is decided by the CLI's --api-only
# flag alone, and the backend only ever reads that variable back out (main.py, to pick
# a CORS profile) after run.py has set it from the flag. So every caller here has in
# fact been booting a server that serves the frontend, and the Playwright UI smokes
# depend on exactly that -- passing --api-only unconditionally would leave them
# driving a browser at a backend with no UI. Hence opt-in: callers with no built
# `studio/frontend/dist` (mlx-ci.yml boots on a bare pip install) must ask for it, or
# the server prints "Unsloth frontend build not found" and exits before it binds.
# Twenty steps across eight workflows ran this same five-line body, varying only
# in those three values. Extracted so the three easy-to-get-wrong parts have one
# definition:
#  * `rm -rf`, not `unsloth studio reset-password`. The boot below has to re-seed
#    a fresh `.bootstrap_password`, and it only does that when the auth directory
#    is absent. A caller that "resets" instead silently keeps the old password and
#    the test then authenticates against stale state.
#  * The pid has to reach `$GITHUB_ENV`, because the step that stops the server is
#    a different step with a different shell. `$!` alone dies with the step.
#  * stdout AND stderr go to the log. The server writes its startup diagnostics to
#    stderr, so a `>` without `2>&1` produces an empty log on exactly the failure
#    a reader needs it for.
# NOT for `unsloth run`: that is serve-unsloth-run.sh, which boots a different
# command with a different contract (banner API key, /v1/models resolution) and
# has nothing to share with this beyond the word "boot".
# Deliberately does not wait for health. The callers' waits differ -- some poll
# /api/health and stop, others go on to rotate the bootstrap password and load a
# model in the same step -- and folding the simple case in here would leave the
# rest calling a script that does half their work.

set -uo pipefail

PORT=""
LOG="logs/studio.log"
PID_VAR="STUDIO_PID"
API_ONLY=""

while [ "$#" -gt 0 ]; do
  case "$1" in
    --port)     PORT="$2"; shift 2 ;;
    --log)      LOG="$2"; shift 2 ;;
    --pid-var)  PID_VAR="$2"; shift 2 ;;
    --api-only) API_ONLY="--api-only"; shift ;;
    *) echo "boot-studio-api-only.sh: unknown arg '$1'" >&2; exit 2 ;;
  esac
done

[ -n "$PORT" ] || { echo "boot-studio-api-only.sh: --port is required" >&2; exit 2; }

# Wipe rather than reset: the boot below re-seeds .bootstrap_password only when
# the directory is gone. See the header.
# Through $UNSLOTH_STUDIO_HOME, matching run-studio-permission-browser.sh and
# run-studio-indicator-browser.sh, which have read it since #9158. This script was
# the odd one out, hardcoding the legacy path, and that is what forced every
# Playwright step sharing this boot to run one after another: two concurrent lanes
# on one home race destructively, one wiping the .bootstrap_password the other just
# minted and is about to log in with. Unset, this is byte-for-byte the old path.
studio_home="${UNSLOTH_STUDIO_HOME:-$HOME/.unsloth/studio}"
rm -rf "$studio_home/auth"
mkdir -p "$(dirname "$LOG")"

# shellcheck disable=SC2086  # $API_ONLY is one flag or empty, and must not become ''
UNSLOTH_API_ONLY=1 unsloth studio -H 127.0.0.1 -p "$PORT" $API_ONLY > "$LOG" 2>&1 &
SERVER_PID=$!

echo "[boot] unsloth studio ${API_ONLY:---with-frontend} on 127.0.0.1:${PORT}, pid ${SERVER_PID}, log ${LOG}"
if [ -n "${GITHUB_ENV:-}" ]; then
  echo "${PID_VAR}=${SERVER_PID}" >> "$GITHUB_ENV"
else
  echo "${PID_VAR}=${SERVER_PID}"
fi

```

## /.github/scripts/ci-connect-prompt.txt

You are a helpful assistant in a CI connectivity check. Answer the user directly in plain text. Do not use any tools, do not take any actions, and do not explain. Just reply with the answer.


## /.github/scripts/ci-min-system-prompt.txt

You are a coding assistant running non-interactively in a CI smoke test. Use the available file-editing and shell tools to complete the user's request directly and concisely. Do not ask questions or explain; just do the task.


## /.github/scripts/clean-machine-assert.sh

```sh path="/.github/scripts/clean-machine-assert.sh" 
#!/usr/bin/env bash
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.
# Assert the clean-machine contract after an install attempt.
#   absent   The toolchain really was absent for the whole run. Catches a leg that
#            "passed" because masking silently failed, or because the installer
#            quietly installed Xcode CLT behind our back.
#   notools       The trace recorded no compiler/git/brew invocation (trace mode),
#                 except uv's exact optional libpython self-ID operation.
#   nodylibtool   No install_name_tool invocation escaped the CLT-absent guard.
#   dylibpatch    A CLT-present control observed only exact libpython self-ID patches.
#   nobuild  Wheels-only: no "Building wheel" from pip, no "Building <pkg>==<ver>"
#            from uv. Needs UNSLOTH_VERBOSE=1, or run_install_cmd
#            (install.sh:193-243) discards uv's output on success.
#   macho    Every Mach-O under $MACHO_ROOT is the host architecture, and every
#            Mach-O MAIN EXECUTABLE is signed. Closes the Rosetta 2 gap, the one
#            divergence masking cannot reproduce.
# Usage: bash .github/scripts/clean-machine-assert.sh absent nodylibtool notools dylibpatch nobuild macho
set -uo pipefail

LOG="${INSTALL_LOG:-logs/install.log}"
TRACE="${UNSLOTH_TOOL_TRACE:-}"
rc=0

fail() { echo "::error::$*"; rc=1; }
ok()   { echo "[assert] OK  $*"; }

_decode_trace_arg() { # encoded, destination variable
  _encoded=$1
  case "$_encoded" in h*) _hex=${_encoded#h} ;; *) return 1 ;; esac
  case "$_hex" in *[!0123456789abcdef]* ) return 1 ;; esac
  [ $(( ${#_hex} % 2 )) -eq 0 ] || return 1
  _decoded=""
  while [ -n "$_hex" ]; do
    _rest=${_hex#??}
    _pair=${_hex%"$_rest"}
    _hex=$_rest
    printf -v _byte '%b' "\\x$_pair"
    _decoded+=$_byte
  done
  printf -v "$2" '%s' "$_decoded"
}

_is_uv_libpython_self_id_patch() { # argc, operation, source, destination, extra
  [ "$1" = "3" ] && [ "$2" = "-id" ] && [ -n "$3" ] && [ "$3" = "$4" ] \
    && [ -z "$5" ] || return 1
  _patch_name=${3##*/}
  case "$_patch_name" in libpython*.dylib) ;; *) return 1 ;; esac
  _patch_dir=${3%/*}

  if [ -n "${UV_PYTHON_INSTALL_DIR:-}" ]; then
    _patch_root=${UV_PYTHON_INSTALL_DIR%/}
  else
    # Default uv data locations end in uv/python; this fallback keeps the assertion
    # useful outside CI, where UV_PYTHON_INSTALL_DIR is normally unset.
    case "$3" in */uv/python/*) ;; *) return 1 ;; esac
    _patch_root=${3%%/uv/python/*}/uv/python
  fi

  # Resolve both directories physically before comparing them. A lexical shell glob
  # would accept "$root/x/../../outside/..." (and symlink escapes) because * spans '/'.
  _patch_root=$(CDPATH= cd "$_patch_root" 2>/dev/null && pwd -P) || return 1
  _patch_dir=$(CDPATH= cd "$_patch_dir" 2>/dev/null && pwd -P) || return 1
  case "$_patch_dir" in "$_patch_root"/*/lib) ;; *) return 1 ;; esac
  _patch_install=${_patch_dir#"$_patch_root"/}
  _patch_install=${_patch_install%/lib}
  [ -n "$_patch_install" ] || return 1
  case "$_patch_install" in */*) return 1 ;; esac
  return 0
}

for check in "$@"; do
  case "$check" in

    absent)
      # NOT `command -v`: on a virgin Mac /usr/bin/{git,cc} EXIST as CLT stubs, so it
      # succeeds and only RUNNING them fails. The invariant is: must not WORK.
      if xcode-select -p >/dev/null 2>&1; then
        fail "xcode-select -p still resolves to $(xcode-select -p 2>/dev/null); not a clean Mac"
      else
        ok "xcode-select -p fails (the gate a virgin Mac hits)"
      fi
      # The whole set clean-machine-env.sh moves aside, not the four it used to check: that
      # helper warns and carries on when a move fails, so a surviving gcc -- which
      # install.sh probes to decide build-essential is available -- passed unnoticed.
      for tool in git cc clang cmake gcc g++ make ninja cargo rustc; do
        command -v "$tool" >/dev/null 2>&1 || { ok "$tool not on PATH"; continue; }
        if "$tool" --version >/dev/null 2>&1; then
          # Intel runners' /usr/bin/git is not CLT-provided, so masking cannot take it
          # away; cc/clang do become stubs and macOS needs no git, so report, not fail.
          case " ${UNSLOTH_CLEAN_ALLOW_WORKING:-} " in
            *" $tool "*)
              echo "[assert] NOTE $tool still works ($(command -v "$tool")); allowed on this runner"
              continue
              ;;
          esac
          fail "toolchain still usable: '$tool --version' succeeded ($(command -v "$tool")); masking failed"
        else
          ok "$tool present but non-functional (CLT stub), as on a clean Mac"
        fi
      done
      # brew is a plain binary with no stub, so absence from PATH is the right test.
      if command -v brew >/dev/null 2>&1; then
        fail "Homebrew still on PATH at $(command -v brew); masking failed"
      else
        ok "brew absent"
      fi
      ;;

    nodylibtool)
      if [ -z "$TRACE" ] || [ ! -f "$TRACE" ]; then
        fail "nodylibtool requested but no trace file (\$UNSLOTH_TOOL_TRACE=$TRACE)"
      else
        _dylib_hits=0
        while IFS={{contextString}}#39;\t' read -r tool _rest; do
          [ "$tool" = "install_name_tool" ] && _dylib_hits=$((_dylib_hits + 1))
        done < "$TRACE"
        if [ "$_dylib_hits" -ne 0 ]; then
          fail "install_name_tool escaped the CLT-absent uv guard ($_dylib_hits invocation(s))"
          grep '^install_name_tool[[:space:]]' "$TRACE" | head -20 || true
        else
          ok "install_name_tool was never reached on the CLT-absent path"
        fi
      fi
      ;;

    dylibpatch)
      if [ -z "$TRACE" ] || [ ! -f "$TRACE" ]; then
        fail "dylibpatch requested but no trace file (\$UNSLOTH_TOOL_TRACE=$TRACE)"
      else
        _dylib_hits=0
        _dylib_bad=0
        while IFS={{contextString}}#39;\t' read -r tool argc operation_encoded source_encoded destination_encoded extra; do
          [ "$tool" = "install_name_tool" ] || continue
          _dylib_hits=$((_dylib_hits + 1))
          operation=""; source=""; destination=""
          if ! _decode_trace_arg "$operation_encoded" operation \
             || ! _decode_trace_arg "$source_encoded" source \
             || ! _decode_trace_arg "$destination_encoded" destination \
             || ! _is_uv_libpython_self_id_patch "$argc" "$operation" "$source" "$destination" "$extra"; then
            _dylib_bad=$((_dylib_bad + 1))
            echo "::error::invalid install_name_tool trace record: $tool argc=$argc"
          fi
        done < "$TRACE"
        if [ "$_dylib_hits" -eq 0 ]; then
          fail "CLT-present control recorded no install_name_tool patch; managed Python may have been reused"
        elif [ "$_dylib_bad" -ne 0 ]; then
          fail "$_dylib_bad of $_dylib_hits install_name_tool invocation(s) were not exact libpython self-ID patches"
        else
          ok "all $_dylib_hits install_name_tool invocation(s) were exact libpython self-ID patches"
        fi
      fi
      ;;


    notools)
      if [ -z "$TRACE" ] || [ ! -f "$TRACE" ]; then
        fail "notools requested but no trace file (\$UNSLOTH_TOOL_TRACE=$TRACE)"
      else
        # git is legitimate under --local (unsloth-zoo comes from a git URL), so that
        # leg allow-lists it via UNSLOTH_ALLOW_TOOLS.
        allow="${UNSLOTH_ALLOW_TOOLS:-}"
        hits=""
        while IFS={{contextString}}#39;\t' read -r tool argc_or_rest arg1 arg2 arg3 extra; do
          [ -n "$tool" ] || continue
          # This optional uv operation is the only permitted developer-tool use. Keep it
          # structural rather than name-only: arbitrary install_name_tool calls still fail.
          if [ "$tool" = "install_name_tool" ]; then
            operation=""; source=""; destination=""
            if _decode_trace_arg "$arg1" operation \
               && _decode_trace_arg "$arg2" source \
               && _decode_trace_arg "$arg3" destination \
               && _is_uv_libpython_self_id_patch "$argc_or_rest" "$operation" "$source" "$destination" "$extra"; then
              continue
            fi
            hits="$hits $tool"
            continue
          fi
          case " $allow " in *" $tool "*) continue ;; esac
          # `xcode-select -p` only ASKS whether a toolchain is selected and the fix is
          # carrying on without one, so it is not USE. `--install` stays a hit.
          if [ "$tool" = "xcode-select" ]; then
            case "$argc_or_rest" in
              -p|--print-path|-v|--version|"") continue ;;
            esac
          fi
          hits="$hits $tool"
        done < "$TRACE"
        if [ -n "$hits" ]; then
          fail "installer invoked toolchain:$(echo "$hits" | tr ' ' '\n' | sort -u | tr '\n' ' ')"
          echo "---- tool trace ----"; sort -u "$TRACE" | head -50
        else
          ok "no compiler/git/brew invocation recorded"
        fi
      fi
      ;;

    nobuild)
      # "Built an sdist" is NOT "needed a compiler". Every name was verified against its
      # own sdist: setuptools.build_meta, no ext_modules, no .c/.cpp/.pyx/.rs, so the
      # PEP 517 build is a pure-Python copy step.
      #   openai-whisper, argbind, randomname  -- no version ever ships a wheel
      #   antlr4-python3-runtime==4.9.3        -- pinned below the 4.13.2 wheel
      #   triton-kernels  -- a git URL under the triton repo's python/triton_kernels
      #     subdir: 75 Python files, no setup.py, kernels compiled at runtime. Named by
      #     the installer, not chosen by resolution, and only the Linux legs reach it.
      #   diffusers  -- overlay:false releases still pin a pure-Python source archive.
      #     Remove this once a published Unsloth release carries the wheel pin.
      # UNSLOTH_ALLOW_SDIST extends it. Lowercased and underscore-folded on both sides:
      # the distribution name and the name uv prints can differ on the separator.
      _allow="$(printf '%s' "openai-whisper argbind randomname antlr4-python3-runtime triton-kernels diffusers ${UNSLOTH_ALLOW_SDIST:-}" | tr 'A-Z_' 'a-z-')"
      if [ ! -f "$LOG" ]; then
        fail "nobuild requested but $LOG is missing"
      else
        # uv prints `Building <name>==<ver>`, pip `Building wheel for <name>`
        # (astral-sh/uv#11165), so match both; the `==` / ` @ ` keeps this off the
        # installer's own "building frontend..." text, and ANSI is stripped so a
        # coloured run parses. `Building <name> @ file://` is dropped -- a local-path
        # build is one the caller pointed at (--local, the overlay), never one
        # resolution chose, while index deps always print `<name>==<ver>`, so a genuine
        # PyPI sdist is still caught, including one named unsloth.
        _esc=$(printf '\033')
        _built="$(sed -E "s/${_esc}\[[0-9;]*[A-Za-z]//g" "$LOG" 2>/dev/null \
                  | grep -viE "building [a-z0-9._-]+ @ file://" \
                  | grep -oiE "building wheel for [a-z0-9._-]+|building [a-z0-9._-]+(==| @ )" \
                  | tr 'A-Z' 'a-z' \
                  | sed -E -e 's/^building wheel for //' -e 's/^building //' -e 's/(==| @ )$//' \
                  | tr '_' '-' \
                  | sort -u || true)"
        _bad=""
        for pkg in $_built; do
          case " $_allow " in *" $pkg "*) continue ;; esac
          _bad="$_bad $pkg"
        done
        if [ -n "$_bad" ]; then
          fail "built from source:$_bad -- these must resolve to wheels on a clean machine"
        else
          [ -n "$_built" ] && say_built="$(echo "$_built" | tr '\n' ' ')" || say_built="none"
          ok "no non-allowlisted source build (built: $say_built)"
        fi
        # Independent of package names: a compiler error means a toolchain was needed.
        if grep -qiE "error: command '(cc|gcc|clang|cl)' failed|no such file or directory: 'cc'|clang: error|cargo: not found|error: linker \`cc\` not found" "$LOG"; then
          fail "compiler invocation appears in the install log"
          grep -iE "error: command '(cc|gcc|clang|cl)' failed|clang: error" "$LOG" | head -10
        fi
      fi
      ;;

    macho)
      # The one thing masking cannot reproduce: Rosetta 2 ships on hosted runners and
      # not on a factory-fresh Mac, so an x86_64-only payload runs green here and dies
      # with "bad CPU type in executable" for the user. `lipo` is an xcrun shim and gone
      # after masking, so read `file -Lb`, keyed off `uname -m` (macos-15-intel is x86_64).
      # SCOPE: all of $MACHO_ROOT, .venv_t5_510/_530/_550 sidecars included -- payload,
      # not scratch (setup.sh:579-581 creates them, transformers_version.py:338-348 puts
      # them on sys.path). Any exclusion must be a named path rule, never a narrowed find.
      root="${MACHO_ROOT:-${UNSLOTH_STUDIO_HOME:-$HOME/.unsloth}}"
      want="$(uname -m)"
      [ "$want" = "aarch64" ] && want=arm64
      if [ ! -d "$root" ]; then
        fail "macho requested but $root does not exist"
      else
        # SCOPE, part 2: the two payloads the install RUNS ON live outside $root. `uv
        # venv` links <venv>/bin/python at its base interpreter and the find below has no
        # -L, so the interpreter that ran every step is invisible to it; the uv that
        # fetched it lands in $HOME/.local/bin. Both are what Rosetta 2 hides: an x86_64
        # one runs green here and dies on the factory-fresh Mac this stands in for.
        # -L follows that symlink; -maxdepth keeps this a bin/ lookup, not a second walk
        # of site-packages through the venv's lib64 link -- depth 4 covers
        # <root>/unsloth_studio, the .venv_t5_* sidecars and <root>/studio/unsloth_studio.
        # In a variable so it can be counted separately: uv alone would satisfy $nout.
        base_py="$(find -L "$root" -maxdepth 4 -type f -path '*/bin/python' 2>/dev/null)"
        _macho_targets() {
          find "$root" -type f \( -perm -u+x -o -name '*.dylib' -o -name '*.so' -o -name '*.node' \) 2>/dev/null
          [ -n "$base_py" ] && printf '%s\n' "$base_py"
          for _uv in "$HOME/.local/bin/uv" "$(command -v uv 2>/dev/null || true)"; do
            [ -n "$_uv" ] && [ -f "$_uv" ] && printf '%s\n' "$_uv"
          done
        }
        n=0 nexe=0 nout=0 nbase=0 bad_arch="" unsigned="" broken=""
        while IFS= read -r f; do
          # -L: find printed the SYMLINK path for <venv>/bin/python, and plain `file` does
          # not dereference, so it answered "symbolic link to ..." and the Mach-O test
          # below dropped the very interpreter this scan exists to check.
          desc="$(file -Lb "$f" 2>/dev/null || true)"
          case "$desc" in *Mach-O*) ;; *) continue ;; esac
          n=$((n + 1))
          case "$f" in "$root"/*) ;; *) nout=$((nout + 1)) ;; esac
          # Classified, not merely found: an entry `file` could not read is invisible here.
          case "
$base_py
" in *"
$f
"*) nbase=$((nbase + 1)) ;; esac
          # Substring, not equality: a universal binary lists every slice it carries,
          # and one that includes the host arch is fine.
          case "$desc" in
            *"$want"*) ;;
            *) bad_arch="$bad_arch $f [$desc]" ;;
          esac

          # Signature: MAIN EXECUTABLES ONLY. Asserting it on every Mach-O failed the
          # mask/pipe leg on 29 ordinary PyPI extension modules plus libportaudio.dylib:
          # MH_BUNDLE/MH_DYLIB images dlopen'd without library validation ship unsigned,
          # and that run had already imported them with the installer exiting 0. macOS
          # enforces on main executables and gatekept .app bundles. Key off the filetype
          # `file` reports, not the path (a .so may be either); the library veto is second
          # so a mixed-type fat file counts as a library, and substring tests are
          # order-independent (Apple prints `executable arm64`, GNU `arm64 executable`).
          _is_exe=0
          case "$desc" in *executable*) _is_exe=1 ;; esac
          case "$desc" in *"shared library"*|*bundle*) _is_exe=0 ;; esac
          # Named rule so a failure says which path matched; the filetype test covers it.
          case "$f" in *.app/Contents/MacOS/*) _is_exe=1 ;; esac
          [ "$_is_exe" = 1 ] && nexe=$((nexe + 1))

          # arm64 only: the kernel refuses to exec an unsigned arm64 main binary
          # ("Killed: 9"); x86_64 execs it happily, so it is not the same defect.
          if [ "$want" = "arm64" ] && [ "$_is_exe" = 1 ]; then
            # Ad-hoc counts as signed (arm64 linkers seal ad-hoc by default): the test is
            # "has a verifying seal", not "has an identity", which spctl/--strict demand.
            if ! codesign -v "$f" >/dev/null 2>&1; then
              # Nothing to verify and a seal that does not match differ. Captured, not
              # piped: `codesign -dvv` exits non-zero on an unsigned file, and under
              # pipefail that would be the pipeline's status even on a match.
              _sig="$(codesign -dvv "$f" 2>&1 || true)"
              case "$_sig" in
                *"not signed at all"*) unsigned="$unsigned $f" ;;
                *)                     broken="$broken $f" ;;
              esac
            fi
          fi
        done < <(_macho_targets | sort -u)
        if [ "$n" = "0" ]; then
          # An empty scan reads exactly like a clean one, so a wrong root would pass.
          fail "no Mach-O found under $root; the arch/signature assertion proved nothing"
        elif [ "$nbase" = "0" ]; then
          fail "no */bin/python under $root was classified as Mach-O, so the venv's base interpreter went unchecked (found: ${base_py:-none})"
        elif [ "$nout" = "0" ]; then
          # install.sh always bootstraps uv into $HOME/.local/bin, so zero hits outside
          # $root means the extra scan matched nothing and uv's arch went unproven.
          fail "no Mach-O outside $root was scanned, so uv and the venv's base interpreter escaped the check"
        elif [ -n "$bad_arch" ]; then
          fail "Mach-O is not $want, so it runs here only under Rosetta 2, which a fresh Mac does not have:$bad_arch"
        elif [ -n "$unsigned" ]; then
          fail "unsigned Mach-O main executable, which arm64 macOS refuses to exec:$unsigned"
        elif [ -n "$broken" ]; then
          fail "Mach-O main executable carries a signature that does not verify:$broken"
        else
          ok "$n Mach-O files under $root, plus uv and the venv's base interpreter, are $want$([ "$want" = arm64 ] && echo "; all $nexe main executable(s) signed")"
        fi
      fi
      ;;

    *)
      fail "unknown check '$check'"
      ;;
  esac
done

exit "$rc"

```

## /.github/scripts/clean-machine-env.sh

```sh path="/.github/scripts/clean-machine-env.sh" 
#!/usr/bin/env bash
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.
# Simulate a virgin developer machine on a GitHub-hosted runner. Two modes, because
# "the tool is absent" and "the installer never called the tool" need different
# mechanisms:
#   mask   Make the toolchain genuinely ABSENT: scrub PATH to OS defaults and (with
#          --remove) move the real toolchain aside so `command -v git` correctly
#          FAILS. Deliberately no general "poison shims": a failing shim is still FOUND
#          by `command -v`, which reports the tool as present, the opposite of clean.
#          macOS has one observation-only exception: install_name_tool gets a logging
#          sentinel because the installer must shadow Apple's dialog-producing shim and
#          never uses this command to decide whether a dependency is installed.
#   trace  Leave the toolchain working behind wrappers that log the call then exec
#          the real binary, answering whether the installer ever REACHES for a
#          compiler/git without changing behaviour.
# Writes shell exports to $CLEAN_ENV_FILE (default ./clean-machine.env) to `source`;
# nothing is exported globally, so other steps keep a normal environment.
# Usage:
#   bash .github/scripts/clean-machine-env.sh mask [--remove]
#   bash .github/scripts/clean-machine-env.sh trace
#   source ./clean-machine.env
set -uo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
INSTALL_NAME_TOOL_HELPER="$SCRIPT_DIR/clean-machine-install-name-tool.sh"

MODE="${1:-}"
REMOVE=0
[ "${2:-}" = "--remove" ] && REMOVE=1

case "$MODE" in
  mask|trace) ;;
  *) echo "usage: $0 {mask|trace} [--remove]" >&2; exit 2 ;;
esac

OS="$(uname -s)"
WORK="${CLEAN_MACHINE_DIR:-$PWD/.clean-machine}"
ENV_FILE="${CLEAN_ENV_FILE:-$PWD/clean-machine.env}"
TRACE="$WORK/tool-invocations.log"
BIN="$WORK/bin"
RESTORE="$WORK/restore.sh"
mkdir -p "$BIN"
: > "$TRACE"
: > "$ENV_FILE"
printf '#!/usr/bin/env bash\n# Undo clean-machine-env.sh --remove. Safe to run twice.\nset -uo pipefail\n' > "$RESTORE"
chmod +x "$RESTORE"

# The toolchain we care about: a consumer install must need none of it.
# cctools binaries are included because their /usr/bin shims can trigger the same
# developer-tools dialog. uv's exact optional install_name_tool self-ID patch is
# observed separately and narrowly allow-listed by clean-machine-assert.sh.
TOOLS="xcode-select xcrun clang clang++ cc c++ gcc g++ git cmake make brew ninja cargo rustc
install_name_tool lipo otool objdump vtool strip nm"

note() { echo "[clean-machine] $*"; }

# Move a path aside and record the reverse in restore.sh. PATH scrubbing only HIDES
# these -- uv, the py launcher and framework lookups find them anyway -- so absence has
# to be real. The restore line is guarded: the install may have recreated the path, and
# an unguarded `mv` would bury the original inside it.
mask_aside() {
  local src="$1" dst="${2:-$1.masked}" as=""
  [ -e "$src" ] || return 0
  [ -w "$(dirname "$src")" ] || as="sudo"
  if $as mv "$src" "$dst" 2>/dev/null; then
    note "moved $src aside"
    printf "[ -e '%s' ] || %s mv '%s' '%s' 2>/dev/null || true\n" "$src" "$as" "$dst" "$src" >> "$RESTORE"
  else
    note "WARN could not move $src"
  fi
}

# ── PATH scrub ────────────────────────────────────────────────────────────────
# Keep only OS-default system dirs: drops Homebrew, the hosted Python toolcache,
# setup-* shims, pipx, cargo and every other preinstalled developer dir.
scrub_path() {
  local keep out=""
  if [ "$OS" = "Darwin" ]; then
    keep="/usr/bin:/bin:/usr/sbin:/sbin"
  else
    keep="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
  fi
  local IFS=":"
  for d in $keep; do
    [ -d "$d" ] && out="${out:+$out:}$d"
  done
  echo "$out"
}

# ── mask ──────────────────────────────────────────────────────────────────────
if [ "$MODE" = "mask" ]; then
  NEWPATH="$(scrub_path)"
  if [ "$OS" = "Darwin" ]; then
    # Do not execute /usr/bin/install_name_tool as a self-test on a CLT-free Mac: that
    # is the GUI prompt this lane exists to prevent. This sentinel is ahead of /usr/bin,
    # logs argv with explicit argc and hex-encoded argument boundaries, and fails without
    # touching a dylib. install.sh's still-more-local uv guard must win over it.
    bash "$INSTALL_NAME_TOOL_HELPER" write sentinel "$BIN/install_name_tool"
    NEWPATH="$BIN:$NEWPATH"
  fi
  {
    echo "export PATH='$NEWPATH'"
    # UNSET, not a fake path: `xcode-select -p` honours DEVELOPER_DIR and prints it
    # verbatim with exit 0, so a nonexistent dir makes the probe SUCCEED. On a clean
    # Mac it is unset and the missing xcode_select_link is what makes the probe fail.
    echo "unset DEVELOPER_DIR || true"
    echo "unset SDKROOT CC CXX CFLAGS CXXFLAGS LDFLAGS CMAKE_GENERATOR CMAKE_PREFIX_PATH || true"
    echo "export HOMEBREW_NO_AUTO_UPDATE=1"
    echo "export UNSLOTH_CLEAN_MACHINE=1"

    echo "export UNSLOTH_TOOL_TRACE='$TRACE'"
  } >> "$ENV_FILE"

  if [ "$REMOVE" = "1" ] && [ "$OS" = "Darwin" ]; then
    # Best effort, each step independent and recorded in restore.sh so an `if: always()`
    # step can put the runner back. `xcode-select -p` reads xcode_select_link, so
    # removing it reproduces a virgin Mac's gate; `--reset` can reselect Xcode.app.
    # Captured now, re-selected LAST: restore.sh runs in order, and a --switch emitted here
    # would name a directory the later lines have not moved back yet, fail, and be
    # swallowed, leaving the link unrestored while the step reported success.
    _orig_dev=""
    if [ -e /var/db/xcode_select_link ]; then
      _orig_dev="$(xcode-select -p 2>/dev/null || true)"
      if sudo rm -f /var/db/xcode_select_link 2>/dev/null; then
        note "removed /var/db/xcode_select_link (was: ${_orig_dev:-unset})"
      else
        note "WARN could not remove /var/db/xcode_select_link"
        _orig_dev=""
      fi
    fi
    # Moving the CLT dir aside turns /usr/bin/{cc,clang,git} into dead shims, proving
    # the install needs no compiler at all.
    if [ -d /Library/Developer/CommandLineTools ]; then
      if sudo mv /Library/Developer/CommandLineTools /Library/Developer/CommandLineTools.masked 2>/dev/null; then
        note "moved CommandLineTools aside"
        echo "sudo mv /Library/Developer/CommandLineTools.masked /Library/Developer/CommandLineTools 2>/dev/null || true" >> "$RESTORE"
      else
        note "WARN could not move CommandLineTools"
      fi
    fi
    # Xcode.app too: with the link removed AND CommandLineTools moved, `xcode-select -p`
    # still succeeds via the image's Xcode bundle (observed:
    # /Applications/Xcode_16.4.app/Contents/Developer), which re-arms /usr/bin/{git,cc}.
    for app in /Applications/Xcode*.app; do
      [ -d "$app" ] || continue
      if sudo mv "$app" "${app}.masked" 2>/dev/null; then
        note "moved $(basename "$app") aside"
        echo "sudo mv '${app}.masked' '$app' 2>/dev/null || true" >> "$RESTORE"
      else
        note "WARN could not move $app"
      fi
    done
    # After both directory restores above, so the path it names is back. Still `|| true`:
    # the runner is ephemeral and a failed re-selection must not fail an otherwise green
    # job, but it can no longer fail for the trivial reason of running too early.
    if [ -n "$_orig_dev" ]; then
      echo "sudo xcode-select --switch '$_orig_dev' 2>/dev/null || true" >> "$RESTORE"
    fi
    # /usr/local EXISTS on a factory-fresh Mac (a SIP-exempt firmlink) but is empty, so
    # empty it rather than remove it. Before the Homebrew block, so /usr/local/Homebrew
    # is stashed once, with one restore line, in the right order.
    if [ -d /usr/local ]; then
      STASH="$WORK/usr-local"
      mkdir -p "$STASH"
      for entry in /usr/local/* /usr/local/.[!.]*; do
        [ -e "$entry" ] || continue
        base="$(basename "$entry")"
        if sudo mv "$entry" "$STASH/$base" 2>/dev/null; then
          note "emptied /usr/local/$base"
          printf "[ -e '/usr/local/%s' ] || sudo mv '%s/%s' '/usr/local/%s' 2>/dev/null || true\n" \
            "$base" "$STASH" "$base" "$base" >> "$RESTORE"
        else
          note "WARN could not move $entry"
        fi
      done
    fi
    # The hosted toolcache and the python.org framework are what a PATH scrub cannot
    # reach: uv discovers interpreters by probing well-known locations.
    mask_aside "${AGENT_TOOLSDIRECTORY:-$HOME/hostedtoolcache}"
    mask_aside /Library/Frameworks/Python.framework
    # A virgin $HOME has none of these, and a populated uv/pip cache can satisfy a
    # resolution that would fail on a user's machine.
    for d in .cargo .rustup .nvm .rbenv .pyenv .local .cache \
             Library/Caches/uv Library/Caches/pip Library/Caches/Homebrew; do
      mask_aside "$HOME/$d"
    done
    for brewdir in /opt/homebrew /usr/local/Homebrew; do
      if [ -d "$brewdir" ]; then
        if sudo mv "$brewdir" "${brewdir}.masked" 2>/dev/null; then
          note "moved $brewdir aside"
          echo "sudo mv '${brewdir}.masked' '$brewdir' 2>/dev/null || true" >> "$RESTORE"
        else
          note "WARN could not move $brewdir"
        fi
      fi
    done
  fi

  if [ "$REMOVE" = "1" ] && [ "$OS" = "Linux" ]; then
    # A hosted Linux runner keeps git, gcc, cmake and make in /usr/bin, which the PATH
    # scrub must keep, so move the resolved binaries aside (recorded in restore.sh).
    # Versioned siblings like gcc-11 survive; a consumer install invokes the unsuffixed
    # names, which is what `absent` checks.
    for tool in $TOOLS; do
      # Repeated: the same name can sit in /usr/bin and /usr/local/bin, and moving only
      # the first leaves the second on PATH.
      for _ in 1 2 3 4; do
        real="$(command -v "$tool" 2>/dev/null || true)"
        [ -n "$real" ] && [ -e "$real" ] || break
        if sudo mv "$real" "$real.masked" 2>/dev/null; then
          note "moved $real aside"
          echo "sudo mv '$real.masked' '$real' 2>/dev/null || true" >> "$RESTORE"
        else
          note "WARN could not move $real"
          break
        fi
      done
    done
  fi
fi

# ── trace ─────────────────────────────────────────────────────────────────────
if [ "$MODE" = "trace" ]; then
  for tool in $TOOLS; do
    real="$(command -v "$tool" 2>/dev/null || true)"
    [ -n "$real" ] || continue
    # Logs then execs the REAL binary, so behaviour is unchanged and the trace answers
    # "did the installer reach for this?" honestly. install_name_tool needs preserved
    # argument boundaries via hex so the assertion can require exact -id PATH PATH argv.
    if [ "$tool" = "install_name_tool" ]; then
      bash "$INSTALL_NAME_TOOL_HELPER" write passthrough "$BIN/$tool" "$real"
    else
      cat > "$BIN/$tool" <<WRAP
#!/bin/sh
printf '%s\t%s\n' "$tool" "\$*" >> "$TRACE"
exec "$real" "\$@"
WRAP
    fi
    chmod +x "$BIN/$tool"
  done
  {
    echo "export PATH='$BIN:$PATH'"
    echo "export UNSLOTH_TOOL_TRACE='$TRACE'"
    echo "export UNSLOTH_CLEAN_MACHINE=trace"
  } >> "$ENV_FILE"
fi

note "mode=$MODE remove=$REMOVE"
note "env file: $ENV_FILE"
note "trace:    $TRACE"
note "restore:  $RESTORE"

```

## /.github/scripts/clean-machine-install-name-tool.sh

```sh path="/.github/scripts/clean-machine-install-name-tool.sh" 
#!/usr/bin/env bash
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.
# Shared install_name_tool trace wrapper and CLT-absent sentinel contract.
set -euo pipefail

usage() {
  echo "usage: $0 write {sentinel|passthrough} TARGET [REAL_TOOL]" >&2
  echo "       $0 verify-sentinel TRACE MARKER" >&2

  echo "       $0 decode TRACE_ARG" >&2
  exit 2
}


decode_trace_arg() {
  encoded=$1
  case "$encoded" in h*) hex=${encoded#h} ;; *) return 1 ;; esac
  case "$hex" in *[!0123456789abcdef]*) return 1 ;; esac
  [ $(( ${#hex} % 2 )) -eq 0 ] || return 1
  decoded=""
  while [ -n "$hex" ]; do
    rest=${hex#??}
    pair=${hex%"$rest"}
    hex=$rest
    printf -v byte '%b' "\\x$pair"
    decoded+=$byte
  done
  printf '%s' "$decoded"
}

case "${1:-}" in
  write)
    kind="${2:-}"
    target="${3:-}"
    [ -n "$target" ] || usage
    case "$kind" in sentinel|passthrough) ;; *) usage ;; esac

    cat > "$target" <<'WRAPPER'
#!/bin/sh
: "${UNSLOTH_TOOL_TRACE:?UNSLOTH_TOOL_TRACE is required}"
encode_trace_arg() {
  printf '%s' "$1" | od -An -v -tx1 | tr -d ' \n'
}
printf 'install_name_tool\t%s' "$#" >> "$UNSLOTH_TOOL_TRACE"
for arg in "$@"; do printf '\th%s' "$(encode_trace_arg "$arg")" >> "$UNSLOTH_TOOL_TRACE"; done
printf '\n' >> "$UNSLOTH_TOOL_TRACE"
WRAPPER
    if [ "$kind" = "sentinel" ]; then
      printf '%s\n' 'exit 97' >> "$target"
    else
      real_tool="${4:-}"
      [ -n "$real_tool" ] || usage
      case "$real_tool" in *'"'*|*{{contextString}}#39;\n'*) echo "unsupported tool path: $real_tool" >&2; exit 2 ;; esac
      printf 'exec "%s" "$@"\n' "$real_tool" >> "$target"
    fi
    chmod +x "$target"
    ;;

  decode)
    [ "$#" -eq 2 ] || usage
    decode_trace_arg "$2"
    ;;


  verify-sentinel)
    trace="${2:-}"
    marker="${3:-}"
    [ -n "$trace" ] && [ -n "$marker" ] || usage
    [ -n "${UNSLOTH_TOOL_TRACE:-}" ] && [ "$UNSLOTH_TOOL_TRACE" = "$trace" ] || {
      echo "::error::install_name_tool sentinel trace environment is not active" >&2
      exit 1
    }

    set +e
    install_name_tool "--${marker}-sentinel-self-test" >/dev/null 2>&1
    sentinel_rc=$?
    set -e
    [ "$sentinel_rc" -eq 97 ] || {
      echo "::error::install_name_tool sentinel returned $sentinel_rc, expected 97" >&2
      exit 1
    }
    marker_hex=$(printf '%s' "--${marker}-sentinel-self-test" | od -An -v -tx1 | tr -d ' \n')
    expected=$(printf 'install_name_tool\t1\th%s' "$marker_hex")
    grep -Fqx "$expected" "$trace" || {
      echo "::error::install_name_tool sentinel did not preserve/record its self-test argv" >&2
      cat "$trace" >&2 || true
      exit 1
    }
    : > "$trace"
    ;;

  *) usage ;;
esac

```

## /.github/scripts/ensure-docker-daemon.ps1

```ps1 path="/.github/scripts/ensure-docker-daemon.ps1" 
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.

# Waits for the Windows Docker daemon on a hosted runner, starting the service if
# it is installed but not running.
# Docker is installed on every windows-2022 image (runner-images uses Microsoft's
# install-docker-ce.ps1 without -HyperV, so the daemon serves WINDOWS containers) but is
# not always RUNNING at job start: a spike run died 21s in with "failed to connect to the
# docker API at npipe:////./pipe/docker_engine" while a sibling job was fine. Without the
# wait that flake reads as "Windows containers are unavailable on hosted runners".

[CmdletBinding()]
param([int] $TimeoutMinutes = 5)

$deadline = (Get-Date).AddMinutes($TimeoutMinutes)
while ($true) {
    docker info *>&1 | Out-Null
    if ($LASTEXITCODE -eq 0) {
        Write-Host "docker daemon is up"
        break
    }
    if ((Get-Date) -ge $deadline) {
        Write-Host "::error::the Docker daemon never became reachable within $TimeoutMinutes minutes"
        Get-Service docker -ErrorAction SilentlyContinue | Format-List | Out-String | Write-Host
        exit 1
    }
    $svc = Get-Service -Name docker -ErrorAction SilentlyContinue
    Write-Host "docker service status: $(if ($svc) { $svc.Status } else { 'NOT INSTALLED' }); retrying..."
    if ($svc -and $svc.Status -ne 'Running') {
        Start-Service docker -ErrorAction SilentlyContinue
    }
    Start-Sleep -Seconds 5
}

# Failing `docker info` probes leave $LASTEXITCODE non-zero and the runner appends
# `exit $LASTEXITCODE` to every pwsh step (actions/runner#351), so a successful wait
# would still fail the step.
$global:LASTEXITCODE = 0
exit 0

```

## /.github/scripts/hf-download-with-retry.sh

```sh path="/.github/scripts/hf-download-with-retry.sh" 
#!/usr/bin/env bash
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
# Download a single file from a Hugging Face repo with a stall-retry
# watchdog. Used by the Unsloth CI workflows so a hung hf-xet transfer
# kills + retries instead of silently consuming the job's timeout.
# Usage: hf-download-with-retry.sh REPO FILE LOCAL_DIR
# Why this exists
# huggingface_hub 1.15+ deprecated `hf_transfer` and routes every
# transfer through the `hf-xet` binary package. In CI we observed
# `hf download` on a 3 GB GGUF (gemma-4-E2B-it-UD-Q4_K_XL) progress
# to ~46% via Xet, then go completely silent for the remainder of
# the 30-min job timeout -- no progress bytes, no error, no exit.
# A sibling 940 MB mmproj on the same step downloaded in ~21s
# moments earlier, so the hang is per-file inside hf-xet rather
# than a network outage. The Xet env-vars below put hf-xet into
# its highest-throughput mode and force a 500 s client-read
# timeout; the watchdog loop ensures a stall does not eat the
# whole job: if the hf process has not exited after STALL_S
# seconds (default 180 = 3 min), we SIGTERM, then SIGKILL, then
# start a fresh attempt. Retries are unbounded -- the enclosing
# GitHub Actions step's (or, absent one, job's) `timeout-minutes` is
# the real bound, so give every step that calls this script one.
# See https://huggingface.co/docs/huggingface_hub/package_reference/environment_variables
# for the HF_XET_* documentation, and npm/cli#7308's pattern (silent
# CI hang with no error) for prior art on this class of failure.

set -uo pipefail

REPO="${1:?usage: hf-download-with-retry.sh REPO FILE [LOCAL_DIR]}"
FILE="${2:?usage: hf-download-with-retry.sh REPO FILE [LOCAL_DIR]}"
# LOCAL_DIR is optional. If empty, hf falls back to HF_HUB_CACHE
# (~/.cache/huggingface/hub) which is the desired path for callers
# that populate HF_HOME for a downstream Unsloth model load.
LOCAL_DIR="${3:-}"

# Stall threshold per attempt, in seconds. Override with
# HF_DOWNLOAD_STALL_SECONDS in the workflow env if 3 min is too tight
# for a specific runner / file. The script keeps retrying past this
# until the job timeout fires.
STALL_S="${HF_DOWNLOAD_STALL_SECONDS:-180}"

# hf-xet tuning. HF_HUB_ENABLE_HF_TRANSFER is deliberately NOT set --
# it is a no-op on huggingface_hub>=1.15 and only emits a deprecation
# FutureWarning. The five HF_XET_* knobs below mirror the settings
# Daniel asked for: max bandwidth + 64 parallel range gets, no chunk
# cache (download-once usage pattern), parallel disk writes (SSD/NVMe
# runners), and a generous 500 s read timeout so individual chunk
# requests fail loudly instead of stalling forever.
export HF_XET_HIGH_PERFORMANCE=1
export HF_XET_CHUNK_CACHE_SIZE_BYTES=0
export HF_XET_NUM_CONCURRENT_RANGE_GETS=64
export HF_XET_RECONSTRUCT_WRITE_SEQUENTIALLY=0
export HF_XET_CLIENT_READ_TIMEOUT=500

if [ -n "$LOCAL_DIR" ]; then
  mkdir -p "$LOCAL_DIR"
fi

attempt=1
while : ; do
  log="$(mktemp -t hf-download.XXXXXX)"
  echo "[hf-download] $FILE attempt $attempt (stall threshold ${STALL_S}s, log=$log)"

  if [ -n "$LOCAL_DIR" ]; then
    hf download "$REPO" "$FILE" --local-dir "$LOCAL_DIR" > "$log" 2>&1 &
  else
    hf download "$REPO" "$FILE" > "$log" 2>&1 &
  fi
  pid=$!

  elapsed=0
  while kill -0 "$pid" 2>/dev/null && [ "$elapsed" -lt "$STALL_S" ]; do
    sleep 5
    elapsed=$((elapsed + 5))
  done

  if kill -0 "$pid" 2>/dev/null; then
    echo "[hf-download] $FILE attempt $attempt exceeded ${STALL_S}s -- killing PID $pid and retrying"
    kill -TERM "$pid" 2>/dev/null || true
    sleep 2
    kill -KILL "$pid" 2>/dev/null || true
    wait "$pid" 2>/dev/null || true
    echo "[hf-download] $FILE attempt $attempt log tail (last 40 lines):"
    tail -40 "$log" || true
    attempt=$((attempt + 1))
    continue
  fi

  if wait "$pid"; then
    rc=0
  else
    rc=$?
  fi

  if [ "$rc" -eq 0 ]; then
    echo "[hf-download] $FILE attempt $attempt succeeded"
    tail -20 "$log" || true
    exit 0
  fi

  echo "[hf-download] $FILE attempt $attempt failed (exit $rc) -- retrying"
  tail -40 "$log" || true
  attempt=$((attempt + 1))
done

```

## /.github/scripts/interrupt-install.ps1

```ps1 path="/.github/scripts/interrupt-install.ps1" 
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.
# Windows counterpart of interrupt-install.sh: run install.ps1 and kill it partway
# through, reproducing a user quitting the desktop app mid-install.
# Windows has no process groups (hence the app's windows_job.rs), so this kills the whole
# process TREE: killing the leader alone leaves uv/python children to finish the dep pass.
# Usage:
#   pwsh -File .github/scripts/interrupt-install.ps1 -Marker 'studio deps' `
#        -LogPath logs/install.log -InstallArgs '--tauri --no-torch --local'
[CmdletBinding()]
param(
  [string]$Marker = '',
  [string]$LogPath = 'logs/install.log',
  [string]$InstallArgs = '',
  [int]$KillAtSeconds = 900
)

$ErrorActionPreference = 'Continue'
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $LogPath) | Out-Null
Set-Content -Path $LogPath -Value '' -Encoding utf8

# Stand in for the desktop app, which writes this before spawning the installer
# (install.rs). We kill install.ps1 directly, so without it #7490's marker is absent for an
# unrelated reason, exactly what the Windows legs reported. Both roots: Rust hardcodes
# ~/.unsloth/studio, CI overrides UNSLOTH_STUDIO_HOME. Never cleared, by design.
foreach ($dir in @($env:UNSLOTH_STUDIO_HOME, (Join-Path $HOME '.unsloth\studio'))) {
  if ([string]::IsNullOrWhiteSpace($dir)) { continue }
  try {
    New-Item -ItemType Directory -Force -Path $dir -ErrorAction Stop | Out-Null
    Set-Content -Path (Join-Path $dir '.desktop-install-in-progress') -Value '' -ErrorAction Stop
  } catch { Write-Host "[interrupt] could not seed install marker in ${dir}: $_" }
}

# Its own host, so stdout can be redirected to the log while we poll. That host is WINDOWS
# PowerShell 5.1, not pwsh, with install.rs:325-339's exact flags: the only host a real
# desktop install uses, while every other Windows job in .github runs install.ps1 under
# pwsh 7, leaving 5.1 behaviour (.NET Framework, OEM/ANSI console encoding, different
# native-command and OSArchitecture reporting) covered by nothing. Only the installer child
# and the repair re-run change host; the driver stays under pwsh.
$argList = @(
  '-NoLogo', '-NoProfile', '-NonInteractive',
  '-WindowStyle', 'Hidden',
  '-ExecutionPolicy', 'Bypass',
  '-File', 'install.ps1'
)
if ($InstallArgs) { $argList += $InstallArgs.Split(' ') }
$proc = Start-Process -FilePath 'powershell.exe' -ArgumentList $argList `
  -RedirectStandardOutput $LogPath -RedirectStandardError "$LogPath.err" `
  -PassThru -NoNewWindow
Write-Host "[interrupt] installer pid=$($proc.Id) marker='$Marker' deadline=${KillAtSeconds}s"

# Proof that the signal was DELIVERED, not merely attempted. The installer can fail on its
# own between the last HasExited check and Stop-Tree, and a natural failure carries a
# non-zero exit code just like a kill does, so the exit status alone cannot separate the two
# on Windows. Stop-Process throws on a process already gone, so this flag is false exactly
# when there was nothing left to interrupt.
$script:rootKilled = $false

function Get-Descendants([int]$RootId) {
  # Depth-first, deepest first. CIM gives the parent link Windows has no process groups for.
  $ids = @()
  foreach ($k in @(Get-CimInstance Win32_Process -Filter "ParentProcessId=$RootId" -ErrorAction SilentlyContinue)) {
    $kid = [int]$k.ProcessId
    $ids += Get-Descendants $kid
    $ids += $kid
  }
  return $ids
}

function Stop-Tree([int]$RootId) {
  # Snapshot the whole tree BEFORE killing anything: once a parent is gone its children are
  # orphaned with no ParentProcessId left to walk, so the walk has to happen first.
  $descendants = @(Get-Descendants $RootId)
  # Then the ROOT, ahead of its children. install.ps1 watches the child it waits on: in
  # staging run 30424366953 it had already printed "unsloth studio setup failed (exit code
  # -1)" by the time Stop-Process reached it. Killing children first races the leader's own
  # exit, and a leader that wins makes Stop-Process throw over an interruption the driver
  # did deliver, failing the leg for nothing. Dead first, it can neither react nor respawn
  # what we are about to kill.
  try {
    Stop-Process -Id $RootId -Force -ErrorAction Stop
    Write-Host "[interrupt] killed installer pid=$RootId"
    if ($RootId -eq $proc.Id) { $script:rootKilled = $true }
  }
  catch { if ($RootId -eq $proc.Id) { Write-Host "[interrupt] installer pid=$RootId was already gone: $_" } }
  foreach ($id in $descendants) {
    try { Stop-Process -Id $id -Force -ErrorAction Stop; Write-Host "[interrupt] killed pid=$id" }
    catch { }
  }
}

# A leg can be aimed at either kind of phase, and only one of them is a line. install.ps1
# prints "[TAURI:STEP] <name>" lines, while the dependency pass rewrites ONE physical line
# with \r (install_python_stack.py:2499), so its sub-steps are CR-separated SEGMENTS.
# Splitting on \r is what makes a sub-step's END observable at all.
$SubRe = '\[[=-]+\]\s*\d+/\d+\s'

function Get-PhaseLines([string]$Path) {
  $raw = Get-Content -Path $Path -Raw -ErrorAction SilentlyContinue
  if (-not $raw) { return @() }
  return @(($raw -replace "`r", "`n") -split "`n")
}

function Get-LastPhase([string]$Path) {
  $p = @(Get-PhaseLines $Path | Where-Object { $_ -match '^\[TAURI:STEP\]' -or $_ -match $SubRe })
  if ($p.Count) { return $p[-1] }
  return ''
}

# True when the phase the marker named is no longer the running one. A sub-step marker is
# judged against the running sub-step, a step marker against the running step -- a step is
# not "over" because the sub-steps beneath it advanced.
function Test-MarkedPhaseOver {
  if (-not $Marker) { return $false }
  $lines = @(Get-PhaseLines $LogPath)
  $subs = @($lines | Where-Object { $_ -match $SubRe })
  if ($subs | Where-Object { $_ -match $Marker }) {
    $last = Get-LastPhase $LogPath
    return -not ($last -match $SubRe -and $last -match $Marker)
  }
  $steps = @($lines | Where-Object { $_ -match '^\[TAURI:STEP\]' })
  if ($steps | Where-Object { $_ -match $Marker }) {
    return ($steps[-1] -notmatch $Marker)
  }
  return $false
}

$killed = $false
$reason = ''
# Fifth-of-a-second slices, matching the POSIX driver: every phase label prints BEFORE its
# work, so this delay IS the whole distance between the label and the signal and the only
# thing that can push the kill past the end of a short phase. It slept 500ms while claiming
# a fifth, carrying 2.5 slices of overshoot the POSIX side does not.
for ($i = 0; $i -lt ($KillAtSeconds * 5); $i++) {
  if ($proc.HasExited) { $reason = 'exited-before-marker'; break }
  if ($Marker) {
    $hit = Select-String -Path $LogPath -Pattern $Marker -SimpleMatch:$false -ErrorAction SilentlyContinue
    if ($hit) {
      # Same as the POSIX driver: signal at detection, never after a delay. The label
      # prints before the work, so the kill is inside the phase the moment the line appears,
      # and any wait is a bet on the phase outlasting it that staging runs 30419729244 and
      # 30426111484 both lost.
      # The installer can still exit on its own between the match and the signal, which
      # would record marker-hit over an install that interrupted nothing.
      if ($proc.HasExited) { $reason = 'exited-before-signal'; break }
      $reason = 'marker-hit'
      $killed = $true
      break
    }
  }
  Start-Sleep -Milliseconds 200
}
if (-not $killed -and -not $proc.HasExited) { if (-not $reason) { $reason = 'deadline' }; $killed = $true }

if ($killed) {
  Write-Host "[interrupt] killing process tree of $($proc.Id) ($reason)"
  Stop-Tree $proc.Id
  # Any straggler uv/python that reparented away from the installer. The old sweep matched
  # nothing: UNSLOTH_STUDIO_HOME arrives as `D:\a\r\r/.studio-home` (github.workspace joined
  # with a forward slash) while Process.Path is all backslashes, so the literal -like missed
  # even the venv's own python -- hence the separator normalisation, and uv by name (it
  # lives outside the studio home and the ephemeral runner has no other uv). Under --tauri
  # there is no UNSLOTH_STUDIO_HOME, so fall back to install.ps1's root.
  $studioRoot = if ([string]::IsNullOrWhiteSpace($env:UNSLOTH_STUDIO_HOME)) { Join-Path $HOME '.unsloth\studio' }
                else { $env:UNSLOTH_STUDIO_HOME }
  $homeNorm = if ([string]::IsNullOrWhiteSpace($studioRoot)) { $null }
              else { ($studioRoot -replace '/', '\').TrimEnd('\') }
  foreach ($p in @(Get-Process -Name 'uv', 'python', 'pythonw' -ErrorAction SilentlyContinue)) {
    $path = $null
    try { $path = $p.Path } catch { }
    $inHome = $homeNorm -and $path -and ($path -like "$homeNorm\*")
    if ($p.ProcessName -eq 'uv' -or $inHome) {
      try { Stop-Process -Id $p.Id -Force; Write-Host "[interrupt] swept $($p.ProcessName) pid=$($p.Id)" } catch { }
    }
  }
}

try { $proc.WaitForExit(30000) | Out-Null } catch { }
$rc = if ($proc.HasExited) { $proc.ExitCode } else { 'running' }
Write-Host "[interrupt] installer exit=$rc reason=$reason killed=$killed root_killed=$($script:rootKilled)"
Write-Host '[interrupt] last log lines:'
Get-Content $LogPath -Tail 15 -ErrorAction SilentlyContinue

if ($Marker -and -not (Select-String -Path $LogPath -Pattern $Marker -ErrorAction SilentlyContinue)) {
  Write-Host "::warning::marker '$Marker' never appeared -- killed at the deadline, not the intended step"
}
# Where the signal actually landed. A phase that ended before the poll saw the marker sends
# the kill into a LATER phase, so the leg duplicates whichever leg owns that phase while its
# own label claims otherwise.
$lastPhase = Get-LastPhase $LogPath
Write-Host "[interrupt] phase at kill: $lastPhase"
$mismatch = Test-MarkedPhaseOver
if ($mismatch) {
  Write-Host "::warning::killed in '$lastPhase', not the marked phase -- that phase was already over"
}
# Lower-cased so the workflow compares it the same way on every platform, and only simple
# values: the POSIX side sources this file.
@(
  "interrupt_reason=$reason"
  "interrupt_killed=$killed"
  "interrupt_root_killed=$(if ($script:rootKilled) { 'true' } else { 'false' })"
  "installer_exit=$rc"
  "interrupt_phase_mismatch=$(if ($mismatch) { 'true' } else { 'false' })"
) | Set-Content -Path (Join-Path (Split-Path -Parent $LogPath) 'interrupt.env') -Encoding utf8
exit 0

```

## /.github/scripts/interrupt-install.sh

```sh path="/.github/scripts/interrupt-install.sh" 
#!/usr/bin/env bash
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.
# Run install.sh and SIGTERM it partway through, reproducing a user quitting the desktop
# app mid-install: main.rs cleanup_child_processes() -> install::stop_install() kills the
# installer PROCESS GROUP (install.rs:798-807). Group, not leader: the `uv`/`python`
# children would otherwise finish the dep pass and the leg would prove nothing.
# Usage: bash .github/scripts/interrupt-install.sh "<marker>" "<logfile>" [-- install args]
#   <marker>  log regex to wait for before killing, e.g. "studio deps"; "" kills at deadline.
# Env: KILL_AT_SECONDS deadline (default 900), KILL_GRACE grace before SIGKILL (default 10)
set -uo pipefail

MARKER="${1:-}"
LOG="${2:-logs/install.log}"
shift 2 || true
[ "${1:-}" = "--" ] && shift
KILL_AT_SECONDS="${KILL_AT_SECONDS:-900}"
KILL_GRACE="${KILL_GRACE:-10}"

mkdir -p "$(dirname "$LOG")"
: > "$LOG"

# The desktop writes this before spawning the installer (install.rs); we kill the installer
# directly, so without it #7490's marker is absent for an unrelated reason. Both roots: Rust
# hardcodes ~/.unsloth/studio, CI overrides UNSLOTH_STUDIO_HOME. Never cleared, by design.
for _marker_dir in "${UNSLOTH_STUDIO_HOME:-}" "$HOME/.unsloth/studio"; do
  [ -n "$_marker_dir" ] || continue
  mkdir -p "$_marker_dir" 2>/dev/null || continue
  : > "$_marker_dir/.desktop-install-in-progress" 2>/dev/null || true
done

# Job control puts the child in its own group, so $! is the pgid and `kill -- -$!`
# reaches every descendant, as the Rust side does.
set -m
bash install.sh "$@" > "$LOG" 2>&1 &
PID=$!
set +m
echo "[interrupt] installer pid/pgid=$PID marker='${MARKER}' deadline=${KILL_AT_SECONDS}s"

# A leg can be aimed at either kind of phase, and only one of them is a line. install.sh
# prints "[TAURI:STEP] <name>" lines, while the dependency pass rewrites ONE physical line
# with \r (install_python_stack.py:2499), so its ten sub-steps are CR-separated SEGMENTS.
# Splitting on \r is what makes a sub-step's END observable: without it the "studio deps"
# leg of staging run 30419729244 killed at "7/10 data designer deps" with backend_ok=true,
# having installed the structlog it exists to remove.
SUB_RE='\[[=-]+\][[:space:]]*[0-9]+/[0-9]+[[:space:]]'
phase_lines() { tr '\r' '\n' < "$LOG" 2>/dev/null || true; }

# True when the phase the marker named is no longer the running one. A sub-step marker is
# judged against the running sub-step, a step marker against the running step -- a step is
# not "over" because the sub-steps beneath it advanced; a marker naming neither is not
# judged. Results go through variables, never `| grep -q`, which can report SIGPIPE through
# pipefail on a long log.
marked_phase_over() {
  [ -n "$MARKER" ] || return 1
  local lines steps subs last
  lines="$(phase_lines)"
  steps="$(printf '%s\n' "$lines" | grep -aE '^\[TAURI:STEP\]')" || true
  subs="$(printf '%s\n' "$lines" | grep -aE "$SUB_RE")" || true
  if [ -n "$subs" ] && [[ $subs =~ $MARKER ]]; then
    last="$(printf '%s\n' "$lines" | grep -aE "^\[TAURI:STEP\]|$SUB_RE" | tail -1)" || true
    [[ $last =~ $SUB_RE && $last =~ $MARKER ]] && return 1
    return 0
  fi
  if [ -n "$steps" ] && [[ $steps =~ $MARKER ]]; then
    last="$(printf '%s\n' "$steps" | tail -1)"
    [[ $last =~ $MARKER ]] && return 1
    return 0
  fi
  return 1
}

killed=false
reason=""
# Fifth-of-a-second slices: every phase label prints BEFORE its work, so the poll delay is
# the whole distance between the label and the signal.
for i in $(seq 1 $(( KILL_AT_SECONDS * 5 ))); do
  if ! kill -0 "$PID" 2>/dev/null; then
    reason="exited-before-marker"
    break
  fi
  if [ -n "$MARKER" ] && grep -qE "$MARKER" "$LOG" 2>/dev/null; then
    # Signal at detection, never after a delay: every label prints BEFORE its work, so the
    # kill is inside the phase the moment the line appears, and any wait is a bet on how
    # long that phase runs. The bet lost twice -- a flat 3s wait put 5 of the 12 legs of
    # staging run 30419729244 into a LATER phase, and in 30426111484 it carried the macOS
    # torch leg from "Installing PyTorch" into "Installing Unsloth", a step the workflow
    # called minutes long that finished in under three seconds.
    # Between the grep and the signal the installer can still exit on its own, which would
    # record marker-hit over an install that interrupted nothing.
    if ! kill -0 "$PID" 2>/dev/null; then
      reason="exited-before-signal"
      break
    fi
    reason="marker-hit"
    killed=true
    break
  fi
  sleep 0.2
done

if [ "$killed" != "true" ] && kill -0 "$PID" 2>/dev/null; then
  reason="${reason:-deadline}"
  killed=true
fi

if [ "$killed" = "true" ]; then
  echo "[interrupt] SIGTERM to process group -$PID ($reason)"
  kill -TERM -- -"$PID" 2>/dev/null || kill -TERM "$PID" 2>/dev/null || true
  for _ in $(seq 1 "$KILL_GRACE"); do
    kill -0 "$PID" 2>/dev/null || break
    sleep 1
  done
  # Unconditional, and to the GROUP: the leader exits on SIGTERM while a uv or python
  # descendant does not, and gating on `kill -0 "$PID"` left that child finishing the dep
  # pass under the probe. Signalling an empty group is a no-op.
  echo "[interrupt] SIGKILL to process group -$PID"
  kill -KILL -- -"$PID" 2>/dev/null || kill -KILL "$PID" 2>/dev/null || true
fi

wait "$PID" 2>/dev/null
rc=$?

# Only after the reap: an unreaped leader is still a member of its own group, so this poll
# would report it alive forever. No installer may still run when the probe starts.
if [ "$killed" = "true" ]; then
  for _ in $(seq 1 "$KILL_GRACE"); do
    kill -0 -- -"$PID" 2>/dev/null || break
    kill -KILL -- -"$PID" 2>/dev/null || true
    sleep 1
  done
  if kill -0 -- -"$PID" 2>/dev/null; then
    echo "::warning::processes from installer group -$PID outlived SIGKILL"
  fi
fi
echo "[interrupt] installer exit=$rc reason=$reason killed=$killed"
echo "[interrupt] last log lines:"
tail -15 "$LOG" || true

# A leg that never reached the target step must be visible, not quietly green.
if [ -n "$MARKER" ] && ! grep -qE "$MARKER" "$LOG" 2>/dev/null; then
  echo "::warning::marker '$MARKER' never appeared -- this leg killed at the deadline, not at the intended step"
fi
# Where the signal actually landed. A phase that ended before the poll saw the marker sends
# the kill into a LATER phase, so the leg duplicates whichever leg owns that phase while its
# own label claims otherwise.
_last_phase="$(phase_lines | grep -aE "^\[TAURI:STEP\]|$SUB_RE" | tail -1)" || true
echo "[interrupt] phase at kill: $_last_phase"
mismatch=false
if marked_phase_over; then
  mismatch=true
  echo "::warning::killed in '$_last_phase', not the marked phase -- that phase was already over"
fi
# Only simple values: the workflow sources this file, so the phase text stays out of it.
{
  echo "interrupt_reason=$reason"
  echo "interrupt_killed=$killed"
  echo "installer_exit=$rc"
  echo "interrupt_phase_mismatch=$mismatch"
} > "$(dirname "$LOG")/interrupt.env"
exit 0

```

## /.github/scripts/interrupted_install_probe.py

```py path="/.github/scripts/interrupted_install_probe.py" 
#!/usr/bin/env python3
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0

"""After an install is interrupted, decide whether the desktop app WOULD report the resulting venv as healthy, reproducing the Tauri preflight probes so the regression is testable without building the app.

The reported bug: quitting the app during the dependency pass SIGTERMs the installer (install.rs stop_install), and landing in "studio deps" drops studio/backend/requirements/studio.txt, where structlog is declared. Preflight probes `unsloth -h` (managed.rs:419) and `studio desktop-capabilities` (managed.rs:318); both SUCCEED because typer/click/rich are core, so the app reports ManagedReady with can_auto_repair=false while the backend dies on `import structlog`.

ONE implementation for all three platforms. The bespoke inline PowerShell probe it replaced ran only `-h` and `desktop-capabilities`, so it could not observe `studio_install_ok`, `verify-install` or `desktop-runtime-check`, and would have failed the very PRs that add them: a probe that cannot see the fix is worse than no probe.

Verdicts: HEALTHY (the backend boots AND desktop-capabilities reports the install complete, so preflight would report ManagedReady and be right), REPAIRABLE (the backend is broken AND a probe the DESKTOP consumes reports it, so the app can offer a repair), FALSE_READY (the backend is broken and every probe says ready, THE BUG).

Exit: 0 for HEALTHY/REPAIRABLE/NO_CLI, 1 for FALSE_READY, 2 for a usage error.
"""

from __future__ import annotations

import argparse
import json
import os
import socket
import subprocess
import sys
import time
import urllib.error
import urllib.request
from pathlib import Path


def run(cmd: list[str], timeout: int = 120) -> tuple[int, str, str]:
    """(rc, stdout, stderr), kept SEPARATE: preflight pipes stdout and sends stderr to /dev/null (managed.rs:358), so anything folded in here is text the desktop never sees."""
    try:
        p = subprocess.run(cmd, capture_output = True, text = True, timeout = timeout)
        return p.returncode, p.stdout or "", p.stderr or ""
    except (subprocess.TimeoutExpired, OSError) as e:
        return 127, "", f"{type(e).__name__}: {e}"


def merged(rc_out_err: tuple[int, str, str]) -> str:
    """Both streams, for artefact logs only -- never for parsing."""
    return rc_out_err[1] + rc_out_err[2]


def has_subcommand(bin_path: str, args: list[str]) -> bool:
    """Whether the CLI knows the subcommand: older builds lack the verify commands, and 'absent' must not read as 'reported failure'."""
    rc, _, _ = run([bin_path, *args, "--help"], timeout = 60)
    return rc == 0


def free_port() -> int:
    with socket.socket() as s:
        s.bind(("127.0.0.1", 0))
        return int(s.getsockname()[1])


def main(argv: list[str]) -> int:
    ap = argparse.ArgumentParser(description = __doc__)
    ap.add_argument("bin", help = "path to the unsloth CLI")
    ap.add_argument("--port", type = int, default = 0, help = "0 picks a free port")
    ap.add_argument("--out", default = "probe", help = "directory for probe artefacts")
    # The desktop's own grace, BACKEND_STARTUP_GRACE_PERIOD = 5 min (commands.rs:9): less fails a leg the app would wait out. It cannot mask the bug, since a missing import kills the backend and the loop breaks on proc.poll(), so this only bounds a LIVE backend.
    ap.add_argument("--boot-timeout", type = int, default = 300)
    a = ap.parse_args(argv)

    binp = a.bin
    if not Path(binp).exists():
        print(f"::error::unsloth bin not found: {binp}")
        return 2
    out = Path(a.out)
    out.mkdir(parents = True, exist_ok = True)
    port = a.port or free_port()
    facts: dict[str, object] = {}

    def say(k: str, v: object) -> None:
        facts[k] = v
        print(f"[probe] {k:28} = {v}")

    # ── the two probes Tauri preflight actually runs ─────────────────────────
    # The DESKTOP's deadline, not a generous CI one: preflight allows each call 10s (managed.rs:337 for `-h`, :390 for desktop-capabilities) then reports Stale (managed.rs:471, :521). Longer would call a slow torn venv HEALTHY and skip the re-run assertion; run() reports a timeout as a non-zero rc, the same REPAIRABLE arm.
    PREFLIGHT_TIMEOUT = 10

    t0 = time.time()
    r = run([binp, "-h"], timeout = PREFLIGHT_TIMEOUT)
    (out / "cli-h.log").write_text(merged(r), encoding = "utf-8", errors = "replace")
    say("cli_h_ok", r[0] == 0)
    say("cli_h_seconds", round(time.time() - t0, 2))

    t0 = time.time()
    caps_rc, caps_out, caps_err = run(
        [binp, "studio", "desktop-capabilities", "--json"], timeout = PREFLIGHT_TIMEOUT
    )
    (out / "desktop-capabilities.json").write_text(caps_out, encoding = "utf-8", errors = "replace")
    (out / "desktop-capabilities.stderr.log").write_text(
        caps_err, encoding = "utf-8", errors = "replace"
    )
    say("capabilities_ok", caps_rc == 0)
    say("capabilities_seconds", round(time.time() - t0, 2))

    # Parse EXACTLY as the desktop does: managed.rs:414 hands the whole stdout buffer to serde_json, which rejects leading or trailing non-JSON, and stderr was already discarded at managed.rs:358. Folding stderr in made one warning line enough to fail the parse and report FALSE_READY over an install the real app offers to repair.
    # "absent" (studio_install_ok predates the install manifest) and "unparseable" split only for a readable artefact: the desktop reports Stale for both ("desktop_capability_probe_failed", managed.rs:521).
    # The field is Option<bool> (managed.rs:43), so serde rejects a non-boolean and the whole payload fails to deserialize into Stale; bool() instead read the JSON string "false" as True and reported HEALTHY over a torn install. Only a literal JSON true counts.
    install_ok: object = "absent"
    try:
        parsed = json.loads(caps_out)
        if not isinstance(parsed, dict):
            install_ok = "unparseable"
        else:
            v = parsed.get("studio_install_ok")
            if v is None:
                install_ok = "absent"
            elif isinstance(v, bool):
                install_ok = v
            else:
                install_ok = "non-boolean"
    except json.JSONDecodeError:
        install_ok = "unparseable"
    say("capabilities.studio_install_ok", install_ok)

    # The desktop's own conclusion: Ready only on rc 0 plus a true studio_install_ok. The predicate is `!= Some(true)` (managed.rs:445), so an ABSENT field is Stale exactly like a false one, and a CLI too old to answer is rejected one check earlier on desktop_manageability_version. Leaving "absent" undecided reported HEALTHY on every booting leg and skipped the repair assertion, over the regression in `unsloth_cli/commands/studio.py` that the path filter exists to catch.
    caps_ready = caps_rc == 0 and install_ok is True
    say("desktop_would_call_install_ok", caps_ready)

    # ── the deeper probes the fix PRs add ────────────────────────────────────
    # RECORDED, not repair evidence: preflight runs only `-h` and `studio desktop-capabilities --json` (managed.rs:357, :445), so counting these would pass a leg while the real app still reports ManagedReady over a torn install.
    for label, args in (
        ("verify_install", ["studio", "verify-install"]),
        ("desktop_runtime_check", ["studio", "desktop-runtime-check"]),
    ):
        if not has_subcommand(binp, args):
            say(label, "absent")
            continue
        r = run([binp, *args], timeout = 300)
        (out / f"{label}.log").write_text(merged(r), encoding = "utf-8", errors = "replace")
        say(label, "ok" if r[0] == 0 else "failed")

    # The in-progress marker #7490 writes before spawning the installer. RECORDED ONLY: both drivers seed it and never clear it, so it is true on every leg by construction, and using it in the verdict would make FALSE_READY, the one failing outcome, unreachable.
    home = Path(os.environ.get("UNSLOTH_STUDIO_HOME") or (Path.home() / ".unsloth" / "studio"))
    say("install_in_progress_marker", (home / ".desktop-install-in-progress").exists())

    # ── ground truth: does the backend actually boot? ────────────────────────
    # Own the whole process tree: the CLI spawns uvicorn/python children that would hold the port and hang the next leg's probe. Same reason the driver kills the group.
    popen_kw: dict = {}
    if os.name == "posix":
        popen_kw["start_new_session"] = True
    else:
        popen_kw["creationflags"] = getattr(subprocess, "CREATE_NEW_PROCESS_GROUP", 0)
    # Straight to the artefact file, never a PIPE: nothing drains a pipe until after the polling loop, so a backend whose imports outrun the OS buffer (64 KiB on Linux and macOS, one page on Windows) blocks BEFORE binding the port, and backend_ok, what the verdict pivots on, would be false for a perfectly good install.
    blog_path = out / "backend.log"
    blog_fh = blog_path.open("w", encoding = "utf-8", errors = "replace")
    # An interrupted install can leave the console script with its venv interpreter gone, and an unguarded spawn raises, so no verdict.json is written and both workflows die on json.load. An unlaunchable CLI is a broken backend that `-h` flags.
    proc = None
    try:
        proc = subprocess.Popen(
            [binp, "studio", "--api-only", "-H", "127.0.0.1", "-p", str(port)],
            stdout = blog_fh,
            stderr = subprocess.STDOUT,
            text = True,
            **popen_kw,
        )
    except OSError as e:
        say("backend_spawn_error", f"{type(e).__name__}: {e}")
    backend_ok = False
    deadline = time.time() + a.boot_timeout
    while proc is not None and time.time() < deadline:
        if proc.poll() is not None:
            break
        for path in ("/api/health", "/healthz"):
            try:
                with urllib.request.urlopen(f"http://127.0.0.1:{port}{path}", timeout = 2) as r:
                    if r.status == 200:
                        backend_ok = True
                        break
            except (urllib.error.URLError, OSError, TimeoutError):
                pass
        if backend_ok:
            break
        time.sleep(1)

    def reap() -> None:
        if proc is None:
            return
        if os.name == "posix":
            import signal

            # start_new_session made this child its own group leader. Read the pgid BEFORE the reap: once waited on, os.getpgid() raises and escalation hits nothing.
            try:
                pgid = os.getpgid(proc.pid)
            except OSError:
                pgid = proc.pid
            for sig in (signal.SIGTERM, signal.SIGKILL):
                try:
                    os.killpg(pgid, sig)
                except OSError:
                    pass
                try:
                    proc.wait(timeout = 10)
                    break
                except subprocess.TimeoutExpired:
                    continue
            # Unconditional, and to the GROUP, the same escalation interrupt-install.sh makes: the leader exits promptly on SIGTERM while a uvicorn worker does not, so returning once proc.wait() succeeded left that worker holding the port and venv while the repair reinstalled underneath. Signalling an empty group is a no-op.
            try:
                os.killpg(pgid, signal.SIGKILL)
            except OSError:
                pass
        else:
            # On win32 the CLI re-spawns the server as a CHILD and waits on it (unsloth_cli/commands/studio.py:1543), and CREATE_NEW_PROCESS_GROUP does not make terminate() reach descendants, so killing the wrapper alone leaves the venv locked against the repair. taskkill /T takes the tree.
            run(["taskkill", "/F", "/T", "/PID", str(proc.pid)], timeout = 30)
            try:
                proc.wait(timeout = 10)
            except subprocess.TimeoutExpired:
                proc.terminate()
                try:
                    proc.wait(timeout = 10)
                except subprocess.TimeoutExpired:
                    proc.kill()

    reap()
    blog_fh.close()
    blog = blog_path.read_text(encoding = "utf-8", errors = "replace")
    say("backend_ok", backend_ok)

    missing = ""
    for line in blog.splitlines():
        if "ModuleNotFoundError" in line:
            missing = line.strip()
    if missing:
        say("backend_error", missing)

    # ── verdict ──────────────────────────────────────────────────────────────
    # A booting backend is not enough. The manifest is written LAST (install_python_stack.py:3255), so the data-designer leg boots while desktop-capabilities still says studio_install_ok=false and preflight reports Stale (managed.rs:445); calling that HEALTHY skipped the re-run step. `-h` gates it for the same reason: probe_managed_bin runs it FIRST and returns Stale "cli_unusable" without reaching the capability probe (managed.rs:465-478), so consulting cli_h_ok only in the repairable arm called a help-less CLI HEALTHY.
    if backend_ok and caps_ready and facts.get("cli_h_ok"):
        verdict = "HEALTHY"
    elif not caps_ready or not facts.get("cli_h_ok"):
        verdict = "REPAIRABLE"
    else:
        verdict = "FALSE_READY"

    facts["verdict"] = verdict
    (out / "verdict.json").write_text(json.dumps(facts, indent = 2), encoding = "utf-8")
    print(f"[probe] VERDICT = {verdict}")

    if verdict == "FALSE_READY":
        print(
            "::error::Interrupted install reports READY but the backend cannot boot"
            f" ({missing or 'import failure'}). Preflight sees -h ok + desktop-capabilities"
            " ok, so the app shows ManagedReady with can_auto_repair=false and the user"
            " is stuck."
        )
        return 1
    if verdict == "REPAIRABLE":
        print("[probe] incomplete install is detectable -> the desktop app can auto-repair")
    return 0


if __name__ == "__main__":
    raise SystemExit(main(sys.argv[1:]))

```

## /.github/scripts/lane-load-orchestrator.sh

```sh path="/.github/scripts/lane-load-orchestrator.sh" 
#!/usr/bin/env bash
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.
# The load-orchestrator freeze suite, in ONE definition.
# This used to be a whole workflow holding its own runner slot for ~33s. It now runs as a
# background lane inside Lint CI, which was going to occupy a runner on every commit
# anyway. studio-load-orchestrator-ci.yml still exists as a manual escape hatch and calls
# this same script, so the two cannot drift apart.
# Deliberately installs no torch and no unsloth: that is what keeps it cheap enough to run
# on every commit rather than only on the four paths that used to trigger it.
# Takes its venv directory as $1 so the caller decides the isolation. Inside Lint CI that
# is a private venv, because the lane installs packages while the foreground lint steps are
# using the job's interpreter, and two concurrent installs into one site-packages race.
set -euo pipefail

venv_dir="${1:-}"

if [ -n "$venv_dir" ]; then
    python3 -m venv "$venv_dir"
    # shellcheck disable=SC1091
    . "$venv_dir/bin/activate"
fi

python -m pip install --upgrade pip
python -m pip install \
    'pytest>=8' \
    'httpx>=0.27,<1' \
    'fastapi>=0.110,<1' \
    'uvicorn>=0.30,<1' \
    'anyio>=4'

python -m pytest -v --tb=short tests/studio/load_freeze/

```

## /.github/scripts/lane-lockfile-audit.sh

```sh path="/.github/scripts/lane-lockfile-audit.sh" 
#!/usr/bin/env bash
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.
# The lockfile supply-chain audit, in ONE definition.
# Ran as its own workflow on its own runner slot for ~6s of work. It now runs as a
# background lane inside Lint CI. lockfile-audit.yml keeps its nightly `schedule` and calls
# this same script, so the scheduled audit is unchanged and the two cannot drift apart.
# Needs no dependencies at all, which is why it needs no venv: it is stdlib Python over
# files already in the checkout.
set -euo pipefail

# Parses before it runs, so a syntax error in the auditor is reported as a syntax error
# rather than as an audit finding.
python3 -c "import ast; ast.parse(open('scripts/lockfile_supply_chain_audit.py').read())"
python3 scripts/lockfile_supply_chain_audit.py

```

## /.github/scripts/parity-find-unsloth.sh

```sh path="/.github/scripts/parity-find-unsloth.sh" 
#!/usr/bin/env bash
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.
# Print the absolute path of the `unsloth` CLI belonging to ONE Unsloth home.
# Usage:
#   parity-find-unsloth.sh <studio-home>
# Why this is not `command -v unsloth`. install.sh writes a shim into
# $HOME/.local/bin, which is a single name shared by every install on the
# machine; the second of two installs overwrites the first. A job that runs two
# builds side by side and then asks PATH which one to launch gets the same build
# twice, wearing two labels, and the comparison reports "no difference" -- which
# is exactly the shape of failure the parity job exists to detect elsewhere.
# The layout is `$STUDIO_HOME/unsloth_studio/bin/unsloth` (install.sh sets
# VENV_DIR="$STUDIO_HOME/unsloth_studio"). The other candidates are the legacy
# layouts `runtime/lifecycle._find_unsloth_bin` still accepts; they are checked
# so this script and that function cannot disagree about where an Unsloth lives.
# Nothing is guessed: if no candidate exists this fails loudly rather than
# falling back to whatever PATH offers.

set -euo pipefail

HOME_DIR="${1:?parity-find-unsloth.sh: <studio-home> is required}"

for candidate in \
  "$HOME_DIR/unsloth_studio/bin/unsloth" \
  "$HOME_DIR/bin/unsloth" \
  "$HOME_DIR"/.venv*/bin/unsloth
do
  if [ -x "$candidate" ]; then
    printf '%s\n' "$candidate"
    exit 0
  fi
done

{
  echo "parity-find-unsloth.sh: no unsloth CLI under $HOME_DIR"
  echo "looked for unsloth_studio/bin/unsloth, bin/unsloth and .venv*/bin/unsloth"
  echo "contents:"
  ls -la "$HOME_DIR" 2>&1 || true
} >&2
exit 1

```

## /cli.py

```py path="/cli.py" 
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0

import sys

# Match the console-script setup before importing commands.
if __name__ == "__main__":
    sys.argv[0] = "unsloth"

from unsloth_cli import app

if __name__ == "__main__":
    app()

```

## /docker/.dockerignore

```dockerignore path="/docker/.dockerignore" 
**
!Dockerfile
!entrypoint.sh
!smoke_test.py
!fetch_llama_prebuilt.py
!supervisord.conf
!studio_launch.sh
!studio_password.sh
!studio_run.sh
!unsloth_studio_update.sh
!unsloth_llama_update.sh
!unsloth_jupyter_tunnel.sh
!unsloth_nb_compat.py
!unsloth_pip_shim.py
!unsloth_nb_pip_magic.py
!unsloth_ipython_startup.py
!unsloth_run.py
!unsloth_sync_notebooks.sh
!unsloth_nb_content_sig.py
!unsloth_nb_view.py
!unsloth_nb_strip_colab.py
!unsloth_colab_compat.py
!jupyter
!jupyter/unsloth_branding.py
!jupyter/jupyter_server_config.d
!jupyter/jupyter_server_config.d/**
!jupyter/overrides.json
!jupyter/favicon.ico
!jupyter/logo.png
!jupyter/login.html
!jupyter/install_sloth_stickers.py
!jupyter/unsloth_labext
!jupyter/unsloth_labext/package.json
!jupyter/unsloth_labext/tsconfig.json
!jupyter/unsloth_labext/.yarnrc.yml
!jupyter/unsloth_labext/src
!jupyter/unsloth_labext/src/**
!jupyter/unsloth_labext/style
!jupyter/unsloth_labext/style/**

```


The content has been capped at 50000 tokens. The user could consider applying other filters to refine the result. The better and more specific the context, the better the LLM can follow instructions. If the context seems verbose, the user can refine the filter using uithub. Thank you for using https://uithub.com - Perfect LLM context for any GitHub repo.
Copied!