Skip to content

bug: openshell sandbox upload <local-dir> <remote-dir> flattens contents instead of creating named subdirectory #885

@mjamiv

Description

@mjamiv

Agent Diagnostic

  • Loaded openshell-cli skill and walked the sandbox upload command path in crates/openshell-cli/.
  • When <local> is a directory, the CLI walks the directory and uploads each entry into <remote> directly. The local directory's name is dropped from the destination path.
  • Confirmed by the minimal repro below. Behavior diverges from the standard scp -r and cp -r semantics operators expect from any *nix-style file-transfer tool.
  • Agent identified the workaround: tar -czf foo.tgz -C parent foo && openshell sandbox upload <name> foo.tgz /tmp/ && ssh ... 'tar -xzf /tmp/foo.tgz -C <remote>/'. The tarball preserves the source-directory prefix deterministically.

Description

openshell sandbox upload <local-dir> <remote-dir> flattens the local directory's contents into the remote destination instead of creating a subdirectory named after the local directory.

In our case this caused a real near-miss: a directory of content was uploaded into a sibling location alongside existing files at the destination. No data was lost (all uploaded files were new and didn't collide), but the recovery path required a full diff against backups to confirm. A future variant of the same operation could silently shadow files at the destination with no warning.

Reproduction Steps

  1. Create a local directory with content:
    mkdir -p /tmp/upload-test/sub
    echo a > /tmp/upload-test/a.txt
    echo b > /tmp/upload-test/sub/b.txt
    
  2. Upload it: openshell sandbox upload <name> /tmp/upload-test /sandbox/dest/
  3. SSH in and inspect: ssh <sandbox> 'ls /sandbox/dest/'
  4. Observed: a.txt sub/ — the upload-test/ prefix is gone; contents are flat in /sandbox/dest/.
  5. Expected: upload-test/ containing a.txt and sub/b.txt, mirroring scp -r ./upload-test <remote>:/sandbox/dest/.

Environment

  • OpenShell: v0.0.31 host CLI, v0.0.31 supervisor
  • OS: Ubuntu 24.04 LTS
  • Docker: 27.x
  • Cluster image: ghcr.io/nvidia/openshell/cluster:0.0.16

Proposed direction

Two options:

  1. Match scp -r / cp -r semantics — preserve the source directory's basename as a subdirectory of the destination. Principle-of-least-surprise fix; aligns with every comparable file-transfer tool.
  2. Keep current flatten behavior, add a --preserve-dir flag for the standard semantics, plus a CLI help update calling out the divergence loudly.

I prefer (1). The current behavior is a quiet footgun for any operator with prior file-transfer experience. Cost is one breaking-change note in the release. Happy to convert this to a PR if a maintainer signals direction.

Agent-First Checklist

  • I pointed my agent at the repo and had it investigate this issue
  • I loaded relevant skills (openshell-cli)
  • My agent could not resolve this — the diagnostic above explains the root cause; resolution needs an upstream code change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    state:triage-neededOpened without agent diagnostics and needs triage

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions