actions

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Nov 11, 2026 License: MIT Imports: 24 Imported by: 0

Documentation

Overview

Package actions changes things: it opens projects in herdr and starts and stops dev servers. Every action writes its intent to the audit log before it runs and its result after, and passes the safety checks first.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Fetchable

func Fetchable(p *scan.Project) bool

Fetchable reports whether fetch-all includes a project: a repo with a remote, not cloning, not archived.

func HumanBytes

func HumanBytes(n int64) string

HumanBytes is a short size like 812M or 1.4G.

func ProcGroups

func ProcGroups(pids []int) map[int]int

ProcGroups maps each PID to its process group, in one ps call.

func Propose

func Propose(p *scan.Project) []string

Propose guesses a dev command from the project's files. It returns nil when nothing fits; the panel then asks you to type one.

func Tail

func Tail(path string, n int) ([]string, error)

Tail returns up to n final lines of a run log, as written.

Types

type Actions

type Actions struct {
	Runs      *Runs
	Approvals *Approvals
	// contains filtered or unexported fields
}

func New

func New(cfg *config.Config, h *herdr.Client, a *audit.Logger, debug *log.Logger, stateDir string) (*Actions, error)

func (*Actions) ActiveRun

func (a *Actions) ActiveRun(rel string) *Run

ActiveRun returns the panel-started run for a project that is still alive.

func (*Actions) Archive

func (a *Actions) Archive(ctx context.Context, p *scan.Project, mv ArchiveMove, trigger string) Result

Archive moves a project into the archive folder, or back out of it. It is a rename on the same disk; nothing is copied or deleted.

func (*Actions) CanTrash

func (a *Actions) CanTrash(p *scan.Project) error

CanTrash reports why a project can't be moved to the Trash, or nil.

func (*Actions) Cancelled

func (a *Actions) Cancelled(action, trigger string, p *scan.Project, argv []string, details map[string]any)

Cancelled records an action you declined at the confirmation prompt.

func (*Actions) Clean

func (a *Actions) Clean(ctx context.Context, p *scan.Project, plan CleanPlan, trigger string) Result

Clean moves the planned folders to the Trash. Each one is checked again right before it moves; the audit result lists every path and its size.

func (*Actions) DevCommand

func (a *Actions) DevCommand(p *scan.Project) DevCommand

DevCommand returns the dev command for a project: config.toml first, then one you approved before, then a guess that must be confirmed.

func (*Actions) FetchAll

func (a *Actions) FetchAll(ctx context.Context, ps []scan.Project, trigger string, progress func(done, total int)) Result

FetchAll runs `git fetch --all` in every fetchable repo, 6 at a time. The full output of each goes to one log in the runs folder; the audit result lists every repo with its outcome.

func (*Actions) Finder

func (a *Actions) Finder(ctx context.Context, p *scan.Project, trigger string) Result

Finder shows the project folder in a Finder window. It only opens the folder and needs no herdr.

func (*Actions) FocusRun

func (a *Actions) FocusRun(ctx context.Context, r Run, trigger string) Result

FocusRun switches herdr to the workspace a run was started in.

func (*Actions) Init

func (a *Actions) Init(ctx context.Context, p *scan.Project, trigger string) Result

Init runs `git init` in a top-level folder that has no git anywhere inside. Nothing is committed and no remote is added.

func (*Actions) Open

func (a *Actions) Open(ctx context.Context, p *scan.Project, trigger string) Result

Open focuses the project's herdr workspace, creating it if needed.

func (*Actions) PlanArchive

func (a *Actions) PlanArchive(p *scan.Project) (ArchiveMove, error)

PlanArchive works out the move. A project keeps its path: acme/web goes to archive/acme/web, and restore moves it back.

func (*Actions) PlanClean

func (a *Actions) PlanClean(ctx context.Context, p *scan.Project) (CleanPlan, error)

PlanClean looks for allowlisted build folders directly in the project (Safety rule 2). A folder is left out when it is a symlink, holds files tracked in git, holds a nested repo, or, outside a git repo, is a dist or build folder that cannot be confirmed as generated.

func (*Actions) PruneRuns

func (a *Actions) PruneRuns(keep int, maxBytes int64)

PruneRuns keeps the runs folder bounded. Finished runs and fetch logs past the newest keep are removed (record and log together), and finished logs over maxBytes are cut down to their last maxBytes. A run that is still alive is never touched, however old or large. The audit log itself is never pruned; this records what it removed there.

func (*Actions) Pull

func (a *Actions) Pull(ctx context.Context, p *scan.Project, trigger string) Result

Pull runs `git pull --ff-only`: it only ever fast-forwards, never merges or rebases, and git refuses if local changes would be overwritten.

func (*Actions) StartRun

func (a *Actions) StartRun(ctx context.Context, p *scan.Project, dev DevCommand, trigger string) Result

StartRun runs the dev command in a new pane of the project's workspace, with all output teed into the run log, and records the PID.

func (*Actions) StopRun

func (a *Actions) StopRun(ctx context.Context, r Run, trigger string) Result

StopRun stops a run the panel started: Ctrl-C to its pane first, then SIGTERM and finally SIGKILL to the recorded process group, each only after checking the PID still belongs to the same process. Nothing else is touched.

func (*Actions) Tool

func (a *Actions) Tool(ctx context.Context, p *scan.Project, action, label, command, trigger string) Result

Tool opens a pane in the project's workspace running command, e.g. the editor or Claude Code. label names the pane in herdr.

func (*Actions) Trash

func (a *Actions) Trash(ctx context.Context, p *scan.Project, warnings []string, trigger string) Result

Trash moves a whole project folder to the macOS Trash, where Finder's Put Back restores it. The UI asks for the project's path to be typed out first; warnings shown at that prompt are recorded with the action.

type Approvals

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

Approvals remembers dev commands you confirmed once, so "run" does not ask again. Kept in <state>/dev-commands.json; config.toml always wins.

func OpenApprovals

func OpenApprovals(stateDir string) *Approvals

func (*Approvals) Get

func (a *Approvals) Get(rel string) []string

func (*Approvals) Set

func (a *Approvals) Set(rel string, argv []string) error

type ArchiveMove

type ArchiveMove struct {
	From, To string
	Restore  bool // moving out of the archive back under the root
}

ArchiveMove is where archive or restore would move a project.

type CleanItem

type CleanItem struct {
	Dir  string `json:"dir"` // e.g. node_modules, src-tauri/target
	Path string `json:"path"`
	Size int64  `json:"size"`
}

type CleanPlan

type CleanPlan struct {
	Items   []CleanItem `json:"items"`
	Skipped []CleanSkip `json:"skipped,omitempty"`
	Total   int64       `json:"total"`
}

CleanPlan is the dry run: what would move to the Trash, and what was left alone and why.

type CleanSkip

type CleanSkip struct {
	Dir    string `json:"dir"`
	Reason string `json:"reason"`
}

type DevCommand

type DevCommand struct {
	Argv   []string
	Source string // config | approved | proposed | none
}

DevCommand is the command "run" will use for a project and where it came from.

func (DevCommand) Confirmed

func (d DevCommand) Confirmed() bool

Confirmed reports whether the command may run without asking first.

type Result

type Result struct {
	Msg       string
	Err       error
	Remeasure string // a project folder whose size changed
}

Result is what the panel shows after an action: a one-line message, or the error.

type Run

type Run struct {
	ID          string    `json:"id"`
	Project     string    `json:"project"`
	Cwd         string    `json:"cwd"`
	Argv        []string  `json:"argv"`
	Shell       string    `json:"shell"` // the line typed into the pane, secrets masked
	WorkspaceID string    `json:"workspace_id"`
	PaneID      string    `json:"pane_id"`
	PID         int       `json:"pid"`
	PGID        int       `json:"pgid"`
	ProcStart   string    `json:"proc_start"` // ps lstart, guards against PID reuse
	Port        int       `json:"port,omitempty"`
	Log         string    `json:"log"`
	Started     time.Time `json:"started"`
	Stopped     time.Time `json:"stopped,omitzero"`
	StopNote    string    `json:"stop_note,omitempty"`
}

Run is one dev server the panel started. Records live in <state>/runs as <id>.json next to the full output in <id>.log.

func (*Run) Alive

func (r *Run) Alive() bool

Alive reports whether the recorded process is still the one the panel started: same PID and same start time.

type Runs

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

func OpenRuns

func OpenRuns(stateDir string) (*Runs, error)

func (*Runs) Dir

func (s *Runs) Dir() string

func (*Runs) List

func (s *Runs) List() []Run

List returns every recorded run, newest first.

func (*Runs) Save

func (s *Runs) Save(r *Run) error

Jump to

Keyboard shortcuts

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