Documentation
¶
Index ¶
- Constants
- Variables
- type CreatedEvent
- type DelegateResult
- type DeletedEvent
- type InitRequiredEvent
- type Instance
- type Manager
- func (m *Manager) Activate(ctx context.Context, projectID string) error
- func (m *Manager) ActiveID() string
- func (m *Manager) ActiveProject(ctx context.Context) (*Project, error)
- func (m *Manager) CompleteInit(ctx context.Context, projectID string) error
- func (m *Manager) Deactivate(_ context.Context) error
- func (m *Manager) Delegate(ctx context.Context, projectID, promptText string) (*DelegateResult, error)
- func (m *Manager) DelegationInfo(projectID string) (inflight int, spawned, running bool)
- func (m *Manager) EnsureInstance(ctx context.Context, projectID string, autoStart bool) (*Instance, error)
- func (m *Manager) List(ctx context.Context) ([]Project, error)
- func (m *Manager) ListSessions(_ context.Context, projectID string) ([]sessionEntry, error)
- func (m *Manager) Register(ctx context.Context, name, path string) (*Project, error)
- func (m *Manager) Rename(ctx context.Context, projectID, newName string) error
- func (m *Manager) Runtime(projectID, path string) (running, external bool, pid int)
- func (m *Manager) SeedFromGlobal(ctx context.Context)
- func (m *Manager) Shutdown()
- func (m *Manager) Stop(ctx context.Context, projectID string) error
- func (m *Manager) StopReport(ctx context.Context, projectID string) (cancelled int, err error)
- func (m *Manager) Subscribe(ctx context.Context) <-chan pubsub.Event[ManagerEvent]
- func (m *Manager) Unregister(ctx context.Context, projectID string) error
- func (m *Manager) WarmDelegate(ctx context.Context, projectID, projectPath, promptText string, autoStart bool, ...) (*DelegateResult, error)
- type ManagerEvent
- type ManagerEventType
- type Project
- type Service
- type StatusChangedEvent
- type SwitchedEvent
Constants ¶
const ( StatusStopped = "stopped" StatusRunning = "running" StatusError = "error" StatusInitializing = "initializing" StatusMissing = "missing" // path no longer exists on disk )
Status constants for project lifecycle states.
Variables ¶
var ErrExternalInstance = errors.New("project instance was launched externally and cannot be stopped from here")
ErrExternalInstance is returned by Stop when the project is running but its ACP instance was launched by another application (e.g. an editor's ACP integration) rather than by this manager. Such an instance cannot be stopped from here; the user must close it from the application that started it.
var ErrInstanceNotRunning = errors.New("no running manager-owned instance for project")
ErrInstanceNotRunning is returned by Delegate when no manager-owned child ACP instance is currently running for the requested project. Routing the work to a warm instance is only possible while one is live; callers that want auto-start must spawn the instance first (see the warm-target routing phase).
var ErrProjectNeedsInit = errors.New("project needs initialization: no .pando.toml found at path")
ErrProjectNeedsInit is returned when Activate is called on a project path that has no .pando.toml (or .pando.json) configuration file. The caller should guide the user through the init flow before retrying.
var ErrProjectNotRegistered = errors.New("project is not registered")
ErrProjectNotRegistered is returned by WarmDelegate when neither a project id nor a resolvable project path maps to a registered project, so no warm target can be selected. The caller should take the cold path.
var ErrWarmCapReached = errors.New("warm instance concurrency cap reached")
ErrWarmCapReached is returned by WarmDelegate when the per-instance concurrency cap (Delegation.MaxConcurrent) is already reached. The caller should fall back to the cold path rather than overloading a single warm instance.
Functions ¶
This section is empty.
Types ¶
type CreatedEvent ¶
type CreatedEvent struct {
Project Project
}
CreatedEvent is published when a new project is registered.
type DelegateResult ¶ added in v0.601.2
type DelegateResult struct {
// ChildSessionID is the ACP session id created in the child for this run.
// It is stored on the task (ACPSessionID) for correlation/recovery.
ChildSessionID string
// Output is the agent's full streamed message text for the turn.
Output string
// StopReason is the ACP stop reason reported by the child (e.g. end_turn).
StopReason string
}
DelegateResult is the raw outcome of running a delegated prompt inside a warm per-project instance. The orchestrator (warm-target routing) wraps it into a terminal models.Task — populating Output so the existing conclusion pipeline (conclusion.Enrich → supervisor) extracts the <pando:conclusion> block — and fills software-owned launch metadata (model, parent session, correlation, depth) which this transport layer does not know about.
type DeletedEvent ¶
type DeletedEvent struct {
ProjectID string
}
DeletedEvent is published when a project is removed from the registry.
type InitRequiredEvent ¶
InitRequiredEvent is published when activation is attempted on an uninitialized path.
type Instance ¶
type Instance struct {
Project Project
// contains filtered or unexported fields
}
Instance represents a running (or stopped) child Pando ACP process for a registered project directory.
func (*Instance) InflightDelegations ¶ added in v0.601.2
InflightDelegations reports how many delegated sessions are currently running inside this instance. Used by the Projects panel to show "N delegated loops".
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager tracks child Pando ACP processes for registered project directories and routes lifecycle events to subscribers via a generic pubsub broker.
func NewManager ¶
NewManager creates a new Manager. Call Shutdown() when done to stop all child processes and release resources.
func (*Manager) Activate ¶
Activate starts (if needed) the child ACP process for projectID and makes it the active project. Returns ErrProjectNeedsInit if the path has no .pando.toml or .pando.json configuration file.
func (*Manager) ActiveID ¶
ActiveID returns the currently active project ID. An empty string means the main (non-project) pando instance is active.
func (*Manager) ActiveProject ¶
ActiveProject returns the currently active Project, or nil when the main instance is active.
func (*Manager) CompleteInit ¶
CompleteInit initializes the Pando configuration at the project's directory and then activates the project. It is called after the user confirms the initialization prompt shown when Activate returns ErrProjectNeedsInit.
It creates .pando.toml, .pando/ directory structure, and the init flag, then retries Activate. On success the project becomes the active project.
func (*Manager) Deactivate ¶
Deactivate clears the active project (the main pando instance becomes active again).
func (*Manager) Delegate ¶ added in v0.601.2
func (m *Manager) Delegate(ctx context.Context, projectID, promptText string) (*DelegateResult, error)
Delegate runs promptText inside the already-running ("warm") child ACP instance for projectID and captures the agent's streamed output over the wire. It opens a fresh ephemeral session in the child (the child keeps its own session history; the orchestrator's FileStore remains the single source of truth) and closes it on completion.
It returns ErrInstanceNotRunning when no manager-owned instance is live for the project — auto-start is the responsibility of the warm-target routing layer. If ctx is cancelled while the turn is in flight, the child session is cancelled and the context error is returned so the caller can fall back to the cold path.
func (*Manager) DelegationInfo ¶ added in v0.601.2
DelegationInfo reports the warm-delegation state of a manager-owned instance: the count of in-flight delegated sessions, whether the instance was auto-started by the delegation router (vs user-activated), and whether an instance is running at all. All zero/false when the project has no manager-owned instance (e.g. stopped or external).
func (*Manager) EnsureInstance ¶ added in v0.601.2
func (m *Manager) EnsureInstance(ctx context.Context, projectID string, autoStart bool) (*Instance, error)
EnsureInstance returns a running manager-owned instance for projectID, reusing an existing one or auto-starting a new child WITHOUT changing the active project (delegation must never switch the user's focused project).
When the project is served by an external (editor-launched) instance it returns ErrExternalInstance — such instances are never warm targets. When no instance is running and autoStart is false it returns ErrInstanceNotRunning; when autoStart is true but the path has no Pando config it returns ErrProjectNeedsInit.
func (*Manager) ListSessions ¶
ListSessions returns the cached session list for the given project instance. Returns nil when the project is not currently running.
NOTE: Actual session fetching will be implemented in Phase 5 via the REST API. For now this returns the in-memory cache which starts empty and is refreshed by future implementations.
func (*Manager) Register ¶
Register adds a new project path to the registry. If name is empty, filepath.Base(path) is used. The path is expanded (~ resolved) and symlinks are evaluated before storing.
func (*Manager) Rename ¶ added in v0.290.1
Rename changes the display name of a registered project and propagates the change to the global projects registry so other instances can see it.
func (*Manager) Runtime ¶ added in v0.504.1
Runtime reports the live execution state of a project.
running is true when a Pando ACP instance is currently serving the project's directory. external is true when that instance was launched by another application (e.g. an editor's ACP integration) rather than by this manager, and therefore cannot be stopped from here. pid is the OS process id of the serving instance when known.
Ownership is determined by the in-memory instance map: an instance this manager spawned is tracked there. Anything else that holds the project's IPC lock on disk with a live PID is considered an external instance.
func (*Manager) SeedFromGlobal ¶ added in v0.290.1
SeedFromGlobal upserts every entry from the global projects registry into the local DB so that any Pando instance can see all known projects. Entries whose path is already registered are skipped. This is called once during startup.
func (*Manager) Shutdown ¶
func (m *Manager) Shutdown()
Shutdown stops all running child processes and cleans up resources. It is safe to call Shutdown more than once.
func (*Manager) Stop ¶ added in v0.504.1
Stop terminates the child ACP instance this manager launched for projectID.
It returns ErrExternalInstance when the project is running but its instance was launched by another application, which this manager has no authority to terminate. When nothing is running, Stop is a no-op that ensures the registry reflects a stopped state.
func (*Manager) StopReport ¶ added in v0.601.2
StopReport is Stop with bookkeeping: it returns the number of in-flight delegated sessions that were running inside the instance at stop time. Those sessions are cancelled by the process teardown; the orchestrator observes the failed turn and synthesizes a terminal conclusion (cold-path fallback), so the parent loop never hangs. The count lets the UI warn the user how many delegated loops were interrupted.
func (*Manager) Subscribe ¶
Subscribe returns a channel of ManagerEvents for real-time notifications.
func (*Manager) Unregister ¶
Unregister removes a project from the registry and stops its running instance (if any).
func (*Manager) WarmDelegate ¶ added in v0.601.2
func (m *Manager) WarmDelegate(ctx context.Context, projectID, projectPath, promptText string, autoStart bool, maxConcurrent int) (*DelegateResult, error)
WarmDelegate is the high-level warm-routing entry point used by the orchestrator adapter. It ensures a warm instance for the project (reuse-then-autostart, excluding external instances), enforces the per-instance concurrency cap, and runs promptText in the instance, capturing the conclusion over the wire.
projectID may be empty, in which case projectPath is resolved to a registered project. autoStart selects reuse-then-autostart (true) vs reuse-only (false). maxConcurrent (>0) bounds concurrent delegated sessions per instance.
It returns a sentinel error the caller should treat as "use the cold path": ErrInstanceNotRunning (reuse-only, nothing running), ErrExternalInstance (the project is served by an editor-launched instance), ErrProjectNeedsInit (no config to start a child), ErrProjectNotRegistered (unknown project), or ErrWarmCapReached (cap reached). Any other error is a genuine warm-run failure.
type ManagerEvent ¶
type ManagerEvent struct {
Type ManagerEventType
ProjectID string
Status string
Error string
// Count carries the current in-flight delegated-session count for
// EvDelegationChanged events; zero for other event types.
Count int
}
ManagerEvent is the union event type published by Manager.
type ManagerEventType ¶
type ManagerEventType string
ManagerEventType identifies the kind of ManagerEvent.
const ( // EvProjectSwitched is published when the active project changes. EvProjectSwitched ManagerEventType = "switched" // EvStatusChanged is published when a project's running status changes. EvStatusChanged ManagerEventType = "status_changed" // EvInitRequired is published when activation fails because the project // path has no Pando configuration file. EvInitRequired ManagerEventType = "init_required" // EvDelegationChanged is published when the count of in-flight delegated // sessions running inside a warm instance changes (start/end). The current // count is carried in ManagerEvent.Count. EvDelegationChanged ManagerEventType = "delegation_changed" )
type Project ¶
type Project struct {
ID string
Name string
Path string
Status string
Initialized bool
// External is a computed (non-persisted) flag: true when the project is
// running but its ACP instance was launched by another application (e.g. an
// editor in ACP mode) rather than by this manager, so it cannot be stopped
// from here. It is populated on demand via Manager.Runtime and is zero in
// values returned directly from the database.
External bool
// Delegations is a computed (non-persisted) count of delegated agent loops
// currently running inside this project's warm instance. Populated on demand
// via Manager.DelegationInfo; zero for stopped or DB-only values.
Delegations int
// DelegationSpawned is a computed (non-persisted) flag: true when the running
// instance was auto-started by the delegation router (warm reuse) rather than
// activated by the user. Populated on demand via Manager.DelegationInfo.
DelegationSpawned bool
ACPPID int
ACPPort int
LastOpened *time.Time
CreatedAt time.Time
UpdatedAt time.Time
}
Project represents a registered project directory managed by Pando.
type Service ¶
type Service interface {
// Create registers a new project directory.
// name defaults to filepath.Base(path) if empty.
Create(ctx context.Context, name, path string) (*Project, error)
// Get retrieves a project by ID.
Get(ctx context.Context, id string) (*Project, error)
// GetByPath retrieves a project by its directory path.
GetByPath(ctx context.Context, path string) (*Project, error)
// List returns all registered projects, newest first.
List(ctx context.Context) ([]Project, error)
// UpdateStatus updates the running state and optional process info.
// pid and port should be 0 when not applicable.
UpdateStatus(ctx context.Context, id, status string, pid, port int) error
// MarkInitialized marks the project's config as having been initialized.
MarkInitialized(ctx context.Context, id string) error
// TouchLastOpened records the current time as last_opened for the project.
TouchLastOpened(ctx context.Context, id string) error
// Rename updates the display name of a project.
Rename(ctx context.Context, id, name string) error
// Delete removes a project from the registry (does NOT delete files).
Delete(ctx context.Context, id string) error
}
Service defines operations for managing registered projects.
func NewService ¶
NewService creates a new project service backed by the given DB queries.
type StatusChangedEvent ¶
StatusChangedEvent is published when a project's status changes.
type SwitchedEvent ¶
type SwitchedEvent struct {
ProjectID string // empty string means "back to main instance"
}
SwitchedEvent is published when the active project changes.