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

actors

package
v0.2.5 Latest Latest
Warning

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

Go to latest
Published: Aug 9, 2026 License: Apache-2.0 Imports: 72 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ImageMaxBytes int64 = 5 * 1024 * 1024

ImageMaxBytes caps the pre-encode image file size accepted by the command. ~5 MB matches Anthropic's per-image limit. Exposed as a var so a host can tune it per deployment.

Functions

func BuildSoftdevPrompt

func BuildSoftdevPrompt(language, phase, sourceAlias, userText, context string) (string, bool)

BuildSoftdevPrompt constructs the agentic prompt for an AI softdev event. It checks the pipeline overlay first, falling back to the built-in softdevPrompts. userText is optional inline instructions from the event line (text after the phase).

func LookupSoftdevCommand

func LookupSoftdevCommand(language, phase string) (string, bool)

LookupSoftdevCommand returns the shell command for a SH softdev event.

func ParseAISoftdevEvent

func ParseAISoftdevEvent(line string) (language, phase, userText string, ok bool)

ParseAISoftdevEvent checks if a line matches ##>event:ai:softdev:<language>:<phase> [userText]. Any text after the phase (separated by space) is returned as userText.

func ParseShSoftdevEvent

func ParseShSoftdevEvent(line string) (language, phase, userText string, ok bool)

ParseShSoftdevEvent checks if a line matches ##>event:sh:softdev:<language>:<phase> [userText]. Any text after the phase (separated by space) is returned as userText.

func RyshCommandIsStatusAware added in v0.2.3

func RyshCommandIsStatusAware(word string) bool

RyshCommandIsStatusAware reports whether a command word's handler has been audited to report failure (see ryshCommand.statusAware). Unknown words report false.

func RyshCommandWords added in v0.2.3

func RyshCommandWords() []string

RyshCommandWords returns every dispatchable ## command word — canonical names and aliases alike — sorted.

It exists so cmd/rysh can stop hand-maintaining its own list. The CLI's "rysh --<name> ..." forms were gated on a literal map that had drifted to 31 of these 52 words, leaving ##secret, ##var, ##mode, ##policy, ##worktree and eleven others reachable only by typing them into a pane. A list derived from the table cannot drift.

func StreamNameForSession

func StreamNameForSession(session string) string

StreamNameForSession is exposed for tests that assert against the stream.

func WebFSBrowse

func WebFSBrowse(pub *msg.NATSPublisher, op, paneID, path string, offset, length int64) (any, string, string)

WebFSBrowse handles one file-browse request from the embedded web UI. op is "list" or "read"; paneID selects the pane whose cwd is the sandbox root. Returns the reply value, or an error code + message ("" code = ok).

Types

type AgentActor

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

AgentActor represents a single autonomous agent. It is a headless actor (no PTY, no terminal) that has its own LLMPromptExecutionActor child for LLM execution. Agents can be registered to panes so their output appears in the pane's chat buffer.

All fields are unguarded -- proto.actor mailbox guarantees sequential Receive().

func NewAgentActor

func NewAgentActor(
	name, systemPrompt string,
	cfg config.Config,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
	agSetup *agentic.Setup,
	autoApprove *bool,
) *AgentActor

NewAgentActor creates a new AgentActor for an autonomous agent.

func (*AgentActor) Receive

func (a *AgentActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

type AgentBoardListenerActor added in v0.2.4

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

AgentBoardListenerActor is the session-scoped board collector.

It is spawned at the actor-system root with the session (see cmd/rysh), NOT under a workspace, NOT with a pane and NOT with the TUI: it has to be listening before anything exists that could post.

func NewAgentBoardListenerActor added in v0.2.4

func NewAgentBoardListenerActor(nc *nats.Conn, codecs *msg.CodecRegistry, kv nats.KeyValue) *AgentBoardListenerActor

NewAgentBoardListenerActor builds the collector. A nil conn or a nil kv is tolerated: the actor degrades (to no feed, or to a live-only board) rather than taking the session down with it. agents-board is a monitoring view, and a monitoring view that stops a session from starting is worse than no view.

func (*AgentBoardListenerActor) Dropped added in v0.2.4

func (a *AgentBoardListenerActor) Dropped() uint64

Dropped reports how many live events the render buffer refused. They are not lost — the KV write is unconditional — so this is "not applied to the in-memory copy", recoverable by restoring from the KV.

func (*AgentBoardListenerActor) Listening added in v0.2.4

func (a *AgentBoardListenerActor) Listening() bool

Listening reports whether the subscription is live. Used by tests and by anything that wants to say "the board is not recording" out loud rather than letting it be silently false.

func (*AgentBoardListenerActor) Receive added in v0.2.4

func (a *AgentBoardListenerActor) Receive(ctx actor.Context)

Receive is the proto.actor entry point.

func (*AgentBoardListenerActor) Start added in v0.2.4

func (a *AgentBoardListenerActor) Start()

Start restores history, then subscribes, then pumps the live feed into the store. It is IDEMPOTENT: a second call is a no-op.

SINGLE-WRITER IS A CORRECTNESS REQUIREMENT, NOT TIDINESS. Two board Persistence instances each keep their own arrival ordinal, so both write post-...0001 and the second Put OVERWRITES the first. A second writer does not duplicate history, it DESTROYS it — silently, with nothing reporting a loss (TestASecondWriterDestroysHistory pins the behaviour). That is why this method is idempotent, why the TUI passes a nil persister, and why the call site uses SpawnNamed: a second spawn under the same name fails rather than quietly starting a second writer.

Errors are swallowed on purpose and reported through Err(): there is no caller that could do anything useful with them, and the alternative is a session that refuses to start because a monitoring view could not subscribe.

func (*AgentBoardListenerActor) Stop added in v0.2.4

func (a *AgentBoardListenerActor) Stop()

func (*AgentBoardListenerActor) Store added in v0.2.4

func (a *AgentBoardListenerActor) Store() *board.Store

Store is the session's authoritative in-memory board. Exposed for callers in this process; a TUI in another process cannot use it (see the file header) and reads the subjects and the KV instead.

func (*AgentBoardListenerActor) WriteErrors added in v0.2.4

func (a *AgentBoardListenerActor) WriteErrors() uint64

WriteErrors reports KV writes that failed. Non-zero means the board is live-only for those messages: delivered, but they will not survive a restart.

type AgentNervousSystemActor added in v0.2.4

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

AgentNervousSystemActor is the session-scoped router. One per session, always on, spawned by the WorkspaceActor.

PER SESSION, NOT PER FLEET — the founder's ruling. Fleet is metadata on a message, never a boundary on an actor, so this actor knows nothing about fleets and a non-fleet claude routes exactly like a fleet member.

func NewAgentNervousSystemActor added in v0.2.4

func NewAgentNervousSystemActor(pub *msg.NATSPublisher, nc *nats.Conn) *AgentNervousSystemActor

NewAgentNervousSystemActor builds the router over the live session.

func (*AgentNervousSystemActor) Receive added in v0.2.4

func (a *AgentNervousSystemActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

type AgentRegistryActor

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

AgentRegistryActor manages all autonomous agents in the workspace. It spawns AgentActor children and routes commands to them. Follows the same pattern as ShareRegistryActor.

All fields are unguarded -- proto.actor mailbox guarantees sequential Receive().

func NewAgentRegistryActor

func NewAgentRegistryActor(
	sessionName string,
	cfg config.Config,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
	agSetup *agentic.Setup,
	kvStore nats.KeyValue,
) *AgentRegistryActor

NewAgentRegistryActor creates a new agent registry.

func (*AgentRegistryActor) AgentExists

func (r *AgentRegistryActor) AgentExists(name string) bool

AgentExists returns true if an agent with the given name exists.

func (*AgentRegistryActor) Receive

func (r *AgentRegistryActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

type ApprovalPaneActor

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

ApprovalPaneActor is a lightweight ephemeral pane actor that holds approval request data for display. It has no PTY, no shell, and no LLM. The TUI handles input for approval panes directly.

func NewApprovalPaneActor

func NewApprovalPaneActor(cfg ApprovalPaneConfig) *ApprovalPaneActor

NewApprovalPaneActor creates a new ApprovalPaneActor from the given config.

func (*ApprovalPaneActor) ApprovalPaneSnapshotData

func (a *ApprovalPaneActor) ApprovalPaneSnapshotData() domain.ApprovalPaneSnapshot

ApprovalPaneSnapshotData returns the detailed approval pane snapshot for the TUI.

func (*ApprovalPaneActor) BuildSnapshot

func (a *ApprovalPaneActor) BuildSnapshot() domain.PaneSnapshot

BuildSnapshot returns a PaneSnapshot representing this approval pane. It uses the standard PaneSnapshot type with PaneType="approval" and embeds approval-specific data into the existing fields for TUI rendering.

type ApprovalPaneConfig

type ApprovalPaneConfig struct {
	ID              string
	RequestID       string
	SourcePaneID    string
	SourcePaneName  string
	ApprovalRequest *msg.MsgApprovalRequest
	ResponseSubject string
	PaneGroupID     string
}

ApprovalPaneConfig holds the configuration for creating an ApprovalPaneActor.

type AutoLoopActor

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

AutoLoopActor drives one looped automation run. It is spawned by the WorkspaceActor (startAutoLoop) and stops itself when the loop ends.

func (*AutoLoopActor) Receive

func (l *AutoLoopActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

type ConversationContext

type ConversationContext struct {
	ChannelType   string
	SenderID      string
	SenderName    string
	ThreadID      string
	History       []ConversationTurn
	MemorySummary string // LLM-curated summary of older turns (Phase 3 memory)
	TotalTurns    int    // total turns processed (including summarized ones)
	LastActive    time.Time
}

ConversationContext maintains per-thread conversation state for a humanoid channel.

type ConversationTurn

type ConversationTurn struct {
	Role    string // "user" or "assistant"
	Content string
	Time    time.Time
}

ConversationTurn represents a single turn in a humanoid conversation thread.

type ForgeShareActor

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

ForgeShareActor implements first-class forged-API sharing, decoupled from pane/tab sharing (##share). A session can be both a SOURCE (it shared an API with `##forge share api <name>`) and a SUBSCRIBER (it consumed someone else's API with `##forge subscribe <name> [--scope ...]`).

Transport is peer-to-peer over the upstream workspace namespace ws.{ws}.forge.* (the transparent proxy relays it between same-workspace sessions; no server changes needed):

ws.{ws}.forge.catalog.req       discovery (scatter-gather request/reply)
ws.{ws}.forge.api.{name}.invoke per-API invocation (request/reply)

SOURCE responsibilities: answer discovery with its shared APIs' op specs, and answer invocations by running the op on the owner's forge runner under the same governance as before (forge-origin + default-deny-mutation allow/deny + redaction + timeout; NO per-call approval) via evaluateInvoke.

SUBSCRIBER responsibilities: discover, then register a tools.ForgedAPIProxy per op into the SUBSCRIBER-CHOSEN scope registry (pane/panegroup/lane/tab) — the source has no say in the subscriber's scope. Each proxy's Execute round-trips the invoke subject to the source.

It is spawned as a child of WorkspaceActor when upstream is enabled.

func NewForgeShareActor

func NewForgeShareActor(sessionName string, cfg config.UpstreamConfig, pub *msg.NATSPublisher, fm *forge.Manager, scopes *agentic.ScopeRegistries) *ForgeShareActor

NewForgeShareActor builds the actor. fm/scopes come from the agentic Setup.

func (*ForgeShareActor) Receive

func (a *ForgeShareActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

type HeadlessBrowserActor

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

HeadlessBrowserActor executes browser_action requests for a pane in a CLI-owned headless Chromium — a drop-in peer of the desktop app's embedded browser on the same NATS subjects (`pane.<id>.browser.request/response`). It exists so web automations run without rysh-cli-app attached (Phase 4): `##web headless on` / `##auto web run --headless <name>` spawn it as a child of the PaneActor; its Chromium binds a per-profile user-data-dir under the browser-instances root, so auth persists across headless runs (log in once with `##web headless login <profile>`).

Concurrency: actions execute in a goroutine capturing only immutable values (the goroutine-safe *cdp.Browser, the publisher, subjects) per the actor rules; the mailbox stays responsive for Stop.

func NewHeadlessBrowserActor

func NewHeadlessBrowserActor(paneID, profile, url, profileDir string, pub *msg.NATSPublisher, nc *nats.Conn) *HeadlessBrowserActor

NewHeadlessBrowserActor creates the actor. profileDir is the Chromium user-data-dir (…/browser-instances/<profile>/headless).

func (*HeadlessBrowserActor) Receive

func (h *HeadlessBrowserActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

type HoppedInfo

type HoppedInfo struct {
	Content     string
	ChatContent string
	Alias       string
	ID          string
	MemoryTurns int // LLM conversation turns forked into this pane (0 = text-only hop)
}

HoppedInfo holds hopped content metadata for cross-actor reads.

type HumanoidActor

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

HumanoidActor represents a single humanoid — an autonomous agent with external communication channels (WhatsApp, Slack, Email, Phone, Chatbot). It extends the AgentActor pattern with channel adapter management.

All fields are unguarded — proto.actor mailbox guarantees sequential Receive().

func NewHumanoidActor

func NewHumanoidActor(
	name, systemPrompt string,
	contacts map[string]msg.ChannelConfig,
	cfg config.Config,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
	agSetup *agentic.Setup,
	secrets *secretResolver,
) *HumanoidActor

NewHumanoidActor creates a new HumanoidActor.

func (*HumanoidActor) Receive

func (h *HumanoidActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

type HumanoidRegistryActor

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

HumanoidRegistryActor manages all humanoids in the workspace. It spawns HumanoidActor children and routes commands to them. Follows the same pattern as AgentRegistryActor.

All fields are unguarded — proto.actor mailbox guarantees sequential Receive().

func NewHumanoidRegistryActor

func NewHumanoidRegistryActor(
	sessionName string,
	cfg config.Config,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
	agSetup *agentic.Setup,
	kvStore nats.KeyValue,
	secrets *secretResolver,
) *HumanoidRegistryActor

NewHumanoidRegistryActor creates a new humanoid registry.

func (*HumanoidRegistryActor) HumanoidExists

func (r *HumanoidRegistryActor) HumanoidExists(name string) bool

HumanoidExists returns true if a humanoid with the given name exists.

func (*HumanoidRegistryActor) Receive

func (r *HumanoidRegistryActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

type LaneActor

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

LaneActor manages the pane groups within a single lane (column).

All fields are unguarded -- the proto.actor mailbox guarantees sequential Receive().

func NewLaneActor

func NewLaneActor(
	id string,
	tabID string,
	flex int,
	initialPaneID, initialTitle string,
	cfg config.Config,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
	agSetup *agentic.Setup,
	kvStore nats.KeyValue,
	secrets *secretResolver,
) *LaneActor

NewLaneActor creates a new LaneActor with an initial pane group.

func NewLaneActorFromKV

func NewLaneActorFromKV(
	tabID string,
	cfg config.Config,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
	agSetup *agentic.Setup,
	kvStore nats.KeyValue,
	secrets *secretResolver,
	kv laneKV,
) *LaneActor

NewLaneActorFromKV creates a LaneActor that will restore state from KV data on its first *actor.Started message.

func (*LaneActor) ActiveGroupIndex

func (l *LaneActor) ActiveGroupIndex() int

ActiveGroupIndex returns the current active group index.

func (*LaneActor) ActiveGroupPaneCount

func (l *LaneActor) ActiveGroupPaneCount() int

ActiveGroupPaneCount returns the number of panes in the active group.

func (*LaneActor) ActivePaneID

func (l *LaneActor) ActivePaneID() string

ActivePaneID returns the ID of the currently active pane, or "".

func (*LaneActor) AppendPaneRyshOutput

func (l *LaneActor) AppendPaneRyshOutput(paneID, text string)

AppendPaneRyshOutput appends text to a pane's rysh-mode output buffer.

func (*LaneActor) AppendPaneSystemOutput

func (l *LaneActor) AppendPaneSystemOutput(paneID, text string)

AppendPaneSystemOutput appends text to a pane's display-only output buffer.

func (*LaneActor) ContainsPane

func (l *LaneActor) ContainsPane(paneID string) bool

ContainsPane returns true if this lane contains a pane with the given ID.

func (*LaneActor) DeleteAllPaneKV

func (l *LaneActor) DeleteAllPaneKV()

DeleteAllPaneKV removes all pane entries from the KV store.

func (*LaneActor) FlushAllPanes

func (l *LaneActor) FlushAllPanes()

FlushAllPanes forces KV persistence for all pane actors in all groups.

func (*LaneActor) GroupCount

func (l *LaneActor) GroupCount() int

GroupCount returns the number of pane groups in this lane.

func (*LaneActor) HasGivenName

func (l *LaneActor) HasGivenName(name, excludePaneID string) bool

HasGivenName checks if any pane in this lane already uses the given name. excludePaneID allows excluding a specific pane (the one being renamed).

func (*LaneActor) Name

func (l *LaneActor) Name() string

Name returns the user-assigned lane name (empty if unset).

func (*LaneActor) PaneChatOutput

func (l *LaneActor) PaneChatOutput(paneID string) string

PaneChatOutput returns the chat output buffer for a pane. Cross-actor read — informational only.

func (*LaneActor) PaneHistory

func (l *LaneActor) PaneHistory(paneID, mode string) []string

PaneHistory returns the shell or prompt history for a specific pane.

func (*LaneActor) PaneHoppedInfo

func (l *LaneActor) PaneHoppedInfo(paneID string) *HoppedInfo

PaneHoppedInfo returns the hopped content info for a pane. Cross-actor read — informational only.

func (*LaneActor) PaneIDs

func (l *LaneActor) PaneIDs() []string

PaneIDs returns the IDs of all panes across all groups in this lane (in order).

func (*LaneActor) PanePrivateOutput

func (l *LaneActor) PanePrivateOutput(paneID string) string

PanePrivateOutput returns the dedicated private (raw) output buffer for a pane.

func (*LaneActor) PaneSnapshot

func (l *LaneActor) PaneSnapshot(paneID string) *domain.PaneSnapshot

PaneSnapshot returns the current snapshot for a specific pane (no NATS round-trip).

func (*LaneActor) Receive

func (l *LaneActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

func (*LaneActor) SetActiveGroup

func (l *LaneActor) SetActiveGroup(idx int)

SetActiveGroup sets the active group index.

func (*LaneActor) SetName

func (l *LaneActor) SetName(name string)

SetName sets the user-assigned name of this lane. Empty means the lane inherits the tab's pipeline name for display.

func (*LaneActor) ToKV

func (l *LaneActor) ToKV() laneKV

ToKV serialises the lane state for JetStream KV persistence.

Deprecated for cross-actor use: this reads child pane-group structs directly and therefore races with those actors. It is retained only as the fallback path in toKVViaActors / TabActor.toKVViaActors (and for tests). Callers on another goroutine must use the cascade instead.

type LoadedPipeline

type LoadedPipeline struct {
	Name         string          `json:"name"`          // from rysh.name in YAML
	File         string          `json:"file"`          // source filename
	Language     string          `json:"language"`      // e.g., "golang"
	Phases       []PipelinePhase `json:"phases"`        // ordered phases
	Status       string          `json:"status"`        // "idle", "running", "done", "error"
	CurrentPhase int             `json:"current_phase"` // index of currently executing phase (-1 if idle)
}

LoadedPipeline represents a pipeline loaded from a YAML file.

type LoopStatus

type LoopStatus struct {
	Label       string    // kind (web/task/agent/humanoid/code)
	Recipe      string    // recipe name
	ExecID      string    // pane ID or agent/humanoid name
	Pass        int       // 1-based current pass
	MaxPasses   int       // outer cap
	State       string    // "running pass" | "judging"
	LastVerdict string    // most recent judge reason ("" before the first)
	StartedAt   time.Time // loop start
	Deadline    time.Time // outer deadline (zero = no time cap)
}

LoopStatus is the introspection snapshot behind `##auto <kind> status`.

type MemoryManagerActor

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

MemoryManagerActor manages the memory lifecycle for a single pane.

func NewMemoryManagerActor

func NewMemoryManagerActor(
	paneID string,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
	prov provider.AgenticProvider,
) *MemoryManagerActor

NewMemoryManagerActor creates a MemoryManagerActor for the given pane.

func (*MemoryManagerActor) Receive

func (m *MemoryManagerActor) Receive(ctx actor.Context)

Receive handles actor lifecycle and NATS messages.

type MirrorTabListenerActor

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

MirrorTabListenerActor subscribes to a remote shared tab's layout stream on the upstream NATS server and forwards each received layout document to the WorkspaceActor, which renders it as a read-only mirror tab.

It is the tab-level counterpart of RemoteShareListenerActor (which forwards a single pane's output into a local pane). Unlike that actor it does not own a local pane: it pushes whole-tab layout snapshots to the WorkspaceActor via MsgMirrorTabUpdate.

func NewMirrorTabListenerActor

func NewMirrorTabListenerActor(
	shareID, alias, mode, profileName string,
	cfg config.UpstreamConfig,
	pub *msg.NATSPublisher,
	workspacePID *actor.PID,
) *MirrorTabListenerActor

NewMirrorTabListenerActor creates a MirrorTabListenerActor for a remote share. mode is "view" (output only) or "control" (subscriber can run commands on the source panes). profileName labels the sender of control commands.

func (*MirrorTabListenerActor) Receive

func (r *MirrorTabListenerActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

type MsgMirrorPaneScrollback

type MsgMirrorPaneScrollback struct {
	ShareID      string
	SourcePaneID string
	Rows         []string
	Reset        bool
	Seed         bool
}

MsgMirrorPaneScrollback carries scrollback rows (rendered ANSI, oldest first) for a single interactive source pane to the WorkspaceActor, which accumulates them per mirror pane so copy-mode scroll-up shows the session history. Produced by MirrorTabListenerActor, delivered in-process like MsgMirrorPaneVTUpdate. The three modes are mutually exclusive:

  • Reset: clear the pane's accumulated scrollback and its seeded flag (sent when the source pane leaves interactive mode — the session ended).
  • Seed: replace the scrollback with Rows once (the source's pre-join backlog), guarded by the seeded flag so a join broadcast does not clobber an already-seeded subscriber.
  • otherwise (append): append Rows (lines newly evicted from the per-pane VTerm as the live session scrolls).

type MsgMirrorPaneVTUpdate

type MsgMirrorPaneVTUpdate struct {
	ShareID      string
	SourcePaneID string
	Interactive  bool
	Screen       []string
	CursorRow    int
	CursorCol    int
}

MsgMirrorPaneVTUpdate carries a freshly rendered VT screen for a single interactive source pane to the WorkspaceActor, which patches it into the matching mirror tab. It is produced by MirrorTabListenerActor as it demuxes the per-pane raw VT stream (one VTerm per source pane) and is delivered in-process to the WorkspaceActor mailbox (not over NATS), like MsgMirrorTabUpdate. Interactive=false signals the source pane left interactive mode, so the mirror drops its live VT and falls back to scrollback text.

type MsgMirrorTabRemove

type MsgMirrorTabRemove struct {
	ShareID string
}

MsgMirrorTabRemove tells the WorkspaceActor to drop a mirror tab and stop its listener.

type MsgMirrorTabUpdate

type MsgMirrorTabUpdate struct {
	ShareID          string
	Alias            string
	Tab              domain.TabSnapshot
	Deltas           map[string]string   // source pane ID -> appended merged output
	ScrollbackDeltas map[string][]string // source pane ID -> newly-evicted scrollback rows
	Closed           bool                // shared entity gone -> drop the mirror tab
}

MsgMirrorTabUpdate carries a freshly received remote layout to the WorkspaceActor so it can refresh the corresponding mirror tab.

type PaneActor

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

PaneActor manages a single terminal pane — a PTY shell and optional LLM.

All fields are unguarded; the proto.actor mailbox ensures sequential Receive() calls so no sync.RWMutex is needed.

The PTY readLoop goroutine publishes directly to {session}.pane.{id}.output and {session}.pane.{id}.status rather than going through the actor's mailbox, keeping high-frequency data off the control-plane path.

func NewPaneActor

func NewPaneActor(
	id, title string,
	tabID, laneID, groupID string,
	cfg config.Config,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
	agSetup *agentic.Setup,
	kvStore nats.KeyValue,
	secrets *secretResolver,
) *PaneActor

NewPaneActor creates a new PaneActor. It does not start any goroutines; that happens in *actor.Started.

func (*PaneActor) ActiveTurn

func (p *PaneActor) ActiveTurn(ct msg.ConversationType) string

ActiveTurn returns the active turn ID for a conversation type.

func (*PaneActor) AppendRyshOutput

func (p *PaneActor) AppendRyshOutput(text string)

AppendRyshOutput appends text to the rysh-mode output buffer. Cross-actor write — used by the AppendPaneRyshOutput chain and NATS handler.

func (*PaneActor) AppendSystemOutput

func (p *PaneActor) AppendSystemOutput(text string)

AppendSystemOutput appends text to the display output buffer only. It does NOT write to privateBuffer, does NOT publish to NATS, and does NOT mark state as KV-dirty. Used for ## system command output that the user should see but that must never be recorded. Cross-actor write — display only (same pattern as PaneHistory reads).

func (*PaneActor) ChatOutput

func (p *PaneActor) ChatOutput() string

ChatOutput returns the chat-mode output buffer. Cross-actor read — informational only (same pattern as PrivateOutput).

func (*PaneActor) DeleteKV

func (p *PaneActor) DeleteKV()

DeleteKV removes this pane's entry and its buffer entries from the KV store.

func (*PaneActor) ExternalOutput

func (p *PaneActor) ExternalOutput() string

ExternalOutput returns the external-mode output buffer. Cross-actor read — informational only.

func (*PaneActor) FlushKV

func (p *PaneActor) FlushKV()

FlushKV forces an immediate KV write of the current state. Called externally (e.g. by WorkspaceActor during shutdown).

func (*PaneActor) GivenName

func (p *PaneActor) GivenName() string

GivenName returns the user-assigned given-name for this pane.

func (*PaneActor) History

func (p *PaneActor) History(mode string) []string

History returns a copy of the command history for the given mode.

func (*PaneActor) HoppedInfo

func (p *PaneActor) HoppedInfo() *HoppedInfo

HoppedInfo returns the hopped content and source info. Cross-actor read — informational only.

func (*PaneActor) ModeOutput

func (p *PaneActor) ModeOutput(mode string) string

ModeOutput returns a dynamic mode's buffer contents (empty when absent). Cross-actor read — informational only.

func (*PaneActor) PrivateOutput

func (p *PaneActor) PrivateOutput() string

PrivateOutput returns the dedicated private (raw) output buffer. Cross-actor read — informational only (same pattern as PaneHistory).

func (*PaneActor) Program added in v0.2.3

func (p *PaneActor) Program() string

Program returns the pane's live foreground executable name, "" at the shell prompt or where the platform cannot resolve it.

func (*PaneActor) Receive

func (p *PaneActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

func (*PaneActor) RestoreState

func (p *PaneActor) RestoreState(snap domain.PaneSnapshot)

RestoreState loads previously persisted state including output, mode, status, lastCommand, command history, and private/public buffers. The buffers are read from their own KV keys ({paneID}.private, {paneID}.public) which are separate from the pane snapshot. Called before the actor is started when restoring a session.

func (*PaneActor) SetActiveTurn

func (p *PaneActor) SetActiveTurn(ct msg.ConversationType, turnID string)

SetActiveTurn records the active turn ID for a conversation type. Used when starting a new shell command or AI prompt to track which turn subsequent streaming answers belong to.

func (*PaneActor) SetTitle

func (p *PaneActor) SetTitle(title string)

SetTitle updates the pane's display title (used externally from workspace).

func (*PaneActor) Sharing

func (p *PaneActor) Sharing() bool

Sharing returns whether this pane is currently sharing to the upstream.

type PaneGroupActor

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

PaneGroupActor manages the panes within a single pane group (stack of panes).

All fields are unguarded -- the proto.actor mailbox guarantees sequential Receive().

func NewPaneGroupActor

func NewPaneGroupActor(
	id string,
	tabID, laneID string,
	initialPaneID, initialTitle string,
	cfg config.Config,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
	agSetup *agentic.Setup,
	kvStore nats.KeyValue,
	secrets *secretResolver,
) *PaneGroupActor

NewPaneGroupActor creates a new PaneGroupActor with an initial pane.

func NewPaneGroupActorFromKV

func NewPaneGroupActorFromKV(
	tabID, laneID string,
	cfg config.Config,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
	agSetup *agentic.Setup,
	kvStore nats.KeyValue,
	secrets *secretResolver,
	kv paneGroupKV,
) *PaneGroupActor

NewPaneGroupActorFromKV creates a PaneGroupActor that will restore pane state from restoreData on its first *actor.Started message.

func (*PaneGroupActor) ActivePaneID

func (g *PaneGroupActor) ActivePaneID() string

ActivePaneID returns the ID of the currently active pane, or "".

func (*PaneGroupActor) AppendPaneRyshOutput

func (g *PaneGroupActor) AppendPaneRyshOutput(paneID, text string)

AppendPaneRyshOutput appends text to a pane's rysh-mode output buffer.

func (*PaneGroupActor) AppendPaneSystemOutput

func (g *PaneGroupActor) AppendPaneSystemOutput(paneID, text string)

AppendPaneSystemOutput appends text to a pane's display-only output buffer. Nothing is published to NATS, recorded in private/shared buffers, or persisted.

func (*PaneGroupActor) ContainsPane

func (g *PaneGroupActor) ContainsPane(paneID string) bool

ContainsPane returns true if this group contains a pane with the given ID.

func (*PaneGroupActor) DeleteAllPaneKV

func (g *PaneGroupActor) DeleteAllPaneKV()

DeleteAllPaneKV removes all pane entries from the KV store.

func (*PaneGroupActor) FlushAllPanes

func (g *PaneGroupActor) FlushAllPanes()

FlushAllPanes forces KV persistence for all pane actors in this group.

func (*PaneGroupActor) HasGivenName

func (g *PaneGroupActor) HasGivenName(name, excludePaneID string) bool

HasGivenName checks if any pane in this group already uses the given name. excludePaneID allows excluding a specific pane (the one being renamed).

func (*PaneGroupActor) PaneChatOutput

func (g *PaneGroupActor) PaneChatOutput(paneID string) string

PaneChatOutput returns the chat output buffer for a pane. Cross-actor read — informational only.

func (*PaneGroupActor) PaneCount

func (g *PaneGroupActor) PaneCount() int

PaneCount returns the number of panes in this group.

func (*PaneGroupActor) PaneHistory

func (g *PaneGroupActor) PaneHistory(paneID, mode string) []string

PaneHistory returns the shell or prompt history for a specific pane.

func (*PaneGroupActor) PaneHoppedInfo

func (g *PaneGroupActor) PaneHoppedInfo(paneID string) *HoppedInfo

PaneHoppedInfo returns the hopped content info for a pane. Cross-actor read — informational only.

func (*PaneGroupActor) PaneIDs

func (g *PaneGroupActor) PaneIDs() []string

PaneIDs returns the IDs of all panes in this group (in order).

func (*PaneGroupActor) PanePrivateOutput

func (g *PaneGroupActor) PanePrivateOutput(paneID string) string

PanePrivateOutput returns the dedicated private (raw) output buffer for a pane.

func (*PaneGroupActor) PaneSnapshot

func (g *PaneGroupActor) PaneSnapshot(paneID string) *domain.PaneSnapshot

PaneSnapshot returns the current snapshot for a specific pane (no NATS round-trip).

func (*PaneGroupActor) Receive

func (g *PaneGroupActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

func (*PaneGroupActor) ToKV

func (g *PaneGroupActor) ToKV() paneGroupKV

ToKV serialises the group state for JetStream KV persistence.

type PaneSharedOutputListenerActor

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

PaneSharedOutputListenerActor subscribes to another pane's shared output NATS topic and forwards the text to the owner pane. Lines starting with "##>event:print:" are intercepted and the payload is forwarded separately. Regular (non-event) lines are prefixed with "[<targetAlias>] " so the user knows where the output is from.

It is spawned as a child of PaneActor when the user runs ##pane listen.

func NewPaneSharedOutputListenerActor

func NewPaneSharedOutputListenerActor(
	ownerPaneID, targetPaneID, targetAlias string,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
) *PaneSharedOutputListenerActor

NewPaneSharedOutputListenerActor creates a PaneSharedOutputListenerActor.

func (*PaneSharedOutputListenerActor) Receive

Receive implements actor.Actor.

type PipelinePhase

type PipelinePhase struct {
	Name        string `json:"name"`
	Description string `json:"description"`
}

PipelinePhase represents a single phase in a pipeline.

type ProxyAuditActor

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

ProxyAuditActor is the DURABLE audit plane for the governance proxy (design 001 §4.5). It is a child of WorkspaceActor, spawned once per session under the same gate as the UsageActor.

Why it exists: the proxy records each forwarded request in a 256-entry in-process ring that dies with the daemon — so the only trail of governed traffic did not survive a restart, and design 013's org-audit forwarding had nothing durable to forward. This actor closes that gap by capturing every MsgProxyRequestAudit into a per-session JetStream stream (file-backed, so it outlives the process), and serving the ##proxy audit view from it.

The actor does NOT subscribe to the audit subject itself: the JetStream stream is configured on that subject, so the broker captures every published record with no mailbox hop. The actor only (1) ensures the stream exists and (2) answers snapshot requests by reading the tail of the stream. That keeps the hot path a pure data-plane publish and the actor's job small.

Degradation: if JetStream is unavailable the stream cannot be created; the actor then reports Durable=false and empty records, and ##proxy audit falls back to the proxy's in-process ring. This mirrors the UsageActor, which also degrades to in-memory when KV is unavailable.

func NewProxyAuditActor

func NewProxyAuditActor(sessionName string, pub *msg.NATSPublisher, nc *nats.Conn) *ProxyAuditActor

NewProxyAuditActor constructs the audit-plane actor. The JetStream stream is opened lazily in the Started handler; if JetStream is unavailable the actor still serves (empty, non-durable) snapshots rather than failing to start.

func (*ProxyAuditActor) Receive

func (a *ProxyAuditActor) Receive(ctx actor.Context)

type RemoteShareListenerActor

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

RemoteShareListenerActor subscribes to a remote share's output on the upstream NATS server and forwards it to a local pane. In control mode, it can also send commands to the shared entity via the upstream.

func NewRemoteShareListenerActor

func NewRemoteShareListenerActor(
	shareID, ownerPaneID, mode, origin, sessionName, profileName string,
	cfg config.UpstreamConfig,
	pub *msg.NATSPublisher,
	localNC *nats.Conn,
) *RemoteShareListenerActor

NewRemoteShareListenerActor creates a RemoteShareListenerActor. localNC is the local embedded NATS connection used to subscribe to owner pane resize events so the remote VTerm can be sized to the subscriber's dimensions.

func (*RemoteShareListenerActor) Receive

func (r *RemoteShareListenerActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

type RemoteUpstreamActor

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

RemoteUpstreamActor subscribes to the local pane's sharedOutput NATS topic and forwards each message to the remote upstream server via a WebSocket NATS connection. It mirrors the PaneSharedOutputListenerActor pattern but targets a remote server instead of a local pane.

It is spawned as a child of PaneActor when pane sharing is activated.

func NewRemoteUpstreamActor

func NewRemoteUpstreamActor(
	paneID, paneAlias, sessionName string,
	cfg config.UpstreamConfig,
	pub *msg.NATSPublisher,
	localNC *nats.Conn,
) *RemoteUpstreamActor

NewRemoteUpstreamActor creates a RemoteUpstreamActor for the given pane.

func (*RemoteUpstreamActor) Connected

func (r *RemoteUpstreamActor) Connected() bool

Connected returns whether the remote NATS connection is established.

func (*RemoteUpstreamActor) Receive

func (r *RemoteUpstreamActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

type RunSkill

type RunSkill struct {
	Name      string // frontmatter name, or derived from the file path
	Isolation string // "" or "worktree" (validated by parseSkillFile)
	Prompt    string // the file body, ${VAR}-expanded
}

RunSkill is the subset of a parsed skill file that the headless CI runner consumes (`rysh run <skill.md>`, design 009 §3.1). It exists so `rysh run` reuses THIS package's skill-file parsing — frontmatter handling, ${VAR} expansion, isolation validation — instead of growing a second parser.

func ParseRunSkillFile

func ParseRunSkillFile(path string) (*RunSkill, error)

ParseRunSkillFile parses a skill .md file for a headless run. Environment variables are the only ${VAR} source (the run CLI has no session-scoped secret/variable stores to consult).

type ShareEntry

type ShareEntry struct {
	ShareID          string
	EntityType       string
	EntityID         string
	EntityAlias      string
	Mode             string
	ActorPID         *actor.PID
	Connected        bool
	PaneIDs          []string
	SharedRootFolder string
}

ShareEntry tracks a single active share.

type ShareRegistryActor

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

ShareRegistryActor manages all active upstream shares for the session. It is spawned as a child of WorkspaceActor and coordinates share lifecycle.

func NewShareRegistryActor

func NewShareRegistryActor(
	sessionName string,
	cfg config.UpstreamConfig,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
	system *actor.ActorSystem,
	subscribeWebInbox bool,
	forge forgeOpRunner,
) *ShareRegistryActor

NewShareRegistryActor creates a new ShareRegistryActor. subscribeWebInbox should be true for exactly one registry per session (the primary workspace).

func (*ShareRegistryActor) Receive

func (s *ShareRegistryActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

type TabActor

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

TabActor manages the lanes within a single tab.

All fields are unguarded -- the proto.actor mailbox guarantees sequential Receive().

func NewTabActor

func NewTabActor(
	id, title string,
	cfg config.Config,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
	agSetup *agentic.Setup,
	kvStore nats.KeyValue,
	secrets *secretResolver,
	initialPaneTitles []string,
) *TabActor

NewTabActor creates a new TabActor.

initialPaneTitles specifies pane titles that will be created as lanes during *actor.Started, eliminating the publish-before-subscribe race that occurs when the caller publishes MsgTabCreatePane before the bridge is ready.

func NewTabActorFromKV

func NewTabActorFromKV(
	cfg config.Config,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
	agSetup *agentic.Setup,
	kvStore nats.KeyValue,
	secrets *secretResolver,
	kv tabKV,
) *TabActor

NewTabActorFromKV creates a TabActor that will restore state from restoreData on its first *actor.Started message.

func (*TabActor) ActiveLaneName

func (t *TabActor) ActiveLaneName() string

ActiveLaneName returns the effective name of the active lane (its explicit name, or the tab's pipeline name when unset). Returns "" if no active lane.

func (*TabActor) ActivePaneID

func (t *TabActor) ActivePaneID() string

ActivePaneID returns the ID of the currently active pane, or "".

func (*TabActor) ActivePaneIndex

func (t *TabActor) ActivePaneIndex() int

ActivePaneIndex returns the 0-based active lane index.

func (*TabActor) AppendPaneRyshOutput

func (t *TabActor) AppendPaneRyshOutput(paneID, text string)

AppendPaneRyshOutput appends text to a pane's rysh-mode output buffer.

func (*TabActor) AppendPaneSystemOutput

func (t *TabActor) AppendPaneSystemOutput(paneID, text string)

AppendPaneSystemOutput appends text to a pane's display-only output buffer.

func (*TabActor) FlushAllPanes

func (t *TabActor) FlushAllPanes()

FlushAllPanes forces KV persistence for all pane actors in all lanes.

func (*TabActor) IsGivenNameTakenInLane

func (t *TabActor) IsGivenNameTakenInLane(paneID, name string) bool

IsGivenNameTakenInLane checks if the given name is already used by another pane within the same lane as the specified pane.

func (*TabActor) PaneChatOutput

func (t *TabActor) PaneChatOutput(paneID string) string

PaneChatOutput returns the chat output buffer for a pane. Cross-actor read — informational only.

func (*TabActor) PaneHistory

func (t *TabActor) PaneHistory(paneID, mode string) []string

PaneHistory returns the shell or prompt history for a specific pane.

func (*TabActor) PaneHoppedInfo

func (t *TabActor) PaneHoppedInfo(paneID string) *HoppedInfo

PaneHoppedInfo returns the hopped content info for a pane. Cross-actor read — informational only.

func (*TabActor) PaneIDs

func (t *TabActor) PaneIDs() []string

PaneIDs returns the IDs of all panes across all lanes in this tab (in order).

func (*TabActor) PanePrivateOutput

func (t *TabActor) PanePrivateOutput(paneID string) string

PanePrivateOutput returns the dedicated private (raw) output buffer for a pane.

func (*TabActor) PaneRefs

func (t *TabActor) PaneRefs() []paneKV

PaneRefs returns a flattened copy of all pane references for KV persistence.

func (*TabActor) PaneSnapshot

func (t *TabActor) PaneSnapshot(paneID string) *domain.PaneSnapshot

PaneSnapshot returns the current snapshot for a specific pane (no NATS round-trip).

func (*TabActor) Receive

func (t *TabActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

func (*TabActor) SetActiveLaneName

func (t *TabActor) SetActiveLaneName(name string) bool

SetActiveLaneName sets the name of the active lane. Returns false if there is no active lane. Used by the WorkspaceActor for ## lane-naming commands, mirroring the direct-write pattern used for pipelineName.

func (*TabActor) ToKV

func (t *TabActor) ToKV() tabKV

ToKV serialises the tab state for JetStream KV persistence.

Deprecated for cross-actor use: this reads child lane structs directly and therefore races with those actors. It is retained only as the fallback path in toKVViaActors / the workspace shutdown flush (and for tests). Callers on another goroutine must use the cascade instead.

type UpstreamShareActor

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

UpstreamShareActor manages a single shared entity's connection to the upstream NATS server. It subscribes to local shared output for tracked paneIDs and forwards them to the remote upstream. In control mode, it also subscribes to remote command subjects and routes inbound commands to local actors.

It is spawned as a child of ShareRegistryActor.

func NewUpstreamShareActor

func NewUpstreamShareActor(
	shareID, entityType, entityID, entityAlias, mode, sessionName string,
	cfg config.UpstreamConfig,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
	paneIDs []string,
	sharedRootFolder string,
	shareAPI bool,
	forgedOps []msg.ForgedOpSpec,
	redact bool,
	forgeRunner forgeOpRunner,
) *UpstreamShareActor

NewUpstreamShareActor creates a new UpstreamShareActor for the given entity. The shareID must be provided by the caller (ShareRegistryActor) so that the registry and the actor use the same ID on NATS subjects.

func (*UpstreamShareActor) Receive

func (u *UpstreamShareActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

type UsageActor

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

UsageActor is the cost-observability ledger (design 003). It is a child of WorkspaceActor. It subscribes to every pane's usage subject, aggregates token/cost spend by day and pane, persists day aggregates to a per-session KV bucket (time-gated), serves a hot-path budget-check request/reply, and answers snapshot requests for the ##cost command and status bar.

One usage schema, multiple producers: the agentic orchestrator today; the governance proxy (design 001) and CI/eval runners (design 009) later — all publish MsgUsageRecord to rysh.pane.{paneID}.usage.

func NewUsageActor

func NewUsageActor(sessionName string, pub *msg.NATSPublisher, nc *nats.Conn) *UsageActor

NewUsageActor constructs the ledger actor. The KV bucket is opened lazily in the Started handler; if JetStream/KV is unavailable the ledger runs in-memory (no persistence) rather than failing.

func (*UsageActor) Receive

func (u *UsageActor) Receive(ctx actor.Context)

func (*UsageActor) SetCeilings

func (u *UsageActor) SetCeilings(c map[string]int64)

SetCeilings pre-seeds per-pane token ceilings (e.g. from policy-as-code, design 013). Called before the actor starts, so it races nothing.

func (*UsageActor) SetRetentionDays

func (u *UsageActor) SetRetentionDays(d int)

SetRetentionDays overrides the default 90-day retention window.

func (*UsageActor) SetTenantCeilings added in v0.2.3

func (u *UsageActor) SetTenantCeilings(c map[string]int64)

SetTenantCeilings pre-seeds per-tenant token ceilings (design 022 §4.3), from proxy tenants and from policy keys of the form "tenant:<name>". Called before the actor starts, so it races nothing.

func (*UsageActor) SetUsageObserver added in v0.2.3

func (u *UsageActor) SetUsageObserver(o UsageObserver)

SetUsageObserver installs the org-wide reporter. Called before the actor starts, so it races nothing. nil ⇒ local-only, which is the default.

type UsageObserver added in v0.2.3

type UsageObserver interface {
	Record(rec msg.MsgUsageRecord)
}

UsageObserver is a side-channel consumer of the same records the ledger aggregates (design 023 §4.4). It exists so the shared-ledger client can be fed without UsageActor knowing anything about the network — the observer is expected to batch and never to block.

type WebRecorderActor

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

WebRecorderActor records one `##auto web run`. Spawned by the WorkspaceActor, it stops itself once encoding finishes.

func NewWebRecorderActor

func NewWebRecorderActor(paneID, recipeName string, spec webauto.RecordSpec, outPath string,
	supervised bool, pub *msg.NATSPublisher, nc *nats.Conn) *WebRecorderActor

NewWebRecorderActor builds the recorder. outPath must be absolute and already resolved (see webauto.RecordSpec.ResolvePath).

func (*WebRecorderActor) Receive

func (r *WebRecorderActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

type WorkspaceActor

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

WorkspaceActor is the root actor for the session. It manages tabs, routes commands to TabActors, and serves snapshot requests for the TUI.

All fields are unguarded -- the proto.actor mailbox guarantees sequential Receive().

func NewWorkspaceActor

func NewWorkspaceActor(
	cfg config.Config,
	pub *msg.NATSPublisher,
	agSetup *agentic.Setup,
	nc *nats.Conn,
	wKV nats.KeyValue,
	paneKV nats.KeyValue,
	agentKV nats.KeyValue,
	secretKV nats.KeyValue,
	variableKV nats.KeyValue,
	sessionName string,
	workspaceName string,
	workspaceIdx int,
	workspaceNames []string,
	active bool,
	spawnRegistries bool,
) *WorkspaceActor

NewWorkspaceActor creates a new WorkspaceActor. It is spawned as a child of the WorkspaceFarmActor (one per workspace). workspaceName identifies the workspace (and is its KV key); workspaceIdx/workspaceNames describe its place in the session's workspace list; active controls whether it subscribes to the session-scoped ws.* subjects at startup; spawnRegistries controls whether the agent/humanoid/share registries are created here.

func (*WorkspaceActor) Receive

func (w *WorkspaceActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

type WorkspaceFarmActor

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

WorkspaceFarmActor is the session root actor. It hosts one WorkspaceActor per workspace defined in the config and keeps exactly one of them "active" (the only one subscribed to the session-scoped ws.* subjects). All coordination is in-process: it has no NATS bridge and no subscriptions of its own. Switch requests reach it only by being forwarded from the currently active WorkspaceActor (which received them on ws.inbox).

All fields are unguarded -- the proto.actor mailbox guarantees sequential Receive().

func NewWorkspaceFarmActor

func NewWorkspaceFarmActor(
	cfg config.Config,
	pub *msg.NATSPublisher,
	agSetup *agentic.Setup,
	nc *nats.Conn,
	wKV nats.KeyValue,
	paneKV nats.KeyValue,
	agentKV nats.KeyValue,
	secretKV nats.KeyValue,
	variableKV nats.KeyValue,
	sessionName string,
	configPath string,
) *WorkspaceFarmActor

NewWorkspaceFarmActor creates the session root actor. It takes the same dependencies the WorkspaceActor needs, because it constructs the per-workspace WorkspaceActors itself. Subscription limits are enforced per-workspace: each WorkspaceActor builds its own limits checker from its resolved upstream.

func (*WorkspaceFarmActor) Receive

func (f *WorkspaceFarmActor) Receive(ctx actor.Context)

Receive implements actor.Actor.

Source Files

Jump to

Keyboard shortcuts

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