Documentation
¶
Overview ¶
Package protocol defines the shared wire protocol types for the AgentD relay system. Both the daemon (agentd) and relay server (agentd-relay) import this module to guarantee type identity across the WebSocket JSON contract.
This module has zero external dependencies — only encoding/json, time, crypto/rand, and encoding/hex.
Package protocol — git sync wire protocol (feature 172).
This file defines the request/response types, streaming progress events, and classified error codes for the git sync action family (branch list, branch switch, fetch, pull, push, cancel) introduced in feature 172.
The DAEMON is the source of truth for every Msg* constant in this file. A matching constant block lives in agentd/internal/session/wsserver_gitsync.go with an init() panic that cross-checks equality at daemon startup — the explicit drift prevention for the feature 170 incident class.
Index ¶
- Constants
- Variables
- func NewTraceID() string
- func ValidTraceID(s string) bool
- func Validate(cfg *MCPServerConfig) error
- func ValidateName(name string) error
- func ValidateRemote(cfg *MCPServerConfig) error
- func ValidateScope(scope MCPServerScope) error
- func ValidateStdio(cfg *MCPServerConfig) error
- func ValidateTransport(transport string) error
- type AckPayload
- type AuditEntryPayload
- type ClientConnectedPayload
- type ClientCountPayload
- type ControlMessage
- type ControlType
- type DeactivateDeveloperPayload
- type ErrorPayload
- type GitBranch
- type GitBranchListRequest
- type GitBranchListResponse
- type GitBranchSwitchRequest
- type GitBranchSwitchResponse
- type GitDiffRequest
- type GitDiffResponse
- type GitFetchRequest
- type GitFetchResponse
- type GitFileStatus
- type GitNotAvailablePayload
- type GitPullRequest
- type GitPullResponse
- type GitPushRequest
- type GitPushResponse
- type GitStatusPayload
- type GitStatusRequest
- type GitSyncCancelRequest
- type GitSyncCancelResponse
- type GitSyncProgressPayload
- type JoinPayload
- type KeyRotatePayload
- type MCPListPayload
- type MCPListResponse
- type MCPMutationPayload
- type MCPMutationResponse
- type MCPReconnectPayload
- type MCPRemovePayload
- type MCPServerConfig
- type MCPServerScope
- type MCPServerStatusEntry
- type MCPServersChangedPayload
- type MCPTogglePayload
- type PolicyJSON
- type PolicyMatchJSON
- type RegisterPayload
- type RelayEnvelope
- type StatusUpdatePayload
- type SyncPoliciesPayload
Constants ¶
const ( GitDiffStatusModified string = "modified" GitDiffStatusAdded string = "added" GitDiffStatusDeleted string = "deleted" GitDiffStatusRenamed string = "renamed" GitDiffStatusConflict string = "conflict" GitDiffStatusRemoved string = "removed" )
GitDiffStatus enum values for GitDiffResponse.Status.
const ( GitNotAvailableReasonNotARepo string = "not_a_git_repo" GitNotAvailableReasonGitMissing string = "git_binary_missing" GitNotAvailableReasonWorkDirInvalid string = "work_dir_invalid" )
GitNotAvailableReason enum values for GitNotAvailablePayload.Reason.
const ( MsgGitBranchList = "git_branch_list" MsgGitBranchListResponse = "git_branch_list_response" MsgGitBranchSwitch = "git_branch_switch" MsgGitBranchSwitchResponse = "git_branch_switch_response" MsgGitFetch = "git_fetch" MsgGitFetchResponse = "git_fetch_response" MsgGitPull = "git_pull" MsgGitPullResponse = "git_pull_response" MsgGitPush = "git_push" MsgGitPushResponse = "git_push_response" MsgGitSyncProgress = "git_sync_progress" MsgGitSyncCancel = "git_sync_cancel" MsgGitSyncCancelResponse = "git_sync_cancel_response" )
Message-type constants — DAEMON-side source of truth. Mirror MUST exist in agentd/internal/session/wsserver_gitsync.go with an init() panic cross-check that the two blocks agree at daemon startup.
const ( GitSyncErrAuthFailed = "auth_failed" GitSyncErrSSHPromptHang = "ssh_prompt_hang" GitSyncErrNonFastForward = "non_fast_forward" GitSyncErrMergeConflict = "merge_conflict" GitSyncErrDirtyWorkTree = "dirty_work_tree" GitSyncErrNoUpstream = "no_upstream" GitSyncErrNotAGitRepo = "not_a_git_repo" GitSyncErrNetwork = "network" GitSyncErrCanceled = "canceled" GitSyncErrTimeout = "timeout" GitSyncErrLockedIndex = "locked_index" GitSyncErrInternal = "internal" )
Classified error codes. Every GitSync*Response.ErrorCode field holds one of these values (or the empty string when OK is true). The PWA maps each code to a user-facing ErrorBanner headline + suggested-action chips.
Variables ¶
var ( // ErrInvalidName indicates a server Name failed the name regex or a // reserved-name check. ErrInvalidName = errors.New("mcp: invalid server name") // ErrInvalidTransport indicates Transport is not stdio/sse/http. ErrInvalidTransport = errors.New("mcp: invalid transport") // ErrInvalidScope indicates Scope is not project/user. ErrInvalidScope = errors.New("mcp: invalid scope") // ErrInvalidCommand indicates a stdio Command is empty, too long, or // contains shell metacharacters. ErrInvalidCommand = errors.New("mcp: invalid command") // ErrInvalidArgs indicates stdio Args exceed count or length limits. ErrInvalidArgs = errors.New("mcp: invalid args") // ErrInvalidEnv indicates stdio Env has too many keys, or a key/value // that fails validation. ErrInvalidEnv = errors.New("mcp: invalid env") // ErrInvalidURL indicates sse/http URL is missing, unparseable, too long, // or uses a disallowed scheme. ErrInvalidURL = errors.New("mcp: invalid url") // ErrInvalidHeaders indicates sse/http Headers has too many keys or a // malformed key/value. ErrInvalidHeaders = errors.New("mcp: invalid headers") // ErrInvalidTransportFields indicates transport-exclusive fields are // populated for the wrong transport (e.g., URL set on stdio, Command set // on sse). ErrInvalidTransportFields = errors.New("mcp: transport-exclusive fields mismatched") )
Validation sentinel errors. Use errors.Is to check for a specific class; the wrapper error from Validate contains additional context.
Functions ¶
func NewTraceID ¶
func NewTraceID() string
NewTraceID generates a random W3C-compatible trace ID (32 lowercase hex chars).
Panics on crypto/rand failure. This is an accepted deviation from the "no panic in library code" rule: crypto/rand failure indicates a catastrophic OS-level entropy issue where no cryptographic operation in the system can be trusted (AES-GCM encryption, key generation, token signing). Crashing immediately is safer than continuing with broken cryptography.
func ValidTraceID ¶
ValidTraceID returns true if s is a valid W3C trace ID (32 lowercase hex chars, non-zero).
func Validate ¶
func Validate(cfg *MCPServerConfig) error
Validate runs the full validation suite for an MCPServerConfig and returns the first sentinel-wrapped error it finds. Callers should use errors.Is to match the specific ErrInvalidXxx class.
func ValidateName ¶
ValidateName checks that name matches the MCP server name rules: byte length ≤64, matches ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$, is not a reserved filename, and contains no path separators or leading dot.
func ValidateRemote ¶
func ValidateRemote(cfg *MCPServerConfig) error
ValidateRemote checks the sse/http-transport fields of cfg: URL must be non-empty, ≤2048 bytes, parseable via net/url.Parse, and either use scheme=https OR have a loopback host (localhost/127.0.0.1/::1) with any scheme. Headers must respect count, RFC 7230 token syntax for keys, and length limits for values. Command/Args/Env must be empty.
func ValidateScope ¶
func ValidateScope(scope MCPServerScope) error
ValidateScope checks that scope is exactly project or user. The CLI's third scope (`local`) is not supported by feature 169.
func ValidateStdio ¶
func ValidateStdio(cfg *MCPServerConfig) error
ValidateStdio checks the stdio-transport fields of cfg: Command must be non-empty, ≤2048 bytes, and contain no shell metacharacters; Args must respect count and length limits; Env keys must match ^[A-Z_][A-Z0-9_]*$ and values must be ≤4096 bytes; there must be no URL or Headers set.
func ValidateTransport ¶
ValidateTransport checks that transport is exactly stdio, sse, or http. The Claude Code CLI also supports an in-process `sdk` transport, which is explicitly out of scope for user-manageable MCP servers — see spec Non-Goals.
Types ¶
type AckPayload ¶
type AckPayload struct {
SessionID string `json:"sid"`
ClientID string `json:"client_id,omitempty"`
}
AckPayload is the relay's acknowledgement of a successful registration or join.
type AuditEntryPayload ¶
type AuditEntryPayload struct {
Timestamp time.Time `json:"ts"`
SessionID string `json:"session_id"`
DeveloperID string `json:"developer_id"`
AgentType string `json:"agent"`
EventType string `json:"event"`
Tool string `json:"tool,omitempty"`
InputHash string `json:"input_hash,omitempty"`
Decision string `json:"decision,omitempty"`
PolicyName string `json:"policy,omitempty"`
CostUSD float64 `json:"cost_usd,omitempty"`
}
AuditEntryPayload carries a single audit event from daemon to relay. InputHash is sha256hex of raw tool_input JSON bytes — NOT plaintext.
type ClientConnectedPayload ¶
type ClientConnectedPayload struct {
SessionID string `json:"session_id"`
}
ClientConnectedPayload is sent by the relay to the daemon when a PWA client connects or reconnects. The daemon uses this to replay message history.
type ClientCountPayload ¶
ClientCountPayload is sent by the relay to the daemon after every client join and disconnect. Informs the daemon of the current connected client count for replay optimization (first client: full replay, subsequent: session list only).
type ControlMessage ¶
type ControlMessage struct {
Type ControlType `json:"type"`
Payload json.RawMessage `json:"payload"`
}
ControlMessage is the wire format for relay control protocol messages.
type ControlType ¶
type ControlType string
ControlType discriminates control messages in the relay protocol.
const ( CtrlRegister ControlType = "register" CtrlJoin ControlType = "join" CtrlHeartbeat ControlType = "heartbeat" // reserved for future application-level keepalive; WebSocket ping/pong handles heartbeats CtrlAck ControlType = "ack" CtrlError ControlType = "error" CtrlSyncPolicies ControlType = "sync_policies" CtrlStatusUpdate ControlType = "status_update" CtrlAuditEntry ControlType = "audit_entry" CtrlDeactivateDeveloper ControlType = "deactivate_developer" CtrlClientConnected ControlType = "client_connected" CtrlClientCount ControlType = "client_count" CtrlKeyRotate ControlType = "key_rotate" )
Control message types for the relay protocol.
type DeactivateDeveloperPayload ¶
type DeactivateDeveloperPayload struct {
DeveloperID string `json:"developer_id"`
}
DeactivateDeveloperPayload is sent by the relay to the daemon when a developer is deactivated via SCIM.
type ErrorPayload ¶
ErrorPayload is the relay's error response to a failed control operation.
type GitBranch ¶
type GitBranch struct {
Name string `json:"name"`
IsCurrent bool `json:"is_current"`
Upstream string `json:"upstream,omitempty"`
Ahead int `json:"ahead"`
Behind int `json:"behind"`
LastCommitAt int64 `json:"last_commit_at"`
LastCommitSha string `json:"last_commit_sha,omitempty"`
}
GitBranch is a single row in the branch switcher. Transient per request. Sorted by LastCommitAt descending for MRU behavior in the UI.
type GitBranchListRequest ¶
type GitBranchListRequest struct {
SessionID string `json:"session_id"`
RequestID string `json:"request_id"`
}
GitBranchListRequest — PWA → daemon.
type GitBranchListResponse ¶
type GitBranchListResponse struct {
RequestID string `json:"request_id"`
OK bool `json:"ok"`
Error string `json:"error,omitempty"`
ErrorCode string `json:"error_code,omitempty"`
CurrentBranch string `json:"current_branch,omitempty"`
Branches []GitBranch `json:"branches,omitempty"`
}
GitBranchListResponse — daemon → PWA. Echoes RequestID.
type GitBranchSwitchRequest ¶
type GitBranchSwitchRequest struct {
SessionID string `json:"session_id"`
RequestID string `json:"request_id"`
Branch string `json:"branch"`
StashDirty bool `json:"stash_dirty"`
}
GitBranchSwitchRequest — PWA → daemon. First request always has StashDirty=false; on DirtyRequired=true response, the PWA opens the ConfirmRail and retries with StashDirty=true.
type GitBranchSwitchResponse ¶
type GitBranchSwitchResponse struct {
RequestID string `json:"request_id"`
OK bool `json:"ok"`
Error string `json:"error,omitempty"`
ErrorCode string `json:"error_code,omitempty"`
Stderr string `json:"stderr,omitempty"`
NewBranch string `json:"new_branch,omitempty"`
StashRef string `json:"stash_ref,omitempty"`
DirtyRequired bool `json:"dirty_required,omitempty"`
}
GitBranchSwitchResponse — daemon → PWA.
type GitDiffRequest ¶
type GitDiffRequest struct {
SessionID string `json:"session_id"`
RequestID string `json:"request_id"`
Path string `json:"path"`
}
GitDiffRequest is the PWA → daemon request for one file's unified diff. Path must be repo-root-relative and must not escape the repo root.
type GitDiffResponse ¶
type GitDiffResponse struct {
RequestID string `json:"request_id"`
Path string `json:"path"`
Status string `json:"status"`
IsBinary bool `json:"is_binary"`
IsRedacted bool `json:"is_redacted"`
IsTruncated bool `json:"is_truncated"`
DiffText string `json:"diff_text"`
SizeBytes int64 `json:"size_bytes"`
Insertions int `json:"insertions"`
Deletions int `json:"deletions"`
}
GitDiffResponse is the daemon → PWA response carrying one file's diff (or a safe placeholder state). DiffText is raw unified diff and is empty when IsBinary, IsRedacted, or Status is "removed".
type GitFetchRequest ¶
type GitFetchRequest struct {
SessionID string `json:"session_id"`
RequestID string `json:"request_id"`
Remote string `json:"remote,omitempty"`
Prune bool `json:"prune,omitempty"`
}
GitFetchRequest — PWA → daemon. Empty Remote triggers git-native default resolution (upstream-tracking → origin → fail). See FR-003a in spec.md.
type GitFetchResponse ¶
type GitFetchResponse struct {
RequestID string `json:"request_id"`
OK bool `json:"ok"`
Error string `json:"error,omitempty"`
ErrorCode string `json:"error_code,omitempty"`
Stderr string `json:"stderr,omitempty"`
FetchedAt int64 `json:"fetched_at"`
}
GitFetchResponse — daemon → PWA.
type GitFileStatus ¶
type GitFileStatus struct {
Path string `json:"path"`
OrigPath string `json:"orig_path,omitempty"`
XY string `json:"xy"`
IsStaged bool `json:"is_staged"`
IsUntracked bool `json:"is_untracked"`
IsConflict bool `json:"is_conflict"`
IsRename bool `json:"is_rename"`
Insertions int `json:"insertions"`
Deletions int `json:"deletions"`
IsBinary bool `json:"is_binary"`
IsRedacted bool `json:"is_redacted"`
SizeBytes int64 `json:"size_bytes"`
}
GitFileStatus describes one dirty file reported by `git status --porcelain=v2`. Shipped inside GitStatusPayload.Files. Paths are repo-root-relative and never absolute.
type GitNotAvailablePayload ¶
GitNotAvailablePayload is a one-shot notice emitted when gitwatch cannot observe a session (WorkDir is not a git repo, or git binary missing).
type GitPullRequest ¶
type GitPullRequest struct {
SessionID string `json:"session_id"`
RequestID string `json:"request_id"`
Rebase bool `json:"rebase,omitempty"`
}
GitPullRequest — PWA → daemon. Rebase=false (default) → --ff-only.
type GitPullResponse ¶
type GitPullResponse struct {
RequestID string `json:"request_id"`
OK bool `json:"ok"`
Error string `json:"error,omitempty"`
ErrorCode string `json:"error_code,omitempty"`
Stderr string `json:"stderr,omitempty"`
NewHead string `json:"new_head,omitempty"`
FilesChanged int `json:"files_changed,omitempty"`
}
GitPullResponse — daemon → PWA.
type GitPushRequest ¶
type GitPushRequest struct {
SessionID string `json:"session_id"`
RequestID string `json:"request_id"`
Remote string `json:"remote,omitempty"`
ForceWithLease bool `json:"force_with_lease,omitempty"`
Force bool `json:"force,omitempty"`
SetUpstream bool `json:"set_upstream,omitempty"`
}
GitPushRequest — PWA → daemon. Force semantics:
ForceWithLease=true, Force=false → --force-with-lease (safe) Force=true, ForceWithLease=false → raw --force (unsafe, advanced UI) both false → plain push both true → daemon rejects with GitSyncErrInternal (ambiguous)
type GitPushResponse ¶
type GitPushResponse struct {
RequestID string `json:"request_id"`
OK bool `json:"ok"`
Error string `json:"error,omitempty"`
ErrorCode string `json:"error_code,omitempty"`
Stderr string `json:"stderr,omitempty"`
PushedRef string `json:"pushed_ref,omitempty"`
}
GitPushResponse — daemon → PWA.
type GitStatusPayload ¶
type GitStatusPayload struct {
RepoRoot string `json:"repo_root"`
Files []GitFileStatus `json:"files"`
TotalInsertions int `json:"total_insertions"`
TotalDeletions int `json:"total_deletions"`
GeneratedAt int64 `json:"generated_at"`
// Feature 172 additive fields — all omitempty for backward compat.
Branch string `json:"branch,omitempty"`
Upstream string `json:"upstream,omitempty"`
Ahead int `json:"ahead,omitempty"`
Behind int `json:"behind,omitempty"`
LastFetchedAt int64 `json:"last_fetched_at,omitempty"`
}
GitStatusPayload is the full per-session status snapshot returned by GetGitStatus and carried in MsgGitStatusUpdate pushes. Files is sorted ascending by path and capped at 500 entries.
Feature 172 extended this struct with five omitempty fields (Branch, Upstream, Ahead, Behind, LastFetchedAt) so the PWA's BranchChip and FreshnessPill can render current-branch context alongside the existing file-level status. All new fields are omitempty — older daemons emit the original 5-field shape and older PWAs ignore the new fields.
type GitStatusRequest ¶
type GitStatusRequest struct {
SessionID string `json:"session_id"`
RequestID string `json:"request_id"`
}
GitStatusRequest is the PWA → daemon request to fetch the current status snapshot for a session. The response body is a GitStatusPayload.
type GitSyncCancelRequest ¶
type GitSyncCancelRequest struct {
SessionID string `json:"session_id"`
RequestID string `json:"request_id"`
TargetID string `json:"target_id"`
}
GitSyncCancelRequest — PWA → daemon.
type GitSyncCancelResponse ¶
type GitSyncCancelResponse struct {
RequestID string `json:"request_id"`
TargetID string `json:"target_id"`
OK bool `json:"ok"`
Error string `json:"error,omitempty"`
ErrorCode string `json:"error_code,omitempty"`
}
GitSyncCancelResponse — daemon → PWA. OK=true means the target's context.CancelFunc was found and invoked; the target op will emit its own terminal response shortly after with ErrorCode=canceled.
type GitSyncProgressPayload ¶
type GitSyncProgressPayload struct {
RequestID string `json:"request_id"`
Op string `json:"op"`
Stage string `json:"stage"`
Percent int `json:"percent,omitempty"`
Line string `json:"line,omitempty"`
}
GitSyncProgressPayload is a streaming daemon → PWA event emitted during long-running fetch/pull/push/switch operations. Lossy on the daemon side (buffered channel with drop-oldest on full). The terminal response is always delivered.
type JoinPayload ¶
type JoinPayload struct {
SessionID string `json:"sid"`
JWT string `json:"jwt"`
ClientID string `json:"client_id,omitempty"`
}
JoinPayload is sent by the mobile client to join a session. JWT carries the clientToken from QRPayload.token.
type KeyRotatePayload ¶
type KeyRotatePayload struct {
NewKeyHMAC string `json:"new_key_hmac"`
PrevKeyHMAC string `json:"prev_key_hmac"`
PrevExpiresAt int64 `json:"prev_expires_at"`
Epoch uint64 `json:"epoch"`
}
KeyRotatePayload is sent by the daemon to the relay to update the session's auth KeyHMAC during automatic key rotation. The relay retains the previous HMAC until PrevExpiresAt so in-flight client tokens pass validation during the grace window. Fields are NOT omitempty because the relay needs all four.
type MCPListPayload ¶
type MCPListPayload struct {
RequestID string `json:"request_id,omitempty"`
Scope MCPServerScope `json:"scope,omitempty"`
SessionID string `json:"session_id,omitempty"`
}
MCPListPayload is the PWA → daemon request for the merged MCP server list. Empty Scope means both scopes; SessionID is required for project-scope resolution. RequestID is an opaque client-generated identifier echoed back in the response so the PWA can match replies to in-flight requests (feature 170).
type MCPListResponse ¶
type MCPListResponse struct {
RequestID string `json:"request_id,omitempty"`
Servers []MCPServerConfig `json:"servers"`
Status []MCPServerStatusEntry `json:"status,omitempty"`
ProjectWorkdir string `json:"project_workdir,omitempty"`
}
MCPListResponse is the daemon → PWA response to mcp_list_servers. Servers is ordered deterministically: user scope first, then project, sorted by name within each scope. Status is empty when no session is active. RequestID echoes the originating request's request_id so the PWA can route the response to the right in-flight callback (feature 170).
type MCPMutationPayload ¶
type MCPMutationPayload struct {
RequestID string `json:"request_id,omitempty"`
SessionID string `json:"session_id,omitempty"`
Server MCPServerConfig `json:"server"`
}
MCPMutationPayload is the PWA → daemon request for add/update operations. SessionID is required for project-scope mutations so the daemon can resolve the target workdir; user-scope mutations may omit it. RequestID is echoed back in the response (feature 170).
type MCPMutationResponse ¶
type MCPMutationResponse struct {
RequestID string `json:"request_id,omitempty"`
OK bool `json:"ok"`
Error string `json:"error,omitempty"`
ErrorCode string `json:"error_code,omitempty"`
AppliedToLive bool `json:"applied_to_live"`
LiveStatus []MCPServerStatusEntry `json:"live_status,omitempty"`
Server *MCPServerConfig `json:"server,omitempty"`
}
MCPMutationResponse is the daemon → PWA response for add/update/remove/ toggle/reconnect operations. AppliedToLive is true when the SDK's SetMCPServers call succeeded against a live session; false for user-scope mutations without an active session, or when the session ended mid-op. RequestID echoes the originating request's request_id (feature 170).
type MCPReconnectPayload ¶
type MCPReconnectPayload struct {
RequestID string `json:"request_id,omitempty"`
SessionID string `json:"session_id"`
Name string `json:"name"`
}
MCPReconnectPayload is the PWA → daemon request to force a reconnect of a named MCP server on a live session. SessionID is required — reconnect is session-scoped. Shares MCPMutationResponse for the reply. RequestID is echoed back (feature 170).
type MCPRemovePayload ¶
type MCPRemovePayload struct {
RequestID string `json:"request_id,omitempty"`
SessionID string `json:"session_id,omitempty"`
Scope MCPServerScope `json:"scope"`
Name string `json:"name"`
}
MCPRemovePayload is the PWA → daemon request to delete a server from a given scope. Shares MCPMutationResponse for the reply. RequestID is echoed back (feature 170).
type MCPServerConfig ¶
type MCPServerConfig struct {
Name string `json:"name"`
Scope MCPServerScope `json:"scope"`
Transport string `json:"transport"`
Enabled bool `json:"enabled"`
Command string `json:"command,omitempty"`
Args []string `json:"args,omitempty"`
Env map[string]string `json:"env,omitempty"`
URL string `json:"url,omitempty"`
Headers map[string]string `json:"headers,omitempty"`
}
MCPServerConfig is the canonical representation of a single MCP server configuration. Field set depends on Transport:
- transport=stdio : Command (required), Args (optional), Env (optional)
- transport=sse : URL (required), Headers (optional)
- transport=http : URL (required), Headers (optional)
Env and Headers values are secrets — never log them.
type MCPServerScope ¶
type MCPServerScope string
MCPServerScope identifies where an MCP server configuration is persisted. `project` entries live in `<workdir>/.mcp.json`; `user` entries live in `~/.claude.json`. Claude Code CLI's third scope (`local`) is explicitly out of scope for feature 169 — see spec.md Non-Goals.
const ( // MCPScopeProject persists the server in <workdir>/.mcp.json. MCPScopeProject MCPServerScope = "project" // MCPScopeUser persists the server in ~/.claude.json. MCPScopeUser MCPServerScope = "user" )
MCPServerScope values.
type MCPServerStatusEntry ¶
type MCPServerStatusEntry struct {
Name string `json:"name"`
Status string `json:"status"`
Message string `json:"message,omitempty"`
ToolCount int `json:"tool_count,omitempty"`
ShadowedBy MCPServerScope `json:"shadowed_by,omitempty"`
}
MCPServerStatusEntry is the live connection state for a single MCP server as reported by the Go SDK's client.MCPServerStatus(). Not persisted — the daemon computes it on demand. `disabled` is synthesized locally when a config entry has Enabled=false (the SDK has no entry for those servers).
type MCPServersChangedPayload ¶
type MCPServersChangedPayload struct {
Scope MCPServerScope `json:"scope"`
SessionID string `json:"session_id,omitempty"`
Action string `json:"action"`
ServerName string `json:"server_name"`
}
MCPServersChangedPayload is the daemon → PWA broadcast emitted after every successful mutation. Clients re-dispatch mcp_list_servers to refresh their view. Action is diagnostic only (add|update|remove|toggle|reconnect).
type MCPTogglePayload ¶
type MCPTogglePayload struct {
RequestID string `json:"request_id,omitempty"`
SessionID string `json:"session_id,omitempty"`
Scope MCPServerScope `json:"scope"`
Name string `json:"name"`
Enabled bool `json:"enabled"`
}
MCPTogglePayload is the PWA → daemon request to enable/disable a server without rewriting its full config. Shares MCPMutationResponse for the reply. RequestID is echoed back (feature 170).
type PolicyJSON ¶
type PolicyJSON struct {
Name string `json:"name"`
Match PolicyMatchJSON `json:"match"`
Action string `json:"action"`
Approvers []string `json:"approvers,omitempty"`
TimeoutS int `json:"timeout_s,omitempty"`
Reason string `json:"reason,omitempty"`
}
PolicyJSON represents a single policy rule in the relay wire format.
type PolicyMatchJSON ¶
type PolicyMatchJSON struct {
Tool []string `json:"tool,omitempty"`
FilePattern string `json:"file_pattern,omitempty"`
Branch string `json:"branch,omitempty"`
Command string `json:"command,omitempty"`
RiskLevel []string `json:"risk_level,omitempty"`
}
PolicyMatchJSON represents the match criteria for a policy rule.
type RegisterPayload ¶
type RegisterPayload struct {
SessionID string `json:"sid"`
KeyHMAC string `json:"key_hmac"`
AgentType string `json:"agent"`
ProjectName string `json:"project"`
DisplayName string `json:"display"`
DeveloperID string `json:"dev_id,omitempty"`
}
RegisterPayload is sent by the daemon to register a session on the relay.
type RelayEnvelope ¶
type RelayEnvelope struct {
SessionID string `json:"sid"`
Seq uint64 `json:"seq"`
Encrypted []byte `json:"enc"`
TraceID string `json:"tid,omitempty"` // W3C trace-id (32 hex chars); optional for backward compat
}
RelayEnvelope is the wire format for encrypted session messages routed between daemon and PWA via the relay. The relay routes by SessionID and NEVER inspects the Encrypted payload.
type StatusUpdatePayload ¶
type StatusUpdatePayload struct {
SessionID string `json:"sid"`
State string `json:"state"`
CostUSD float64 `json:"cost_usd,omitempty"`
Project string `json:"project,omitempty"`
AgentType string `json:"agent,omitempty"`
DeveloperID string `json:"dev_id,omitempty"`
CreatedAt int64 `json:"created_at,omitempty"`
}
StatusUpdatePayload is sent by the daemon to the relay every 30s with current session state. The relay intercepts this and updates its in-memory state; it is never forwarded to clients.
type SyncPoliciesPayload ¶
type SyncPoliciesPayload struct {
Policies []PolicyJSON `json:"policies"`
}
SyncPoliciesPayload is sent by relay to daemon after CtrlAck. Carries the current org/team policy set.