mode

package
v0.2.8-alpha.2 Latest Latest
Warning

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

Go to latest
Published: May 23, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package mode hosts agent-mode and isolation tools: EnterPlanMode / ExitPlanMode (read-only planning) and EnterWorktree / ExitWorktree (filesystem-isolated worktrees).

Each pair is wired through a narrow controller supplied by the agent: PlanModeController mutates the owning agent's permission mode and reads the plan-file path off its workdir; WorktreeController switches the agent's workdir into / out of a git worktree and rebuilds workdir-bound active tools. See worktree.go / worktree_controller.go.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CleanupSubagentWorktree

func CleanupSubagentWorktree(ctx context.Context, sess WorktreeSession, removeAlways bool) (bool, string)

CleanupSubagentWorktree tears down a worktree created by CreateForSubagent. If the worktree has any uncommitted changes the caller can decide to keep it (return the path to the user) instead of removing it. RemoveAlways=true forces removal regardless.

Returns (wasRemoved, summary). On wasRemoved=false the worktree is still on disk; summary describes why (e.g. "had 3 uncommitted file(s)").

func Names

func Names() []tools.ToolName

Names lists every tool name this package contributes.

func PlanFilePath

func PlanFilePath(workdir, planName string) string

PlanFilePath returns the absolute path of the plan file for the given planName. When planName is empty it defaults to "current" (backward compatible — the legacy single-plan-per-session filename). Exposed so tests and the user-guide doc can reference the canonical location.

Types

type ControllerLookup

type ControllerLookup func() PlanModeController

ControllerLookup is the late-bound factory closure passed to the EnterPlanMode / ExitPlanMode constructors. Returning nil disables the tool — Execute surfaces a clear "no controller installed" error instead of crashing.

type EnterPlanModeTool

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

EnterPlanModeTool flips the session into plan mode, stashes the prior mode for restore, and prepares an empty plan file the model writes to.

func NewEnterPlanMode

func NewEnterPlanMode(lookup ControllerLookup) *EnterPlanModeTool

NewEnterPlanMode constructs the tool with a late-bound controller lookup. The lookup is invoked once per Execute call — passing a closure (rather than the controller directly) lets toolset.Build resolve the agent after agent.New returns.

func (*EnterPlanModeTool) Description

func (t *EnterPlanModeTool) Description() string

func (*EnterPlanModeTool) Execute

func (t *EnterPlanModeTool) Execute(_ context.Context, logger *slog.Logger, input json.RawMessage) (tools.Result, error)

func (*EnterPlanModeTool) Name

func (t *EnterPlanModeTool) Name() string

func (*EnterPlanModeTool) Schema

func (t *EnterPlanModeTool) Schema() json.RawMessage

type EnterWorktreeTool

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

EnterWorktreeTool creates `.evva/worktrees/<slug>/` on a new branch `worktree-<slug>` and switches the agent's workdir into it.

func NewEnterWorktree

func NewEnterWorktree(lookup WorktreeControllerLookup) *EnterWorktreeTool

func (*EnterWorktreeTool) Description

func (t *EnterWorktreeTool) Description() string

func (*EnterWorktreeTool) Execute

func (t *EnterWorktreeTool) Execute(ctx context.Context, logger *slog.Logger, input json.RawMessage) (tools.Result, error)

func (*EnterWorktreeTool) Name

func (t *EnterWorktreeTool) Name() string

func (*EnterWorktreeTool) Schema

func (t *EnterWorktreeTool) Schema() json.RawMessage

type ExitPlanModeTool

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

ExitPlanModeTool reads the plan file, asks the user to approve, and restores the pre-plan permission mode on approval. Rejection leaves the session in ModePlan with the user's reason surfaced to the model.

func NewExitPlanMode

func NewExitPlanMode(lookup ControllerLookup) *ExitPlanModeTool

func (*ExitPlanModeTool) Description

func (t *ExitPlanModeTool) Description() string

func (*ExitPlanModeTool) Execute

func (t *ExitPlanModeTool) Execute(ctx context.Context, logger *slog.Logger, input json.RawMessage) (tools.Result, error)

func (*ExitPlanModeTool) Name

func (t *ExitPlanModeTool) Name() string

func (*ExitPlanModeTool) Schema

func (t *ExitPlanModeTool) Schema() json.RawMessage

type ExitWorktreeTool

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

ExitWorktreeTool tears down (or keeps) a worktree session opened by EnterWorktree, restoring the agent's original workdir.

func NewExitWorktree

func NewExitWorktree(lookup WorktreeControllerLookup) *ExitWorktreeTool

func (*ExitWorktreeTool) Description

func (t *ExitWorktreeTool) Description() string

func (*ExitWorktreeTool) Execute

func (t *ExitWorktreeTool) Execute(ctx context.Context, logger *slog.Logger, input json.RawMessage) (tools.Result, error)

func (*ExitWorktreeTool) Name

func (t *ExitWorktreeTool) Name() string

func (*ExitWorktreeTool) Schema

func (t *ExitWorktreeTool) Schema() json.RawMessage

type PlanModeController

type PlanModeController interface {
	PermissionMode() permission.Mode
	SetPermissionMode(m permission.Mode)
	PrePlanMode() permission.Mode
	SetPrePlanMode(m permission.Mode)
	Workdir() string
	Broker() permission.Broker
	AgentID() string
	PlanName() string
	SetPlanName(name string)
}

PlanModeController is the seam between the EnterPlanMode / ExitPlanMode tools and the owning agent. The agent satisfies it directly; the tool constructors take a lookup closure (returns a PlanModeController) so builtin registration can stay late-bound — the agent installs itself after toolset.NewToolState runs.

The interface is intentionally narrow: only what the two plan-mode tools actually touch. Permission mode mutation, the pre-plan stash (used by ExitPlanMode to restore), the workdir (for the plan-file path), the approval broker (for ExitPlanMode's user-approval gate), and the AgentID that the broker uses to route the approval event.

type WorktreeController

type WorktreeController interface {
	Workdir() string
	SwitchWorkdir(path string) error
	WorktreeSession() *WorktreeSession
	BeginWorktreeSession(s WorktreeSession)
	EndWorktreeSession()
	AgentID() string
	Logger() *slog.Logger
}

WorktreeController is the seam between the EnterWorktree / ExitWorktree tools and the owning agent — same shape and lifecycle as PlanModeController: the agent satisfies it directly, the tool constructors take a lookup closure so the agent can install itself after toolset construction without an init ordering hazard.

SwitchWorkdir is the load-bearing call: implementations rebuild any active tool that captured the OLD workdir at construction time (filesystem tools, the bash tool), reload the EVVA.md / USER_PROFILE.md memory snapshot from the new path, and re-render the system prompt so the next LLM turn sees the new working directory.

BeginWorktreeSession / EndWorktreeSession bracket a logical session; while a session is live, WorktreeSession() returns a non-nil pointer so EnterWorktree can refuse re-entry and ExitWorktree knows whether to no-op or actually tear the worktree down.

type WorktreeControllerLookup

type WorktreeControllerLookup func() WorktreeController

WorktreeControllerLookup is the late-bound factory closure passed to the EnterWorktree / ExitWorktree constructors. Returning nil disables the tool — Execute surfaces a clear "no controller installed" error instead of crashing.

type WorktreeSession

type WorktreeSession struct {
	// OriginalWorkdir is the workdir the agent was in before EnterWorktree
	// fired. ExitWorktree restores it.
	OriginalWorkdir string
	// Path is the absolute path to the worktree directory.
	Path string
	// Branch is the branch name created with `git worktree add -b`.
	Branch string
	// Slug is the flattened slug used to compose Path and Branch — kept
	// for logging and the tool's confirmation message.
	Slug string
	// CreatedBySubagent marks worktrees the AgentTool's isolation path
	// created (vs the user-invoked EnterWorktree tool). The post-run
	// cleanup in spawn.go uses this to decide whether to auto-remove on
	// clean exit.
	CreatedBySubagent bool
	CreatedAt         time.Time
}

WorktreeSession records the metadata the worktree tools and AgentTool isolation need to clean up a worktree on exit. It is also what the subagent spawner threads into a child constructed under `isolation: "worktree"` — the child carries it so its own ExitWorktree (rarely invoked from a subagent but possible) and the post-run cleanup path in spawn.go agree on what to tear down.

func CreateForSubagent

func CreateForSubagent(ctx context.Context, parentWorkdir, agentName string) (WorktreeSession, error)

CreateForSubagent provisions a worktree for an AgentTool isolation spawn. It is callable from internal/agent/spawn.go (no controller involved — the child agent's workdir is fixed at construction). Returns the worktree session metadata so spawn.go can:

  • construct the child with cfg.WorkDir = session.Path
  • tear down the worktree after the child exits (clean-exit path) or surface its path back to the parent (dirty-exit path).

agentName is folded into the slug so panel rows / logs / branch names stay readable; if the child name is empty, a random suffix is used.

Jump to

Keyboard shortcuts

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