Skip to content

Latest commit

 

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

expri

expri is a repo-local remote workflow tool. The first implemented command is sync, which makes a remote working tree match local HEAD plus dirty and untracked local files.

Sync

Top-level commands are controller-side commands: they run from your workstation and operate on a configured target. expri node ... is the target-machine namespace for commands that run locally on a synced node.

Create an expri.toml in the repo you want to sync, and keep machine targets in a sibling target file. The target filename follows the config filename: expri.toml uses expri.target.toml, and cs336.toml uses cs336.target.toml. Target files are local/private; add them to that repo's .gitignore.

# expri.toml
[project]
name = "my-project"

[sync]
remote_managed = ["uv.lock"]

[download.mappings]
wandb = "wandb"

[tasks]
dev = ["pnpm", "dev"]
train = { command = ["python", "scripts/train.py"], uv = true }
# expri.target.toml
[target.runpod]
host = "user@example.com"
remote_dir = "~/my-project"
protocol = "auto"
node_bin = "expri"

Then run:

expri -T runpod sync --config cs336-assignment5-alignment/expri.toml

See examples/cs336.toml for a CS336-shaped starting point.

Targets default to protocol = "auto", which tries expri node sync-apply first and falls back to the SSH protocol. Set protocol = "expri-node" to require the node binary, or protocol = "ssh" for the fallback path.

Task

expri run <name> runs a repo-local command alias in the repo root:

[tasks]
dev = ["pnpm", "dev"]
train = { command = ["python", "scripts/train.py"], uv = true }

The array form runs exactly that command. The object form supports options; uv = true prefixes the command with uv run.

expri run dev
expri run train --epochs 3
expri -T runpod run train --epochs 3
expri -T runpod run --no-sync train --epochs 3

When -T/--target is provided, run syncs the repo to the target before executing the task there. Pass --no-sync before the task name to skip that sync. Run options must appear before the task name; arguments after the task name are passed through to the task.

Setup

expri -T <target> setup runs repo-configured setup steps on the target. Built-in steps are uv, hf, and script; scripts are resolved relative to the remote repo root.

or from inside that repo:

expri -T runpod sync

The sync algorithm uploads committed history with a git bundle, checks out HEAD on the remote, then overlays a zip archive of local dirty and untracked files. Remote tool state lives under .expri/.

Use sync.remote_managed for repo-relative files that the target should own, even if they are tracked by Git or appear in the dirty patch. For example, remote_managed = ["uv.lock"] preserves the target's lockfile across syncs and excludes local changes to that file from patch.zip.

For a path-scoped rsync, pass paths after --. Only files returned by git ls-files under those paths are transferred:

expri -T runpod sync -- src scripts
expri -T runpod sync --pull -- outputs/checkpoints

Download

expri -T <target> download downloads configured result mappings into results/<target>/. Mappings are declared in expri.toml:

[download]
ignore = ["*.pt"]

[download.mappings]
wandb = "wandb"
jobs = "out/jobs"

That example downloads the remote repo's wandb/ directory into results/<target>/wandb/, and out/jobs/ into results/<target>/jobs/. Ignore patterns are passed to rsync as excludes relative to each mapping root. Pass mapping names after -- to download a subset:

expri -T runpod download -- wandb

Use --dry-run to print the SSH/rsync commands without executing them.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages