workflow

package
v0.1.0 Latest Latest
Warning

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

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

Documentation

Index

Constants

View Source
const DefaultSystemPrompt = `` /* 189-byte string literal not displayed */

DefaultSystemPrompt is used when no system_prompt is configured in .sortie.yml.

View Source
const SortieSettingsDirName = "claude-settings"

SortieSettingsDirName is the directory name (relative to a worktree's .sortie/) that holds the Claude Code settings.json layered onto the spawned agent via the `--settings` CLI flag.

View Source
const StepDoneDirName = "step-done"

StepDoneDirName is the directory name (relative to a worktree's .sortie/) that holds Stop-hook sentinel files for tmux step completion detection.

Variables

This section is empty.

Functions

func BuildDiffStatSummaryPrompt

func BuildDiffStatSummaryPrompt(taskID int64, title, description, diffStat string) string

BuildDiffStatSummaryPrompt constructs the diff-stat-fallback summarizer prompt: the prompt used when no step contexts are available and only the list of changed files is known. Exported so the backfill CLI can reuse the exact prompt shape used by live finalization.

func BuildSystemPrompt

func BuildSystemPrompt(resolvedPrompt, systemPrompt string, imageRelPaths []string) string

BuildSystemPrompt constructs the system prompt string from the configured preamble, resolved task prompt, and optional image paths. systemPrompt controls the preamble; if empty, DefaultSystemPrompt is used. imageRelPaths are worktree-relative paths to attached images (may be nil).

func CopyImagesToWorktree

func CopyImagesToWorktree(worktreePath string, imagePaths []string) ([]string, error)

CopyImagesToWorktree copies the given image files into .sortie/images/ in the worktree. Returns the list of worktree-relative paths for the copied images.

func EnsureWorkDirs

func EnsureWorkDirs(worktreePath string) error

EnsureWorkDirs creates the .sortie/logs directory in a worktree.

func ImagesDir

func ImagesDir(worktreePath string) string

ImagesDir returns the path to the images directory in a worktree.

func InstallStopHook

func InstallStopHook(worktreePath, stepName string) error

InstallStopHook writes a Claude Code settings.json into the worktree's .sortie/claude-settings/ directory wiring the Stop hook to drop a sentinel file under .sortie/step-done/ on every turn end. It is idempotent: calling it again after a step has already installed hooks rewrites the same files with current values (the hook command depends only on absolute paths in the worktree, so identical runs produce identical output).

The stepName parameter scopes sentinel filenames so multiple concurrent steps in the same worktree (e.g. a loop replaying earlier steps) don't collide. Sentinel files include a nanosecond timestamp suffix so a single step that fires the Stop hook multiple times (e.g. user-driven follow-up turns) still produces unique files; the daemon ignores subsequent sentinels once the workflow has advanced past the step.

func LogsDir

func LogsDir(worktreePath string) string

LogsDir returns the path to the logs directory in a worktree.

func ProjectLogPath

func ProjectLogPath(dataDir string, taskID int64) string

ProjectLogPath returns the path to the unified task log file in the project data dir. All steps and the finalization phase append into this single file so the log preserves chronological order across step boundaries.

func ProjectLogsDir

func ProjectLogsDir(dataDir string, taskID int64) string

ProjectLogsDir returns the path to the logs directory for a task in the project data dir.

func ResolveTaskRefs

func ResolveTaskRefs(s string, lookup func(int64) (*task.Task, error)) string

ResolveTaskRefs replaces every {{tasks.<id>.<field>}} reference in s with the field value of the looked-up task. Used to pre-expand a task's own description / context before they are inlined into a step prompt — keeps the substitution single-pass (no recursive expansion into other tasks' refs). Behaviour on lookup miss matches resolveTaskRef: empty string + warning.

func ResolveTemplate

func ResolveTemplate(tmpl string, ctx *TemplateContext) string

ResolveTemplate replaces {{dotted.path}} placeholders in the template string.

func RunWorktreeSetupCommand

func RunWorktreeSetupCommand(ctx context.Context, projectRoot, worktreePath, command string) error

RunWorktreeSetupCommand runs the configured worktree setup command, if any. The command is executed with the project root as the working directory. {{worktree_path}} in the command string is replaced with the actual worktree path.

func RunWorktreeSetupCommands

func RunWorktreeSetupCommands(ctx context.Context, projectRoot, worktreePath string, commands []string) error

RunWorktreeSetupCommands runs multiple worktree setup commands sequentially. Each command is executed with the project root as the working directory. {{worktree_path}} in command strings is replaced with the actual worktree path. Execution stops at the first failure.

func SortieSettingsDir

func SortieSettingsDir(worktreePath string) string

SortieSettingsDir returns the absolute path to the Claude settings directory inside a worktree. The Stop hook is installed at <dir>/settings.json and loaded via `claude --settings <dir>/settings.json`.

func StepDoneDir

func StepDoneDir(worktreePath string) string

StepDoneDir returns the absolute path to the directory holding Stop-hook sentinel files inside a worktree.

func SupportedTaskRefFields

func SupportedTaskRefFields() []string

SupportedTaskRefFields returns the list of valid fields for {{tasks.<id>.<field>}} references (for use in error messages).

func SyncPathsToWorktree

func SyncPathsToWorktree(srcRoot, dstRoot string, paths config.WorktreeSyncPathsConfig) error

SyncPathsToWorktree syncs the configured paths from srcRoot into dstRoot. Copy paths are fully copied (files and directories). Link paths are hard-linked so that Claude Code (which cannot follow symlinks outside its working directory) can read the files directly. Symlink sources are replicated as symlinks since macOS link(2) refuses to hard-link a symlink (EPERM).

Failures on individual paths are collected and returned as a joined error so one bad entry does not prevent the rest from being synced.

func ValidateTaskRefs

func ValidateTaskRefs(refs []TaskRef) error

ValidateTaskRefs returns a descriptive error if any ref uses an unsupported field name. Other validation (existence, project match, status) is the daemon's responsibility because it requires DB access.

Types

type Engine

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

func NewEngine

func NewEngine(cfg *config.Config, database *db.DB, notifier *notify.Notifier, repoRoot string, lock ...*merge.Lock) *Engine

NewEngine creates a new workflow engine. The optional Lock parameter is an externally-owned per-repo merge serializer; when non-nil, the lock survives config reloads (the daemon owns it via merge.Locks). When nil, a fresh lock is created for standalone/test usage.

func (*Engine) Coord

func (e *Engine) Coord() *merge.Coordinator

Coord returns the engine's merge coordinator. The daemon uses it to take the per-repo lock for ad-hoc operations (revert, worktree teardown) that must serialize against merges.

func (*Engine) FinalizeTask

func (e *Engine) FinalizeTask(ctx context.Context, t *task.Task) error

FinalizeTask runs the on_complete action, then the summarizer, then worktree cleanup. Used when finalizing a tmux-continued task.

func (*Engine) ResumeAfterApproval

func (e *Engine) ResumeAfterApproval(ctx context.Context, t *task.Task, outputFn func([]string)) error

ResumeAfterApproval resumes a task from its current step index. If the previously-completed step was a tmux step with summarize_chat strategy, summarisation runs synchronously here (it could not run during the step itself because tmux steps return early and pause the engine).

func (*Engine) RunTask

func (e *Engine) RunTask(ctx context.Context, t *task.Task, outputFn func([]string)) error

RunTask executes the full workflow pipeline for a task. It creates/reuses the worktree, then loops through steps starting from t.StepIndex. outputFn is called with parsed log lines for live streaming (may be nil).

type GitVars

type GitVars struct {
	BaseBranch   string
	TargetBranch string
	RepoRoot     string
}

type LoopVars

type LoopVars struct {
	Iteration     int
	MaxIterations int
}

type TaskRef

type TaskRef struct {
	ID    int64
	Field string
	// Raw is the original placeholder text including braces, e.g. "{{tasks.42.title}}".
	Raw string
}

TaskRef captures a parsed {{tasks.<id>.<field>}} reference.

func ExtractTaskRefs

func ExtractTaskRefs(s string) []TaskRef

ExtractTaskRefs scans s for all {{tasks.<id>.<field>}} placeholders and returns them. Malformed forms (non-numeric id, missing field, extra dots) are skipped. The same (id, field) pair may appear multiple times in the result if it occurs multiple times in s.

type TaskVars

type TaskVars struct {
	ID          int64
	Title       string
	Description string
	Context     string
	Slug        string
	Branch      string
	Images      []string // worktree-relative paths to attached images
}

type TemplateContext

type TemplateContext struct {
	Task  TaskVars
	Steps map[string]string // step name -> result text from DB
	Git   GitVars
	Loop  LoopVars
	// TaskLookup resolves a task by ID for {{tasks.<id>.<field>}} references.
	// When nil, such references resolve to "".
	TaskLookup func(int64) (*task.Task, error)
}

Jump to

Keyboard shortcuts

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