← back to johnjansen__anvil

Function bodies 169 total

All specs Real LLM only Function bodies
main.init function · go · L36-L43 (8 LOC)
cmd/anvil/main.go
func init() {
	if version != "dev" {
		return
	}
	if info, ok := debug.ReadBuildInfo(); ok && info.Main.Version != "" && info.Main.Version != "(devel)" {
		version = info.Main.Version
	}
}
main.main function · go · L45-L109 (65 LOC)
cmd/anvil/main.go
func main() {
	if len(os.Args) < 2 {
		printUsage()
		os.Exit(1)
	}

	switch os.Args[1] {
	case "serve":
		fmt.Fprintln(os.Stderr, "'anvil serve' has been renamed. Did you mean 'anvil watch'?")
		serveCmd()
	case "watch":
		watchCmd2(os.Args[2:])
	case "unwatch":
		fmt.Fprintln(os.Stderr, "'anvil unwatch' has been removed. Did you mean 'anvil project rm [path]'?")
		os.Exit(1)
	case "status":
		statusCmd()
	case "cleanup":
		cleanupCmd(os.Args[2:])
	case "ps":
		psCmd()
	case "init":
		initCmd(os.Args[2:])
	case "register":
		registerCmd(os.Args[2:])
	case "add":
		addCmd(os.Args[2:])
	case "list":
		fmt.Fprintln(os.Stderr, "'anvil list' has been removed. Did you mean 'anvil task ls'?")
		os.Exit(1)
	case "get":
		fmt.Fprintln(os.Stderr, "'anvil get' has been removed. Did you mean 'anvil task get <name>'?")
		os.Exit(1)
	case "delete":
		fmt.Fprintln(os.Stderr, "'anvil delete' has been removed. Did you mean 'anvil task rm <name>'?")
		os.Exit(1)
	case "log":
		fmt.Fprintln(os.Stderr, "
main.printUsage function · go · L111-L181 (71 LOC)
cmd/anvil/main.go
func printUsage() {
	fmt.Fprintf(os.Stderr, `anvil - central task dispatcher for LLM projects

Usage:
  anvil <command> [options]

Commands:
  init [path]              Initialize a project and register it for watching
  register [path]          Register a project for watching (without full init)
  watch [-d|--daemonize]   Start the daemon (once per machine)
  watch --install          Install as system service (auto-start on boot)
  watch --uninstall        Remove the system service
  watch --status           Show system service status
  watch --stop             Stop the background daemon
  add [options] <task>     Add a task to the current project
  logs [<name>]            Raw worker output (all tasks if no name given)
  ps [--json]              Show running tasks
  status                   Show watched projects
  reload                   Reload daemon configuration (SIGHUP)
  usage [options]           Show LLM token usage and estimated costs
  stop-on-idle             Drain running t
main.initCmd function · go · L183-L215 (33 LOC)
cmd/anvil/main.go
func initCmd(args []string) {
	path := "."
	if len(args) > 0 {
		path = args[0]
	}

	abs, err := filepath.Abs(path)
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	if err := project.Init(abs, tools.FS); err != nil {
		log.Fatalf("failed to init project: %v", err)
	}

	created, err := config.EnsureConfig()
	if err != nil {
		log.Fatalf("failed to create ~/.anvil/config.yaml: %v", err)
	}
	if created {
		fmt.Printf("created %s\n", config.Path())
	}

	fmt.Printf("initialized %s\n", abs)

	// Register project for watching (fold in old 'anvil watch' behavior)
	registerProject(abs)

	// Warn if daemon is not running
	if !daemon.IsDaemonRunning() {
		fmt.Fprintf(os.Stderr, "⚠ Daemon is not running. Run 'anvil watch' to start executing tasks.\n")
	}
}
main.registerCmd function · go · L217-L233 (17 LOC)
cmd/anvil/main.go
func registerCmd(args []string) {
	path := "."
	if len(args) > 0 {
		path = args[0]
	}

	abs, err := filepath.Abs(path)
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	registerProject(abs)

	if !daemon.IsDaemonRunning() {
		fmt.Fprintf(os.Stderr, "⚠ Daemon is not running. Run 'anvil watch' to start executing tasks.\n")
	}
}
main.registerProject function · go · L237-L276 (40 LOC)
cmd/anvil/main.go
func registerProject(abs string) {
	if err := config.EnsureDir(); err != nil {
		log.Fatalf("failed to create ~/.anvil: %v", err)
	}

	hash := projectHash(abs)
	watchDir := filepath.Join(config.WatchedDir(), hash)

	if entries, err := os.ReadDir(watchDir); err == nil && len(entries) > 0 {
		fmt.Printf("already watching %s\n", abs)
		return
	}

	if err := os.MkdirAll(watchDir, 0755); err != nil {
		log.Fatalf("failed to create watch dir: %v", err)
	}

	now := time.Now()
	filename := now.Format("2006-01-02T15-04-05") + ".md"

	frontmatter := watchFrontmatter{
		Path:      abs,
		WatchedAt: now,
	}
	data, err := yaml.Marshal(frontmatter)
	if err != nil {
		log.Fatalf("failed to marshal: %v", err)
	}

	var sb strings.Builder
	sb.WriteString("---\n")
	sb.Write(data)
	sb.WriteString("---\n")

	if err := os.WriteFile(filepath.Join(watchDir, filename), []byte(sb.String()), 0644); err != nil {
		log.Fatalf("failed to write watch file: %v", err)
	}

	fmt.Printf("watching %s\n", abs)
}
main.serveCmd function · go · L278-L302 (25 LOC)
cmd/anvil/main.go
func serveCmd() {
	if err := config.EnsureDir(); err != nil {
		log.Fatalf("failed to create ~/.anvil: %v", err)
	}

	cfg, err := config.Load()
	if err != nil {
		log.Fatalf("failed to load config: %v", err)
	}

	d := daemon.New(cfg)

	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)

	go d.Run()

	select {
	case sig := <-sigCh:
		log.Printf("received %v, shutting down", sig)
		d.Stop()
	case <-d.Done():
		// daemon stopped itself (e.g. stop-on-idle drain completed)
	}
}
Repobility · code-quality intelligence platform · https://repobility.com
main.watchCmd2 function · go · L305-L361 (57 LOC)
cmd/anvil/main.go
func watchCmd2(args []string) {
	daemonize := false
	stop := false
	child := false
	install := false
	uninstall := false
	status := false
	for _, arg := range args {
		switch arg {
		case "--daemonize", "-d":
			daemonize = true
		case "--stop":
			stop = true
		case "--child":
			child = true
		case "--install":
			install = true
		case "--uninstall":
			uninstall = true
		case "--status":
			status = true
		}
	}

	if install {
		watchInstall()
		return
	}

	if uninstall {
		watchUninstall()
		return
	}

	if status {
		watchStatus()
		return
	}

	if stop {
		stopDaemon()
		return
	}

	if child {
		runDaemonChild()
		return
	}

	if daemonize {
		daemonizeProcess()
		return
	}

	// Default: run in foreground (existing behavior)
	serveCmd()
}
main.watchInstall function · go · L363-L385 (23 LOC)
cmd/anvil/main.go
func watchInstall() {
	svc, err := service.New()
	if err != nil {
		log.Fatalf("failed to initialize service manager: %v", err)
	}

	binaryPath, err := os.Executable()
	if err != nil {
		log.Fatalf("cannot determine binary path: %v", err)
	}
	binaryPath, err = filepath.EvalSymlinks(binaryPath)
	if err != nil {
		log.Fatalf("cannot resolve binary path: %v", err)
	}

	if err := svc.Install(binaryPath); err != nil {
		log.Fatalf("failed to install service: %v", err)
	}

	fmt.Printf("service installed and started\n")
	fmt.Printf("  binary: %s\n", binaryPath)
	fmt.Printf("  anvil watch will now auto-start on boot and restart on crash\n")
}
main.watchUninstall function · go · L387-L398 (12 LOC)
cmd/anvil/main.go
func watchUninstall() {
	svc, err := service.New()
	if err != nil {
		log.Fatalf("failed to initialize service manager: %v", err)
	}

	if err := svc.Uninstall(); err != nil {
		log.Fatalf("failed to uninstall service: %v", err)
	}

	fmt.Println("service uninstalled")
}
main.watchStatus function · go · L400-L412 (13 LOC)
cmd/anvil/main.go
func watchStatus() {
	svc, err := service.New()
	if err != nil {
		log.Fatalf("failed to initialize service manager: %v", err)
	}

	st, err := svc.Status()
	if err != nil {
		log.Fatalf("failed to get service status: %v", err)
	}

	fmt.Printf("service: %s\n", st.Message)
}
main.readDaemonPID function · go · L416-L436 (21 LOC)
cmd/anvil/main.go
func readDaemonPID() int {
	data, err := os.ReadFile(config.PidFile())
	if err != nil {
		return 0
	}
	pid, err := strconv.Atoi(strings.TrimSpace(string(data)))
	if err != nil {
		return 0
	}
	// Check if process is alive
	proc, err := os.FindProcess(pid)
	if err != nil {
		return 0
	}
	if err := proc.Signal(syscall.Signal(0)); err != nil {
		// Process not alive — clean up stale PID file
		os.Remove(config.PidFile())
		return 0
	}
	return pid
}
main.daemonizeProcess function · go · L439-L471 (33 LOC)
cmd/anvil/main.go
func daemonizeProcess() {
	if err := config.EnsureDir(); err != nil {
		log.Fatalf("failed to create ~/.anvil: %v", err)
	}

	if pid := readDaemonPID(); pid != 0 {
		fmt.Fprintf(os.Stderr, "daemon already running (PID %d)\n", pid)
		return
	}

	exe, err := os.Executable()
	if err != nil {
		log.Fatalf("failed to find executable path: %v", err)
	}

	logFile, err := os.OpenFile(config.DaemonLogPath(), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
	if err != nil {
		log.Fatalf("failed to open daemon log: %v", err)
	}

	cmd := exec.Command(exe, "watch", "--child")
	cmd.Stdout = logFile
	cmd.Stderr = logFile
	cmd.SysProcAttr = &syscall.SysProcAttr{Setsid: true}

	if err := cmd.Start(); err != nil {
		logFile.Close()
		log.Fatalf("failed to start daemon: %v", err)
	}

	logFile.Close()
	fmt.Fprintf(os.Stderr, "daemon started (PID %d)\n", cmd.Process.Pid)
}
main.runDaemonChild function · go · L474-L504 (31 LOC)
cmd/anvil/main.go
func runDaemonChild() {
	if err := config.EnsureDir(); err != nil {
		log.Fatalf("failed to create ~/.anvil: %v", err)
	}

	pid := os.Getpid()
	if err := os.WriteFile(config.PidFile(), []byte(strconv.Itoa(pid)), 0644); err != nil {
		log.Fatalf("failed to write PID file: %v", err)
	}
	defer os.Remove(config.PidFile())

	cfg, err := config.Load()
	if err != nil {
		log.Fatalf("failed to load config: %v", err)
	}

	d := daemon.New(cfg)

	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)

	go d.Run()

	select {
	case sig := <-sigCh:
		log.Printf("received %v, shutting down", sig)
		d.Stop()
	case <-d.Done():
		d.Stop()
	}
}
main.stopDaemon function · go · L507-L534 (28 LOC)
cmd/anvil/main.go
func stopDaemon() {
	pid := readDaemonPID()
	if pid == 0 {
		fmt.Fprintln(os.Stderr, "no daemon running")
		return
	}

	proc, err := os.FindProcess(pid)
	if err != nil {
		fmt.Fprintln(os.Stderr, "no daemon running")
		return
	}

	if err := proc.Signal(syscall.SIGTERM); err != nil {
		fmt.Fprintf(os.Stderr, "failed to stop daemon: %v\n", err)
		return
	}

	// Wait up to 5 seconds for the PID file to disappear
	for i := 0; i < 50; i++ {
		time.Sleep(100 * time.Millisecond)
		if _, err := os.Stat(config.PidFile()); os.IsNotExist(err) {
			fmt.Fprintf(os.Stderr, "daemon stopped (PID %d)\n", pid)
			return
		}
	}
	fmt.Fprintf(os.Stderr, "daemon did not stop in time (PID %d)\n", pid)
}
Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
main.watchCmd function · go · L538-L558 (21 LOC)
cmd/anvil/main.go
func watchCmd(args []string) {
	path := "."
	if len(args) > 0 {
		path = args[0]
	}

	abs, err := filepath.Abs(path)
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	// Initialize project .anvil/ if it doesn't exist
	if _, err := os.Stat(filepath.Join(abs, ".anvil", "todos")); os.IsNotExist(err) {
		if err := project.Init(abs, tools.FS); err != nil {
			log.Fatalf("failed to init project: %v", err)
		}
		fmt.Printf("initialized %s/.anvil/\n", abs)
	}

	registerProject(abs)
}
main.unwatchCmd function · go · L560-L584 (25 LOC)
cmd/anvil/main.go
func unwatchCmd(args []string) {
	path := "."
	if len(args) > 0 {
		path = args[0]
	}

	abs, err := filepath.Abs(path)
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	hash := projectHash(abs)
	watchDir := filepath.Join(config.WatchedDir(), hash)

	if _, err := os.Stat(watchDir); os.IsNotExist(err) {
		fmt.Printf("not watching %s\n", abs)
		return
	}

	if err := os.RemoveAll(watchDir); err != nil {
		log.Fatalf("failed to unwatch: %v", err)
	}

	fmt.Printf("unwatched %s\n", abs)
}
main.statusCmd function · go · L586-L613 (28 LOC)
cmd/anvil/main.go
func statusCmd() {
	watched, err := loadAllWatched()
	if err != nil {
		log.Fatalf("failed to read watched: %v", err)
	}

	// Show daemon drain state if running
	if daemon.IsDaemonRunning() {
		if status, err := daemon.SendStatusRequest(); err == nil && status.Draining {
			fmt.Println("daemon: draining (stop-on-idle active)")
		}
	}

	if len(watched) == 0 {
		fmt.Println("no watched projects")
		return
	}

	for _, w := range watched {
		proj, err := project.Load(w.Path)
		if err != nil {
			fmt.Printf("  %s  (error: %v)\n", w.Path, err)
			continue
		}
		todos, _ := proj.LoadTodos()
		fmt.Printf("  %s  todos=%d\n", w.Path, len(todos))
	}
}
main.reloadCmd function · go · L615-L637 (23 LOC)
cmd/anvil/main.go
func reloadCmd(args []string) {
	if len(args) > 0 && (args[0] == "-h" || args[0] == "--help") {
		fmt.Println("Usage: anvil reload")
		fmt.Println("")
		fmt.Println("Reload the daemon configuration without restarting.")
		fmt.Println("")
		fmt.Println("Sends SIGHUP to the daemon to reload ~/.anvil/config.yaml.")
		fmt.Println("New tasks will use the updated config; running tasks are unaffected.")
		return
	}

	if !daemon.IsDaemonRunning() {
		fmt.Println("daemon not running")
		return
	}

	if err := daemon.SendReloadRequest(); err != nil {
		fmt.Printf("failed to reload config: %v\n", err)
		return
	}

	fmt.Println("config reload triggered")
}
main.cleanupCmd function · go · L639-L722 (84 LOC)
cmd/anvil/main.go
func cleanupCmd(args []string) {
	olderThan := ""
	dryRun := false

	for _, a := range args {
		if a == "--dry-run" || a == "-n" {
			dryRun = true
		} else if strings.HasPrefix(a, "--older-than=") {
			olderThan = strings.TrimPrefix(a, "--older-than=")
		} else if strings.HasPrefix(a, "-o=") {
			olderThan = strings.TrimPrefix(a, "-o=")
		}
	}

	var maxAge time.Duration
	if olderThan != "" {
		var err error
		maxAge, err = time.ParseDuration(olderThan)
		if err != nil {
			log.Fatalf("invalid duration: %s (use format like 7d, 24h)", olderThan)
		}
	}

	watched, err := loadAllWatched()
	if err != nil {
		log.Fatalf("failed to read watched: %v", err)
	}

	if len(watched) == 0 {
		fmt.Println("no watched projects")
		return
	}

	// If no retention config and no --older-than, show current config
	cfg, _ := config.Load()
	if maxAge == 0 && cfg.Retention.MaxAge == 0 && cfg.Retention.MaxRuns == 0 {
		fmt.Println("No retention policy configured. Set in ~/.anvil/config.yaml:")
		fmt.Println(" 
main.pruneDir function · go · L724-L817 (94 LOC)
cmd/anvil/main.go
func pruneDir(dir string, maxAge time.Duration, maxRuns int, dryRun bool) (int, int) {
	entries, err := os.ReadDir(dir)
	if err != nil {
		return 0, 0
	}

	// Collect task directories
	var taskDirs []string
	for _, entry := range entries {
		if entry.IsDir() {
			taskDirs = append(taskDirs, filepath.Join(dir, entry.Name()))
		}
	}

	deleted := 0
	freed := 0

	for _, taskDir := range taskDirs {
		taskEntries, err := os.ReadDir(taskDir)
		if err != nil {
			continue
		}

		// Collect files with modification times
		type fileInfo struct {
			name    string
			path    string
			size    int64
			modTime time.Time
		}

		var files []fileInfo
		for _, entry := range taskEntries {
			if entry.IsDir() {
				continue
			}
			info, err := entry.Info()
			if err != nil {
				continue
			}
			files = append(files, fileInfo{
				name:    entry.Name(),
				path:    filepath.Join(taskDir, entry.Name()),
				size:    info.Size(),
				modTime: info.ModTime(),
			})
		}

		if len(files) == 0 {
			continu
main.psCmd function · go · L819-L889 (71 LOC)
cmd/anvil/main.go
func psCmd() {
	jsonOutput := false
	for _, a := range os.Args[2:] {
		if a == "--json" {
			jsonOutput = true
		}
	}

	if !daemon.IsDaemonRunning() {
		if jsonOutput {
			fmt.Println("[]")
		} else {
			fmt.Println("daemon not running")
		}
		return
	}

	// Show drain status header if applicable (text mode only)
	if !jsonOutput {
		if status, err := daemon.SendStatusRequest(); err == nil && status.Draining {
			fmt.Println("(draining — no new tasks will be dispatched)")
		}
	}

	tasks, err := daemon.SendPsRequest()
	if err != nil {
		if jsonOutput {
			fmt.Println("[]")
		} else {
			fmt.Printf("failed to get tasks: %v\n", err)
		}
		return
	}

	if len(tasks) == 0 {
		if jsonOutput {
			fmt.Println("[]")
		} else {
			fmt.Println("no running tasks")
		}
		return
	}

	if jsonOutput {
		data, err := json.MarshalIndent(tasks, "", "  ")
		if err != nil {
			log.Fatalf("failed to marshal JSON: %v", err)
		}
		fmt.Println(string(data))
		return
	}

	// Print table header
	fmt.Printf("%-30s 
main.truncate function · go · L892-L900 (9 LOC)
cmd/anvil/main.go
func truncate(s string, maxLen int) string {
	if len(s) <= maxLen {
		return s
	}
	if maxLen < 3 {
		return s[:maxLen]
	}
	return s[:maxLen-3] + "..."
}
Same scanner, your repo: https://repobility.com — Repobility
main.addCmd function · go · L902-L936 (35 LOC)
cmd/anvil/main.go
func addCmd(args []string) {
	// Handle -h/--help before creating task
	for _, arg := range args {
		if arg == "-h" || arg == "--help" {
			fmt.Fprintf(os.Stderr, `usage: anvil add [-p priority] [-s schedule] [--pre-check cmd] [--allowed-tools tools] [--max-concurrent n] [--skip-permissions] [-f file | -] <task text>

Add a new task to the project.

Options:
  -p, --priority n        Priority 0-9 (default: 1)
  -s, --schedule cron     Cron schedule (e.g., "*/15 * * * *")
  --pre-check cmd        Command to run before task execution
  --allowed-tools tools  Comma-separated list of allowed tools
  --max-concurrent n     Max concurrent runs (default: 1)
  --skip-permissions     Skip permission checks
  -f, --file path        Read task content from a file
  -                      Read task content from stdin

Frontmatter in file/stdin input is merged with CLI flags (CLI flags take precedence).

Examples:
  anvil add "Review pull requests"
  anvil add -p 2 -s "0 9 * * *" "Daily standup note
main.listCmd function · go · L938-L966 (29 LOC)
cmd/anvil/main.go
func listCmd() {
	abs, err := filepath.Abs(".")
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	proj, err := project.Load(abs)
	if err != nil {
		log.Fatalf("failed to load project: %v", err)
	}

	todos, err := proj.LoadTodos()
	if err != nil {
		log.Fatalf("failed to load todos: %v", err)
	}

	if len(todos) == 0 {
		fmt.Println("no todos")
		return
	}

	for _, t := range todos {
		preview := strings.TrimSpace(t.Content)
		if len(preview) > 60 {
			preview = preview[:60] + "..."
		}
		fmt.Printf("p%d  %-14s  %-40s  %s\n", t.Priority, t.Schedule, t.Name, preview)
	}
}
main.getCmd function · go · L968-L1006 (39 LOC)
cmd/anvil/main.go
func getCmd(args []string) {
	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "usage: anvil get <name>\n")
		os.Exit(1)
	}

	abs, err := filepath.Abs(".")
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	proj, err := project.Load(abs)
	if err != nil {
		log.Fatalf("failed to load project: %v", err)
	}

	todos, err := proj.LoadTodos()
	if err != nil {
		log.Fatalf("failed to load todos: %v", err)
	}

	todo := findTodo(todos, args[0])
	if todo == nil {
		fmt.Fprintf(os.Stderr, "todo not found: %s\n", args[0])
		os.Exit(1)
	}

	fmt.Printf("File:     p%d/%s\n", todo.Priority, todo.Name)
	fmt.Printf("ID:       %s\n", todo.ID)
	fmt.Printf("Schedule: %s\n", todo.Schedule)
	fmt.Printf("Priority: %d\n", todo.Priority)
	if todo.ID != "" {
		sessionPath := project.SessionPath(abs, todo.ID)
		if _, err := os.Stat(sessionPath); err == nil {
			fmt.Printf("Session:  %s\n", sessionPath)
		}
	}
	fmt.Printf("\n%s", todo.Content)
}
main.deleteCmd function · go · L1008-L1040 (33 LOC)
cmd/anvil/main.go
func deleteCmd(args []string) {
	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "usage: anvil delete <name>\n")
		os.Exit(1)
	}

	abs, err := filepath.Abs(".")
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	proj, err := project.Load(abs)
	if err != nil {
		log.Fatalf("failed to load project: %v", err)
	}

	todos, err := proj.LoadTodos()
	if err != nil {
		log.Fatalf("failed to load todos: %v", err)
	}

	todo := findTodo(todos, args[0])
	if todo == nil {
		fmt.Fprintf(os.Stderr, "todo not found: %s\n", args[0])
		os.Exit(1)
	}

	if err := project.RemoveTodo(*todo); err != nil {
		log.Fatalf("failed to delete todo: %v", err)
	}

	fmt.Printf("deleted p%d/%s\n", todo.Priority, todo.Name)
}
main.logCmd function · go · L1042-L1107 (66 LOC)
cmd/anvil/main.go
func logCmd(args []string) {
	follow := false
	var rest []string
	for _, a := range args {
		switch a {
		case "-f", "--follow":
			follow = true
		default:
			rest = append(rest, a)
		}
	}

	if len(rest) == 0 {
		fmt.Fprintf(os.Stderr, "usage: anvil log [-f] <name|uuid>\n")
		os.Exit(1)
	}

	abs, err := filepath.Abs(".")
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	// Try as todo name first, fall back to treating arg as a UUID directly
	id := rest[0]
	var todoName string
	proj, err := project.Load(abs)
	if err == nil {
		todos, err := proj.LoadTodos()
		if err == nil {
			if todo := findTodo(todos, rest[0]); todo != nil {
				id = todo.ID
				todoName = todo.Name
			}
		}
	}

	if id == "" {
		fmt.Fprintf(os.Stderr, "todo has no session ID\n")
		os.Exit(1)
	}

	// Resolve the session ID from the latest run record (not the task ID)
	sessionID, err := project.LatestSessionID(abs, id)
	if err != nil {
		fmt.Fprintf(os.Stderr, "no session log found (looked at %s): %v\n", project
main.taskCmd function · go · L1109-L1156 (48 LOC)
cmd/anvil/main.go
func taskCmd(args []string) {
	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "usage: anvil task <subcommand> [options]\n")
		fmt.Fprintf(os.Stderr, "Run 'anvil help' for more information.\n")
		os.Exit(1)
	}

	switch args[0] {
	case "create":
		taskCreateCmd(args[1:])
	case "ls":
		taskLsCmd(args[1:])
	case "get":
		taskGetCmd(args[1:])
	case "log":
		taskLogCmd(args[1:])
	case "rm":
		taskRmCmd(args[1:])
	case "run":
		taskRunCmd(args[1:])
	case "kill":
		taskKillCmd(args[1:])
	case "history":
		taskHistoryCmd(args[1:])
	case "stop-on-idle":
		taskStopOnIdleCmd(args[1:])
	case "unlock":
		taskUnlockCmd(args[1:])
	case "edit":
		taskEditCmd(args[1:])
	case "pause":
		taskPauseCmd(args[1:])
	case "resume":
		taskResumeCmd(args[1:])
	case "queue":
		taskQueueCmd(args[1:])
	case "timeout":
		taskTimeoutCmd(args[1:])
	case "stop":
		taskStopCmd(args[1:])
	case "start":
		taskStartCmd(args[1:])
	default:
		fmt.Fprintf(os.Stderr, "unknown task command: %s\n", args[0])
		fmt.Fprintf(os.Stderr,
main.taskCreateCmd function · go · L1158-L1324 (167 LOC)
cmd/anvil/main.go
func taskCreateCmd(args []string) {
	priority := 1
	schedule := ""
	preCheck := ""
	allowedTools := ""
	maxConcurrent := 1
	skipPermissions := false
	filePath := ""
	readStdin := false

	// Track which flags were explicitly set on the CLI so they take precedence over frontmatter.
	prioritySet := false
	scheduleSet := false
	preCheckSet := false
	allowedToolsSet := false
	maxConcurrentSet := false

	var rest []string
	for i := 0; i < len(args); i++ {
		switch args[i] {
		case "-p", "--priority":
			if i+1 >= len(args) {
				log.Fatal("missing value for -p/--priority")
			}
			i++
			n := 0
			for _, c := range args[i] {
				if c < '0' || c > '9' {
					log.Fatalf("invalid priority: %s (must be 0-9)", args[i])
				}
				n = n*10 + int(c-'0')
			}
			if n > 9 {
				log.Fatalf("priority must be 0-9, got %d", n)
			}
			priority = n
			prioritySet = true
		case "-s", "--schedule":
			if i+1 >= len(args) {
				log.Fatal("missing value for -s/--schedule")
			}
			i++
			schedule = args[i]
			
main.parseFrontmatterAndMerge function · go · L1330-L1385 (56 LOC)
cmd/anvil/main.go
func parseFrontmatterAndMerge(
	content string,
	priority int, schedule, preCheck, allowedTools string, maxConcurrent int, skipPermissions bool,
	prioritySet, scheduleSet, preCheckSet, allowedToolsSet, maxConcurrentSet bool,
) (string, int, string, string, string, int, bool) {
	if !strings.HasPrefix(content, "---\n") {
		return content, priority, schedule, preCheck, allowedTools, maxConcurrent, skipPermissions
	}

	parts := strings.SplitN(content[4:], "\n---\n", 2)
	if len(parts) != 2 {
		// No closing delimiter found; treat entire content as body.
		return content, priority, schedule, preCheck, allowedTools, maxConcurrent, skipPermissions
	}

	fm := parts[0]
	body := parts[1]

	var fmData struct {
		Priority        *int   `yaml:"priority"`
		Schedule        string `yaml:"schedule"`
		PreCheck        string `yaml:"pre_check"`
		AllowedTools    string `yaml:"allowed_tools"`
		MaxConcurrent   *int   `yaml:"max_concurrent"`
		SkipPermissions bool   `yaml:"skip_permissions"`
	}
	if err := 
Provenance: Repobility (https://repobility.com) — every score reproducible from /scan/
main.taskLsCmd function · go · L1387-L1530 (144 LOC)
cmd/anvil/main.go
func taskLsCmd(args []string) {
	allProjects := false
	jsonOutput := false
	for _, a := range args {
		if a == "--all" || a == "-a" {
			allProjects = true
		}
		if a == "--json" {
			jsonOutput = true
		}
	}

	// Gather running tasks once
	var runningTasks []daemon.TaskInfo
	if daemon.IsDaemonRunning() {
		runningTasks, _ = daemon.SendPsRequest()
	}
	runningByID := make(map[string]daemon.TaskInfo)
	for _, t := range runningTasks {
		runningByID[fmt.Sprintf("%s/%s", t.Project, t.Name)] = t
	}

	type projectTodos struct {
		path  string
		todos []project.Todo
	}

	var projects []projectTodos

	if allProjects {
		watched, err := loadAllWatched()
		if err != nil {
			log.Fatalf("failed to read watched: %v", err)
		}
		for _, w := range watched {
			proj, err := project.Load(w.Path)
			if err != nil {
				continue
			}
			todos, _ := proj.LoadTodos()
			projects = append(projects, projectTodos{path: w.Path, todos: todos})
		}
	} else {
		abs, err := filepath.Abs(".")
		if err != nil {
			l
main.taskGetCmd function · go · L1532-L1655 (124 LOC)
cmd/anvil/main.go
func taskGetCmd(args []string) {
	jsonOutput := false
	var rest []string
	for _, a := range args {
		if a == "--json" {
			jsonOutput = true
		} else {
			rest = append(rest, a)
		}
	}

	if len(rest) == 0 {
		fmt.Fprintf(os.Stderr, "usage: anvil task get <name> [--json]\n")
		os.Exit(1)
	}

	abs, err := filepath.Abs(".")
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	proj, err := project.Load(abs)
	if err != nil {
		log.Fatalf("failed to load project: %v", err)
	}

	todos, err := proj.LoadTodos()
	if err != nil {
		log.Fatalf("failed to load todos: %v", err)
	}

	todo := findTodo(todos, rest[0])
	if todo == nil {
		fmt.Fprintf(os.Stderr, "task not found: %s\n", rest[0])
		os.Exit(1)
	}

	// Check if task is running
	runStatus := "idle"
	var runPID int
	var runElapsed string
	if daemon.IsDaemonRunning() {
		runningTasks, err := daemon.SendPsRequest()
		if err == nil {
			taskName := fmt.Sprintf("%s/%s", abs, todo.Name)
			for _, t := range runningTasks {
				if t.Name == taskNa
main.taskLogCmd function · go · L1657-L1739 (83 LOC)
cmd/anvil/main.go
func taskLogCmd(args []string) {
	follow := false
	var rest []string
	for _, a := range args {
		switch a {
		case "-f", "--follow":
			follow = true
		default:
			rest = append(rest, a)
		}
	}

	if len(rest) == 0 {
		fmt.Fprintf(os.Stderr, "usage: anvil task log [-f] <name|uuid>\n")
		os.Exit(1)
	}

	abs, err := filepath.Abs(".")
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	id := rest[0]
	var todoName string
	proj, err := project.Load(abs)
	if err == nil {
		todos, err := proj.LoadTodos()
		if err == nil {
			if todo := findTodo(todos, rest[0]); todo != nil {
				id = todo.ID
				todoName = todo.Name
			}
		}
	}

	// Try to resolve session ID: first from run records, then from the running daemon.
	var sessionID string

	if id != "" {
		sessionID, _ = project.LatestSessionID(abs, id)
	}

	// If we couldn't resolve a session ID from disk, check if the task is
	// currently running — the daemon tracks the session ID in memory.
	if sessionID == "" && todoName != "" && daemon.Is
main.taskRmCmd function · go · L1741-L1780 (40 LOC)
cmd/anvil/main.go
func taskRmCmd(args []string) {
	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "usage: anvil task rm <name>\n")
		os.Exit(1)
	}

	abs, err := filepath.Abs(".")
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	proj, err := project.Load(abs)
	if err != nil {
		log.Fatalf("failed to load project: %v", err)
	}

	todos, err := proj.LoadTodos()
	if err != nil {
		log.Fatalf("failed to load todos: %v", err)
	}

	todo := findTodo(todos, args[0])
	if todo == nil {
		fmt.Fprintf(os.Stderr, "task not found: %s\n", args[0])
		os.Exit(1)
	}

	// Kill if running
	if daemon.IsDaemonRunning() {
		if err := daemon.SendKillRequest(todo.ID); err == nil {
			fmt.Printf("killed running task %s\n", todo.Name)
		}
	}

	if err := project.RemoveTodo(*todo); err != nil {
		log.Fatalf("failed to remove todo: %v", err)
	}

	fmt.Printf("removed p%d/%s\n", todo.Priority, todo.Name)
}
main.taskRunCmd function · go · L1782-L1820 (39 LOC)
cmd/anvil/main.go
func taskRunCmd(args []string) {
	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "usage: anvil task run <name>\n")
		os.Exit(1)
	}

	abs, err := filepath.Abs(".")
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	proj, err := project.Load(abs)
	if err != nil {
		log.Fatalf("failed to load project: %v", err)
	}

	todos, err := proj.LoadTodos()
	if err != nil {
		log.Fatalf("failed to load todos: %v", err)
	}

	todo := findTodo(todos, args[0])
	if todo == nil {
		fmt.Fprintf(os.Stderr, "task not found: %s\n", args[0])
		os.Exit(1)
	}

	if !daemon.IsDaemonRunning() {
		fmt.Fprintln(os.Stderr, "daemon not running — start it with: anvil watch")
		os.Exit(1)
	}

	if err := daemon.SendRunRequest(abs, todo.ID, todo.Name); err != nil {
		fmt.Fprintf(os.Stderr, "failed to run task: %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("▶ Dispatched %s for immediate execution\n", todo.Name)
}
main.taskKillCmd function · go · L1822-L1860 (39 LOC)
cmd/anvil/main.go
func taskKillCmd(args []string) {
	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "usage: anvil task kill <name>\n")
		os.Exit(1)
	}

	abs, err := filepath.Abs(".")
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	proj, err := project.Load(abs)
	if err != nil {
		log.Fatalf("failed to load project: %v", err)
	}

	todos, err := proj.LoadTodos()
	if err != nil {
		log.Fatalf("failed to load todos: %v", err)
	}

	todo := findTodo(todos, args[0])
	if todo == nil {
		fmt.Fprintf(os.Stderr, "task not found: %s\n", args[0])
		os.Exit(1)
	}

	if !daemon.IsDaemonRunning() {
		fmt.Println("daemon not running")
		return
	}

	if err := daemon.SendKillRequest(todo.ID); err != nil {
		fmt.Printf("failed to kill task: %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("killed task: %s\n", args[0])
}
main.taskStopCmd function · go · L1862-L1900 (39 LOC)
cmd/anvil/main.go
func taskStopCmd(args []string) {
	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "usage: anvil task stop <name>\n")
		os.Exit(1)
	}

	abs, err := filepath.Abs(".")
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	proj, err := project.Load(abs)
	if err != nil {
		log.Fatalf("failed to load project: %v", err)
	}

	todos, err := proj.LoadTodos()
	if err != nil {
		log.Fatalf("failed to load todos: %v", err)
	}

	todo := findTodo(todos, args[0])
	if todo == nil {
		fmt.Fprintf(os.Stderr, "task not found: %s\n", args[0])
		os.Exit(1)
	}

	if !daemon.IsDaemonRunning() {
		fmt.Fprintln(os.Stderr, "daemon not running — start it with: anvil watch")
		os.Exit(1)
	}

	if err := daemon.SendStopRequest(todo.ID); err != nil {
		fmt.Fprintf(os.Stderr, "failed to stop task: %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("stopped %s — will not be re-dispatched until started\n", todo.Name)
}
main.taskStartCmd function · go · L1902-L1940 (39 LOC)
cmd/anvil/main.go
func taskStartCmd(args []string) {
	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "usage: anvil task start <name>\n")
		os.Exit(1)
	}

	abs, err := filepath.Abs(".")
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	proj, err := project.Load(abs)
	if err != nil {
		log.Fatalf("failed to load project: %v", err)
	}

	todos, err := proj.LoadTodos()
	if err != nil {
		log.Fatalf("failed to load todos: %v", err)
	}

	todo := findTodo(todos, args[0])
	if todo == nil {
		fmt.Fprintf(os.Stderr, "task not found: %s\n", args[0])
		os.Exit(1)
	}

	if !daemon.IsDaemonRunning() {
		fmt.Fprintln(os.Stderr, "daemon not running — start it with: anvil watch")
		os.Exit(1)
	}

	if err := daemon.SendStartRequest(abs, todo.ID, todo.Name); err != nil {
		fmt.Fprintf(os.Stderr, "failed to start task: %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("started %s — will be dispatched on next tick\n", todo.Name)
}
Repobility · code-quality intelligence platform · https://repobility.com
main.taskHistoryCmd function · go · L1942-L2076 (135 LOC)
cmd/anvil/main.go
func taskHistoryCmd(args []string) {
	limit := 10
	showFailuresOnly := false
	jsonOutput := false
	followMode := false
	i := 0
	for i < len(args) {
		switch args[i] {
		case "-n", "--limit":
			if i+1 >= len(args) {
				fmt.Fprintf(os.Stderr, "usage: anvil task history <name> [-n limit] [-f] [--failures] [--json]\n")
				os.Exit(1)
			}
			if _, err := fmt.Sscanf(args[i+1], "%d", &limit); err != nil {
				fmt.Fprintf(os.Stderr, "invalid limit: %s\n", args[i+1])
				os.Exit(1)
			}
			i += 2
		case "-f", "--follow":
			followMode = true
			i++
		case "--failures", "--show-failures-only":
			showFailuresOnly = true
			i++
		case "--json":
			jsonOutput = true
			i++
		default:
			break
		}
	}
	taskName := strings.Join(args[i:], " ")
	if taskName == "" {
		fmt.Fprintf(os.Stderr, "usage: anvil task history <name> [-n limit] [-f] [--failures] [--json]\n")
		os.Exit(1)
	}

	abs, err := filepath.Abs(".")
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	proj, err := project.Load(abs)
	i
main.runFollowMode function · go · L2079-L2141 (63 LOC)
cmd/anvil/main.go
func runFollowMode(projectPath string, todo *project.Todo) {
	fmt.Printf("Following runs for task %s (Ctrl+C to exit)...\n\n", todo.Name)

	lastRunID := ""
	for {
		records, err := project.ReadAllRunRecords(projectPath, todo.ID)
		if err != nil || len(records) == 0 {
			time.Sleep(2 * time.Second)
			continue
		}

		// Get the most recent run
		latest := records[0]

		// If this is a new run we haven't displayed yet
		if latest.RunID != lastRunID {
			lastRunID = latest.RunID

			// Wait for the run to complete (Finished time is set)
			for latest.Finished.IsZero() {
				time.Sleep(1 * time.Second)
				records, err = project.ReadAllRunRecords(projectPath, todo.ID)
				if err != nil || len(records) == 0 {
					break
				}
				latest = records[0]
			}

			// Display the completed run
			duration := ""
			if !latest.Finished.IsZero() {
				d := latest.Finished.Sub(latest.Started)
				if d < time.Minute {
					duration = fmt.Sprintf("%.0fs", d.Seconds())
				} else {
					duration = fmt.Sp
main.taskUnlockCmd function · go · L2143-L2176 (34 LOC)
cmd/anvil/main.go
func taskUnlockCmd(args []string) {
	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "usage: anvil task unlock <name>\n")
		os.Exit(1)
	}

	abs, err := filepath.Abs(".")
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	proj, err := project.Load(abs)
	if err != nil {
		log.Fatalf("failed to load project: %v", err)
	}

	todos, err := proj.LoadTodos()
	if err != nil {
		log.Fatalf("failed to load todos: %v", err)
	}

	todo := findTodo(todos, args[0])
	if todo == nil {
		fmt.Fprintf(os.Stderr, "task not found: %s\n", args[0])
		os.Exit(1)
	}

	// Remove the lock file if it exists
	if err := project.RemoveLock(*todo); err != nil {
		log.Fatalf("failed to remove lock: %v", err)
	}

	fmt.Printf("unlocked: %s\n", todo.Name)
}
main.taskQueueCmd function · go · L2178-L2209 (32 LOC)
cmd/anvil/main.go
func taskQueueCmd(_ []string) {
	if !daemon.IsDaemonRunning() {
		fmt.Println("daemon not running")
		return
	}

	tasks, err := daemon.SendQueueRequest()
	if err != nil {
		fmt.Fprintf(os.Stderr, "failed to get queue status: %v\n", err)
		os.Exit(1)
	}

	if len(tasks) == 0 {
		fmt.Println("no tasks in queue")
		return
	}

	fmt.Printf("%-40s %-10s %-10s %s\n", "TASK", "PRIORITY", "STATUS", "SKIP REASON")
	fmt.Printf("%s\n", strings.Repeat("-", 90))

	for _, t := range tasks {
		skipReason := t.SkipReason
		if skipReason == "" {
			skipReason = "-"
		}
		fmt.Printf("%-40s %-10d %-10s %s\n",
			truncate(t.Name, 40),
			t.Priority,
			t.Status,
			skipReason)
	}
}
main.taskTimeoutCmd function · go · L2211-L2262 (52 LOC)
cmd/anvil/main.go
func taskTimeoutCmd(args []string) {
	allTasks := false
	for _, a := range args {
		if a == "--all" || a == "-a" {
			allTasks = true
		}
	}

	if !daemon.IsDaemonRunning() {
		fmt.Println("daemon not running")
		return
	}

	tasks, err := daemon.SendTimeoutRequest()
	if err != nil {
		fmt.Fprintf(os.Stderr, "failed to get timeout status: %v\n", err)
		os.Exit(1)
	}

	if len(tasks) == 0 {
		fmt.Println("no running tasks")
		return
	}

	// Filter by task name if provided and not --all
	targetName := ""
	if !allTasks && len(args) > 0 && !strings.HasPrefix(args[0], "-") {
		targetName = args[0]
	}

	fmt.Printf("%-40s %-15s %-15s %-10s %s\n", "TASK", "ELAPSED", "TIMEOUT", "REMAINING", "PROGRESS")
	fmt.Printf("%s\n", strings.Repeat("-", 100))

	for _, t := range tasks {
		// Filter by target name if specified
		if targetName != "" && !strings.Contains(t.Name, targetName) {
			continue
		}

		elapsed := t.Elapsed
		timeout := t.Timeout
		remaining := t.TimeRemaining
		percent := t.PercentUsed
main.daemonCmd function · go · L2470-L2485 (16 LOC)
cmd/anvil/main.go
func daemonCmd(args []string) {
	if len(args) == 0 {
		fmt.Fprintln(os.Stderr, "usage: anvil daemon <subcommand>")
		fmt.Fprintln(os.Stderr, "")
		fmt.Fprintln(os.Stderr, "Subcommands:")
		fmt.Fprintln(os.Stderr, "  log [-f] [-n lines]   View daemon log (-f to follow, -n for last N lines)")
		os.Exit(1)
	}
	switch args[0] {
	case "log":
		daemonLogCmd(args[1:])
	default:
		fmt.Fprintf(os.Stderr, "unknown daemon subcommand: %s\n", args[0])
		os.Exit(1)
	}
}
main.daemonLogCmd function · go · L2487-L2597 (111 LOC)
cmd/anvil/main.go
func daemonLogCmd(args []string) {
	follow := false
	numLines := 50

	for i := 0; i < len(args); i++ {
		switch args[i] {
		case "-f", "--follow":
			follow = true
		case "-n":
			if i+1 >= len(args) {
				log.Fatal("missing value for -n")
			}
			i++
			n, err := strconv.Atoi(args[i])
			if err != nil || n < 0 {
				log.Fatalf("invalid line count: %s", args[i])
			}
			numLines = n
		case "-h", "--help":
			fmt.Fprintf(os.Stderr, `usage: anvil daemon log [-f] [-n lines]

View the daemon log file (~/.anvil/daemon.log).

Options:
  -f, --follow   Follow the log (like tail -f)
  -n lines       Show last N lines (default 50)
`)
			os.Exit(0)
		}
	}

	logPath := config.DaemonLogPath()
	if _, err := os.Stat(logPath); os.IsNotExist(err) {
		fmt.Fprintln(os.Stderr, "no daemon log found (daemon has not run yet)")
		os.Exit(1)
	}

	// Read and display the last N lines.
	data, err := os.ReadFile(logPath)
	if err != nil {
		log.Fatalf("failed to read daemon log: %v", err)
	}

	lines := strings.Sp
main.stopOnIdleCmd function · go · L2599-L2611 (13 LOC)
cmd/anvil/main.go
func stopOnIdleCmd() {
	if !daemon.IsDaemonRunning() {
		fmt.Println("daemon not running")
		return
	}

	if err := daemon.SendDrainRequest(); err != nil {
		fmt.Printf("failed to set stop-on-idle: %v\n", err)
		os.Exit(1)
	}

	fmt.Println("stop-on-idle: daemon will finish running tasks then exit")
}
Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
main.taskPauseCmd function · go · L2613-L2718 (106 LOC)
cmd/anvil/main.go
func taskPauseCmd(args []string) {
	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "usage: anvil task pause <name>\n")
		os.Exit(1)
	}

	abs, err := filepath.Abs(".")
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	proj, err := project.Load(abs)
	if err != nil {
		log.Fatalf("failed to load project: %v", err)
	}

	todos, err := proj.LoadTodos()
	if err != nil {
		log.Fatalf("failed to load todos: %v", err)
	}

	todo := findTodo(todos, args[0])
	if todo == nil {
		fmt.Fprintf(os.Stderr, "task not found: %s\n", args[0])
		os.Exit(1)
	}

	if todo.Disabled {
		fmt.Printf("task %s is already paused\n", args[0])
		return
	}

	// Read current file content
	raw, err := os.ReadFile(todo.Path)
	if err != nil {
		log.Fatalf("failed to read task file: %v", err)
	}

	// Parse and update front-matter to add disabled: true
	contentStr := string(raw)
	body := contentStr

	if strings.HasPrefix(contentStr, "---\n") {
		parts := strings.SplitN(contentStr[4:], "\n---\n", 2)
		if len(parts) == 2 {
		
main.taskResumeCmd function · go · L2720-L2819 (100 LOC)
cmd/anvil/main.go
func taskResumeCmd(args []string) {
	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "usage: anvil task resume <name>\n")
		os.Exit(1)
	}

	abs, err := filepath.Abs(".")
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	proj, err := project.Load(abs)
	if err != nil {
		log.Fatalf("failed to load project: %v", err)
	}

	todos, err := proj.LoadTodos()
	if err != nil {
		log.Fatalf("failed to load todos: %v", err)
	}

	todo := findTodo(todos, args[0])
	if todo == nil {
		fmt.Fprintf(os.Stderr, "task not found: %s\n", args[0])
		os.Exit(1)
	}

	if !todo.Disabled {
		fmt.Printf("task %s is not paused\n", args[0])
		return
	}

	// Read current file content
	raw, err := os.ReadFile(todo.Path)
	if err != nil {
		log.Fatalf("failed to read task file: %v", err)
	}

	// Parse and update front-matter to remove disabled field
	contentStr := string(raw)
	body := contentStr

	if strings.HasPrefix(contentStr, "---\n") {
		parts := strings.SplitN(contentStr[4:], "\n---\n", 2)
		if len(parts) == 2 {
main.taskStopOnIdleCmd function · go · L2821-L2859 (39 LOC)
cmd/anvil/main.go
func taskStopOnIdleCmd(args []string) {
	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "usage: anvil task stop-on-idle <name>\n")
		os.Exit(1)
	}

	abs, err := filepath.Abs(".")
	if err != nil {
		log.Fatalf("bad path: %v", err)
	}

	proj, err := project.Load(abs)
	if err != nil {
		log.Fatalf("failed to load project: %v", err)
	}

	todos, err := proj.LoadTodos()
	if err != nil {
		log.Fatalf("failed to load todos: %v", err)
	}

	todo := findTodo(todos, args[0])
	if todo == nil {
		fmt.Fprintf(os.Stderr, "task not found: %s\n", args[0])
		os.Exit(1)
	}

	if !daemon.IsDaemonRunning() {
		fmt.Println("daemon not running")
		return
	}

	if err := daemon.SendDrainTaskRequest(todo.ID); err != nil {
		fmt.Printf("failed to set stop-on-idle for task: %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("stop-on-idle: task %s will not be rescheduled after its current run\n", todo.Name)
}
page 1 / 4next ›