# Shifft

Code on the go — control AI coding agents from your phone, browser, or terminal.

Free. Open source. Code anywhere.

## Installation

```bash
npm install -g shifft
```

> Migrated from the `happy-coder` package. Thanks to [@franciscop](https://github.com/franciscop) for donating the `shifft` package name!

## Usage

### Claude Code (default)

```bash
shifft
# or
shifft claude
```

This will:
1. Start a Claude Code session
2. Display a QR code to connect from your mobile device or browser
3. Allow real-time session control — all communication is end-to-end encrypted
4. Start new sessions directly from your phone or web while your computer is online

### More agents

```
shifft codex
shifft gemini
shifft openclaw

# or any ACP-compatible CLI
shifft acp opencode
shifft acp -- custom-agent --flag
```

## Daemon

The daemon is a background service that stays running on your machine. It lets you spawn and manage coding sessions remotely — from your phone or the web app — without needing an open terminal.

```bash
shifft daemon start
shifft daemon stop
shifft daemon status
shifft daemon list
```

The daemon starts automatically when you run `shifft`, so you usually don't need to manage it manually.

### Keeping the daemon running across reboots

If you want the daemon to come back automatically after a reboot — without opening a `shifft` session first — start it from your shell profile so it inherits your normal user session context (PATH, keychain access, OAuth credentials):

```bash
# ~/.zshrc or ~/.bashrc
if [[ -o interactive ]] && [[ -z "$SHIFFT_DAEMON_CHECKED" ]]; then
    export SHIFFT_DAEMON_CHECKED=1
    () {
        local state=$HOME/.shifft/daemon.state.json
        local pid=$(grep -oE '"pid"[[:space:]]*:[[:space:]]*[0-9]+' "$state" 2>/dev/null | grep -oE '[0-9]+')
        if [[ -z "$pid" ]] || ! kill -0 "$pid" 2>/dev/null; then
            shifft daemon start >/dev/null 2>&1
        fi
    } &!
fi
```

The first interactive shell after a reboot triggers the start; subsequent shells short-circuit because the daemon is already running.

> **macOS users:** prefer this shell-init approach over a `launchd` LaunchAgent. A LaunchAgent runs in an agent domain that is **detached from your GUI/Aqua login session**, which means the bundled `claude-agent-sdk` cannot reach the macOS keychain and silently fails authentication ("Failed to authenticate. API Error: 401 terminated", `duration_api_ms: 0`). If you must use launchd, your wrapper has to read the OAuth access token from `~/.claude/.credentials.json` and export it as `CLAUDE_CODE_OAUTH_TOKEN` before exec'ing the daemon — and you'll need to handle token rotation yourself.

## Authentication

```bash
shifft auth login
shifft auth logout
```

Shifft uses cryptographic key pairs for authentication — your private key stays on your machine. All session data is end-to-end encrypted before leaving your device.

To connect third-party agent APIs:

```bash
shifft connect gemini
shifft connect claude
shifft connect codex
shifft connect status
```

## Commands

| Command | Description |
|---------|-------------|
| `shifft` | Start Claude Code session (default) |
| `shifft codex` | Start Codex mode |
| `shifft gemini` | Start Gemini CLI session |
| `shifft openclaw` | Start OpenClaw session |
| `shifft acp` | Start any ACP-compatible agent |
| `shifft resume <id>` | Resume a previous session |
| `shifft notify` | Send push notification to your devices |
| `shifft doctor` | Diagnostics & troubleshooting |

---

## Advanced

### Environment Variables

| Variable | Description |
|----------|-------------|
| `SHIFFT_SERVER_URL` | Custom server URL (default: `http://localhost:3005`) |
| `SHIFFT_WEBAPP_URL` | Custom web app URL (default: `https://app.shifft.app`) |
| `SHIFFT_HOME_DIR` | Custom home directory for Shifft data (default: `~/.shifft`) |
| `SHIFFT_DISABLE_CAFFEINATE` | Disable macOS sleep prevention |
| `SHIFFT_EXPERIMENTAL` | Enable experimental features |

### Sandbox (experimental)

Shifft can run agents inside an OS-level sandbox to restrict file system and network access.

```bash
shifft sandbox configure
shifft sandbox status
shifft sandbox disable
```

### Building from source

```bash
git clone https://github.com/Saif-09/shifft
cd shifft-cli
yarn install
yarn workspace shifft cli --help
```

## Requirements

- Node.js >= 20.0.0
- For Claude: `claude` CLI installed & logged in
- For Codex: `codex` CLI installed & logged in
- For Gemini: `npm install -g @google/gemini-cli` + `shifft connect gemini`

## License

MIT
