Metadata-Version: 2.4
Name: remote-bridge
Version: 0.1.2
Summary: A lightweight bridge for controlling remote notebook kernels like shell sessions.
Author: Jose Garcia Mayen
License: MIT License
        
        Copyright (c) 2026 Jose Garcia Mayen
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Documentation, https://github.com/josegarciamayen/remote-bridge#readme
Project-URL: Issues, https://github.com/josegarciamayen/remote-bridge/issues
Project-URL: Source, https://github.com/josegarciamayen/remote-bridge
Keywords: kaggle,jupyter,machine-learning,remote-execution,notebooks
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Build Tools
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: prompt-toolkit>=3.0.43
Requires-Dist: websockets>=16.1
Requires-Dist: tomli>=2.0; python_version < "3.11"
Requires-Dist: playwright>=1.56
Requires-Dist: kagglehub>=0.3
Dynamic: license-file

# Remote Bridge

[![CI](https://github.com/JoseGarciaMayen/remote-bridge/actions/workflows/ci.yml/badge.svg)](https://github.com/JoseGarciaMayen/remote-bridge/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/remote-bridge.svg)](https://pypi.org/project/remote-bridge/)
[![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](pyproject.toml)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)

For common login, proxy, dependency, and dataset failures, see
[`docs/troubleshooting.md`](docs/troubleshooting.md).
For the trust boundaries around commands, proxy tokens, and local state, see
[`docs/security.md`](docs/security.md).

Remote Bridge is a Kaggle-only command-line client for turning a Kaggle notebook runtime into a
terminal-like development session from your local machine or coding agent.

It uses Kaggle's browser session and native Jupyter protocol. It does not use SSH, third-party
tunnels, or a second remote backend.

## What It Does

- Discover and connect to an already running Kaggle notebook kernel through a browser profile.
- Read Kaggle GPU/TPU quota from the authenticated Kaggle web session.
- Run end-to-end diagnostics before opening a shell.
- Execute Python and shell-like commands through the Jupyter kernel protocol.
- Stream output back to a local interactive shell experience.
- Reuse the same WebSocket while an interactive shell is open.
- Detect the available Kaggle accelerator as GPU, TPU, or none.
- Fail with actionable errors when the browser, proxy, kernel, or notebook is unavailable.

## Quick Demo Flow

Install Remote Bridge once:

```bash
pip install remote-bridge
```

The first `login`, `doctor`, `quota`, `connect`, or `shell` command installs the Playwright
browser automatically when it is missing. The first run needs network access and may download a
large browser binary.

For a new project, use the guided setup:

```bash
remote-bridge setup --notebook owner/notebook
```

It creates the project configuration and prints the login, diagnostic, and shell commands. The
non-interactive `init` command remains available for scripts and agents.

For a project that needs a Kaggle dataset, configure the runtime contract during setup. The
available accelerator is detected automatically:

```bash
remote-bridge setup \
    --notebook owner/notebook \
    --dataset owner/dataset \
    --secret CLEARML_API_HOST \
    --secret CLEARML_WEB_HOST \
    --secret CLEARML_API_ACCESS_KEY \
    --secret CLEARML_API_SECRET_KEY
```

For local development from this repository, use:

```bash
uv sync --dev
```

Build and install the package locally:

```bash
make package
python -m pip install dist/*.whl
```

For a normal installation from PyPI, use:

```bash
python -m pip install remote-bridge
```

Log in once through the persistent browser profile:

```bash
remote-bridge login kaggle
```

Start the Kaggle notebook session in the browser, then run the doctor:

```bash
remote-bridge doctor kaggle owner/notebook
```

Run Python code:

```bash
remote-bridge execute --notebook owner/notebook "print('remote bridge ok')"
```

For a configured project, open the shell-like session:

```bash
remote-bridge shell --notebook owner/notebook
```

Use `--refresh` after changing dependencies or when starting a fresh Kaggle kernel:

```bash
remote-bridge shell --refresh
```

When run from a project containing `remote-bridge.toml`, `shell` prepares the project automatically.
It skips synchronization and dependency installation when the remote project fingerprint is
unchanged. Use `--refresh` to force preparation or `--no-prepare` to open the existing remote
directory directly.

Interactive shell commands stream output as it arrives and do not use an idle timeout by default.
The local editor supports arrow-key navigation, persistent history, Ctrl-C, and multiline pasted
commands. History is stored per project/notebook under `~/.remote-bridge/history/`.

```bash
remote-bridge shell --refresh
remote-bridge history clear
```

When stdin is not a TTY, Remote Bridge automatically uses its plain line-oriented mode so agents
and pipes remain scriptable.

The shell is terminal-like, not a real remote PTY. Interactive programs that require a TTY, such as
`vim`, `top`, and full-screen REPLs, are not supported.

The shell prints `remote-bridge: shell closed` when stdin closes, `exit`/`quit` is entered, or a
local prompt Ctrl-C closes the session. While waiting at the prompt, it also monitors the kernel and
exits visibly if the Kaggle proxy or kernel disappears.

Check quota any time:

```bash
remote-bridge quota kaggle
```

Upload datasets through Kaggle's official dataset API:

```bash
pip install remote-bridge
remote-bridge dataset upload \
    owner/dataset \
    data/processed/feat \
    --version-notes "updated features"
```

The command creates the dataset on the first upload and creates a new version on later uploads.
Authenticate with `KAGGLE_API_TOKEN`, `~/.kaggle/access_token`, or the legacy
`~/.kaggle/kaggle.json` file. Generate credentials from Kaggle account settings; browser login and
API credentials are separate.

Generate the notebook loading code without uploading anything:

```bash
remote-bridge dataset code owner/dataset
```

To load it directly into the connected Kaggle notebook from the local terminal:

```bash
remote-bridge dataset use \
    owner/dataset \
    --notebook "https://www.kaggle.com/code/owner/notebook/edit" \
    --headed \
    --browser-channel chrome \
    --connect-timeout 300
```

This executes `kagglehub.dataset_download()` inside the notebook kernel and prints the remote
dataset path. It does not upload the local project or dataset files through the Jupyter WebSocket.

In a Kaggle notebook, `kagglehub.dataset_download()` attaches the dataset and returns its local
path, which can then be passed to the training script.

## Local Project Training

Use `run` when your code lives locally in your IDE and the compute lives in Kaggle. Remote Bridge
packages the local project directory, syncs it to Kaggle, then runs the script with streaming output:

```bash
remote-bridge run \
  --notebook owner/notebook \
  train_xgb.py
```

By default, the current directory is synced to `/kaggle/working/<local-folder-name>`. The remote
directory is replaced on each run so stale Python files do not affect the next experiment. Common
local-only directories are excluded automatically, including `.git`, `.venv`, `__pycache__`, and
tool caches.

For daily use, initialize project config:

```bash
remote-bridge init \
  --notebook owner/notebook \
  --entrypoint train.py \
  --pull outputs/
```

This creates `remote-bridge.toml` and `.remote-bridgeignore`. You can also write or edit
`remote-bridge.toml` manually:

```toml
notebook = "owner/notebook"
remote_dir = "/kaggle/working/my-project"
entrypoint = "train.py"
install = true
pull = ["outputs/", "metrics.json"]
pull_dir = "remote-bridge"

[runtime]
provider = "kaggle"
dataset = "owner/dataset"
device = "auto"
secrets = ["CLEARML_API_HOST", "CLEARML_API_ACCESS_KEY", "CLEARML_API_SECRET_KEY"]
```

The optional `[runtime]` section is applied before the project command. It exports
`REMOTE_BRIDGE_RUNTIME`, `REMOTE_BRIDGE_DATASET_HANDLE`, `REMOTE_BRIDGE_ACCELERATOR`, and
`PROJECT_DEVICE`; project code can use those variables without adding Kaggle-specific command-line
flags. `PROJECT_DEVICE` is `cuda`, `tpu`, or `cpu`.

This repository includes `remote-bridge.toml.example` and `.remote-bridgeignore.example` as starter
templates. Copy them into a project as `remote-bridge.toml` and `.remote-bridgeignore`, then edit the
notebook, entrypoint, ignored paths, and pull artifacts. `data/`, `datasets/`, `dataset/`, and
`mlartifacts/` are excluded from project synchronization by default; upload datasets through
Kaggle's dataset API.

Then run from the project directory:

```bash
remote-bridge doctor project
remote-bridge run
```

To prepare the Kaggle runtime without starting training, use `prepare`. It syncs the project and
installs dependencies, then leaves the kernel ready for an interactive shell:

```bash
remote-bridge prepare
remote-bridge shell
```

From that shell, run any command in the synced project directory:

```text
cd /kaggle/working/my-project
python -u train.py
python -u evaluate.py
```

The complete manual workflow is therefore: upload or update datasets with `dataset upload`, run
`prepare`, open `shell`, and launch whichever training or evaluation script you need. `prepare`
does not run the configured entrypoint and does not pull artifacts automatically.

`install = true` installs `requirements-kaggle.txt` first when present, then `requirements.txt`,
otherwise installs the project with `pip install -e .` when `pyproject.toml` exists. After a
successful run, configured `pull` paths are
downloaded into `remote-bridge/` by default. Set `pull_dir` to change that directory.

Use `.remote-bridgeignore` for project-specific sync exclusions:

```text
data/raw/
outputs/
*.pt
wandb/
mlruns/
```

Pass script arguments after `--`, or override config values with CLI flags:

```bash
remote-bridge run \
  train_xgb.py \
  -- \
  --learning-rate 0.05
```

Download remote artifacts manually with `pull`:

```bash
remote-bridge pull outputs/ metrics.json
```

Use `--output-dir` to override the pull destination for one command:

```bash
remote-bridge pull --output-dir artifacts outputs/ metrics.json
```

## Agent Workflow

Remote Bridge is designed to be usable by coding agents as well as humans. A project can expose the
remote execution contract in files an agent can inspect:

- `remote-bridge.toml`: notebook, remote directory, entrypoint, dependency install mode, artifacts.
- `.remote-bridgeignore`: large local files and generated outputs that should not be synced.
- `requirements.txt` or `pyproject.toml`: dependencies installed when `install = true`.

With those files present, an agent can run the current project on Kaggle without knowing the notebook
URL or paste commands into a browser:

```bash
remote-bridge doctor project
remote-bridge run
remote-bridge pull outputs/
```

See `AGENTS.md` for the short agent-facing contract.

## Browser-Based Kaggle Connector

Remote Bridge discovers the Kaggle proxy URL with a local browser profile. Browser support is
included in the standard installation:

```bash
uv sync --dev
```

The first browser-backed command installs the configured Playwright browser automatically.

The default browser profile lives outside the repository at:

```text
~/.remote-bridge/browser-profile
```

Open the login flow once. Remote Bridge does not collect Kaggle credentials; it only keeps the
browser profile alive while you sign in normally:

```bash
remote-bridge login kaggle
```

If Google sign-in says the browser is unsupported because it is controlled by automation, use a
Kaggle email/password login in that window.

After login, discover the notebook proxy:

```bash
remote-bridge connect kaggle owner/notebook --headed
```

The discovered proxy URL is cached per notebook in `~/.remote-bridge/state.json` so subsequent
commands do not reopen the browser. `prepare`, `run`, `execute`, and `shell` reuse that URL. If the
cached connection fails, Remote Bridge removes it, discovers a fresh URL, and retries once. The
state file contains a token-bearing URL and is created with private permissions; keep it local.

The notebook used with `--notebook` also becomes the cached default. Once selected, you can open a
shell without repeating it:

```bash
remote-bridge shell --cwd /kaggle/working/my-project
```

Pass another `--notebook` URL on any command to switch the cached default.

After changing the Kaggle session while keeping the same notebook, force a fresh proxy lookup:

```bash
remote-bridge shell \
    --refresh-proxy \
    --cwd /kaggle/working/my-project
```

By default this prints only a redacted proxy URL. To print the full token-bearing proxy URL, opt in:

```bash
remote-bridge connect kaggle owner/notebook --headed --print-proxy-url
```

After the profile is logged in, commands can connect from the notebook URL or slug directly:

```bash
remote-bridge execute --notebook owner/notebook "print(1)"
remote-bridge shell --notebook owner/notebook
```

## Manual Proxy Workflow

You can still pass a Kaggle/Jupyter proxy URL manually. Keep this URL private because it can include
bearer-like path tokens.

Set it once for your shell:

```bash
export REMOTE_BRIDGE_PROXY_URL='https://.../proxy'
```

Run commands against that proxy:

```bash
remote-bridge execute "print(1)"
remote-bridge shell-command "ls -la"
remote-bridge shell
```

`execute`, `doctor`, and checkpoint operations default to a 60 second idle timeout. Interactive
`shell` and one-shot `shell-command` default to no idle timeout, so long training scripts can stay
quiet without Remote Bridge closing them. Use `--idle-timeout` to set an explicit limit, or
`--idle-timeout 0` to disable it:

```bash
remote-bridge shell --idle-timeout 300
remote-bridge execute --idle-timeout 0 "print(1)"
```

Quota reads use the authenticated browser profile and summarize Kaggle's accelerator quota response:

```bash
remote-bridge quota kaggle
```

Use JSON output when debugging the raw Kaggle response:

```bash
remote-bridge quota kaggle --json
```

If no quota response is found, run headed to confirm the selected profile is logged in and can open
Kaggle settings:

```bash
remote-bridge quota kaggle --headed
```

If Kaggle changes the proxy path format, re-run with `--headed` and watch whether the notebook
actually starts a running session.

Remote Bridge does not create notebooks implicitly. If the logged-in account cannot access the
notebook URL, `connect`, `shell`, and other notebook-backed commands fail with a clear access error.
Log in with the owner account, or create/fork the notebook in that account and pass that URL.

## Doctor

Run an end-to-end Kaggle diagnostic before a real session:

```bash
remote-bridge doctor kaggle owner/notebook
```

The doctor checks quota, notebook proxy discovery, kernel status, `print(1)`, and the remote current
directory. It fails at the first broken step with the same error text used by the underlying command.

## Kernel Control

The control commands use the same runtime options as `shell` and `execute`:

```bash
remote-bridge status --notebook owner/notebook
remote-bridge interrupt --notebook owner/notebook
remote-bridge restart --notebook owner/notebook
```

Inside `remote-bridge shell`, pressing `Ctrl-C` sends a Jupyter kernel interrupt and keeps the
local shell session open.

## Checkpoints

Checkpoints are remote tar archives stored under:

```text
/kaggle/working/.remote-bridge/checkpoints/
```

Remote Bridge tracks checkpoint metadata locally in:

```text
~/.remote-bridge/state.json
```

Create a checkpoint:

```bash
remote-bridge checkpoint create \
  --paths project data \
  --notebook owner/notebook
```

List locally tracked checkpoints:

```bash
remote-bridge checkpoint list
```

Restore a checkpoint:

```bash
remote-bridge checkpoint restore checkpoint-20260716T123000Z \
  --notebook owner/notebook
```

## Managed Shell

Managed mode tracks local elapsed time for a Kaggle session. By default it warns at 8 hours and, at
8 hours 45 minutes, creates a checkpoint, reconnects through the browser connector, restores the
checkpoint, and keeps the shell running. This is local lifecycle tracking, not Kaggle quota
automation; users remain responsible for choosing when to stop or restart.

```bash
remote-bridge shell \
  --managed \
  --notebook owner/notebook \
  --managed-paths .
```

For a fast simulated lifecycle test, lower the thresholds:

```bash
remote-bridge shell \
  --managed \
  --notebook owner/notebook \
  --managed-warning-after 30s \
  --managed-critical-after 60s \
  --managed-check-interval 5s \
  --managed-paths test
```

Managed warnings are emitted by a background timer while a long command is running. Critical
recovery is deferred until the next shell prompt so Remote Bridge does not run checkpoint code
concurrently with the active command on the same kernel WebSocket.

## Manual Smoke Tests

Before using a notebook for real work, run these checks:

```bash
remote-bridge doctor kaggle owner/notebook
remote-bridge execute --notebook owner/notebook "print(1)"
remote-bridge shell-command --notebook owner/notebook "echo ready"
remote-bridge shell-command --notebook owner/notebook "ls -la"
remote-bridge shell-command --notebook owner/notebook "python - <<'PY'
for i in range(1000):
    print(i)
PY"
remote-bridge shell-command --notebook owner/notebook "nvidia-smi"
```

Expected behavior:

- `print(1)` and `echo ready` return output immediately.
- `ls -la` lists the remote `/kaggle/working` directory.
- Long output streams incrementally instead of appearing only at the end.
- `nvidia-smi` either prints GPU status or reports that the command is unavailable.
- The interactive shell keeps its current directory after successful `cd` commands and stays open
  after command failures.
- A long-running command can be interrupted with `Ctrl-C`, then the shell accepts the next command.

## Out of Scope for the First Milestone

- Multi-backend orchestration.
- Mobile client UI.
- Paid resource shutdown automation.
- SSH-based access.
- Real PTY behavior and fully interactive child processes such as `vim` or `top`.

## Development

Install development dependencies:

```bash
uv sync --dev
```

Run the full local check:

```bash
make ci
```
