# svamp-cli

AI workspace daemon and CLI for [Hypha Cloud](https://hypha.aicell.io). Run AI agents locally with cloud sync, manage sessions, share with teammates, and orchestrate tasks.

**Svamp** (Swedish for "mushroom") is the interactive layer of Hypha Cloud — where teams and AI agents collaborate in real time.

## Installation

```bash
npm install -g svamp-cli
```

Requires **Node.js >= 22** (for native WebSocket support).

## Quick Start

```bash
# Login to Hypha Cloud
svamp login

# Start interactive Claude session (synced to web app)
svamp

# Or start the daemon for background sessions
svamp daemon start

# Spawn a session
svamp session spawn claude -d ~/my-project

# Send a message
svamp session send <session-id> "Fix the failing tests"
```

## Configuration

Credentials are stored in `~/.svamp/.env`:

```
HYPHA_SERVER_URL=https://hypha.aicell.io
HYPHA_TOKEN=<your-token>
HYPHA_WORKSPACE=<your-workspace>
```

## Commands

### Interactive Mode

```bash
svamp                              # Start Claude in terminal with cloud sync
svamp start [-d <path>]            # Same, with explicit directory
```

When you run `svamp` with no arguments, Claude starts in your terminal with full interactive access. Your session is synced to Hypha Cloud and visible in the web app. When a message arrives from the web app, svamp switches to remote mode automatically. Press Space-Space to return to local mode.

### Login

```bash
svamp login [server-url]           # Login via browser OAuth
```

### Daemon Management

```bash
svamp daemon start                 # Start daemon (detached)
svamp daemon stop                  # Stop (sessions preserved for auto-restore)
svamp daemon stop --cleanup        # Stop and mark all sessions as stopped
svamp daemon restart               # Restart seamlessly
svamp daemon status                # Show daemon status
svamp daemon install               # Install as system service (launchd/systemd)
svamp daemon uninstall             # Remove system service
```

### Session Management

All session commands support `--machine <id>` / `-m <id>` to target a specific machine.

```bash
svamp session list [--active] [--json]
svamp session machines                         # List discoverable machines
svamp session spawn <agent> [-d <path>] [--message <msg>] [--wait]
svamp session archive <id>                     # Stop + archive a session
svamp session info <id> [--json]
svamp session send <id> <message> [--wait] [--timeout N]
svamp session wait <id> [--timeout N]
svamp session messages <id> [--last N] [--json]
svamp session attach <id>                      # Interactive terminal attach
svamp session approve <id>                     # Approve pending permission
svamp session deny <id>                        # Deny pending permission
```

#### Session Sharing

```bash
svamp session share <id> --list
svamp session share <id> --add <email>             # Added users get FULL (owner-equivalent) access
svamp session share <id> --remove <email>
```

#### Isolation & Security Flags (on spawn)

```bash
svamp session spawn claude -d <path> --isolate
svamp session spawn claude -d <path> --share alice@example.com
svamp session spawn claude -d <path> --security-context ./context.json
svamp session spawn claude -d <path> --deny-network
svamp session spawn claude -d <path> --deny-read /etc --allow-write /tmp/work
svamp session spawn claude -d <path> --allow-domain api.anthropic.com
```

> **⚠ Not all of these are enforced (#0878).** `--deny-read` is accepted but enforced by **no** sandbox
> backend; `--allow-write` and `--allow-domain` are **not enforced** under the docker/podman isolation
> backends. Do not rely on them as containment. To actually restrict what a session can read, narrow
> `allowedDirectories` in a `--security-context` file. See
> [`docs/sharing-and-security.md`](../../docs/sharing-and-security.md) for the full
> enforced-vs-advisory table (kept there, not duplicated here, so the two cannot drift).

#### Loop (Self-Verifying Iterative Automation)

```bash
svamp session loop <id> "<task>" --until "<completion criteria>" [--max N]
svamp session loop-cancel <id>
svamp session loop-status <id>
svamp session loop-extend <id> --reason "<why>"    # raise the soft iteration cap
```

The loop iterates a task until it's *objectively* done. The engine is Claude Code's **native `/goal`**
command: svamp composes a completion condition (your task + `--until` + an optional oracle command +
a turn cap) and arms `/goal` on the session; Claude's own session-scoped `Stop` hook then keeps the
agent working until a fresh, independent evaluator confirms the condition holds. Loop status is
mirrored to `.svamp/<session-id>/loop/loop-state.json` (`engine: 'goal'`) for the UI and the CLI.

An issue-backlog loop (oracle = `svamp issue pending`) is **durable**: when the backlog empties it goes
`dormant` — armed and watching, driving zero turns — and re-arms when an issue is added or reopened.

> Historical: an earlier custom engine used a `stop-gate.mjs` hook, an evaluator subagent and a
> git-visible `LOOP.md`, shipped as a `loop` skill. That engine was **retired** — `/goal` is the sole
> engine, `skills/loop/` was deleted, and the daemon now strips those leftover hooks on spawn. The
> `loop-start` / `--criteria` / `--evaluator` spellings survive only as aliases.

**Claude only** — `/goal` is a Claude Code feature, so ACP agents (Gemini, Kimi) kick a loop off but
do not self-verify.

### Machine Management

```bash
svamp machine share --list
svamp machine share --add <email>[:<role>]
svamp machine share --remove <email>
svamp machine share --config <path>            # Apply security context config
svamp machine share --show-config
```

### Skills Marketplace

```bash
svamp skills find <query> [--json]             # Search marketplace
svamp skills install <name> [--force]          # Install to ~/.claude/skills/<name>/
svamp skills list                              # List installed skills
svamp skills remove <name>                     # Remove skill
svamp skills publish <path>                    # Publish to marketplace
```

### Service Exposure (Cloud HTTP Services)

Expose HTTP services from cloud sandboxes or local machines to stable external URLs via frpc tunnels.

```bash
svamp service expose <name> --port <port>      # Expose local port via frpc
svamp service expose <name> --port <port> --group <g> --group-key <key>
                                               # Multi-machine load balancing
svamp service serve <name> [dir]               # Static-files tunnel
svamp service list                             # List active tunnels (with status)
svamp service delete <name>                    # Stop tunnel
```

For dynamic apps the daemon should supervise across restarts (with optional
wake-on-request and idle-stop), prefer `svamp serve apply <yaml>` with a
`process` block — see [`docs/service-exposure.md`](../../docs/service-exposure.md).

The legacy `service create / add-backend / remove-backend / add-port /
tunnel` subcommands were removed in favor of the declarative
`service expose --group …` model.

### Local Agent Sessions

```bash
svamp agent list                               # List known agents (ACP + MCP)
svamp agent <name>                             # Start local agent session (gemini, codex)
svamp agent -- <cmd> [args]                    # Start custom ACP agent
```

## Agent Backends

| Agent | Protocol | Transport |
|-------|----------|-----------|
| Claude | Native | CLI subprocess |
| Codex | MCP | STDIO (`codex mcp-server`) |
| Gemini | ACP | STDIO (`gemini --experimental-acp`) |

## Security & Isolation

Sessions can be isolated using OS-level sandboxes:

| Method | Platform | Description |
|--------|----------|-------------|
| nono | macOS/Linux | Kernel-enforced capability sandbox (preferred) |
| Docker | Any | Container-based isolation |
| Podman | Any | Rootless container fallback |

Security contexts define per-user filesystem and network rules. See `--security-context` flag.

## Development

```bash
yarn install
yarn workspace svamp-cli build
yarn workspace svamp-cli test          # Run unit tests (235+ tests)
yarn workspace svamp-cli test:e2e      # Run E2E session tests
yarn workspace svamp-cli test:hypha    # Run Hypha service integration tests
```

## License

See LICENSE in the repository root.
