Documentation
¶
Index ¶
- Constants
- func QRCodeForURL(url string) (string, error)
- func QRCodeLines(url string) ([]string, error)
- func QRCodePNG(url string) ([]byte, error)
- type ApprovalRequestData
- type ApprovalResponseData
- type AskUserAnswer
- type AskUserChoice
- type AskUserQuestion
- type AskUserRequestData
- type AskUserResponseData
- type Broker
- func (b *Broker) NextMessageID() string
- func (b *Broker) OnClientConnect(fn func())
- func (b *Broker) OnCommand(fn func(cmd GatewayMessage))
- func (b *Broker) PushApprovalRequest(id, toolName, input string)
- func (b *Broker) PushApprovalResult(id, decision string)
- func (b *Broker) PushAskUserRequest(id, title string, questions []AskUserQuestion)
- func (b *Broker) PushAskUserResponse(id, status string, answers []AskUserAnswer)
- func (b *Broker) PushChatClear()
- func (b *Broker) PushChatHistory(messages []HistoryEntry)
- func (b *Broker) PushError(message string)
- func (b *Broker) PushSharingStopped()
- func (b *Broker) PushStatus(status, message string)
- func (b *Broker) PushSubagentComplete(agentID, name, summary string, success bool)
- func (b *Broker) PushSubagentSpawn(agentID, name, task, color, parentID string)
- func (b *Broker) PushSubagentStatus(agentID, status, message string)
- func (b *Broker) PushSubagentText(agentID, msgID, chunk string, done bool)
- func (b *Broker) PushSubagentToolCall(agentID, toolID, toolName, args, detail string)
- func (b *Broker) PushSubagentToolResult(agentID, toolID, toolName, result string, isError bool)
- func (b *Broker) PushText(id, chunk string)
- func (b *Broker) PushTextDone(id string)
- func (b *Broker) PushToolCall(toolID, toolName, args, detail string)
- func (b *Broker) PushToolResult(toolID, toolName, result string, isError bool)
- func (b *Broker) PushUserMessage(text string)
- func (b *Broker) ReplayToClient()
- func (b *Broker) SendSessionInfo(data SessionInfoData)
- func (b *Broker) Stop()
- type Crypto
- type ErrorData
- type GatewayMessage
- type HistoryEntry
- type MessageData
- type ModeChangeData
- type RelayClient
- func (rc *RelayClient) Close()
- func (rc *RelayClient) Connect() error
- func (rc *RelayClient) ConnectURL() string
- func (rc *RelayClient) OnConnect(fn func())
- func (rc *RelayClient) OnMessage(fn func(msg GatewayMessage))
- func (rc *RelayClient) Send(msg GatewayMessage) error
- func (rc *RelayClient) Token() string
- type Session
- type SessionInfo
- type SessionInfoData
- type StatusData
- type SubagentCompleteData
- type SubagentSpawnData
- type SubagentStatusData
- type SubagentTextData
- type SubagentToolCallData
- type SubagentToolResultData
- type TextData
- type ToolCallData
- type ToolResultData
Constants ¶
const ( EventConnected = "connected" EventSessionInfo = "session_info" EventUserMessage = "user_message" // user text from desktop EventText = "text" // streaming text chunk EventTextDone = "text_done" // text stream complete EventStatus = "status" // agent status change EventToolCall = "tool_call" EventToolResult = "tool_result" EventApprovalRequest = "approval_request" EventApprovalResult = "approval_result" EventAskUserRequest = "ask_user_request" EventAskUserResponse = "ask_user_response" EventSubagentSpawn = "subagent_spawn" EventSubagentText = "subagent_text" EventSubagentStatus = "subagent_status" EventSubagentToolCall = "subagent_tool_call" EventSubagentToolResult = "subagent_tool_result" EventSubagentComplete = "subagent_complete" EventError = "error" EventPing = "ping" EventDisconnected = "disconnected" )
Server → Client event types.
const ( EventAck = "ack" // client ACK for sequenced delivery CmdMessage = "message" CmdApprovalResponse = "approval_response" CmdInterrupt = "interrupt" CmdModeChange = "mode_change" CmdAskUserResponse = "ask_user_response" CmdPong = "pong" )
Client → Server command types.
const ( StatusIdle = "idle" StatusThinking = "thinking" StatusRunning = "running" StatusWaiting = "waiting" // waiting for approval StatusError = "error" )
Agent status values.
const ( ModeSupervised = "supervised" ModeAuto = "auto" ModeBypass = "bypass" ModeAutopilot = "autopilot" )
Mode values.
const ( DecisionAllow = "allow" DecisionDeny = "deny" DecisionAlwaysAllow = "always_allow" )
Approval decisions.
const DefaultRelayURL = "wss://gateway.ggcode.dev"
DefaultRelayURL is the default ggcode-relay server URL.
Variables ¶
This section is empty.
Functions ¶
func QRCodeForURL ¶
QRCodeForURL generates a QR code string for the given URL using terminal-friendly block characters. Returns a string that can be printed directly to a terminal.
func QRCodeLines ¶
QRCodeLines returns the QR code as a slice of strings (one per line).
Types ¶
type ApprovalRequestData ¶
type ApprovalRequestData struct {
ID string `json:"id"`
ToolName string `json:"tool_name"`
Input string `json:"input"`
}
ApprovalRequestData carries an approval request to the mobile client.
type ApprovalResponseData ¶
type ApprovalResponseData struct {
ID string `json:"id"`
Decision string `json:"decision"` // allow/deny/always_allow
}
ApprovalResponseData carries the user's approval decision back.
type AskUserAnswer ¶
type AskUserAnswer struct {
QuestionID string `json:"question_id"`
ChoiceIDs []string `json:"choice_ids,omitempty"`
FreeformText string `json:"freeform_text,omitempty"`
}
AskUserAnswer carries a single question answer.
type AskUserChoice ¶
AskUserChoice represents a selectable choice.
type AskUserQuestion ¶
type AskUserQuestion struct {
ID string `json:"id"`
Prompt string `json:"prompt"`
Kind string `json:"kind"` // single/multi/text
Choices []AskUserChoice `json:"choices,omitempty"`
AllowFreeform bool `json:"allow_freeform,omitempty"`
Placeholder string `json:"placeholder,omitempty"`
}
AskUserQuestion represents a single question in the questionnaire.
type AskUserRequestData ¶
type AskUserRequestData struct {
ID string `json:"id"`
Title string `json:"title,omitempty"`
Questions []AskUserQuestion `json:"questions"`
}
AskUserRequestData carries a structured questionnaire from the agent. This is NOT the same as approval_request — it's a multi-question form with single/multi/text question types.
type AskUserResponseData ¶
type AskUserResponseData struct {
ID string `json:"id"`
Status string `json:"status"` // submitted/cancelled
Answers []AskUserAnswer `json:"answers,omitempty"`
}
AskUserResponseData carries the user's answers back.
type Broker ¶
type Broker struct {
// contains filtered or unexported fields
}
Broker bridges agent events and the WebSocket tunnel protocol.
Delivery guarantees:
- Text chunks are batched: PushText appends to a per-msgID buffer; a 300ms ticker flushes all accumulated text as a single message.
- Every outbound message carries a monotonically-increasing Seq.
- A sender goroutine sends one message at a time and waits for the mobile client to ACK (by seq) before sending the next.
- If ACK times out (5s), the next message is sent anyway.
- ReplayToClient bypasses ACK flow control for fast reconnect.
func (*Broker) NextMessageID ¶
func (*Broker) OnClientConnect ¶
func (b *Broker) OnClientConnect(fn func())
func (*Broker) OnCommand ¶
func (b *Broker) OnCommand(fn func(cmd GatewayMessage))
func (*Broker) PushApprovalRequest ¶
func (*Broker) PushApprovalResult ¶
func (*Broker) PushAskUserRequest ¶
func (b *Broker) PushAskUserRequest(id, title string, questions []AskUserQuestion)
func (*Broker) PushAskUserResponse ¶
func (b *Broker) PushAskUserResponse(id, status string, answers []AskUserAnswer)
func (*Broker) PushChatClear ¶
func (b *Broker) PushChatClear()
func (*Broker) PushChatHistory ¶
func (b *Broker) PushChatHistory(messages []HistoryEntry)
func (*Broker) PushSharingStopped ¶
func (b *Broker) PushSharingStopped()
func (*Broker) PushStatus ¶
func (*Broker) PushSubagentComplete ¶
func (*Broker) PushSubagentSpawn ¶
func (*Broker) PushSubagentStatus ¶
func (*Broker) PushSubagentText ¶
func (*Broker) PushSubagentToolCall ¶
func (*Broker) PushSubagentToolResult ¶
func (*Broker) PushTextDone ¶
func (*Broker) PushToolCall ¶
func (*Broker) PushToolResult ¶
func (*Broker) PushUserMessage ¶
func (*Broker) ReplayToClient ¶
func (b *Broker) ReplayToClient()
ReplayToClient resends all logged messages, bypassing ACK flow control.
func (*Broker) SendSessionInfo ¶
func (b *Broker) SendSessionInfo(data SessionInfoData)
type Crypto ¶
type Crypto struct {
// contains filtered or unexported fields
}
Crypto provides AES-GCM encryption/decryption using the token as key.
func NewCrypto ¶
NewCrypto creates a Crypto instance from a hex-encoded token (32+ hex chars = 16+ byte key). The token hex string is decoded to bytes and used directly as AES-128/256 key.
type GatewayMessage ¶
type GatewayMessage struct {
Seq int64 `json:"seq,omitempty"`
Type string `json:"type"`
Data json.RawMessage `json:"data,omitempty"`
}
GatewayMessage is a JSON message exchanged over the encrypted channel.
type HistoryEntry ¶
type HistoryEntry struct {
Role string `json:"role"`
Content string `json:"content"`
// Tool fields (role == "tool_call" or "tool_result")
ToolID string `json:"tool_id,omitempty"`
ToolName string `json:"tool_name,omitempty"`
ToolArgs string `json:"tool_args,omitempty"`
Result string `json:"result,omitempty"`
IsError bool `json:"is_error,omitempty"`
}
type MessageData ¶
type MessageData struct {
Text string `json:"text"`
}
MessageData carries a user message.
type ModeChangeData ¶
type ModeChangeData struct {
Mode string `json:"mode"`
}
ModeChangeData carries a mode change request.
type RelayClient ¶
type RelayClient struct {
// contains filtered or unexported fields
}
RelayClient connects to the ggcode-relay server as the "server" role. It auto-reconnects on disconnect with exponential backoff.
func NewRelayClient ¶
func NewRelayClient(relayURL, token string) (*RelayClient, error)
func (*RelayClient) Close ¶
func (rc *RelayClient) Close()
func (*RelayClient) Connect ¶
func (rc *RelayClient) Connect() error
Connect starts the connection loop. It connects, runs pumps, and auto-reconnects.
func (*RelayClient) ConnectURL ¶
func (rc *RelayClient) ConnectURL() string
func (*RelayClient) OnConnect ¶
func (rc *RelayClient) OnConnect(fn func())
func (*RelayClient) OnMessage ¶
func (rc *RelayClient) OnMessage(fn func(msg GatewayMessage))
func (*RelayClient) Send ¶
func (rc *RelayClient) Send(msg GatewayMessage) error
Send encrypts and sends a GatewayMessage to the relay. Safe to call after Close — returns error instead of panicking.
func (*RelayClient) Token ¶
func (rc *RelayClient) Token() string
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session manages a relay session: connects to ggcode-relay, generates QR code.
Usage:
sess := tunnel.NewSession("wss://relay.ggcode.app")
info, err := sess.Start(ctx)
fmt.Println(info.ConnectURL)
fmt.Println(info.QRCode)
sess.Send(msg)
sess.OnMessage(func(m) { ... })
sess.Stop()
func (*Session) Info ¶
func (s *Session) Info() *SessionInfo
func (*Session) OnMessage ¶
func (s *Session) OnMessage(fn func(msg GatewayMessage))
func (*Session) Send ¶
func (s *Session) Send(msg GatewayMessage) error
type SessionInfo ¶
type SessionInfo struct {
ConnectURL string // wss://relay.ggcode.app/ws?role=client&token=abc123
Token string
QRCode string // terminal-friendly QR code (text)
QRCodePNG []byte // PNG image bytes for GUI display
QRLines []string
}
SessionInfo contains the connection details after a session starts.
type SessionInfoData ¶
type SessionInfoData struct {
Workspace string `json:"workspace"`
Model string `json:"model"`
Provider string `json:"provider"`
Mode string `json:"mode"`
Version string `json:"version"`
}
SessionInfoData carries session metadata sent after connection.
type StatusData ¶
StatusData carries an agent status change.
type SubagentCompleteData ¶
type SubagentCompleteData struct {
AgentID string `json:"agent_id"`
Name string `json:"name"`
Summary string `json:"summary"` // one-line summary of what was done
Success bool `json:"success"`
}
SubagentCompleteData notifies that a sub-agent has finished.
type SubagentSpawnData ¶
type SubagentSpawnData struct {
AgentID string `json:"agent_id"`
Name string `json:"name"` // e.g. "Researcher", "Coder"
Task string `json:"task"` // brief task description
Color string `json:"color,omitempty"` // e.g. "#4CAF50"
ParentID string `json:"parent_id,omitempty"` // empty for top-level
}
SubagentSpawnData notifies mobile that a sub-agent has been spawned. Mobile should show a live activity card for this agent.
type SubagentStatusData ¶
type SubagentStatusData struct {
AgentID string `json:"agent_id"`
Status string `json:"status"` // running/waiting_approval/completed/failed
Message string `json:"message,omitempty"`
}
SubagentStatusData carries status updates for a sub-agent.
type SubagentTextData ¶
type SubagentTextData struct {
AgentID string `json:"agent_id"`
ID string `json:"id"` // message ID for grouping chunks
Chunk string `json:"chunk"`
Done bool `json:"done"`
}
SubagentTextData carries streaming text from a sub-agent.
type SubagentToolCallData ¶
type SubagentToolCallData struct {
AgentID string `json:"agent_id"`
ToolID string `json:"tool_id"`
ToolName string `json:"tool_name"`
Args string `json:"args,omitempty"`
Detail string `json:"detail,omitempty"`
}
SubagentToolCallData carries tool call info from a sub-agent.
type SubagentToolResultData ¶
type SubagentToolResultData struct {
AgentID string `json:"agent_id"`
ToolID string `json:"tool_id"`
ToolName string `json:"tool_name"`
Result string `json:"result"`
IsError bool `json:"is_error"`
}
SubagentToolResultData carries tool result from a sub-agent.
type TextData ¶
type TextData struct {
ID string `json:"id"` // message ID to group chunks
Chunk string `json:"chunk"` // text content
Done bool `json:"done"` // true on last chunk
}
TextData carries a streaming text chunk.