Documentation
¶
Overview ¶
Package hostproxy provides a host-side HTTP server that containers can call to perform actions on the host, such as opening URLs in the browser.
Package hostproxy provides a host-side HTTP server that containers can call to perform actions on the host, such as opening URLs in the browser.
Index ¶
- Constants
- Variables
- func GetDaemonPID(pidFile string) int
- func IsDaemonRunning(pidFile string) bool
- func StopDaemon(pidFile string) error
- type CallbackChannel
- func (c *CallbackChannel) Capture(sessionID string, r *http.Request) error
- func (c *CallbackChannel) Delete(sessionID string)
- func (c *CallbackChannel) GetData(sessionID string) (*CallbackData, bool)
- func (c *CallbackChannel) GetPath(sessionID string) (string, bool)
- func (c *CallbackChannel) GetPort(sessionID string) (int, bool)
- func (c *CallbackChannel) IsReceived(sessionID string) bool
- func (c *CallbackChannel) Register(port int, path string, ttl time.Duration) (*Session, error)
- type CallbackData
- type ContainerLister
- type Daemon
- type DaemonOption
- type HostProxyService
- type Manager
- type Server
- type Session
- type SessionStore
- func (s *SessionStore) Count() int
- func (s *SessionStore) Create(sessionType string, ttl time.Duration, metadata map[string]any) (*Session, error)
- func (s *SessionStore) Delete(id string)
- func (s *SessionStore) Get(id string) *Session
- func (s *SessionStore) SetOnDelete(fn func(session *Session))
- func (s *SessionStore) Stop()
Constants ¶
const CallbackSessionType = "callback"
CallbackSessionType is the session type identifier for callback sessions.
const DefaultCallbackTTL = 5 * time.Minute
DefaultCallbackTTL is the default time-to-live for callback sessions.
const SessionIDLength = 16
SessionIDLength is the number of random bytes used for session IDs. 16 bytes = 32 hex characters, providing 128 bits of entropy.
Variables ¶
var ErrCallbackAlreadyReceived = errors.New("callback already received")
ErrCallbackAlreadyReceived is returned when attempting to capture a callback for a session that has already received one. TODO: this is being printed over the claude REPL when its active. We have to figure out how to print errors without overwriting onto the REPL ui. either supress the printing of this if claude is active, or find a way to print above/below the REPL.
Functions ¶
func GetDaemonPID ¶
GetDaemonPID returns the PID of the running daemon, or 0 if not running.
func IsDaemonRunning ¶
IsDaemonRunning checks if a daemon is running by checking the PID file and verifying the process is alive.
func StopDaemon ¶
StopDaemon sends SIGTERM to the daemon process.
Types ¶
type CallbackChannel ¶
type CallbackChannel struct {
// contains filtered or unexported fields
}
CallbackChannel handles OAuth callback routing. It manages the registration of callback expectations and captures incoming callbacks from the browser.
func NewCallbackChannel ¶
func NewCallbackChannel(store *SessionStore, log *logger.Logger) *CallbackChannel
NewCallbackChannel creates a new callback channel using the provided session store.
func (*CallbackChannel) Capture ¶
func (c *CallbackChannel) Capture(sessionID string, r *http.Request) error
Capture stores the incoming callback request data for the specified session. Only the first callback for each session is captured (single-use). Returns an error if the session is not found or already received a callback.
func (*CallbackChannel) Delete ¶
func (c *CallbackChannel) Delete(sessionID string)
Delete removes a callback session.
func (*CallbackChannel) GetData ¶
func (c *CallbackChannel) GetData(sessionID string) (*CallbackData, bool)
GetData retrieves the captured callback data for the specified session. Returns nil if no callback has been received yet.
func (*CallbackChannel) GetPath ¶
func (c *CallbackChannel) GetPath(sessionID string) (string, bool)
GetPath returns the expected callback path for the specified session.
func (*CallbackChannel) GetPort ¶
func (c *CallbackChannel) GetPort(sessionID string) (int, bool)
GetPort returns the target port for the specified session.
func (*CallbackChannel) IsReceived ¶
func (c *CallbackChannel) IsReceived(sessionID string) bool
IsReceived checks if a callback has been received for the session.
type CallbackData ¶
type CallbackData struct {
Method string `json:"method"`
Path string `json:"path"`
Query string `json:"query"`
Headers map[string]string `json:"headers,omitempty"`
Body string `json:"body,omitempty"`
ReceivedAt time.Time `json:"received_at"`
}
CallbackData contains the captured OAuth callback request data.
type ContainerLister ¶
type ContainerLister interface {
ContainerList(ctx context.Context, options client.ContainerListOptions) (client.ContainerListResult, error)
io.Closer
}
ContainerLister is the minimal interface needed for container watcher functionality. This allows the daemon to work without directly coupling to the full Docker client, and enables testing with mock implementations.
Note: This package imports github.com/moby/moby/client directly rather than going through pkg/whail. This is intentional because the daemon runs as a standalone subprocess that only needs to list containers - it doesn't need whail's jail semantics or label enforcement. The interface pattern still allows for testing.
type Daemon ¶
type Daemon struct {
// contains filtered or unexported fields
}
Daemon manages the host proxy server as a background process. It polls Docker for clawker containers and auto-exits when none are running.
func NewDaemon ¶
NewDaemon creates a new daemon that reads all settings from cfg.HostProxyConfig(). Optional DaemonOption values override individual config settings (used by CLI flags). It creates a Docker client internally. Tests that need a mock docker client construct &Daemon{...} directly (the pattern used by watchContainers tests).
type DaemonOption ¶ added in v0.2.0
type DaemonOption func(*Daemon)
DaemonOption is a functional option for overriding daemon config values. CLI flags use these to take precedence over config without mutating the config object.
func WithDaemonPort ¶ added in v0.2.0
func WithDaemonPort(port int) DaemonOption
WithDaemonPort overrides the daemon listen port.
func WithGracePeriod ¶ added in v0.2.0
func WithGracePeriod(period time.Duration) DaemonOption
WithGracePeriod overrides the initial grace period.
func WithPollInterval ¶ added in v0.2.0
func WithPollInterval(interval time.Duration) DaemonOption
WithPollInterval overrides the container poll interval.
type HostProxyService ¶ added in v0.1.2
type HostProxyService interface {
// EnsureRunning ensures the host proxy is running. Spawns a daemon if needed.
EnsureRunning() error
// IsRunning returns whether the host proxy is currently running.
IsRunning() bool
// ProxyURL returns the URL containers should use to reach the host proxy.
ProxyURL() string
}
HostProxyService is the interface for host proxy operations used by container commands. Commands interact with the host proxy through this interface, enabling test doubles that don't spawn daemon subprocesses.
Concrete implementation: Manager. Mock: hostproxytest.MockManager.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager manages the lifecycle of the host proxy daemon. It spawns a daemon subprocess that persists beyond CLI lifetime, enabling containers to use the proxy even after the CLI exits.
func NewManager ¶
NewManager creates a new host proxy manager. Port is read and validated from cfg.HostProxyConfig().Manager.Port at construction time.
func (*Manager) EnsureRunning ¶
EnsureRunning ensures the host proxy daemon is running. If the daemon is not running, it spawns a new daemon subprocess.
func (*Manager) ProxyURL ¶
ProxyURL returns the URL containers should use to reach the host proxy. This uses host.docker.internal which Docker automatically resolves to the host.
func (*Manager) Stop ¶
func (m *Manager) Stop()
Stop does nothing for the daemon-based manager. The daemon self-terminates when no clawker containers are running. Use StopDaemon() for explicit daemon teardown.
func (*Manager) StopDaemon ¶
StopDaemon explicitly stops the daemon process.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is an HTTP server that handles requests from containers to perform host-side actions.
type Session ¶
type Session struct {
ID string
Type string // e.g., "callback", "webhook", "message"
CreatedAt time.Time
ExpiresAt time.Time
Metadata map[string]any // Channel-specific data
// contains filtered or unexported fields
}
Session is the base type for all proxy sessions. It stores common metadata and provides thread-safe access to session data.
func (*Session) CaptureOnce ¶
CaptureOnce atomically checks if capture happened and marks it if not. Returns true if this call captured (was first), false if already captured.
func (*Session) GetMetadata ¶
GetMetadata safely retrieves a metadata value by key.
func (*Session) SetMetadata ¶
SetMetadata safely sets a metadata value.
type SessionStore ¶
type SessionStore struct {
// contains filtered or unexported fields
}
SessionStore manages sessions across all channels. It provides thread-safe create, get, delete, and cleanup operations.
func NewSessionStore ¶
func NewSessionStore() *SessionStore
NewSessionStore creates a new session store and starts the background cleanup goroutine. Callers MUST call Stop() when done to prevent goroutine leaks.
func (*SessionStore) Count ¶
func (s *SessionStore) Count() int
Count returns the number of active sessions.
func (*SessionStore) Create ¶
func (s *SessionStore) Create(sessionType string, ttl time.Duration, metadata map[string]any) (*Session, error)
Create creates a new session with the given type, TTL, and metadata. Returns the created session with a unique cryptographically random ID.
func (*SessionStore) Delete ¶
func (s *SessionStore) Delete(id string)
Delete removes a session by ID.
func (*SessionStore) Get ¶
func (s *SessionStore) Get(id string) *Session
Get retrieves a session by ID. Returns nil if not found or expired.
func (*SessionStore) SetOnDelete ¶
func (s *SessionStore) SetOnDelete(fn func(session *Session))
SetOnDelete sets a callback function that will be called when a session is deleted. The callback receives the session before it is removed from the store.
func (*SessionStore) Stop ¶
func (s *SessionStore) Stop()
Stop stops the background cleanup goroutine.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package internals provides embedded container-side scripts and source code that run inside clawker containers to communicate with the host proxy and socketbridge.
|
Package internals provides embedded container-side scripts and source code that run inside clawker containers to communicate with the host proxy and socketbridge. |
|
cmd/callback-forwarder
command
callback-forwarder polls the host proxy for captured OAuth callback data and forwards it to the local HTTP server (Claude Code's callback listener).
|
callback-forwarder polls the host proxy for captured OAuth callback data and forwards it to the local HTTP server (Claude Code's callback listener). |
|
cmd/clawker-socket-server
command
socket-forwarder is a multiplexing socket forwarder that runs inside clawker containers.
|
socket-forwarder is a multiplexing socket forwarder that runs inside clawker containers. |