opencode

package
v1.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 22, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package opencode provides an HTTP API client for the OpenCode server, enabling session management, prompt submission, SSE event streaming, and interactive permission handling.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CacheUsage

type CacheUsage struct {
	Write int `json:"write"`
	Read  int `json:"read"`
}

CacheUsage breaks out cached tokens.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client provides HTTP access to the OpenCode server API.

func NewClient

func NewClient(baseURL string) *Client

NewClient creates a new OpenCode API client for the given server URL.

func (*Client) Abort

func (c *Client) Abort(ctx context.Context, sessionID string) error

Abort cancels the current operation in a session.

func (*Client) BaseURL

func (c *Client) BaseURL() string

BaseURL returns the server base URL.

func (*Client) ConnectEvents

func (c *Client) ConnectEvents(ctx context.Context) (io.ReadCloser, error)

ConnectEvents opens the SSE event stream. The caller must close the returned body when done. Use ParseEventStream to consume events.

func (*Client) CreateSession

func (c *Client) CreateSession(ctx context.Context, title string) (*Session, error)

CreateSession creates a new session on the server.

func (*Client) Health

func (c *Client) Health(ctx context.Context) (*HealthResponse, error)

Health checks if the OpenCode server is running.

func (*Client) RejectQuestion

func (c *Client) RejectQuestion(ctx context.Context, questionID string) error

RejectQuestion dismisses a question without answering.

func (*Client) ReplyQuestion

func (c *Client) ReplyQuestion(ctx context.Context, questionID string, answers [][]string) error

ReplyQuestion answers a question with selected option labels. answers is a slice of label arrays, one per question in the prompt.

func (*Client) RespondPermission

func (c *Client) RespondPermission(ctx context.Context, sessionID, permissionID string, approved bool) error

RespondPermission approves or denies a permission request.

func (*Client) SendPrompt

func (c *Client) SendPrompt(ctx context.Context, sessionID string, text string) error

SendPrompt sends a prompt to a session asynchronously. The server responds with 204 No Content immediately; results come via SSE.

type CreateSessionRequest

type CreateSessionRequest struct {
	Title string `json:"title"`
}

CreateSessionRequest is the body for POST /session.

type Event

type Event struct {
	Type       EventType
	Raw        []byte // raw JSON of the full event
	Properties EventProperties
}

Event is a parsed SSE event from the OpenCode server.

type EventProperties

type EventProperties struct {
	SessionID string `json:"sessionID,omitempty"`

	// Populated by event-type-aware parsing:
	Session     *Session       `json:"-"` // session.updated → .info
	MessageInfo *MessageInfo   `json:"-"` // message.updated → .info
	Status      *SessionStatus `json:"status,omitempty"`
	Part        *Part          `json:"part,omitempty"`

	// message.part.delta
	MessageID string `json:"messageID,omitempty"`
	PartID    string `json:"partID,omitempty"`
	Field     string `json:"field,omitempty"`
	Delta     string `json:"delta,omitempty"`

	// file.edited / file.watcher.updated
	File      string `json:"file,omitempty"`
	FileEvent string `json:"event,omitempty"`

	// session.summary
	Summary *SessionSummary `json:"summary,omitempty"`

	// permission.asked
	Permission *Permission `json:"-"`

	// question.asked
	Question *Question `json:"-"`

	// Raw time field
	Time int64 `json:"time,omitempty"`
}

EventProperties is the top-level "properties" field in all events. Because different event types reuse field names (e.g. "info" for both Session and MessageInfo), we decode into raw JSON and dispatch per type.

type EventStream

type EventStream struct {
	// contains filtered or unexported fields
}

EventStream manages an SSE connection and broadcasts events to subscribers.

func NewEventStream

func NewEventStream(ctx context.Context, client *Client) (*EventStream, error)

NewEventStream connects to the SSE endpoint and begins parsing events. Events are broadcast to all subscribers. Call Close() to stop.

func (*EventStream) Close

func (es *EventStream) Close()

Close shuts down the event stream and all subscribers.

func (*EventStream) Subscribe

func (es *EventStream) Subscribe(ctx context.Context, sessionID string) (<-chan Event, func())

Subscribe creates a new event channel filtered for the given session ID. Pass "" for sessionID to receive all events. The returned channel is closed when the stream closes or Unsubscribe is called.

type EventType

type EventType string

EventType enumerates the SSE event types emitted by the OpenCode server.

const (
	EventServerConnected    EventType = "server.connected"
	EventSessionUpdated     EventType = "session.updated"
	EventSessionStatus      EventType = "session.status"
	EventSessionSummary     EventType = "session.summary"
	EventMessageUpdated     EventType = "message.updated"
	EventMessagePartUpdated EventType = "message.part.updated"
	EventMessagePartDelta   EventType = "message.part.delta"
	EventFileEdited         EventType = "file.edited"
	EventFileWatcherUpdated EventType = "file.watcher.updated"
	EventPermissionAsked    EventType = "permission.asked"
	EventPermissionReplied  EventType = "permission.replied"
	EventQuestionAsked      EventType = "question.asked"
	EventQuestionReplied    EventType = "question.replied"
	EventQuestionRejected   EventType = "question.rejected"
)

type HealthResponse

type HealthResponse struct {
	Healthy bool   `json:"healthy"`
	Version string `json:"version"`
}

HealthResponse is returned by GET /global/health.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager is the top-level coordinator for the OpenCode integration. It manages the server lifecycle, shared SSE stream, and per-session routing.

func NewManager

func NewManager(dir string) *Manager

NewManager creates a Manager that will run the server in the given directory.

func (*Manager) Client

func (m *Manager) Client() *Client

Client returns the HTTP client for the running server.

func (*Manager) Context

func (m *Manager) Context() context.Context

Context returns the manager's context (valid while running).

func (*Manager) Start

func (m *Manager) Start(ctx context.Context) error

Start launches the server and connects the SSE event stream. Safe to call multiple times (idempotent).

func (*Manager) Status

func (m *Manager) Status() ServerStatus

Status returns the server connection status.

func (*Manager) Stop

func (m *Manager) Stop()

Stop shuts down the event stream and server.

func (*Manager) Stream

func (m *Manager) Stream() *EventStream

Stream returns the shared SSE event stream.

type MessageInfo

type MessageInfo struct {
	ID         string      `json:"id"`
	ParentID   string      `json:"parentID"`
	Role       string      `json:"role"` // "user" or "assistant"
	Mode       string      `json:"mode"`
	Agent      string      `json:"agent"`
	ModelID    string      `json:"modelID"`
	ProviderID string      `json:"providerID"`
	SessionID  string      `json:"sessionID"`
	Finish     string      `json:"finish,omitempty"` // "end-turn", "tool-calls", etc.
	Cost       float64     `json:"cost"`
	Tokens     TokenUsage  `json:"tokens"`
	Time       MessageTime `json:"time"`
}

MessageInfo describes a completed or in-progress message.

type MessageTime

type MessageTime struct {
	Created   int64 `json:"created"`   // unix millis
	Completed int64 `json:"completed"` // unix millis; 0 if still streaming
}

MessageTime holds created/completed timestamps.

type Part

type Part struct {
	ID        string     `json:"id"`
	MessageID string     `json:"messageID"`
	SessionID string     `json:"sessionID"`
	Type      string     `json:"type"` // "text", "tool", "step-finish"
	Text      string     `json:"text,omitempty"`
	Tool      string     `json:"tool,omitempty"`
	CallID    string     `json:"callID,omitempty"`
	State     *ToolState `json:"state,omitempty"`
	Time      *PartTime  `json:"time,omitempty"`
}

Part represents a message part (text or tool call).

type PartTime

type PartTime struct {
	Start int64 `json:"start"`
	End   int64 `json:"end"`
}

PartTime holds start/end timestamps for a part.

type Permission

type Permission struct {
	ID        string         `json:"id"`
	SessionID string         `json:"sessionID"`
	Tool      string         `json:"tool"`
	Input     map[string]any `json:"input"`
	CreatedAt time.Time      `json:"createdAt"`
}

Permission represents a tool permission request that needs user approval.

type PermissionResponse

type PermissionResponse struct {
	Approved bool `json:"approved"`
}

PermissionResponse is sent to approve or deny a permission request.

type PromptPart

type PromptPart struct {
	Type string `json:"type"` // "text"
	Text string `json:"text,omitempty"`
}

PromptPart is a single part of a prompt message.

type PromptRequest

type PromptRequest struct {
	Parts []PromptPart `json:"parts"`
}

PromptRequest is the body for POST /session/:id/prompt_async.

type Question

type Question struct {
	ID        string           `json:"id"`
	SessionID string           `json:"sessionID"`
	Questions []QuestionPrompt `json:"questions"`
	Tool      *ToolRef         `json:"tool,omitempty"`
}

Question represents an interactive question from the OpenCode agent that requires user input before the session can continue.

type QuestionOption

type QuestionOption struct {
	Label       string `json:"label"`
	Description string `json:"description"`
}

QuestionOption is a selectable choice for a question.

type QuestionPrompt

type QuestionPrompt struct {
	Question string           `json:"question"`
	Header   string           `json:"header"`
	Options  []QuestionOption `json:"options"`
}

QuestionPrompt is a single question with options.

type QuestionReplyRequest

type QuestionReplyRequest struct {
	Answers [][]string `json:"answers"`
}

QuestionReplyRequest is sent to answer a question.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server manages the lifecycle of an `opencode serve` process.

func NewServer

func NewServer(dir string) *Server

NewServer creates a Server that will run in the given directory.

func (*Server) Client

func (s *Server) Client() *Client

Client returns the HTTP client for the running server, or nil if not connected.

func (*Server) Port

func (s *Server) Port() int

Port returns the port the server is listening on (0 if not started).

func (*Server) Start

func (s *Server) Start(ctx context.Context) error

Start launches the opencode server process and waits until it is healthy. It picks a free port automatically. Returns an error if the server fails to start.

func (*Server) Status

func (s *Server) Status() ServerStatus

Status returns the current server connection status.

func (*Server) Stop

func (s *Server) Stop()

Stop gracefully shuts down the server.

type ServerStatus

type ServerStatus int

ServerStatus represents the connection state of the OpenCode server.

const (
	ServerDisconnected ServerStatus = iota
	ServerConnecting
	ServerConnected
)

type Session

type Session struct {
	ID        string       `json:"id"`
	Slug      string       `json:"slug"`
	ProjectID string       `json:"projectID"`
	Directory string       `json:"directory"`
	Path      string       `json:"path"`
	Title     string       `json:"title"`
	Version   string       `json:"version"`
	Summary   *Summary     `json:"summary,omitempty"`
	Time      SessionTimes `json:"time"`
}

Session represents an OpenCode chat session.

type SessionStatus

type SessionStatus struct {
	Type string `json:"type"` // "idle", "busy"
}

SessionStatus describes whether the session is idle or busy.

type SessionSummary

type SessionSummary struct {
	Messages int `json:"messages"`
	Tokens   int `json:"tokens"`
}

SessionSummary holds token/message stats for a session.

type SessionTimes

type SessionTimes struct {
	Created int64 `json:"created"` // unix millis
	Updated int64 `json:"updated"` // unix millis
}

SessionTimes holds created/updated timestamps.

type Summary

type Summary struct {
	Additions int `json:"additions"`
	Deletions int `json:"deletions"`
	Files     int `json:"files"`
}

Summary holds file-change stats for a session.

type TokenUsage

type TokenUsage struct {
	Total     int        `json:"total"`
	Input     int        `json:"input"`
	Output    int        `json:"output"`
	Reasoning int        `json:"reasoning"`
	Cache     CacheUsage `json:"cache"`
}

TokenUsage tracks token consumption.

type ToolRef

type ToolRef struct {
	MessageID string `json:"messageID"`
	CallID    string `json:"callID"`
}

ToolRef references the tool call that triggered this question/permission.

type ToolState

type ToolState struct {
	Status   string         `json:"status"` // "pending", "running", "completed", "error"
	Input    map[string]any `json:"input,omitempty"`
	Output   string         `json:"output,omitempty"`
	Raw      string         `json:"raw,omitempty"`
	Title    string         `json:"title,omitempty"`
	Metadata map[string]any `json:"metadata,omitempty"`
	Time     *ToolTime      `json:"time,omitempty"`
}

ToolState describes a tool call's lifecycle.

type ToolTime

type ToolTime struct {
	Start int64 `json:"start"`
	End   int64 `json:"end"`
}

ToolTime holds start/end for a tool execution.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL