<!--
hoody-pipe Subskill (http)
Auto-generated by Hoody Skills Generator
Generated: 2026-06-20T00:40:52.619Z
Model: mimo-v2.5-pro + fixer:z-ai/glm-5.1
Mode: http


Tokens: 4641

DO NOT EDIT MANUALLY - Changes will be overwritten on next generation
-->

# hoody-pipe Subskill

## Overview

**Hoody Pipe** is a real-time data relay service within the Hoody Kit ecosystem. It enables streaming data between sender and receiver without server-side storage — data flows directly from producer to consumer over HTTP.

### When to Use Hoody Pipe

- **File transfers** between machines (replace `scp` or `ftp`)
- **Streaming logs** from one process to another
- **One-shot data delivery** — send a file to a colleague via a shared path
- **CI/CD artifact passing** between pipeline stages
- **Quick text snippets** pasted from browser to terminal (or vice versa)
- **Cross-environment data relay** where peers cannot directly connect

### How It Fits Hoody Philosophy

Hoody Pipe embodies the Hoody principle of **ephemeral, zero-storage relaying**. No data persists on the server. The sender blocks until a receiver connects, then data streams directly through. This ensures privacy (nothing is stored) and simplicity (no accounts, no cleanup).

Pipe supports **browser-based uploads** via its built-in HTML interface, making it accessible to non-technical users. For developers, `curl` workflows are first-class.

### Key Characteristics

| Property | Behavior |
|---|---|
| Storage | None — data streams in transit only |
| Sender blocking | Sender waits until receiver connects |
| Receiver blocking | Receiver waits until sender connects |
| Authentication | Via Hoody proxy (inherited from container auth) |
| Protocol | HTTP/1.1 streaming, chunked transfer encoding |
| Max timeout | Recommended `` for large transfers |

---

## Common Workflows

### Workflow 1: Send and Receive a File Between Two Terminals

This is the most common pattern — terminal A sends, terminal B receives.

**Terminal A — Sender:**

```
curl -s -X POST \
  "https://{projectId}-{containerId}-pipe-{serviceId}.{node}.containers.hoody.com/api/v1/pipe/my-transfer" \
  --data-binary @myfile.txt
```

The sender blocks. It will not return until a receiver connects.

**Terminal B — Receiver:**

```
curl -s \
  "https://{projectId}-{containerId}-pipe-{serviceId}.{node}.containers.hoody.com/api/v1/pipe/my-transfer" \
  -o received.txt
```

Once the receiver connects, data streams from sender to receiver. Both requests complete.

**Verification:**

```
diff myfile.txt received.txt
# No output = files are identical
```

### Workflow 2: Send a File Using PUT (curl -T shorthand)

PUT is an alias for POST, provided because `curl -T` naturally uses PUT.

**Sender (terminal A):**

```
curl -s -T myfile.bin \
  "https://{projectId}-{containerId}-pipe-{serviceId}.{node}.containers.hoody.com/api/v1/pipe/binary-drop"
```

**Receiver (terminal B):**

```
curl -s \
  "https://{projectId}-{containerId}-pipe-{serviceId}.{node}.containers.hoody.com/api/v1/pipe/binary-drop" \
  -o myfile.bin
```

### Workflow 3: Stream stdout from One Process to Another

Pipe is useful for streaming live output.

**Sender — stream a log tail:**

```
tail -f /var/log/app.log | curl -s -X POST \
  "https://{projectId}-{containerId}-pipe-{serviceId}.{node}.containers.hoody.com/api/v1/pipe/live-logs" \
  --data-binary @-
```

**Receiver — consume the stream:**

```
curl -s \
  "https://{projectId}-{containerId}-pipe-{serviceId}.{node}.containers.hoody.com/api/v1/pipe/live-logs"
```

The receiver prints log lines as they arrive. Both sides stay connected until timeout or interrupt.

### Workflow 4: Browser-Based Upload (Web Interface)

Open in any browser:

```
https://{projectId}-{containerId}-pipe-{serviceId}.{node}.containers.hoody.com/api/v1/pipe
```

This returns an HTML page with a form to upload files or paste text. The form submits to a pipe path you specify.

**No-JavaScript fallback:**

```
https://{projectId}-{containerId}-pipe-{serviceId}.{node}.containers.hoody.com/api/v1/pipe/noscript?path=my-upload
```

This returns a pure HTML form (no JS) that works in restricted environments. The `path` query parameter sets the pipe path.

### Workflow 5: Read the Built-In Help

Get usage instructions tailored to the running instance (the help text includes the server's own URL from the `Host` header):

```
curl -s \
  "https://{projectId}-{containerId}-pipe-{serviceId}.{node}.containers.hoody.com/api/v1/pipe/help"
```

Output is plain text with copy-pasteable `curl` examples.

### Workflow 6: Health Check

Verify the service is running:

```
curl -s \
  "https://{projectId}-{containerId}-pipe-{serviceId}.{node}.containers.hoody.com/api/v1/pipe/health"
```

**Expected response structure (9-field health object):**

```
{
  "status": "healthy",
  "service": "hoody-pipe",
  "version": "1.0.0",
  "uptime": 12345,
  "timestamp": "2025-01-15T10:30:00Z",
  "checks": {},
  "node": "us-east-1",
  "containerId": "abc123",
  "projectId": "def456"
}
```

**Important:** The health endpoint is only reachable at `/api/v1/pipe/health`. A bare `/health` path returns a 404 with an error message directing you to the correct path.

---

## Advanced Operations

### Complex Workflow: Multi-File Parallel Transfer

Transfer multiple files by iterating over paths:

**Sender script:**

```
#!/bin/bash
BASE_URL="https://{projectId}-{containerId}-pipe-{serviceId}.{node}.containers.hoody.com"
FILES=("config.yml" "data.csv" "report.pdf")

for file in "${FILES[@]}"; do
  echo "Sending: $file (waiting for receiver...)"
  curl -s -X POST \
    "${BASE_URL}/api/v1/pipe/batch/${file}" \
    --data-binary @"${file}" &
  SENDER_PID=$!
  sleep 1
done

wait
echo "All files transferred."
```

**Receiver script:**

```
#!/bin/bash
BASE_URL="https://{projectId}-{containerId}-pipe-{serviceId}.{node}.containers.hoody.com"
FILES=("config.yml" "data.csv" "report.pdf")

for file in "${FILES[@]}"; do
  echo "Receiving: $file"
  curl -s \
    "${BASE_URL}/api/v1/pipe/batch/${file}" \
    -o "received_${file}" &
done

wait
echo "All files received."
```

### Error Recovery Patterns

**Timeout handling** — if no peer connects within `--max-time`, curl exits with a timeout error:

```
curl -s \
  "https://{projectId}-{containerId}-pipe-{serviceId}.{node}.containers.hoody.com/api/v1/pipe/my-path"
EXIT_CODE=$?

if [ "$EXIT_CODE" -eq 28 ]; then
  echo "Timed out waiting for peer. Retrying..."
  sleep 5
  # Retry logic here
fi
```

**Automatic retry with backoff:**

```
MAX_RETRIES=5
RETRY=0

while [ $RETRY -lt $MAX_RETRIES ]; do
  curl -s -X POST \
    "https://{projectId}-{containerId}-pipe-{serviceId}.{node}.containers.hoody.com/api/v1/pipe/reliable-transfer" \
    --data-binary @payload.bin && break

  RETRY=$((RETRY + 1))
  WAIT=$((RETRY * 5))
  echo "Attempt $RETRY failed. Waiting ${WAIT}s..."
  sleep $WAIT
done
```

### Performance Considerations

| Factor | Recommendation |
|---|---|
| Large files | Use `` or higher; increase for multi-GB transfers |
| Binary data | Always use `--data-binary` (not `--data`) to prevent newline conversion |
| Compression | Pipe streams raw bytes; pre-compress with `gzip` if bandwidth-limited |
| Concurrent pipes | Each path is independent — multiple transfers can happen in parallel on different paths |
| Connection reuse | Each curl invocation creates one connection; for many small transfers, consider batching |

**Streaming binary with compression:**

```
# Sender
tar czf - ./my-directory | curl -s -X POST \
  "https://{projectId}-{containerId}-pipe-{serviceId}.{node}.containers.hoody.com/api/v1/pipe/compressed-bundle" \
  --data-binary @-

# Receiver
curl -s \
  "https://{projectId}-{containerId}-pipe-{serviceId}.{node}.containers.hoody.com/api/v1/pipe/compressed-bundle" \
  | tar xzf -
```

### CORS / Browser Pre-flight

When calling Pipe from a browser (JavaScript fetch/XHR), the browser sends an OPTIONS preflight request. Pipe handles this automatically; the following curl command is for debugging preflight behavior manually:

```
curl -s -X OPTIONS \
  "https://{projectId}-{containerId}-pipe-{serviceId}.{node}.containers.hoody.com/api/v1/pipe/my-path" \
  -H "Origin: https://myapp.example.com" \
  -H "Access-Control-Request-Method: POST"
```

**Response headers include:**

- `Access-Control-Allow-Origin` — reflects the request Origin
- `Access-Control-Allow-Methods` — permitted methods
- `Access-Control-Allow-Headers` — permitted headers

---

## Quick Reference

### Endpoint Summary

| Method | Path | Purpose |
|---|---|---|
| `GET` | `/api/v1/pipe` | Web interface (HTML) |
| `GET` | `/api/v1/pipe/help` | Plain-text usage guide |
| `GET` | `/api/v1/pipe/health` | Health check (unauthenticated) |
| `GET` | `/api/v1/pipe/noscript` | No-JS upload form |
| `GET` | `/api/v1/pipe/{path}` | Receive data (blocks until sender) |
| `POST` | `/api/v1/pipe/{path}` | Send data (blocks until receiver) |
| `PUT` | `/api/v1/pipe/{path}` | Send data (alias for POST) |
| `OPTIONS` | `/api/v1/pipe/{path}` | CORS preflight |

### Essential Parameters

| Parameter | Location | Type | Description |
|---|---|---|---|
| `path` | URL path segment | string | Pipe channel identifier — sender and receiver must use the same path |
| `path` | Query param (noscript) | string | Pre-fills the upload form's target path |

The base URL pattern (`https://{projectId}-{containerId}-pipe-{serviceId}.{node}.containers.hoody.com`) is shown in the inline examples above.

> **Sender and receiver must target the same `{path}`**.

### Typical Response Formats

**Health check** — JSON (9-field object)
**Help** — Plain text with curl examples
**Web interface** — HTML page
**Receive endpoint** — Streams raw bytes (original content type forwarded from sender)
**Send endpoint** — Streams confirmation on completion