Help us shape the future of Go! Take the 2026 Go Developer Survey

api

package
v0.1.78 Latest Latest
Warning

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

Go to latest
Published: Jun 18, 2026 License: GPL-2.0, GPL-3.0 Imports: 10 Imported by: 0

Documentation

Overview

Package api defines the internal contracts between vibekit components. All cross-component calls go through these interfaces, enabling testability (mock any component) and swappability.

This package contains two concern groups:

  1. Domain types and interfaces — the contract surface (interfaces.go, domain_chat.go, events.go, commands.go, domain_rpc.go, mcp.go, push_types.go, methods.go, strings.go).
  2. HTTP response/request helpers (httputil.go, decode.go) — WriteJSON, BadRequest, MethodNotAllowed, etc.

Atomic file I/O (SaveBytes, bounded reads) lives in the external cplieger/atomicfile package, not here.

Implementation packages import api, never the reverse. Domain types Tag, FileChange, and ConflictPayload live in checkpoint/types (a leaf package with zero internal dependencies).

Index

Constants

View Source
const (
	ElicitationActionAccept  = "accept"
	ElicitationActionDecline = "decline"
	ElicitationActionCancel  = "cancel"
)

Elicitation actions per the MCP ElicitResult contract.

View Source
const (
	WorkingLabelThinking = "Thinking"
	WorkingLabelApproval = "Waiting for approval"
	WorkingLabelInput    = "Waiting for input"
)

Working-label constants. Centralised so hub callers reference these instead of bare string literals; a future label rename lands in one place.

View Source
const (
	// RPCCodeInternal is the JSON-RPC 2.0 "Internal error" code (-32603).
	RPCCodeInternal = -32603
	// RPCCodeNotIdle indicates the session is still processing a prior turn.
	RPCCodeNotIdle = -32001
	// RPCCodeBridgeExited is a server-defined code indicating the ACP bridge process exited.
	RPCCodeBridgeExited = -32000
)

RPC error code constants for typed dispatch in retry logic.

View Source
const (
	MethodInitialize  = "initialize"
	MethodSessionNew  = "session/new"
	MethodSessionLoad = "session/load"
	MethodSetModel    = "session/set_model"
	MethodCancel      = "session/cancel"
)

Bridge lifecycle methods — used by the bridge package to drive the kiro-cli subprocess through initialize → session/new|load → set_model.

View Source
const (
	MethodFSRead  = "fs/read_text_file"
	MethodFSWrite = "fs/write_text_file"
)

File-system protocol method names (ACP fs/* namespace). Exported so test files can reference the canonical string without bare literals.

View Source
const (
	MethodElicitationCreate   = "elicitation/create"
	MethodElicitationComplete = "elicitation/complete"
)

MCP elicitation method names. When an MCP server requests structured input mid-tool-execution, kiro-cli (acting as the MCP client) forwards the request to us over ACP as elicitation/create — sent the same way as the fs/* requests above (see the agent's client-protocol method registry, where elicitation_create sits beside fs_read_text_file). We surface a form to the user and reply with {action, content}. elicitation/complete is an agent→client notification telling us a pending elicitation was cancelled upstream so we dismiss the dialog. Gated by the clientCapabilities.elicitation capability advertised in bridge.initialize(); without it kiro-cli does not forward elicitation.

View Source
const (
	MethodCommandsExecute = "_kiro.dev/commands/execute"
	MethodCommandsOptions = "_kiro.dev/commands/options"
)

Slash-command extension method names (_kiro.dev/commands/* namespace).

View Source
const (
	MethodPrompt = "session/prompt"
	MethodSpawn  = "session/spawn"
)

Session-level ACP method names — prompt and subagent spawn.

View Source
const (
	MethodSessionUpdate     = "session/update"
	MethodRequestPermission = "session/request_permission"
	MethodSetConfigOption   = "session/setConfigOption"
	MethodTerminate         = "session/terminate"
	MethodAttach            = "session/attach"
	MethodList              = "session/list"
	MethodMessageSend       = "message/send"
)

Session-level ACP method names — streaming updates, permissions, config, and subagent lifecycle.

View Source
const (
	ContentKeyType = "type"
	ContentKeyText = "text"
)

ACP content-block JSON field name constants. These are the wire-format keys inside a content block object (distinct from ContentTypeText which is the field VALUE). Single source of truth for hub, command, and translate packages.

View Source
const ContentTypeText = "text"

ACP content-block type discriminator constants. The "text" value is used across hub, command, and translate packages; declaring it here provides a single source of truth so a protocol rename is one edit.

View Source
const DefaultChatName = "New conversation"

DefaultChatName is the fallback name for newly created chats when the client does not supply one.

View Source
const ErrMsgInvalidChatID = "invalid chat_id"

ErrMsgInvalidChatID is the single source of truth for the HTTP error message returned when a chat ID fails validation.

View Source
const ErrMsgUtilityUnavailable = "utility bridge not available"

ErrMsgUtilityUnavailable is the canonical error message returned when the utility bridge (LLM prompt function) is not wired. Used by both the git and server packages to keep the error string in one place.

View Source
const JSONKeyError = "error"

JSONKeyError is the standard JSON error response key.

View Source
const JSONKeyName = "name"

JSONKeyName is the standard JSON field name for "name" in ACP wire format. Used in content blocks, command descriptors, and MCP entries.

View Source
const JSONKeyOutput = "output"

JSONKeyOutput is the standard JSON response key for successful command output. Used by git/ and server/ packages.

View Source
const KeySessionID = "sessionId"

KeySessionID is the ACP wire key for the session identifier in parameter maps. Single source of truth; hub and command packages reference this constant instead of bare "sessionId" literals.

View Source
const MIMETypeJSON = "application/json"

MIMETypeJSON is the standard MIME type for JSON content.

View Source
const MaxChatNameBytes = 512

MaxChatNameBytes caps the byte length of chat names at creation and rename boundaries. All code paths that set Chat.Name should enforce this limit.

View Source
const MaxJSONBody = 1024 * 1024

MaxJSONBody is the maximum size for JSON request bodies (1 MiB).

View Source
const ModelAuto = "auto"

ModelAuto is the sentinel model value meaning "keep current / use task-based selection". Used by bridge, hub, and model-switch logic.

View Source
const MsgInternalError = "internal error"

MsgInternalError is the standard client-facing message for 500 responses.

View Source
const PermissionKindAllowOnce = "allow_once"

PermissionKindAllowOnce is the wire value kiro-cli sends in PermissionOption.Kind to identify the "allow once" choice.

View Source
const SecretMask = "***"

SecretMask is the placeholder value returned for every secret on public reads. Clients send this unchanged on update to keep the stored value; any other value replaces it.

Variables

View Source
var ErrNotIdle = errors.New("session not idle")

ErrNotIdle is the sentinel for "session not idle" errors from kiro-cli. Wraps the raw RPC error when the message contains "not idle" but the code isn't RPCCodeNotIdle, unifying the detection path for callers that need errors.Is classification.

View Source
var HiddenTags = []string{
	"[deprecated]",
	"[legacy]",
}

HiddenTags are the bracketed markers used by the UI model picker and the bridge to hide end-of-life models from the user. This is a subset of the models package's excludedTags: [Internal] and [Experimental] models are shown in the picker but excluded from ambient-task selection.

Functions

func BadRequest

func BadRequest(w http.ResponseWriter, msg string)

BadRequest writes a 400 with {"error": msg}.

func Conflict

func Conflict(w http.ResponseWriter, msg string)

Conflict writes a 409 with {"error": msg}.

func DecodeBody

func DecodeBody(w http.ResponseWriter, r *http.Request, v any, errMsg string) bool

DecodeBody applies LimitBody, decodes JSON into v, and returns true on success. On failure it writes a 400 response with errMsg and returns false.

func DecodeBodyOptional

func DecodeBodyOptional(w http.ResponseWriter, r *http.Request, v any)

DecodeBodyOptional applies LimitBody and decodes JSON into v. Unlike DecodeBody, a decode failure is silently ignored (v keeps its zero value) because the caller accepts an empty request body.

func DecodeJSON

func DecodeJSON(w http.ResponseWriter, r *http.Request, v any) bool

DecodeJSON is the shared three-step JSON decode prelude: check Content-Type, cap body at MaxJSONBody via MaxBytesReader, and distinguish an oversize request (413) from a malformed body (400). Returns true when v was populated successfully; false when an error response has already been written to w.

func ErrorJSON

func ErrorJSON(msg string) map[string]string

ErrorJSON returns the canonical error response map for JSON encoding. Use with WriteJSONStatus to write error responses consistently.

func ErrorJSONWithCode

func ErrorJSONWithCode(msg, code string) map[string]string

ErrorJSONWithCode returns an error response map with an additional machine-readable "code" field. Used by forge handlers that surface a stable error code alongside the human-readable message.

func FindAllowOnce

func FindAllowOnce(options []PermissionOption) string

FindAllowOnce returns the option_id of the first "allow_once" option, or "" if none exists.

func Forbidden

func Forbidden(w http.ResponseWriter, msg string)

Forbidden writes a 403 with {"error": msg}.

func InternalError

func InternalError(w http.ResponseWriter, err error)

InternalError writes a 500 with {"error": "internal error"} and logs the actual error at slog.Error for correlation. Never exposes internal error details to HTTP clients.

func JSONHeaders

func JSONHeaders(w http.ResponseWriter)

JSONHeaders sets the standard JSON response headers (Content-Type and X-Content-Type-Options). Exported for use by internal/fileutil.

func LimitBody

func LimitBody(w http.ResponseWriter, r *http.Request, maxBytes int64)

LimitBody wraps r.Body with MaxBytesReader to prevent oversized requests.

func MethodNotAllowed

func MethodNotAllowed(w http.ResponseWriter)

MethodNotAllowed writes a 405 with a standard message.

func NotFound

func NotFound(w http.ResponseWriter, msg string)

NotFound writes a 404 with {"error": msg}.

func Ok

func Ok(w http.ResponseWriter)

Ok writes a 200 with {"ok": true} — the standard "action succeeded" response used by the handful of endpoints that don't return data.

func RequireMethod

func RequireMethod(w http.ResponseWriter, r *http.Request, method string) bool

RequireMethod returns true if r.Method matches method; otherwise it writes a 405 response and returns false.

func SanitizeOutput

func SanitizeOutput(s string) string

SanitizeOutput applies both ANSI stripping and Unicode sanitization, iterating to a fixed point. A single pass is not enough: removing a hidden Unicode char (e.g. a zero-width space inside "\x1b(\u200b0") can complete an escape sequence that the next StripANSI pass then strips. Iterating guarantees the result is fully sanitized — no residual escapes an attacker hid behind zero-width chars — and makes the function idempotent.

Termination: SanitizeUnicode normalizes any invalid UTF-8 byte to a single U+FFFD rune (via strings.Map), so after the first pass the string is valid UTF-8 and every subsequent pass only removes runes. The rune count is therefore non-increasing and the fixed point is reached in O(len(s)) passes. (Byte length is NOT monotone — an invalid byte expands to a 3-byte U+FFFD on the first pass — so the guarantee is stated in runes, not bytes.) The output is always valid UTF-8, safe to persist to JSON chat files or echo to clients.

func SanitizeUnicode

func SanitizeUnicode(s string) string

SanitizeUnicode strips hidden Unicode characters that could be used for prompt injection via tool output. Covers TAG characters (U+E0000-E007F), zero-width spaces/joiners, format controls, and other invisible codepoints that Q Developer CLI's ExecuteCmd also strips. Apply alongside StripANSI on all tool output before persisting to chat files.

func ServerError

func ServerError(w http.ResponseWriter, clientMsg string, err error)

ServerError writes a 500 with a caller-specified client-visible message and logs the actual error at slog.Error. Use when the handler wants to surface a safe, specific message (e.g. "save failed") while still logging the raw error for debugging.

func StripANSI

func StripANSI(s string) string

StripANSI removes ANSI escape sequences from a string.

func StripCodeFence

func StripCodeFence(s string) string

StripCodeFence removes a single leading/trailing markdown code fence from model output. Models sometimes wrap their answer in ```lang ... ``` despite explicit instructions; this is a low-cost safety net that matters because the output goes straight into the editor buffer or commit message.

Semantics: strips one wrapping fence (the outermost). Intentional fences inside the content (e.g. a PR description containing code blocks) are preserved. This is the correct behaviour for both the git commit-message and server utility-bridge paths.

func TagExcluded

func TagExcluded(text string, tags []string) bool

TagExcluded returns true if text contains any of the given bracketed tags (case-insensitive).

func TextBlock

func TextBlock(content string) map[string]any

TextBlock returns a canonical ACP text content block:

{"type": "text", "text": content}

Eliminates ad-hoc map construction across hub, command, and translate.

func ValidChatID

func ValidChatID(id string) bool

ValidChatID reports whether id is a valid chat identifier. Accepts ULIDs, UUIDs, and the legacy "chat-<ms>" shape: alphanumerics, hyphens, and underscores only. Rejects empty, >128 chars, and anything containing path separators or traversal segments. This is the single source of truth for chat ID validation; hub/command.go and chat/store.go both delegate here.

func ValidIdent

func ValidIdent(s string) bool

ValidIdent reports whether s is safe to use as an agent or model identifier. Empty strings pass (the field is optional); non-empty strings must match identRe AND must not start with '.' or '-' AND must not be all-dot strings. This is the single source of truth; bridge/bridge.go and hub/command.go both delegate here.

func ValidMessageID

func ValidMessageID(id string) bool

ValidMessageID reports whether id is safe to echo on SSE and store on disk as the ID field of a message. This is the single source of truth; hub and command packages delegate here.

func ValidRequestID

func ValidRequestID(id string) bool

ValidRequestID reports whether the given request_id is safe to use as an idempotency cache key. Empty is valid (field is optional).

func ValidSessionID

func ValidSessionID(s string) bool

ValidSessionID reports whether s is safe to use as an ACP session id. Rejects empty strings, strings over 128 bytes, path separators, NUL, and parent-dir references. Session ids are concatenated into filesystem paths under ~/.kiro/sessions/cli; this function is the single source of truth for that safety gate. bridge/bridge.go delegates here.

func WorkingLabelForKind

func WorkingLabelForKind(kind ToolKind, title string) string

WorkingLabelForKind maps a tool kind to a human-readable label. Matches ASAI's VV() function from the frontend reducer.

func WriteJSON

func WriteJSON(w http.ResponseWriter, v any)

WriteJSON encodes v as JSON with status 200.

func WriteJSONStatus

func WriteJSONStatus(w http.ResponseWriter, code int, v any)

WriteJSONStatus encodes v with the given status code. Encode failures after the status has already been committed almost always indicate a non-marshalable value in v (a programmer bug), so they're logged at Warn so Loki picks them up.

func WriteRawJSON

func WriteRawJSON(w http.ResponseWriter, data []byte)

WriteRawJSON writes pre-marshalled JSON bytes with the standard Content-Type + X-Content-Type-Options headers. Use for pass-through of cached command replies and upstream JSON bodies (e.g. kiro-cli slash-command results) where json.Marshal would be a redundant round-trip. Write errors are best-effort (client may have hung up).

Types

type ACPBridge

type ACPBridge interface {
	// Start launches a fresh kiro-cli ACP subprocess. If
	// StartOpts.SessionID is empty, a new ACP session is created
	// (session/new). If populated, the existing session is resumed
	// (session/load). Exactly one call per bridge instance. ctx enables
	// caller-driven cancellation of the startup handshake.
	Start(ctx context.Context, opts *StartOpts) error
	// Stop kills the subprocess. NotifCh closes. Must be called at most
	// once per bridge instance.
	Stop()
	// Call sends a JSON-RPC request and waits for its matching response.
	// The provided context enables caller-driven cancellation; if ctx is
	// cancelled before the response arrives, Call returns ctx.Err().
	Call(ctx context.Context, method string, params any) (*RPCResponse, error)
	// Notify sends a JSON-RPC notification (no response expected). ctx
	// enables cancellation before the write is attempted.
	Notify(ctx context.Context, method string, params any) error
	// Respond writes a JSON-RPC response to an incoming request from
	// kiro-cli (e.g. fs/read_text_file). ctx enables cancellation before
	// the write is attempted.
	Respond(ctx context.Context, id int64, result any, err error) error
	// SessionID returns the ACP session id after Start completes.
	SessionID() SessionID
	// ModelID returns the current model id after Start completes.
	ModelID() ModelID
	// CurrentMode returns the currently-active session mode id (empty
	// if the agent doesn't expose modes).
	CurrentMode() string
	// Modes returns the set of session modes the running agent
	// supports. Empty for agents that don't expose modes.
	Modes() []SessionMode
	// Models returns the set of models the agent can swap to, with
	// deprecated/internal entries filtered out. Zero fallback: if
	// kiro-cli returns nothing, the slice is empty.
	Models() []SessionModel
	// SetModel performs an in-session model swap via session/set_model.
	// ctx enables caller-driven cancellation of the RPC call.
	SetModel(ctx context.Context, modelID string) error
	// NotifCh yields incoming ACP notifications. Closes when the
	// subprocess exits.
	NotifCh() <-chan *RPCResponse
	// SupportsDocuments reports whether the negotiated agent accepts
	// inline document/embedded content blocks, derived from the
	// initialize handshake's promptCapabilities.embeddedContext. When
	// false (kiro-cli 2.7's acp), document attachments must be sent as
	// path references instead of dropped `document` content blocks.
	SupportsDocuments() bool
}

ACPBridge manages a single kiro-cli ACP subprocess for one chat. Methods are safe for concurrent use; Call and Notify serialize writes to the subprocess stdin internally. IsPrompting/SetPrompting are wrappers' state; the bridge itself has no "busy" concept.

type ACPBridgeFactory

type ACPBridgeFactory func() ACPBridge

ACPBridgeFactory creates new ACPBridge instances. The hub calls it once per chat to spawn a fresh kiro-cli subprocess; each factory invocation is a new bridge.

type ACPUpdateKind

type ACPUpdateKind string

ACPUpdateKind identifies the subtype of an ACP session/update notification. Using typed constants prevents typos in the dispatch map and makes the protocol surface discoverable.

const (
	ACPUpdateAgentChunk   ACPUpdateKind = "agent_message_chunk"
	ACPUpdateThoughtChunk ACPUpdateKind = "agent_thought_chunk"
	ACPUpdateToolCall     ACPUpdateKind = "tool_call"
	ACPUpdateToolUpdate   ACPUpdateKind = "tool_call_update"
	ACPUpdatePlan         ACPUpdateKind = "plan"
	ACPUpdateModeChange   ACPUpdateKind = "current_mode_update"
	ACPUpdateSteering     ACPUpdateKind = "steering_inclusion"
)

type Attachment

type Attachment struct {
	Path string `json:"path"` // workspace-relative path
	Name string `json:"name"` // display name (filename.ext)
}

Attachment is a file attached to a prompt. The server reads the file and decides whether to send it as a document content block (PDF, DOCX, etc.) or a text path reference based on the extension.

type AuthHandler

type AuthHandler interface {
	RouteHandler
}

AuthHandler registers /api/whoami, /api/login, /api/logout.

type AvailableCommand

type AvailableCommand struct {
	Meta        map[string]any `json:"meta,omitempty"`
	Name        string         `json:"name"`
	Description string         `json:"description,omitempty"`
}

AvailableCommand is one entry in the slash-command catalogue surfaced by kiro-cli's _kiro.dev/commands/available notification. The wire shape carries opaque metadata; clients consume only Name and Description.

type Block

type Block struct {
	// Type is the discriminator: text | tool_use | thinking.
	Type BlockType `json:"type"`
	// Text carries the markdown text for Type=BlockText. Accumulated
	// across MessageChunkPayload events targeting this block index.
	Text string `json:"text,omitempty"`
	// Thinking carries the reasoning text for Type=BlockThinking.
	Thinking string `json:"thinking,omitempty"`
	// ToolCallID references a tool by ID in Message.ToolCalls for
	// Type=BlockToolUse. Empty for other types.
	ToolCallID string `json:"tool_call_id,omitempty"`
}

Block is one entry in an assistant message's chronological content array. Position in Message.Blocks IS the order in which the agent emitted the block — text → tool → text → tool, etc. — so the client renders them inline as they happened rather than concatenating all text into one bubble at the top with tools dumped below.

Replay-compatible: messages persisted before this field existed have Blocks=nil. Renderers fall back to the legacy Content + ToolCalls layout when Blocks is empty.

type BlockType

type BlockType string

BlockType discriminates content blocks in an assistant message's chronological content array. Mirrors Anthropic's `content_block.type` from the Messages API streaming spec — the same model claude-code uses to render text, tool calls, and thinking traces inline as the agent emits them rather than splitting them into separate sections.

const (
	// BlockText is a markdown text segment from the agent.
	BlockText BlockType = "text"
	// BlockToolUse is a tool invocation. Only the ToolCallID is carried
	// in the block; the full ToolCall lives in Message.ToolCalls so
	// status updates (pending → in_progress → completed) don't need
	// to touch the block array.
	BlockToolUse BlockType = "tool_use"
	// BlockThinking is an extended-thinking trace segment.
	BlockThinking BlockType = "thinking"
)

type Broadcaster

type Broadcaster interface {
	Broadcast(ctx context.Context, evt ServerEvent)
}

Broadcaster sends events to all connected SSE clients.

type Chat

type Chat struct {
	CrewMessageIDs      map[string]string `json:"crew_message_ids,omitempty"`
	Name                string            `json:"name"`
	Agent               string            `json:"agent,omitempty"`
	Model               string            `json:"model,omitempty"`
	ACPSessionID        string            `json:"acp_session_id,omitempty"`
	CurrentModeID       string            `json:"current_mode_id,omitempty"`
	ParentChatID        ChatID            `json:"parent_chat_id,omitempty"`
	CompactionWatermark string            `json:"compaction_watermark,omitempty"`
	Summary             string            `json:"summary,omitempty"`
	OldestCheckpointTag string            `json:"oldest_checkpoint_tag,omitempty"`
	ID                  string            `json:"id"`
	AvailableModels     []SessionModel    `json:"available_models,omitempty"`
	AvailableModes      []SessionMode     `json:"available_modes,omitempty"`
	Messages            []Message         `json:"messages"`
	CurrentPlan         []PlanEntry       `json:"current_plan,omitempty"`
	Usage               Usage             `json:"usage"`
	CreatedAt           int64             `json:"created_at"`
	UpdatedAt           int64             `json:"updated_at"`
	RewindFromTurn      int               `json:"rewind_from_turn,omitempty"`
	MessageCount        int               `json:"message_count"`
	SupervisedMode      bool              `json:"supervised_mode,omitempty"`
	AutoApproveCrew     bool              `json:"auto_approve_crew,omitempty"`
}

Chat is the full persisted chat. Serialized as <dir>/<id>.json.

func (*Chat) Header

func (c *Chat) Header() ChatHeader

Header returns the chat's metadata without messages. Used for list endpoints and SSE broadcasts when messages are not needed.

type ChatDeletedPayload

type ChatDeletedPayload struct {
	ID string `json:"id"`
}

ChatDeletedPayload is the payload for type="chat_deleted".

type ChatHeader

type ChatHeader struct {
	ParentChatID        ChatID         `json:"parent_chat_id,omitempty"`
	Name                string         `json:"name"`
	Agent               string         `json:"agent,omitempty"`
	Model               string         `json:"model,omitempty"`
	ACPSessionID        string         `json:"acp_session_id,omitempty"`
	CurrentModeID       string         `json:"current_mode_id,omitempty"`
	ID                  string         `json:"id"`
	CompactionWatermark string         `json:"compaction_watermark,omitempty"`
	OldestCheckpointTag string         `json:"oldest_checkpoint_tag,omitempty"`
	Summary             string         `json:"summary,omitempty"`
	AvailableModels     []SessionModel `json:"available_models,omitempty"`
	AvailableModes      []SessionMode  `json:"available_modes,omitempty"`
	Usage               Usage          `json:"usage"`
	CreatedAt           int64          `json:"created_at"`
	UpdatedAt           int64          `json:"updated_at"`
	MessageCount        int            `json:"message_count"`
	SupervisedMode      bool           `json:"supervised_mode,omitempty"`
	AutoApproveCrew     bool           `json:"auto_approve_crew,omitempty"`
}

ChatHeader is the metadata-only view of a Chat. Field order is driven by fieldalignment packing, not Chat's field order; both structs serialise to JSON independently so the visual mismatch is harmless.

type ChatID

type ChatID string

ChatID is a typed wrapper for chat identifiers. The underlying string marshals identically to JSON, preserving the wire contract.

func NewChatID

func NewChatID() ChatID

NewChatID generates a fresh UUIDv7 chat identifier. Time-ordered, globally unique, standard format.

func (ChatID) String

func (c ChatID) String() string

String implements fmt.Stringer for logging convenience.

type ChatStore

type ChatStore interface {
	RouteHandler

	// SetBroadcaster wires the SSE broadcaster the store uses to emit
	// chat_created / chat_updated / chat_deleted / message_* events.
	// Called once after construction to break the init cycle with the hub.
	SetBroadcaster(b Broadcaster)

	// Get returns the full chat at id, or false if it does not exist.
	Get(ctx context.Context, id ChatID) (*Chat, bool)
	// List returns every chat's header (no messages) sorted by UpdatedAt
	// descending. Checks ctx.Err() between per-file reads.
	List(ctx context.Context) []ChatHeader
	// ChildrenOf returns the IDs of chats whose ParentChatID equals
	// parentID. Used by delete to cascade to rewind children without
	// loading the full chat list.
	ChildrenOf(ctx context.Context, parentID ChatID) []ChatID
	// BuildHistory returns a plain-text transcript used for compress
	// priming. Returns "" if the chat is missing or empty.
	BuildHistory(ctx context.Context, id ChatID) string

	// Mutate is the single write primitive: load → apply → save →
	// broadcast chat_created / chat_updated.
	Mutate(ctx context.Context, id ChatID, mutate func(c *Chat, exists bool) bool) error
	// Delete removes the chat file and broadcasts chat_deleted.
	Delete(ctx context.Context, id ChatID) error
	// Archive moves a chat to the archive directory instead of deleting.
	Archive(ctx context.Context, id ChatID) error
	// ListArchived returns headers for all archived chats.
	ListArchived(ctx context.Context) []ChatHeader
	// RestoreArchived moves a chat from the archive back to active.
	RestoreArchived(ctx context.Context, id ChatID) error
	// UpdateArchivedSummary rewrites an archived chat's Summary field.
	UpdateArchivedSummary(ctx context.Context, id ChatID, summary string) error
	// LoadArchived returns the parsed archived chat.
	LoadArchived(ctx context.Context, id ChatID) (*Chat, error)
	// DeleteArchived permanently removes a single archived chat.
	DeleteArchived(ctx context.Context, id ChatID) error
	// AppendMessage appends msg to the chat's messages.
	AppendMessage(ctx context.Context, chatID ChatID, msg *Message) error
	// UpdateMessage mutates one message in place (by ID).
	UpdateMessage(ctx context.Context, chatID ChatID, msgID string, mutate func(*Message)) error
}

ChatStore persists chat sessions as one JSON file per chat under <dir>/<chat_id>.json. The directory listing is the index; there is no separate index file. Mutations go through Mutate (atomic load → apply → save → broadcast); there is no event-sourcing replay.

type CheckpointConflictsResponse

type CheckpointConflictsResponse struct {
	Conflicts []checkpoint.ConflictPayload `json:"conflicts"`
}

CheckpointConflictsResponse is the typed response for the conflicts endpoint.

type CheckpointDiffResponse

type CheckpointDiffResponse struct {
	Files []checkpoint.FileChange `json:"files"`
}

CheckpointDiffResponse is the typed response for the checkpoint diff endpoint.

type CheckpointRestorePreviewResponse

type CheckpointRestorePreviewResponse struct {
	Files []string `json:"files"`
}

CheckpointRestorePreviewResponse is the typed response for restore-preview.

type CheckpointRestoredPayload

type CheckpointRestoredPayload struct {
	Tag          string `json:"tag"`
	MessageCount int    `json:"message_count"`
}

CheckpointRestoredPayload is the payload for type="checkpoint_restored". Replaces the ad-hoc map[string]any so the wire shape is discoverable via IDE completion and typos in key names become compile errors.

type CheckpointService

type CheckpointService interface {
	Snapshot(ctx context.Context, chatID ChatID, relPath string, newContent []byte, messageCount int) (checkpoint.Tag, error)
	Restore(ctx context.Context, chatID ChatID, tag checkpoint.Tag) (int, error)
	RestorePreview(ctx context.Context, chatID ChatID, tag checkpoint.Tag) ([]string, error)
	CheckoutFile(ctx context.Context, chatID ChatID, tag checkpoint.Tag, relPath string) error
	Diff(ctx context.Context, chatID ChatID, from, to checkpoint.Tag) ([]checkpoint.FileChange, error)
	Conflicts(ctx context.Context, chatID ChatID) ([]checkpoint.ConflictPayload, error)
	ReadBlob(ctx context.Context, chatID ChatID, sha string) ([]byte, error)
	OldestTag(ctx context.Context, chatID ChatID) checkpoint.Tag
	AdvanceTurn(ctx context.Context, chatID ChatID, messageCount int)
	Cleanup(ctx context.Context, chatID ChatID)
	StartBackgroundTasks(ctx context.Context)
	Stop()
}

CheckpointService is the consumer-side interface for the checkpoint subsystem. Enables stub/mock injection in hub tests without constructing a real checkpoint.Store with filesystem state.

type ClearReason

type ClearReason string

ClearReason identifies why pending changes or trust were cleared. Using a typed string prevents typos at construction sites and makes the valid set discoverable via IDE completion.

const (
	ClearReasonTurnEnded    ClearReason = "turn_ended"
	ClearReasonCancelled    ClearReason = "cancelled"
	ClearReasonModeDisabled ClearReason = "mode_disabled"
	ClearReasonChatDeleted  ClearReason = "chat_deleted"
	ClearReasonShutdown     ClearReason = "shutdown"
	ClearReasonUserCleared  ClearReason = "user_cleared"
)

type ClientCommand

type ClientCommand struct {
	Type      CommandType     `json:"type"`
	RequestID string          `json:"request_id"`
	ChatID    ChatID          `json:"chat_id,omitempty"`
	Payload   json.RawMessage `json:"payload,omitempty"`
}

ClientCommand is the envelope for every command the browser posts. Type determines how Payload unmarshals.

type CommandBridge

type CommandBridge interface {
	// Call sends an RPC call to kiro-cli.
	Call(ctx context.Context, method string, params any) (*RPCResponse, error)
	// Notify sends a one-way notification to kiro-cli.
	Notify(ctx context.Context, method string, params any) error
	// Respond sends a permission response to kiro-cli.
	Respond(ctx context.Context, requestID int64, result any, err error) error
	// SessionID returns the current ACP session ID.
	SessionID() SessionID
	// TryAcquireForPrompt attempts to lock the bridge for prompting.
	TryAcquireForPrompt() bool
	// ReleaseAfterPrompt releases the prompt lock.
	ReleaseAfterPrompt()
	// SetLastActive updates the last-active timestamp.
	SetLastActive()
	// SetPrompting sets the bridge state to prompting (for recovery).
	SetPrompting()
	// IsPrimed reports whether the bridge has been primed.
	IsPrimed() bool
	// SetPrimed marks the bridge as primed.
	SetPrimed()
	// SupportsDocuments reports whether the negotiated agent accepts
	// inline document/embedded content blocks (promptCapabilities.
	// embeddedContext). Gates whether attachments are sent as `document`
	// blocks or as path references. See ACPBridge.SupportsDocuments.
	SupportsDocuments() bool
}

CommandBridge abstracts the per-chat ACP bridge for command handlers. Declared here (consumer-side) so both command and hub can reference the same contract without circular imports.

type CommandType

type CommandType string

CommandType identifies the kind of client command posted to /api/command. Using a typed string instead of bare literals makes typos a compile error and the full command vocabulary discoverable.

const (
	CmdCreateChat               CommandType = "create_chat"
	CmdPrompt                   CommandType = "prompt"
	CmdCancel                   CommandType = "cancel"
	CmdDeleteChat               CommandType = "delete_chat"
	CmdSwitchModel              CommandType = "switch_model"
	CmdPermissionResponse       CommandType = "permission_response"
	CmdElicitationResponse      CommandType = "elicitation_response"
	CmdSpawnSubagent            CommandType = "spawn_subagent"
	CmdMessageSubagent          CommandType = "message_subagent"
	CmdTerminateSubagent        CommandType = "terminate_subagent"
	CmdAttachSubagent           CommandType = "attach_subagent"
	CmdListSessions             CommandType = "list_sessions"
	CmdSetAutoApproveCrew       CommandType = "set_auto_approve_crew"
	CmdRestoreCheckpoint        CommandType = "restore_checkpoint"
	CmdUndoEdit                 CommandType = "undo_edit"
	CmdRewindChat               CommandType = "rewind_chat"
	CmdPromoteRewindChat        CommandType = "promote_rewind_chat"
	CmdDiscardRewindChat        CommandType = "discard_rewind_chat"
	CmdSetEffort                CommandType = "set_effort"
	CmdCreateHook               CommandType = "create_hook"
	CmdResolvePendingChange     CommandType = "resolve_pending_change"
	CmdResolvePendingPartial    CommandType = "resolve_pending_change_partial"
	CmdResolveAllPendingChanges CommandType = "resolve_all_pending_changes"
	CmdSetSupervisedMode        CommandType = "set_supervised_mode"
	CmdTrustPendingChanges      CommandType = "trust_pending_changes"
	CmdClearPendingTrust        CommandType = "clear_pending_trust"
)

Command type constants. Every value here corresponds to a key in hub/command.go's registerCommandHandlers dispatch map.

type CommandsUpdatedPayload

type CommandsUpdatedPayload struct {
	Commands []AvailableCommand `json:"commands"`
	Prompts  []AvailableCommand `json:"prompts,omitempty"`
}

CommandsUpdatedPayload is the payload for type="commands_updated".

type CompactionStartedPayload

type CompactionStartedPayload struct{}

CompactionStartedPayload is the payload for type="compaction_started".

type ConflictDetectedPayload

type ConflictDetectedPayload = checkpoint.ConflictPayload

ConflictDetectedPayload is the payload for type="conflict_detected". Type alias to checkpoint/types.ConflictPayload — single source of truth.

type ConnectedPayload

type ConnectedPayload struct {
	Floor uint64 `json:"floor"`
	Head  uint64 `json:"head"`
}

ConnectedPayload is the payload for type="connected", the SSE handshake event. Floor is the oldest event ID still in the replay ring; Head is the newest. Clients with last-seen-id < Floor know they missed events and should refetch authoritative state.

type CreateChatCommand

type CreateChatCommand struct {
	Name  string `json:"name,omitempty"`
	Agent string `json:"agent,omitempty"`
	Model string `json:"model,omitempty"`
}

CreateChatCommand is the payload for type="create_chat".

Name is optional and capped at 512 bytes (maxChatNameBytes); empty values default to "New conversation". Agent and Model are optional; if non-empty they must match validIdent (ASCII alphanumerics plus `_.-`, 1-128 bytes). Validation failures return HTTP 400.

type Crew

type Crew struct {
	Group         string             `json:"group"`
	Subagents     []CrewSubagent     `json:"subagents"`
	PendingStages []CrewPendingStage `json:"pending_stages,omitempty"`
}

Crew is the live state of one crew message. Subagents is the latest snapshot; Group is the shared group id across the subagents (used for message identity when kiro-cli emits subsequent updates). PendingStages lists subagents that are planned but not yet spawned.

type CrewPendingStage

type CrewPendingStage struct {
	Name      string   `json:"name"`
	AgentName string   `json:"agent_name"`
	Role      string   `json:"role,omitempty"`
	DependsOn []string `json:"depends_on,omitempty"`
}

CrewPendingStage is a planned subagent that hasn't spawned yet. kiro-cli emits these in the pendingStages array of list_update.

type CrewStatus

type CrewStatus string

CrewStatus is the lifecycle state of a crew subagent. The full set reflects what kiro-cli actually emits via _kiro.dev/subagent/list_update; the comment on CrewSubagent.Status previously called these "other kiro-cli types" — they are now first-class enum values.

const (
	CrewWorking    CrewStatus = "working"
	CrewTerminated CrewStatus = "terminated"
	CrewError      CrewStatus = "error"
	CrewPending    CrewStatus = "pending"
)

type CrewSubagent

type CrewSubagent struct {
	SessionID    string     `json:"session_id"`
	SessionName  string     `json:"session_name"`  // short user-facing label ("count_to_3")
	AgentName    string     `json:"agent_name"`    // kiro-cli agent config used
	InitialQuery string     `json:"initial_query"` // task the subagent was given
	Status       CrewStatus `json:"status"`        // see CrewStatus enum above
	StatusMsg    string     `json:"status_msg,omitempty"`
	Group        string     `json:"group"` // grouping key from kiro-cli, e.g. "crew-<desc>"
	Role         string     `json:"role,omitempty"`
	DependsOn    []string   `json:"depends_on,omitempty"`
}

CrewSubagent is one subagent in a `crew` event message, sourced from kiro-cli's `_kiro.dev/subagent/list_update` notification. Each kiro-cli snapshot replaces the full list; we persist the last seen snapshot on the message so reloading a chat shows the final state.

type EffortLevel

type EffortLevel string

EffortLevel is a typed enum for reasoning effort levels.

const (
	EffortLow    EffortLevel = "low"
	EffortMedium EffortLevel = "medium"
	EffortHigh   EffortLevel = "high"
	EffortXHigh  EffortLevel = "xhigh"
	EffortMax    EffortLevel = "max"
)

Valid effort level constants.

func (EffortLevel) Valid

func (e EffortLevel) Valid() bool

Valid reports whether e is a recognised effort level.

type ElicitationCompletePayload added in v0.1.39

type ElicitationCompletePayload struct {
	RequestID int64 `json:"request_id"`
}

ElicitationCompletePayload is the SSE payload for type="elicitation_complete": an upstream cancellation telling the client to dismiss the dialog for RequestID without a user answer.

type ElicitationNeededPayload added in v0.1.39

type ElicitationNeededPayload struct {
	RequestedSchema *ElicitationRequestSchema `json:"requested_schema,omitempty"`
	Mode            string                    `json:"mode,omitempty"`
	Message         string                    `json:"message,omitempty"`
	URL             string                    `json:"url,omitempty"`
	ToolCallID      string                    `json:"tool_call_id,omitempty"`
	SubSessionID    string                    `json:"sub_session_id,omitempty"`
	RequestID       int64                     `json:"request_id"`
}

ElicitationNeededPayload is the SSE payload for type="elicitation_needed". Mirrors PermissionNeededPayload's role: it carries everything the client needs to render the dialog plus the RequestID to echo back in the elicitation_response command. Mode is "form" or "url"; URL-mode elicitations carry URL and no RequestedSchema.

type ElicitationPropertySchema added in v0.1.39

type ElicitationPropertySchema struct {
	Default     any      `json:"default,omitempty"`
	MinLength   *int     `json:"minLength,omitempty"`
	MaxLength   *int     `json:"maxLength,omitempty"`
	Type        string   `json:"type"`
	Title       string   `json:"title,omitempty"`
	Description string   `json:"description,omitempty"`
	Format      string   `json:"format,omitempty"`
	Pattern     string   `json:"pattern,omitempty"`
	Enum        []string `json:"enum,omitempty"`
}

ElicitationPropertySchema describes one field in an elicitation form. Type is the discriminator ("string" | "number" | "integer" | "boolean" | "array"); the other fields are populated as relevant to that type. Unset fields are omitted on the wire.

type ElicitationRequestSchema added in v0.1.39

type ElicitationRequestSchema struct {
	Type        string                               `json:"type,omitempty"`
	Title       string                               `json:"title,omitempty"`
	Description string                               `json:"description,omitempty"`
	Properties  map[string]ElicitationPropertySchema `json:"properties,omitempty"`
	Required    []string                             `json:"required,omitempty"`
}

ElicitationRequestSchema is the JSON-schema-shaped object describing a form: a map of property name to its schema, plus the required set.

type ElicitationResponseCommand added in v0.1.39

type ElicitationResponseCommand struct {
	Action    string          `json:"action"`
	Content   json.RawMessage `json:"content,omitempty"`
	RequestID int64           `json:"request_id"`
}

ElicitationResponseCommand is the payload for type="elicitation_response". RequestID echoes the value from the elicitation_needed event. Action is "accept" | "decline" | "cancel"; Content carries the filled form values (an object) only on accept and is forwarded verbatim to kiro-cli.

type ElicitationResult added in v0.1.39

type ElicitationResult struct {
	Action  string          `json:"action"`
	Content json.RawMessage `json:"content,omitempty"`
}

ElicitationResult is the response we send back on elicitation/create. Action is one of accept/decline/cancel; Content carries the filled form values (object) only on accept.

type ErrorCode

type ErrorCode string

ErrorCode identifies an SSE error event class. Using a typed string prevents typos at construction sites and makes the valid set discoverable via IDE completion.

const (
	ErrCodeRecoveryFailed    ErrorCode = "recovery_failed"
	ErrCodeBridgeStartFailed ErrorCode = "bridge_start_failed"
	ErrCodePromptFailed      ErrorCode = "prompt_failed"
	ErrCodeAgentNotFound     ErrorCode = "agent_not_found"
	ErrCodeModelNotFound     ErrorCode = "model_not_found"
	ErrCodeAgentConfigError  ErrorCode = "agent_config_error"
	ErrCodeRateLimit         ErrorCode = "rate_limit"
	ErrCodeStreamTimeout     ErrorCode = "stream_timeout"
	ErrCodeSpawnFailed       ErrorCode = "spawn_failed"
	ErrCodeSwitchFailed      ErrorCode = "switch_failed"
	ErrCodeCompactionFailed  ErrorCode = "compaction_failed"
)

type ErrorPayload

type ErrorPayload struct {
	Code    ErrorCode `json:"code"`
	Message string    `json:"message"`
}

ErrorPayload is the payload for type="error". Code lets clients react per-class without string-matching.

type Event

type Event[T any] struct {
	Payload T         `json:"payload,omitempty"`
	Type    EventType `json:"type"`
	ChatID  ChatID    `json:"chat_id,omitempty"`
}

Event is the server→client event envelope, generic over payload type. JSON serialization is identical to ServerEvent: {type, chat_id, payload}. Used as a construction helper via NewEvent to provide compile-time type safety at emit sites; the result is converted to ServerEvent for broadcast.

type EventKind

type EventKind string

EventKind identifies subtypes of RoleEvent messages.

const (
	EventInterrupted   EventKind = "interrupted"
	EventCancelled     EventKind = "cancelled"
	EventModelSwitched EventKind = "model_switched" // fresh ACP session with a new model
	EventCompacted     EventKind = "compacted"      // kiro-cli's native /compact, carries summary
	EventCrew          EventKind = "crew"           // kiro-cli's subagent orchestration (list_update snapshots)
	EventAgentSwitched EventKind = "agent_switched" // kiro-cli's agent hand-off mid-session
	EventCompactFailed EventKind = "compaction_failed"
	EventInbox         EventKind = "inbox" // subagent-to-parent message
)

type EventType

type EventType string

EventType identifies the kind of SSE event broadcast to clients. Using a typed string instead of bare literals makes typos a compile error and the full event vocabulary discoverable via IDE completion.

const (
	EventChatCreated           EventType = "chat_created"
	EventChatUpdated           EventType = "chat_updated"
	EventChatDeleted           EventType = "chat_deleted"
	EventCheckpointRestored    EventType = "checkpoint_restored"
	EventCommandsUpdated       EventType = "commands_updated"
	EventCompactionStarted     EventType = "compaction_started"
	EventConflictDetected      EventType = "conflict_detected"
	EventConnected             EventType = "connected"
	EventError                 EventType = "error"
	EventElicitationNeeded     EventType = "elicitation_needed"
	EventElicitationComplete   EventType = "elicitation_complete"
	EventMCPConfigChanged      EventType = "mcp_config_changed"
	EventMCPConnected          EventType = "mcp_connected"
	EventMCPDisconnected       EventType = "mcp_disconnected"
	EventMCPFailed             EventType = "mcp_failed"
	EventMCPOAuthNeeded        EventType = "mcp_oauth_needed"
	EventMCPPrewarm            EventType = "mcp_prewarm"
	EventMessageAppended       EventType = "message_appended"
	EventMessageChunk          EventType = "message_chunk"
	EventMessageCreated        EventType = "message_created"
	EventMessageUpdated        EventType = "message_updated"
	EventModeChanged           EventType = "mode_changed"
	EventPendingChangeAdded    EventType = "pending_change_added"
	EventPendingChangeResolved EventType = "pending_change_resolved"
	EventPendingChangesCleared EventType = "pending_changes_cleared"
	EventPendingTrustCleared   EventType = "pending_trust_cleared"
	EventPendingTrustEnabled   EventType = "pending_trust_enabled"
	EventPermissionNeeded      EventType = "permission_needed"
	EventForgesChanged         EventType = "forges_changed"
	EventSessionListUpdated    EventType = "session_list_updated"
	EventSettingsUpdated       EventType = "settings_updated"
	EventSteeringLoaded        EventType = "steering_loaded"
	EventSubagentActivity      EventType = "subagent_activity"
	EventTerminalCreated       EventType = "terminal_created"
	EventTerminalExited        EventType = "terminal_exited"
	EventTerminalOutput        EventType = "terminal_output"
	EventToolCall              EventType = "tool_call"
	EventToolCallUpdate        EventType = "tool_call_update"
	EventTurnEnded             EventType = "turn_ended"
	EventWorkingLabel          EventType = "working_label"
)

SSE event type constants. Using these instead of bare string literals makes typos a compile error and the full event vocabulary discoverable.

type FileChange

type FileChange struct {
	LinesAdded   int  `json:"lines_added"`
	LinesRemoved int  `json:"lines_removed"`
	IsNewFile    bool `json:"is_new_file,omitempty"`
}

FileChange tracks per-file change stats during a turn.

type FileHandler

type FileHandler interface {
	RouteHandler
}

FileHandler registers file browsing and editing routes under /api/file/* and /api/files/*.

type ForgesChangedPayload

type ForgesChangedPayload struct{}

ForgesChangedPayload is the payload for type="forges_changed". Sent after a forge is connected, disconnected, or re-probed.

type GitHandler

type GitHandler interface {
	RouteHandler
}

GitHandler registers git-related HTTP routes under /api/git/*.

type Hub

type Hub interface {
	Broadcaster
	RouteHandler

	// RegisterSlashRoutes wires /api/slash/execute and /api/slash/options.
	RegisterSlashRoutes(mux *http.ServeMux)

	// Shutdown drains in-flight prompts and closes all bridges.
	Shutdown()
}

Hub manages SSE connections and dispatches POST /api/command.

type LimitedWriter

type LimitedWriter struct {
	W io.Writer
	N int64
}

LimitedWriter writes at most N bytes to W and silently drops the rest. Used for bounded stderr/stdout capture from subprocess handlers so a misbehaving or hostile subprocess can't OOM the container.

func (*LimitedWriter) Write

func (lw *LimitedWriter) Write(p []byte) (int, error)

Write implements io.Writer, enforcing the byte cap.

type MCPConfig

type MCPConfig interface {
	// ACPServers returns the enabled servers shaped for kiro-cli's
	// session/new and session/load mcpServers parameter. Each entry
	// is an opaque map whose shape follows the ACP spec's
	// McpServerStdio / McpServerHttp / McpServerSse schema —
	// internal/mcp populates per-transport fields; the hub passes
	// through verbatim.
	ACPServers(ctx context.Context) []map[string]any
	// EnabledNames returns the set of enabled server names. Used by the
	// hub to filter server_initialized notifications that belong to
	// disabled entries (defensive — kiro-cli shouldn't send them, but
	// we don't trust the boundary).
	EnabledNames(ctx context.Context) map[string]struct{}
	// SetKnownTools persists the tool list for a server so the UI can
	// show suggestions in the per-tool deny section.
	SetKnownTools(ctx context.Context, name string, tools []string)
}

MCPConfig is the hub's view of the user's configured MCP servers. The hub does not care about persistence or validation; it only needs to know which ACP server configs to pass on bridge spawn and which raw records to expose for pre-warm.

type MCPConfigChangedPayload

type MCPConfigChangedPayload struct{}

MCPConfigChangedPayload is the payload for type="mcp_config_changed".

type MCPConnectedPayload

type MCPConnectedPayload struct {
	Server string `json:"server"`
}

MCPConnectedPayload is the payload for type="mcp_connected", emitted when kiro-cli reports _kiro.dev/mcp/server_initialized.

type MCPDisconnectedPayload

type MCPDisconnectedPayload struct {
	Server string `json:"server"`
}

MCPDisconnectedPayload is the payload for type="mcp_disconnected". Emitted when the hub's last bridge exits: kiro-cli's MCP subprocesses shut down with it, so no configured server is currently live. Clients use this to clear their runtime-state map.

type MCPFailedPayload

type MCPFailedPayload struct {
	Server string `json:"server"`
	Error  string `json:"error"`
}

MCPFailedPayload is the payload for type="mcp_failed", emitted when kiro-cli reports _kiro.dev/mcp/server_init_failure.

type MCPOAuthPayload

type MCPOAuthPayload struct {
	Server string `json:"server"`
	URL    string `json:"url"`
}

MCPOAuthPayload is the payload for type="mcp_oauth_needed", emitted when kiro-cli reports _kiro.dev/mcp/oauth_request. URL is the provider's authorisation endpoint; the user completes the flow in a new tab.

type MCPPrewarmPayload

type MCPPrewarmPayload struct {
	Package string `json:"package"`
	State   string `json:"state"` // "installing", "done", "failed"
}

MCPPrewarmPayload is the payload for type="mcp_prewarm", emitted when a prewarm install starts, succeeds, or fails. The UI uses this to show "Installing..." next to the server name in the MCP panel.

type MCPServerState

type MCPServerState string

MCPServerState is the lifecycle status of one configured MCP server. Exported so the hub's mcpRegistry and the /api/mcp/status endpoint share a single typed enum with compile-time safety.

const (
	MCPStateIdle      MCPServerState = "idle"       // configured but no bridge running
	MCPStateConnected MCPServerState = "connected"  // kiro-cli reported server_initialized
	MCPStateOAuth     MCPServerState = "needs_auth" // kiro-cli sent oauth_request
	MCPStateFailed    MCPServerState = "failed"     // kiro-cli sent server_init_failure
)

type MCPSnapshotServer

type MCPSnapshotServer struct {
	Name string `json:"name"`
}

MCPSnapshotServer is one entry in a hub-to-steering MCP registry snapshot. Defined here to keep the steering package decoupled from internal/hub.

type Message

type Message struct {
	// Crew is populated only for EventKind=crew messages; holds the
	// latest subagent snapshot from kiro-cli's list_update stream.
	Crew    *Crew  `json:"crew,omitempty"`
	ID      string `json:"id"`
	Role    Role   `json:"role"`
	Content string `json:"content,omitempty"`
	// Reasoning is the agent's "thinking" trace for this turn —
	// extended-thinking models emit it as a parallel stream alongside
	// Content. Persisted on the same message so the one-message-per-turn
	// invariant holds; rendered above the content bubble in the UI.
	Reasoning string      `json:"reasoning,omitempty"`
	EventKind EventKind   `json:"event_kind,omitempty"`
	ToolCalls []ToolCall  `json:"tool_calls,omitempty"`
	Plan      []PlanEntry `json:"plan,omitempty"`
	// Blocks is the chronologically-ordered content array — text /
	// tool_use / thinking blocks in the order the agent emitted them.
	// Mirrors Anthropic's Messages API content array. Newly-streamed
	// assistant messages populate Blocks alongside Content / ToolCalls
	// (the latter two are kept for back-compat with replay of older
	// messages that don't have Blocks). The client prefers Blocks when
	// non-empty and falls back to Content + ToolCalls otherwise.
	Blocks []Block `json:"blocks,omitempty"`
	Ts     int64   `json:"ts"`
}

Message is one entry in a chat transcript. Tool calls are embedded in assistant messages (not standalone messages). Event messages carry an EventKind for inline rendering (compression, cancellation, restart, subagent orchestration).

type MessageChunkPayload

type MessageChunkPayload struct {
	MessageID   string `json:"message_id"`
	Delta       string `json:"delta"`
	IsReasoning bool   `json:"is_reasoning,omitempty"`
	BlockIndex  int    `json:"block_index"`
}

MessageChunkPayload is the payload for type="message_chunk" (assistant streaming deltas). IsReasoning distinguishes reasoning deltas from regular content deltas — both flow through the same SSE event but land on different fields client-side (Message.Reasoning vs Content). BlockIndex addresses the chronological content block this delta belongs to (Anthropic's content_block_delta.index): consecutive text chunks share an index; a tool_call between text segments bumps the next text chunk to a new index. Clients use this to accumulate deltas into the right block in Message.Blocks.

type MessageSubagentCommand

type MessageSubagentCommand struct {
	SubSessionID string `json:"sub_session_id"`
	Text         string `json:"text"`
}

MessageSubagentCommand is the payload for type="message_subagent". Sends a message to a specific subagent via message/send.

type MeteringItem

type MeteringItem struct {
	UnitSingular string  `json:"unit_singular"`
	UnitPlural   string  `json:"unit_plural"`
	Value        float64 `json:"value"`
}

MeteringItem is one usage dimension reported by kiro-cli's meteringUsage array. UnitPlural is the canonical identifier ("credits", "tokens", "requests"); UnitSingular is its singular form.

type ModeChangedPayload

type ModeChangedPayload struct {
	ModeID string `json:"mode_id"`
}

ModeChangedPayload is the payload for type="mode_changed".

type ModelID

type ModelID string

ModelID is a typed wrapper for model identifiers. Values are validated via ValidIdent before assignment; the type makes invalid-state propagation a compile-time-visible decision.

func (ModelID) String

func (m ModelID) String() string

String implements fmt.Stringer for logging convenience.

func (ModelID) Valid

func (m ModelID) Valid() bool

Valid reports whether the model id passes identifier validation. Empty is valid (the field is optional).

type PendingAction

type PendingAction string

PendingAction discriminates between the two resolution outcomes for a staged pending change. Using a typed string prevents typos at construction sites and makes the valid set discoverable.

const (
	PendingActionAccept PendingAction = "accept"
	PendingActionReject PendingAction = "reject"
)

func (PendingAction) Valid

func (a PendingAction) Valid() bool

Valid reports whether a is one of the recognised pending actions.

type PendingChange

type PendingChange struct {
	ToolCallID string            `json:"tool_call_id"`
	ChatID     ChatID            `json:"chat_id"`
	Path       string            `json:"path"`
	Kind       PendingChangeKind `json:"kind"` // "create" | "edit" | "delete"
	OldText    string            `json:"old_text,omitempty"`
	NewText    string            `json:"new_text,omitempty"`
	CreatedAt  int64             `json:"created_at"`
	Truncated  bool              `json:"truncated,omitempty"`
}

PendingChange is one staged file operation awaiting user approval in Supervised mode. Key is ToolCallID (kiro-cli's id; unique per call); the Kind discriminates between writes, creates (no OldText), and deletes (no NewText).

OldText and NewText are capped at pendingTextCap on the server side (4 MiB). When truncated, the client's "View diff" tab falls back to a file fetch for the full content; the staged payload only carries enough for the pill-popover summary and the inline diff preview.

type PendingChangeAddedPayload

type PendingChangeAddedPayload struct {
	Change PendingChange `json:"change"`
}

PendingChangeAddedPayload is the payload for type="pending_change_added". Emitted when the Supervised-mode fs handler has received a write from kiro-cli and is blocking the agent until the user resolves it. Clients render a tool-card-level Accept/Reject pair and surface the op in the Supervised pill's popover.

type PendingChangeKind

type PendingChangeKind string

PendingChangeKind discriminates between the three staged-file operations in Supervised mode. Using a typed string prevents typos at construction sites and makes the valid set discoverable.

const (
	PendingKindCreate PendingChangeKind = "create"
	PendingKindEdit   PendingChangeKind = "edit"
	PendingKindDelete PendingChangeKind = "delete"
)

func (PendingChangeKind) Valid

func (k PendingChangeKind) Valid() bool

Valid reports whether k is one of the recognised pending change kinds.

type PendingChangeResolvedPayload

type PendingChangeResolvedPayload struct {
	ToolCallID string        `json:"tool_call_id"`
	Action     PendingAction `json:"action"` // "accept" | "reject"
	Path       string        `json:"path,omitempty"`
}

PendingChangeResolvedPayload is the payload for type="pending_change_resolved". Emitted after the user accepts or rejects a staged change, after the fs handler has unblocked and the disk state reflects the decision. Clients drop the op from the pending pill and update the source tool card's status.

type PendingChangesClearedPayload

type PendingChangesClearedPayload struct {
	Reason ClearReason `json:"reason,omitempty"` // "cancelled" | "mode_disabled" | "chat_deleted"
}

PendingChangesClearedPayload is the payload for type="pending_changes_cleared". Emitted when a turn is cancelled or the chat's Supervised mode is disabled while ops are outstanding; every pending op for the chat is rejected server-side and the client flushes its pending list.

type PendingStore

type PendingStore interface {
	// ListForChat returns all pending changes for the given chat.
	ListForChat(chatID ChatID) []PendingChange
	// Get returns a single pending change by tool-call ID.
	Get(toolCallID string) (PendingChange, bool)
	// ChatIDs returns the IDs of all chats with pending changes.
	ChatIDs() []ChatID
	// RejectAllForChat rejects all pending changes for the given chat,
	// returning the rejected snapshots.
	RejectAllForChat(chatID ChatID) []PendingChange
	// Resolve resolves a single pending change with the given action.
	Resolve(ctx context.Context, toolCallID string, action PendingAction) (PendingChange, error)
}

PendingStore is the consumer-side interface for the pending-change subsystem. The hub uses these methods for SSE replay, rejection on bridge teardown, and full-content retrieval. The concrete *pending.Store satisfies this interface implicitly.

type PendingTrustClearedPayload

type PendingTrustClearedPayload struct {
	Reason ClearReason `json:"reason,omitempty"` // "turn_ended" | "cancelled" | "mode_disabled" | "chat_deleted"
}

PendingTrustClearedPayload is the payload for type="pending_trust_cleared". Emitted when the perTurnTrust flag drops: end of turn, cancel, chat-delete, or supervised-mode toggle-off. The pill reverts to the standard Supervised state. Reason mirrors pending_changes_cleared's vocabulary so both events can share dispatch semantics on the client.

type PendingTrustEnabledPayload

type PendingTrustEnabledPayload struct{}

PendingTrustEnabledPayload is the payload for type="pending_trust_enabled". Emitted when the user clicks "Trust remaining" in the Supervised pill, setting the chat's perTurnTrust flag so subsequent agent writes in the same turn bypass staging. The pill flips to a visibly-distinct "Trusted · this turn" state; the flag clears on turn_ended via the paired pending_trust_cleared event. Replayed on SSE reconnect so the UI state survives disconnects mid-turn.

type PermissionNeededPayload

type PermissionNeededPayload struct {
	ToolCallID string `json:"tool_call_id,omitempty"`
	Title      string `json:"title,omitempty"`
	// Kind forwards the ACP toolCall.kind so the client can style
	// distinctive permission prompts (switch_mode gets a different
	// dialog vs an execute_bash prompt).
	Kind         ToolKind           `json:"kind,omitempty"`
	SubSessionID string             `json:"sub_session_id,omitempty"`
	Options      []PermissionOption `json:"options"`
	RequestID    int64              `json:"request_id"`
}

PermissionNeededPayload is the payload for type="permission_needed".

type PermissionOption

type PermissionOption struct {
	OptionID string `json:"option_id"`
	Name     string `json:"name"`
	Kind     string `json:"kind"`
}

PermissionOption is one selectable response in a permission dialog.

type PermissionOutcome

type PermissionOutcome struct {
	Outcome PermissionOutcomeInner `json:"outcome"`
}

PermissionOutcome is the typed wire shape for ACP permission-outcome responses. Replaces anonymous map[string]any for compile-time safety.

func PermissionOutcomeCancelled

func PermissionOutcomeCancelled() *PermissionOutcome

PermissionOutcomeCancelled builds the ACP permission-outcome response for a cancelled/denied permission. Single source of truth for the wire shape.

func PermissionOutcomeSelected

func PermissionOutcomeSelected(optionID string) *PermissionOutcome

PermissionOutcomeSelected builds the ACP permission-outcome response for a selected option. Single source of truth for the wire shape.

type PermissionOutcomeInner

type PermissionOutcomeInner struct {
	Outcome  string `json:"outcome"`
	OptionID string `json:"optionId,omitempty"`
}

PermissionOutcomeInner is the nested outcome payload.

type PermissionResponseCommand

type PermissionResponseCommand struct {
	OptionID  string `json:"option_id"`
	RequestID int64  `json:"request_id"`
}

PermissionResponseCommand is the payload for type="permission_response".

type PlanEntry

type PlanEntry struct {
	Content  string     `json:"content"`
	Priority string     `json:"priority"`
	Status   PlanStatus `json:"status"`
}

PlanEntry is one item in an agent-authored plan.

type PlanStatus

type PlanStatus string

PlanStatus is the lifecycle state of a plan entry.

const (
	PlanPending    PlanStatus = "pending"
	PlanInProgress PlanStatus = "in_progress"
	PlanCompleted  PlanStatus = "completed"
)

type PromptCapabilities added in v0.1.57

type PromptCapabilities struct {
	// Image reports acceptance of image content blocks.
	Image bool `json:"image"`
	// Audio reports acceptance of audio content blocks.
	Audio bool `json:"audio"`
	// EmbeddedContext reports acceptance of inline embedded-resource
	// (document) content blocks. kiro-cli 2.7's `acp` advertises false,
	// so document attachments must be sent as path references instead.
	EmbeddedContext bool `json:"embeddedContext"`
}

PromptCapabilities are the prompt content-block capabilities the agent advertises in the ACP initialize handshake (under agentCapabilities.promptCapabilities). They gate which content-block types a session/prompt may carry.

type PromptCommand

type PromptCommand struct {
	Text        string       `json:"text"`
	MessageID   string       `json:"message_id"` // client-generated ULID
	Agent       string       `json:"agent,omitempty"`
	Model       string       `json:"model,omitempty"`
	ActiveFile  string       `json:"active_file,omitempty"` // editor active file path
	OpenFiles   []string     `json:"open_files,omitempty"`  // all open editor tabs
	Attachments []Attachment `json:"attachments,omitempty"` // files attached via pill row
}

PromptCommand is the payload for type="prompt".

Text is required, trimmed, and capped at 512 KiB; oversize returns HTTP 413. MessageID is required and must match the ULID/id character set enforced by the hub's validMessageID check (128-byte cap, no control chars). Agent and Model are optional; if non-empty they must match validIdent (ASCII alphanumerics plus `_.-`, 1-128 bytes). ActiveFile and OpenFiles are forwarded to kiro-cli as _meta.kiro metadata; they do not reach a filesystem sink directly in vibekit. Attachments are resolved via resolveInsideWorkDir before read.

type PushKind

type PushKind string

PushKind identifies a push notification category. The underlying string is the wire value stored in settings and matched by the client's service worker.

const (
	PushKindAgentFinished PushKind = "agent_finished"
	PushKindPermission    PushKind = "permission"
)

Push notification kind constants. These live in the api package so hub callers can reference them without importing the push package (eliminating the hub→push import that existed solely for constant access).

func (PushKind) Valid

func (k PushKind) Valid() bool

Valid reports whether k is a known push notification kind. Used at the settings-load boundary to reject corrupted keys at load time rather than at send time.

type PushService

type PushService interface {
	RouteHandler
	Subscribe(sub PushSubscription)
	Unsubscribe(endpoint string)
	Send(ctx context.Context, title, body string, notifyType PushKind)
	HasSubscribers() bool
	SetPreferences(prefs map[PushKind]bool)
	// ReloadPreferences re-reads notification toggles from disk,
	// deduplicating concurrent calls via singleflight. Called on SSE
	// reconnect so externally-edited config.json changes take effect
	// without a container restart.
	ReloadPreferences(ctx context.Context)
	// Close cancels any in-flight pushes via context so the hub's
	// shutdown path doesn't block on the 10s HTTP client timeout
	// per pending subscriber.
	Close()
}

PushService manages Web Push subscriptions and sends notifications.

type PushSubscription

type PushSubscription struct {
	Endpoint string               `json:"endpoint"`
	Keys     PushSubscriptionKeys `json:"keys"`
}

PushSubscription is a Web Push subscription from the browser (RFC 8030).

type PushSubscriptionKeys

type PushSubscriptionKeys struct {
	P256dh string `json:"p256dh"`
	Auth   string `json:"auth"`
}

PushSubscriptionKeys holds the client-side encryption keys.

type RPCError

type RPCError struct {
	Message string `json:"message"`
	Code    int    `json:"code"`
}

RPCError is a JSON-RPC 2.0 error object.

func (*RPCError) Error

func (e *RPCError) Error() string

Error makes RPCError implement the error interface by returning the server-provided message verbatim. Callers that need the code use errors.As to recover the concrete *RPCError.

type RPCErrorOut

type RPCErrorOut struct {
	Message string `json:"message"`
	Code    int    `json:"code"`
}

RPCErrorOut is the error object in an outbound JSON-RPC response.

type RPCNotification

type RPCNotification struct {
	Params  any    `json:"params,omitempty"`
	JSONRPC string `json:"jsonrpc"`
	Method  string `json:"method"`
}

RPCNotification is an outbound JSON-RPC 2.0 notification (no id, no response expected). Used by Bridge.Notify instead of ad-hoc map[string]any construction.

type RPCRequest

type RPCRequest struct {
	JSONRPC string `json:"jsonrpc"`
	Params  any    `json:"params,omitempty"`
	Method  string `json:"method"`
	ID      int64  `json:"id"`
}

RPCRequest is an outbound JSON-RPC 2.0 request sent to kiro-cli.

type RPCResponse

type RPCResponse struct {
	Error   *RPCError       `json:"error,omitempty"`
	ID      *int64          `json:"id,omitempty"`
	JSONRPC string          `json:"jsonrpc"`
	Method  string          `json:"method,omitempty"`
	Result  json.RawMessage `json:"result,omitempty"`
	Params  json.RawMessage `json:"params,omitempty"`
}

RPCResponse is a JSON-RPC 2.0 message from kiro-cli. A populated ID with Result or Error is a response; an empty ID with Method and Params is a server-sent notification.

func ExecuteSlashCommand

func ExecuteSlashCommand(ctx context.Context, b slashCaller, name string, args ...string) (*RPCResponse, error)

ExecuteSlashCommand dispatches a kiro-cli TUI slash command (e.g. "effort", "model") to a running ACP bridge via the _kiro.dev/commands/execute extension method.

It centralizes the nested {command:{command,args}} payload shape and the MethodCommandsExecute method name so call sites don't re-hand-roll the wire format with drifting key literals. The returned *RPCResponse is the raw command result; most callers only care about the error.

This is the mid-session lever (e.g. CmdSetEffort). For the *initial* effort of a new session, prefer the StartOpts.Effort launch flag (kiro-cli >=2.6 `acp --effort`) over a post-start dispatch.

type RPCResponseOut

type RPCResponseOut struct {
	Result  any          `json:"result,omitempty"`
	Error   *RPCErrorOut `json:"error,omitempty"`
	JSONRPC string       `json:"jsonrpc"`
	ID      int64        `json:"id"`
}

RPCResponseOut is an outbound JSON-RPC 2.0 response to a request received from kiro-cli. Used by Bridge.Respond instead of ad-hoc map[string]any construction.

type ResolveAllPendingChangesCommand

type ResolveAllPendingChangesCommand struct {
	Action PendingAction `json:"action"` // "accept" | "reject"
}

ResolveAllPendingChangesCommand is the payload for type="resolve_all_pending_changes". Bulk-resolve every outstanding staged op in the chat with the same action. Convenience for the Supervised pill's "Accept all" / "Reject all" buttons.

type ResolvePendingChangeCommand

type ResolvePendingChangeCommand struct {
	ToolCallID string        `json:"tool_call_id"`
	Action     PendingAction `json:"action"` // "accept" | "reject"
}

ResolvePendingChangeCommand is the payload for type="resolve_pending_change". Accept or reject ONE staged file op. The ToolCallID identifies the op; Action is "accept" or "reject". Unknown actions or unknown ids produce a 400; idempotent re-resolve of an already-settled op produces a success no-op.

type ResolvePendingChangePartialCommand

type ResolvePendingChangePartialCommand struct {
	ToolCallID string `json:"tool_call_id"`
	MergedText string `json:"merged_text"`
}

ResolvePendingChangePartialCommand is the payload for type="resolve_pending_change_partial". Applies a user-authored MergedText in place of the agent's proposed write — the fs handler unblocks with accept semantics but writes the caller-supplied text instead of the staged NewText. Used by per-hunk Accept/Reject in the editor: the client starts from OldText, splices in only the accepted hunks, and sends the result. Rejecting every hunk should use resolve_pending_change with action="reject" instead (no write).

MergedText is capped the same way staging is: 4 MiB max. Larger payloads are rejected at the JSON body limit layer.

type RewindChatCommand

type RewindChatCommand struct {
	TurnIndex int `json:"turn_index"` // 0-based index into parent's messages array
}

RewindChatCommand is the payload for type="rewind_chat". Creates a new chat branched from a specific turn of the current chat.

type Role

type Role string

Role identifies the speaker of a message.

const (
	RoleUser      Role = "user"
	RoleAssistant Role = "assistant"
	RoleEvent     Role = "event" // system / ui events rendered inline
)

type RouteHandler

type RouteHandler interface {
	RegisterRoutes(mux *http.ServeMux)
}

RouteHandler is the minimal contract for any component that wires its own routes under a sub-tree of /api/*. Used by the MCP config store, the MCP runtime registry, and anything else that owns its own mux subset.

type ServerEvent

type ServerEvent = Event[any]

ServerEvent is the envelope broadcast to every SSE client. Payload is the event-specific JSON object; handlers type-assert based on Type.

func NewEvent

func NewEvent[T any](t EventType, chatID ChatID, payload T) ServerEvent

NewEvent constructs a ServerEvent with a typed payload, providing compile-time type safety at the construction site.

type SessionID

type SessionID string

SessionID is a typed wrapper for ACP session identifiers. Values are validated via ValidSessionID before assignment; the type makes invalid-state propagation a compile-time-visible decision.

func (SessionID) String

func (s SessionID) String() string

String implements fmt.Stringer for logging convenience.

func (SessionID) Valid

func (s SessionID) Valid() bool

Valid reports whether the session id passes path-safety validation.

type SessionListUpdatedPayload

type SessionListUpdatedPayload struct {
	Sessions []map[string]any `json:"sessions"`
}

SessionListUpdatedPayload is the payload for type="session_list_updated".

type SessionMode

type SessionMode struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	Description string `json:"description,omitempty"`
}

SessionMode describes one mode the running agent supports. Populated from the `modes.availableModes` field of kiro-cli's session/new or session/load response; kept on the chat so the UI can render a mode pill without re-querying the bridge.

type SessionModel

type SessionModel struct {
	ID             string  `json:"id"`
	Name           string  `json:"name"`
	Description    string  `json:"description,omitempty"`
	RateMultiplier float64 `json:"rate_multiplier,omitempty"`
}

SessionModel describes one model the running agent can swap to, as declared by kiro-cli's session/new response. Replaces our prior shell-out to `kiro-cli chat --list-models`.

type SetEffortCommand

type SetEffortCommand struct {
	Level EffortLevel `json:"level"` // "low" | "medium" | "high" | "xhigh" | "max"
}

SetEffortCommand is the payload for type="set_effort". Applies a reasoning effort level to the active session.

type SetSupervisedModeCommand

type SetSupervisedModeCommand struct {
	Enabled bool `json:"enabled"`
}

SetSupervisedModeCommand is the payload for type="set_supervised_mode". Toggles the chat's SupervisedMode field. Disabling while ops are outstanding auto-rejects them (broadcast as pending_changes_cleared with reason="mode_disabled"); the agent unblocks with an error per op.

type SettingsUpdatedPayload

type SettingsUpdatedPayload struct{}

SettingsUpdatedPayload is the payload for type="settings_updated".

type SpawnSubagentCommand

type SpawnSubagentCommand struct {
	Task string `json:"task"`
	Name string `json:"name,omitempty"`
}

SpawnSubagentCommand is the payload for type="spawn_subagent". Spawns a new ephemeral subagent via session/spawn.

type StartOpts

type StartOpts struct {
	// SessionID is the ACP session id to resume. Empty means create new.
	SessionID string
	// Agent is the agent identifier to launch.
	Agent string
	// Model is the model id to use for the session.
	Model string
	// Effort is the initial reasoning effort level passed to kiro-cli
	// >=2.6 via `acp --effort` (low|medium|high|xhigh|max). Empty leaves
	// the model/service default; invalid values are dropped at launch.
	Effort string
	// ExtraArgs are permission-mode flags derived from user settings.
	ExtraArgs []string
	// MCPServers is the ACP mcpServers array (enabled user-configured
	// MCP servers). Nil means empty set.
	MCPServers []map[string]any
}

StartOpts collects the parameters for ACPBridge.Start. All fields are optional; a zero-value StartOpts creates a new session with no agent, no model override, no extra args, and no MCP servers.

type SteeringGenerator

type SteeringGenerator interface {
	Generate(ctx context.Context)
	CustomPath() string
}

SteeringGenerator generates steering files for kiro-cli.

type SteeringLoadedPayload

type SteeringLoadedPayload struct {
	Documents []string `json:"documents"`
}

SteeringLoadedPayload is the payload for type="steering_loaded".

type StopReason

type StopReason string

StopReason identifies why a turn ended. The underlying string is the wire value sent over SSE; typed constants prevent typos at construction sites.

const (
	StopReasonEndTurn     StopReason = "end_turn"
	StopReasonCancelled   StopReason = "cancelled"
	StopReasonInterrupted StopReason = "interrupted"
)

type SubagentActivityPayload

type SubagentActivityPayload struct {
	Event        any    `json:"event"`
	SubSessionID string `json:"sub_session_id"`
}

SubagentActivityPayload is the payload for type="subagent_activity".

type SwitchModelCommand

type SwitchModelCommand struct {
	// Target model id. Empty or "auto" = keep current model (a bare
	// restart of the bridge, useful when the session is wedged).
	Model string `json:"model,omitempty"`
}

SwitchModelCommand is the payload for type="switch_model". Ends the current ACP session and starts a fresh one with a new model, priming the replacement with the chat transcript so kiro-cli has context. kiro-cli cannot swap models mid-session, so we rebuild the bridge. Agent changes are intentionally NOT part of this command — the agent itself is responsible for switching modes, and the user cannot force an agent change on a live chat from the client.

Model accepted forms: empty or "auto" keep the current model (a bare restart of the bridge, useful when the session is wedged); any other value must match validIdent (ASCII alphanumerics plus `_.-`, 1-128 bytes).

type TerminalCreatedPayload

type TerminalCreatedPayload struct {
	TerminalID string   `json:"terminal_id"`
	Command    string   `json:"command"`
	Args       []string `json:"args"`
}

TerminalCreatedPayload is the payload for type="terminal_created".

type TerminalExitedPayload

type TerminalExitedPayload struct {
	TerminalID string `json:"terminal_id"`
	ExitCode   int    `json:"exit_code"`
}

TerminalExitedPayload is the payload for type="terminal_exited".

type TerminalOutputPayload

type TerminalOutputPayload struct {
	TerminalID string `json:"terminal_id"`
	Data       string `json:"data"`
}

TerminalOutputPayload is the payload for type="terminal_output".

type ToolCall

type ToolCall struct {
	ID           string          `json:"id"`
	Title        string          `json:"title"`
	Kind         ToolKind        `json:"kind"`
	Status       ToolStatus      `json:"status"`
	Output       string          `json:"output,omitempty"`
	SubSessionID string          `json:"sub_session_id,omitempty"`
	Input        json.RawMessage `json:"input,omitempty"`
	Locations    []ToolLocation  `json:"locations,omitempty"`
	Diffs        []ToolDiff      `json:"diffs,omitempty"`
	DurationMs   int             `json:"duration_ms,omitempty"`
	Ts           int64           `json:"ts"`
}

ToolCall is a tool invocation inside an assistant message. One assistant message may have multiple tool calls; each can be updated in place as status changes (pending → in_progress → completed/failed).

type ToolCallPayload

type ToolCallPayload struct {
	MessageID  string   `json:"message_id"`
	ToolCall   ToolCall `json:"tool_call"`
	BlockIndex int      `json:"block_index"`
}

ToolCallPayload is the payload for type="tool_call". BlockIndex is the position of the tool_use block in the assistant message's chronological Blocks array — the client uses it to insert the tool card at the right spot relative to surrounding text blocks.

type ToolCallUpdatePayload

type ToolCallUpdatePayload struct {
	MessageID string   `json:"message_id"`
	ToolCall  ToolCall `json:"tool_call"`
}

ToolCallUpdatePayload is the payload for type="tool_call_update".

type ToolDiff

type ToolDiff struct {
	Path    string `json:"path"`
	OldText string `json:"old_text,omitempty"`
	NewText string `json:"new_text"`
}

ToolDiff is a before/after text change from a write tool call. Sent by kiro-cli in tool_call notifications for edit operations. Path is workspace-relative (absolute paths from kiro-cli are normalised via hub.relPath before being stored here); OldText/NewText are the changed fragments, not full-file contents.

type ToolKind

type ToolKind string

ToolKind identifies the category of a tool invocation. Values are assigned by kiro-cli and flow through the ACP protocol unchanged. The full set spans both the original ACP kinds and the richer classifications kiro-cli's translate layer emits for permission dialogs and tool-card rendering.

const (
	ToolKindExecute    ToolKind = "execute"
	ToolKindShell      ToolKind = "shell"
	ToolKindRead       ToolKind = "read"
	ToolKindSearch     ToolKind = "search"
	ToolKindFetch      ToolKind = "fetch"
	ToolKindEdit       ToolKind = "edit"
	ToolKindThink      ToolKind = "think"
	ToolKindHook       ToolKind = "hook"
	ToolKindWrite      ToolKind = "write"
	ToolKindDelete     ToolKind = "delete"
	ToolKindMove       ToolKind = "move"
	ToolKindCommand    ToolKind = "command"
	ToolKindBrowser    ToolKind = "browser"
	ToolKindSwitchMode ToolKind = "switch_mode"
	ToolKindMCP        ToolKind = "mcp"
	ToolKindOther      ToolKind = "other"
)

type ToolLocation

type ToolLocation struct {
	Path string `json:"path"`
	Line int    `json:"line,omitempty"`
}

ToolLocation is a file path (and optional line) the agent is working with. Sent by kiro-cli in tool_call and tool_call_update notifications. Used by the editor to scroll to the file the agent is accessing or modifying.

type ToolStatus

type ToolStatus string

ToolStatus is the lifecycle state of a tool invocation.

const (
	ToolPending    ToolStatus = "pending"
	ToolInProgress ToolStatus = "in_progress"
	ToolCompleted  ToolStatus = "completed"
	ToolFailed     ToolStatus = "failed"
)

type TransportError

type TransportError struct {
	Err       error
	Retryable bool
}

TransportError wraps bridge-level transport failures (pipe closed, write timeout, process exited) with explicit retryability semantics. Callers use errors.As to classify without substring matching.

func (*TransportError) Error

func (e *TransportError) Error() string

func (*TransportError) Unwrap

func (e *TransportError) Unwrap() error

type TurnEndedPayload

type TurnEndedPayload struct {
	ChangedFiles map[string]*FileChange `json:"changed_files,omitempty"`
	StopReason   StopReason             `json:"stop_reason,omitempty"`
	CreditsDelta float64                `json:"credits_delta,omitempty"`
	ElapsedMs    float64                `json:"elapsed_ms,omitempty"`
}

TurnEndedPayload is the payload for type="turn_ended".

type Usage

type Usage struct {
	MeteringItems []MeteringItem `json:"metering_items,omitempty"`
	ContextPct    float64        `json:"context_pct"`
	ContextSize   int            `json:"context_size"`
	Credits       float64        `json:"credits"`
	TurnCount     int            `json:"turn_count"`
	LastTurnMs    float64        `json:"last_turn_ms"`
	HasRealData   bool           `json:"has_real_data"`
}

Usage is a chat's last-known context and billing snapshot.

type UtilityPrompter

type UtilityPrompter interface {
	UtilityPrompt(ctx context.Context, prompt string) (string, error)
}

UtilityPrompter is the narrow interface for AI-backed prompt generation (error explanations, conflict resolution, commit messages). Declared here so both the server and git packages share a single typed contract.

type WorkingLabelPayload

type WorkingLabelPayload struct {
	Label string `json:"label"`
}

WorkingLabelPayload is the payload for type="working_label". Sent when the agent starts or finishes a tool call so the client can show a contextual label ("Reading", "Searching", "Running <title>", etc.) instead of a generic "Thinking" indicator.

Jump to

Keyboard shortcuts

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