Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: boxlite-ai/boxlite
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.5.12
Choose a base ref
...
head repository: boxlite-ai/boxlite
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.5.13
Choose a head ref
  • 5 commits
  • 88 files changed
  • 3 contributors

Commits on Feb 13, 2026

  1. fix(copy): file-to-file extraction for copy_in/copy_out (#238) (#261)

    copy_in("file.py", "/workspace/script.py") previously created a
    directory named script.py instead of copying the file. The root cause
    was that both guest upload and host download unconditionally treated
    the destination as a directory to extract into.
    
    Add mode-aware extraction that inspects tar contents and destination
    state to choose between two modes:
    - FileToFile: single regular file in tar + dest is not trailing '/' +
      dest is not an existing directory → use entry.unpack(dest)
    - IntoDirectory: everything else → archive.unpack(dest) (unchanged)
    
    This follows Docker cp semantics: trailing slash forces directory mode,
    existing directory receives files inside it, and non-existent non-slash
    paths with single-file source create a file at that exact path.
    DorianZheng authored Feb 13, 2026
    Configuration menu
    Copy the full SHA
    9272e38 View commit details
    Browse the repository at this point in the history

Commits on Feb 14, 2026

  1. feat(sdks): extract boxlite-ffi from the C SDK. (#226)

    Signed-off-by: 季扎 <[email protected]>
    qidi1 authored Feb 14, 2026
    Configuration menu
    Copy the full SHA
    0f5b390 View commit details
    Browse the repository at this point in the history
  2. feat: add log and stat command (#263)

    * feat: add log and stat command
    
    * fix: fix format error
    
    * chore: resolve comment issue
    fatelei authored Feb 14, 2026
    Configuration menu
    Copy the full SHA
    aeec89a View commit details
    Browse the repository at this point in the history
  3. feat(rest): REST API client with Python SDK and examples (#262)

    * feat(rest): complete REST API client implementation with examples
    
    **New modules in `boxlite/src/rest/`:**
    - `client.rs`: HTTP client with OAuth2 authentication, token refresh
    - `runtime.rs`: RestRuntime implementing RuntimeBackend trait
    - `litebox.rs`: RestBox implementing BoxBackend with SSE streaming
    - `exec.rs`: REST-based execution with stdin/stdout/stderr streams
    - `options.rs`: BoxliteRestOptions with environment variable support
    - `types.rs`: Request/response types matching OpenAPI spec
    - `error.rs`: REST-specific error handling
    
    **Runtime abstraction:**
    - `runtime/backend.rs`: RuntimeBackend trait for pluggable backends
    - Updated `runtime/core.rs` to use backend trait
    - Local and REST backends use same API surface
    
    **Features:**
    - OAuth2 client credentials flow with automatic token refresh
    - Server-Sent Events (SSE) for streaming command output
    - Tar-based file upload/download (copy_in/copy_out)
    - Full metrics support (runtime and per-box)
    - Box lifecycle: create, start, stop, remove
    - Command execution with exit codes and streams
    
    **Updated `sdks/python/src/`:**
    - `runtime.rs`: Added `Boxlite.rest()` static method
    - `options.rs`: Added `PyRestOptions` with `from_env()`
    - `lib.rs`: Exported RestOptions to Python
    
    **Python API:**
    ```python
    from boxlite import Boxlite, RestOptions
    
    opts = RestOptions(url="http://localhost:8080",
                       client_id="...", client_secret="...")
    rt = Boxlite.rest(opts)
    
    opts = RestOptions.from_env()
    rt = Boxlite.rest(opts)
    ```
    
    **`openapi/reference-server/server.py`:**
    - FastAPI implementation of OpenAPI spec
    - OAuth2 token endpoint (test credentials)
    - 22 of 24 endpoints implemented
    - SSE streaming for command output
    - Tar-based file transfer
    
    **Prerequisites:**
    ```bash
    make dev:python
    cd openapi/reference-server
    uv run --active server.py --port 8080
    ```
    
    **New `examples/python/08_rest_api/`:**
    - `connect_and_list.py`: Basic connection, auth, list boxes
    - `manage_boxes.py`: CRUD operations
    - `run_commands.py`: Command execution, streaming
    - `copy_files.py`: File upload with copy_in()
    - `monitor_metrics.py`: Runtime and box metrics
    - `configure_boxes.py`: Custom CPU, memory, env vars
    - `use_env_config.py`: Environment-based config
    
    All examples tested and passing.
    
    **`boxlite/tests/rest_integration.rs`:**
    - 9 test cases covering all REST operations
    - Gated with `#[cfg(feature = "rest")]`
    - All tests `#[ignore]` (require running server)
    - Verified against reference server
    
    - Moved from `boxlite/openapi/` to `openapi/rest-sandbox-open-api.yaml`
    - Centralized location for spec and reference server
    
    - Updated C and Node.js SDKs to use new RuntimeBackend
    - Added ImageInfo fields for REST compatibility
    - Updated CLI pull command to use new ImageInfo API
    
    * refactor(python)!: rename RestOptions to BoxliteRestOptions
    
    BREAKING CHANGE: Python's RestOptions is now BoxliteRestOptions to
    match the Rust implementation and follow consistent naming conventions.
    
    Why:
    - Rust uses BoxliteRestOptions, Python exposed RestOptions (inconsistent)
    - RestOptions is too generic and may cause namespace collisions
    - Follows project pattern: runtime-level configs use Boxlite*Options prefix
    - Exception: Options (primary config) remains as-is (justified singleton)
    
    Impact:
    - Affects all REST API examples (7 files)
    - Clean failure mode: ImportError for old name (type-safe)
    - Low risk: REST API just landed, no production users yet
    
    Migration:
    ```python
    # Before (v0.4.4)
    from boxlite import RestOptions
    opts = RestOptions(url="http://localhost:8080")
    
    # After (v0.5.0)
    from boxlite import BoxliteRestOptions
    opts = BoxliteRestOptions(url="http://localhost:8080")
    ```
    
    Changed:
    - Core SDK (3 files):
      - sdks/python/src/options.rs - pyclass name, docstrings, __repr__
      - sdks/python/boxlite/__init__.py - import and export names
      - sdks/python/src/runtime.rs - docstring examples
    - Examples (7 files):
      - All files in examples/python/08_rest_api/ - imports and constructors
    - Documentation (1 file):
      - examples/python/08_rest_api/README.md - description
    
    Verification:
    ✓ make dev:python builds successfully
    ✓ from boxlite import BoxliteRestOptions works
    ✓ from boxlite import RestOptions raises ImportError
    ✓ All examples tested and passing
    ✓ Docstrings show BoxliteRestOptions
    
    * fix(ci): resolve clippy warnings and apply formatting
    
    - Fix collapsible_if in rest/runtime.rs (use && for nested if-let)
    - Fix redundant_closure in rest/types.rs (use BoxID::new directly)
    - Apply cargo fmt to all REST API code
    
    These fixes resolve CI failures caused by clippy warnings.
    
    Files changed: 10 files (REST API and Python SDK)
    
    * fix(clippy): use unwrap_or_default for BoxID
    
    Replace .unwrap_or_else(BoxID::new) with .unwrap_or_default() in
    boxlite/src/rest/types.rs:140.
    
    This is more idiomatic Rust since BoxID implements Default trait.
    The behavior is functionally equivalent as Default::default() delegates
    to Self::new().
    
    Resolves clippy::unwrap_or_default warning.
    
    * refactor: separate image operations into ImageHandle
    
    Separates image operations from RuntimeBackend into a dedicated ImageHandle
    abstraction, following the same pattern as LiteBox for box operations.
    
    Changes:
    - Created ImageManager trait and ImageHandle struct for image operations
    - LocalRuntime implements ImageManager (pull_image, list_images)
    - REST runtime returns None for image_manager (unsupported)
    - BoxliteRuntime.images() returns ImageHandle or error
    - Removed image methods from RuntimeBackend trait
    - Updated CLI commands to use runtime.images().pull() pattern
    - Removed REST image types and endpoints from reference server
    - Exported ImageHandle in lib.rs
    
    Benefits:
    - Consistent API pattern (runtime → handle → operations)
    - Type-safe: REST runtime can't expose unsupported operations
    - Clean separation: images are separate domain from runtime management
    - Extensible: easy to add more image operations to handle
    
    Refs: Plan at ~/.claude/plans/immutable-napping-blum.md
    
    * fix(images): restore ImageObject as ImageHandle::pull() return type
    
    During the ImageHandle refactoring, we incorrectly changed the return
    type from ImageObject to ImageInfo, breaking the CLI's method-based API.
    
    Changes:
    - ImageHandle::pull() now returns ImageObject (handle with methods)
    - ImageHandle::list() still returns Vec<ImageInfo> (display metadata)
    - CLI pull command restored to use methods: config_digest(), reference(), layer_count()
    - Removed unnecessary to_info() conversion in LocalRuntime
    
    This restores the correct abstraction:
    - Pull → ImageObject (working handle)
    - List → Vec<ImageInfo> (display data)
    
    * refactor(images): remove unused ImageObject methods
    
    Removed two unused methods from ImageObject:
    - manifest_digest(): Never used, already marked #[allow(dead_code)]
    - to_info(): Added during REST API implementation when RuntimeBackend
      returned ImageInfo, but no longer needed after separating image
      operations into ImageManager trait
    
    These methods were leftovers from the REST API refactoring and serve
    no current purpose. Removing them follows YAGNI principle and keeps
    the codebase clean.
    
    Verified with:
    - git grep '\.to_info\(\)|\.manifest_digest\(\)' → no results
    - cargo build && cargo clippy → no errors
    
    * fix(c-sdk): correct ffi.rs to use boxlite-ffi thin wrapper
    
    During rebase, ffi.rs was incorrectly resolved to keep the old full
    implementation (1560 lines) instead of the new thin wrapper (504 lines)
    that imports from boxlite-ffi crate.
    
    This commit corrects the resolution by adopting main's refactored
    structure:
    - ffi.rs is now a thin wrapper (504 lines)
    - Imports types from boxlite-ffi (error, runtime, runner modules)
    - Creates C-compatible type aliases
    - Delegates all operations to boxlite_ffi::ops::*
    
    Additionally fixes boxlite-ffi/src/ops.rs to handle Result return type
    from runtime.metrics() method.
    
    No functionality is lost - all code is in boxlite-ffi crate.
    
    * refactor(python): rename PyRestOptions to PyBoxliteRestOptions
    
    Aligns Rust internal type name with the exported Python class name
    (BoxliteRestOptions) for better consistency and maintainability.
    
    This follows the established naming convention where Rust types reflect
    their Python exports:
    - PyBoxOptions → BoxOptions
    - PyCopyOptions → CopyOptions
    - PyBoxlite → Boxlite
    - PyBoxliteRestOptions → BoxliteRestOptions (now consistent)
    
    Changes:
    - sdks/python/src/options.rs: Renamed struct and implementations
    - sdks/python/src/runtime.rs: Updated import and method parameter
    - sdks/python/src/lib.rs: Updated import and module export
    
    No changes to Python API - BoxliteRestOptions remains the same for users.
    
    * style: apply rustfmt to Python SDK imports
    
    Reorder imports alphabetically per Rust style guidelines.
    DorianZheng authored Feb 14, 2026
    Configuration menu
    Copy the full SHA
    b6fb94f View commit details
    Browse the repository at this point in the history
  4. docs: bump minimum SDK versions for Rust/C/Python/Node (#265)

    * docs: bump minimum SDK versions for Rust/C/Python/Node
    
    * docs: replace sdk release pins with language/toolchain requirements
    
    * feat(security): disable jailer and seccomp by default
    
    * chore(release): bump patch versions
    DorianZheng authored Feb 14, 2026
    Configuration menu
    Copy the full SHA
    56da643 View commit details
    Browse the repository at this point in the history
Loading