← back to jorge-barreto__orc

Function bodies 82 total

All specs Real LLM only Function bodies
main.main function · go · L22-L40 (19 LOC)
cmd/orc/main.go
func main() {
	app := &cli.Command{
		Name:        "orc",
		Usage:       "Deterministic agent orchestrator",
		Description: "Run 'orc docs' for documentation on config syntax, variables, phases, and more.",
		Commands: []*cli.Command{
			initCmd(),
			runCmd(),
			statusCmd(),
			doctorCmd(),
			docsCmd(),
		},
	}

	if err := app.Run(context.Background(), os.Args); err != nil {
		fmt.Fprintf(os.Stderr, "%serror:%s %v\n", ux.Red, ux.Reset, err)
		os.Exit(1)
	}
}
main.runCmd function · go · L42-L163 (122 LOC)
cmd/orc/main.go
func runCmd() *cli.Command {
	return &cli.Command{
		Name:      "run",
		Usage:     "Run the workflow for a ticket",
		ArgsUsage: "<ticket>",
		Flags: []cli.Flag{
			&cli.BoolFlag{Name: "auto", Usage: "Skip human gates"},
			&cli.IntFlag{Name: "retry", Usage: "Retry from phase N (1-indexed)"},
			&cli.IntFlag{Name: "from", Usage: "Start from phase N (1-indexed)"},
			&cli.BoolFlag{Name: "dry-run", Usage: "Print phase plan without executing"},
		},
		Action: func(ctx context.Context, cmd *cli.Command) error {
			// CLAUDECODE guard
			if os.Getenv("CLAUDECODE") != "" {
				return fmt.Errorf("orc cannot run inside Claude Code (CLAUDECODE env var is set). Run from a regular terminal")
			}

			ticket := cmd.Args().First()
			if ticket == "" {
				return fmt.Errorf("ticket argument is required")
			}

			projectRoot, err := findProjectRoot()
			if err != nil {
				return err
			}

			configPath := filepath.Join(projectRoot, ".orc", "config.yaml")
			cfg, err := config.Load(configPath, proj
main.statusCmd function · go · L165-L201 (37 LOC)
cmd/orc/main.go
func statusCmd() *cli.Command {
	return &cli.Command{
		Name:      "status",
		Usage:     "Show workflow status for a ticket",
		ArgsUsage: "<ticket>",
		Action: func(ctx context.Context, cmd *cli.Command) error {
			ticket := cmd.Args().First()
			if ticket == "" {
				return fmt.Errorf("ticket argument is required")
			}

			projectRoot, err := findProjectRoot()
			if err != nil {
				return err
			}

			configPath := filepath.Join(projectRoot, ".orc", "config.yaml")
			cfg, err := config.Load(configPath, projectRoot)
			if err != nil {
				return fmt.Errorf("loading config: %w", err)
			}

			artifactsDir := filepath.Join(projectRoot, ".orc", "artifacts")
			st, err := state.Load(artifactsDir)
			if err != nil {
				return fmt.Errorf("loading state: %w", err)
			}

			if st.Ticket != "" && st.Ticket != ticket {
				return fmt.Errorf("state is for ticket %q, not %q", st.Ticket, ticket)
			}

			ux.RenderStatus(cfg, st, artifactsDir)
			return nil
		},
	}
}
main.doctorCmd function · go · L203-L228 (26 LOC)
cmd/orc/main.go
func doctorCmd() *cli.Command {
	return &cli.Command{
		Name:  "doctor",
		Usage: "Diagnose a failed workflow run using AI",
		Action: func(ctx context.Context, cmd *cli.Command) error {
			projectRoot, err := findProjectRoot()
			if err != nil {
				return err
			}

			configPath := filepath.Join(projectRoot, ".orc", "config.yaml")
			cfg, err := config.Load(configPath, projectRoot)
			if err != nil {
				return fmt.Errorf("loading config: %w", err)
			}

			artifactsDir := filepath.Join(projectRoot, ".orc", "artifacts")
			st, err := state.Load(artifactsDir)
			if err != nil {
				return fmt.Errorf("loading state: %w", err)
			}

			return doctor.Run(ctx, projectRoot, artifactsDir, cfg, st)
		},
	}
}
main.initCmd function · go · L230-L242 (13 LOC)
cmd/orc/main.go
func initCmd() *cli.Command {
	return &cli.Command{
		Name:  "init",
		Usage: "Initialize a new .orc/ directory with example config",
		Action: func(ctx context.Context, cmd *cli.Command) error {
			dir, err := os.Getwd()
			if err != nil {
				return err
			}
			return scaffold.Init(ctx, dir)
		},
	}
}
main.docsCmd function · go · L244-L267 (24 LOC)
cmd/orc/main.go
func docsCmd() *cli.Command {
	return &cli.Command{
		Name:      "docs",
		Usage:     "Show documentation",
		ArgsUsage: "[topic]",
		Action: func(ctx context.Context, cmd *cli.Command) error {
			name := cmd.Args().First()
			if name == "" {
				fmt.Print("\nAvailable topics:\n\n")
				for _, t := range docs.All() {
					fmt.Printf("  %-14s %s\n", t.Name, t.Summary)
				}
				fmt.Println("\nRun 'orc docs <topic>' to read a topic.")
				return nil
			}
			t, err := docs.Get(name)
			if err != nil {
				return err
			}
			fmt.Print(t.Content)
			return nil
		},
	}
}
main.findProjectRoot function · go · L270-L286 (17 LOC)
cmd/orc/main.go
func findProjectRoot() (string, error) {
	dir, err := os.Getwd()
	if err != nil {
		return "", err
	}
	for {
		configPath := filepath.Join(dir, ".orc", "config.yaml")
		if _, err := os.Stat(configPath); err == nil {
			return dir, nil
		}
		parent := filepath.Dir(dir)
		if parent == dir {
			return "", fmt.Errorf("no .orc/config.yaml found (searched from cwd to root)")
		}
		dir = parent
	}
}
Repobility · open methodology · https://repobility.com/research/
config.OrderedVars.UnmarshalYAML method · go · L41-L60 (20 LOC)
internal/config/config.go
func (ov *OrderedVars) UnmarshalYAML(value *yaml.Node) error {
	if value.Kind != yaml.MappingNode {
		return fmt.Errorf("config: vars: must be a mapping")
	}
	for i := 0; i < len(value.Content)-1; i += 2 {
		keyNode := value.Content[i]
		valNode := value.Content[i+1]
		if keyNode.Kind != yaml.ScalarNode {
			return fmt.Errorf("config: vars: key at position %d is not a scalar", i/2+1)
		}
		if valNode.Kind != yaml.ScalarNode {
			return fmt.Errorf("config: vars: value for %q is not a scalar (nested maps/sequences are not supported)", keyNode.Value)
		}
		*ov = append(*ov, VarEntry{
			Key:   keyNode.Value,
			Value: valNode.Value,
		})
	}
	return nil
}
config.Load function · go · L70-L83 (14 LOC)
internal/config/config.go
func Load(path, projectRoot string) (*Config, error) {
	data, err := os.ReadFile(path)
	if err != nil {
		return nil, err
	}
	var cfg Config
	if err := yaml.Unmarshal(data, &cfg); err != nil {
		return nil, err
	}
	if err := Validate(&cfg, projectRoot); err != nil {
		return nil, err
	}
	return &cfg, nil
}
config.Config.PhaseIndex method · go · L86-L93 (8 LOC)
internal/config/config.go
func (c *Config) PhaseIndex(name string) int {
	for i, p := range c.Phases {
		if p.Name == name {
			return i
		}
	}
	return -1
}
config.Validate function · go · L21-L150 (130 LOC)
internal/config/validate.go
func Validate(cfg *Config, projectRoot string) error {
	if cfg.Name == "" {
		return fmt.Errorf("config: 'name' is required")
	}
	if len(cfg.Phases) == 0 {
		return fmt.Errorf("config: at least one phase is required")
	}

	// Validate vars
	builtins := map[string]bool{
		"TICKET": true, "ARTIFACTS_DIR": true,
		"WORK_DIR": true, "PROJECT_ROOT": true,
		"PHASE_INDEX": true, "PHASE_COUNT": true,
	}
	seenVars := make(map[string]bool)
	for _, v := range cfg.Vars {
		if v.Key == "" {
			return fmt.Errorf("config: vars: empty variable name")
		}
		if !varNameRe.MatchString(v.Key) {
			return fmt.Errorf("config: vars: %q is not a valid variable name (must match [A-Za-z_][A-Za-z0-9_]*)", v.Key)
		}
		if builtins[v.Key] {
			return fmt.Errorf("config: vars: %q overrides a built-in variable", v.Key)
		}
		if seenVars[v.Key] {
			return fmt.Errorf("config: vars: duplicate variable %q", v.Key)
		}
		seenVars[v.Key] = true
	}

	seen := make(map[string]bool)
	for i := range cfg.Phases {
		p := &cfg.
config.ValidateTicket function · go · L154-L171 (18 LOC)
internal/config/validate.go
func ValidateTicket(pattern, ticket string) error {
	if pattern == "" {
		return nil
	}
	// Enforce full-match semantics: anchor the pattern if not already anchored.
	anchored := pattern
	if !strings.HasPrefix(anchored, "^") {
		anchored = "^(?:" + anchored + ")$"
	}
	re, err := regexp.Compile(anchored)
	if err != nil {
		return fmt.Errorf("config: invalid ticket-pattern %q: %w", pattern, err)
	}
	if !re.MatchString(ticket) {
		return fmt.Errorf("ticket %q does not match pattern %q", ticket, pattern)
	}
	return nil
}
config.phaseExists function · go · L173-L180 (8 LOC)
internal/config/validate.go
func phaseExists(phases []Phase, name string) bool {
	for _, p := range phases {
		if p.Name == name {
			return true
		}
	}
	return false
}
contextgather.Gather function · go · L55-L65 (11 LOC)
internal/contextgather/gather.go
func Gather(projectRoot string) (*ProjectContext, error) {
	pc := &ProjectContext{
		Files: make(map[string]string),
	}

	pc.DirTree = buildTree(projectRoot)
	gatherFiles(projectRoot, pc)
	pc.GitLog = gatherGitLog(projectRoot)

	return pc, nil
}
contextgather.ProjectContext.Render method · go · L68-L97 (30 LOC)
internal/contextgather/gather.go
func (pc *ProjectContext) Render() string {
	var buf strings.Builder

	buf.WriteString("## Project Directory Structure\n\n```\n")
	buf.WriteString(pc.DirTree)
	buf.WriteString("```\n")

	if len(pc.Files) > 0 {
		buf.WriteString("\n## Key Files\n")

		// Sort paths for deterministic output
		paths := make([]string, 0, len(pc.Files))
		for p := range pc.Files {
			paths = append(paths, p)
		}
		sort.Strings(paths)

		for _, p := range paths {
			buf.WriteString(fmt.Sprintf("\n### %s\n\n```\n%s\n```\n", p, pc.Files[p]))
		}
	}

	if pc.GitLog != "" {
		buf.WriteString("\n## Recent Git History\n\n```\n")
		buf.WriteString(pc.GitLog)
		buf.WriteString("```\n")
	}

	return buf.String()
}
Repobility — same analyzer, your code, free for public repos · /scan/
contextgather.buildTree function · go · L99-L130 (32 LOC)
internal/contextgather/gather.go
func buildTree(root string) string {
	entries, err := os.ReadDir(root)
	if err != nil {
		return "(unable to read directory)\n"
	}

	var buf strings.Builder
	for _, e := range entries {
		if skipDirs[e.Name()] {
			continue
		}
		if e.IsDir() {
			buf.WriteString(e.Name() + "/\n")
			// One level deeper
			subPath := filepath.Join(root, e.Name())
			subEntries, err := os.ReadDir(subPath)
			if err != nil {
				continue
			}
			for _, se := range subEntries {
				if se.IsDir() {
					buf.WriteString("  " + se.Name() + "/\n")
				} else {
					buf.WriteString("  " + se.Name() + "\n")
				}
			}
		} else {
			buf.WriteString(e.Name() + "\n")
		}
	}
	return buf.String()
}
contextgather.gatherFiles function · go · L132-L169 (38 LOC)
internal/contextgather/gather.go
func gatherFiles(root string, pc *ProjectContext) {
	// Direct file probes
	for _, name := range wellKnownFiles {
		path := filepath.Join(root, name)
		data, err := os.ReadFile(path)
		if err != nil {
			continue
		}
		content := string(data)
		if len(content) > maxFileSize {
			content = content[:maxFileSize] + "\n... (truncated)"
		}
		pc.Files[name] = content
	}

	// Glob patterns
	for _, pattern := range wellKnownGlobs {
		matches, err := filepath.Glob(filepath.Join(root, pattern))
		if err != nil {
			continue
		}
		for _, match := range matches {
			data, err := os.ReadFile(match)
			if err != nil {
				continue
			}
			rel, err := filepath.Rel(root, match)
			if err != nil {
				continue
			}
			content := string(data)
			if len(content) > maxFileSize {
				content = content[:maxFileSize] + "\n... (truncated)"
			}
			pc.Files[rel] = content
		}
	}
}
contextgather.gatherGitLog function · go · L171-L179 (9 LOC)
internal/contextgather/gather.go
func gatherGitLog(root string) string {
	cmd := exec.Command("git", "log", "--oneline", "-10")
	cmd.Dir = root
	out, err := cmd.Output()
	if err != nil {
		return ""
	}
	return strings.TrimSpace(string(out))
}
dispatch.buildAgentArgs function · go · L24-L50 (27 LOC)
internal/dispatch/agent.go
func buildAgentArgs(phase config.Phase, prompt, sessionID string, isFirst bool, extraTools []string) []string {
	args := []string{"-p", prompt,
		"--output-format", "stream-json",
		"--verbose",
		"--include-partial-messages",
		"--model", phase.Model,
	}

	if sessionID != "" {
		if isFirst {
			args = append(args, "--session-id", sessionID)
		} else {
			args = append(args, "--resume", sessionID)
		}
	}

	// Merge phase allow-tools with any dynamically approved tools
	tools := make([]string, 0, len(phase.AllowTools)+len(extraTools))
	tools = append(tools, phase.AllowTools...)
	tools = append(tools, extraTools...)
	if len(tools) > 0 {
		args = append(args, "--allowedTools")
		args = append(args, tools...)
	}

	return args
}
dispatch.runAgentTurn function · go · L59-L92 (34 LOC)
internal/dispatch/agent.go
func runAgentTurn(ctx context.Context, phase config.Phase, env *Environment, prompt, sessionID string, isFirst bool, logFile io.Writer, extraTools []string) (*turnResult, error) {
	args := buildAgentArgs(phase, prompt, sessionID, isFirst, extraTools)

	cmd := exec.CommandContext(ctx, "claude", args...)
	cmd.Dir = PhaseWorkDir(phase, env)
	cmd.Env = BuildEnv(env)
	cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
	cmd.Cancel = func() error {
		return syscall.Kill(-cmd.Process.Pid, syscall.SIGTERM)
	}
	cmd.WaitDelay = 5 * time.Second
	cmd.Stderr = io.MultiWriter(os.Stderr, logFile)

	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, fmt.Errorf("stdout pipe: %w", err)
	}

	if err := cmd.Start(); err != nil {
		return nil, fmt.Errorf("starting claude: %w", err)
	}

	streamResult, streamErr := processStream(ctx, stdout, os.Stdout, logFile)

	code, waitErr := exitCode(cmd.Wait())
	if waitErr != nil {
		return nil, waitErr
	}
	if streamErr != nil && ctx.Err() == nil {
		retur
dispatch.RunAgent function · go · L96-L141 (46 LOC)
internal/dispatch/agent.go
func RunAgent(ctx context.Context, phase config.Phase, env *Environment) (*Result, error) {
	if phase.Timeout > 0 {
		var cancel context.CancelFunc
		ctx, cancel = context.WithTimeout(ctx, time.Duration(phase.Timeout)*time.Minute)
		defer cancel()
	}

	// Read and render the prompt template
	promptData, err := os.ReadFile(filepath.Join(env.ProjectRoot, phase.Prompt))
	if err != nil {
		return nil, err
	}
	rendered := ExpandVars(string(promptData), env.Vars())

	// Save rendered prompt for inspection
	if err := os.WriteFile(state.PromptPath(env.ArtifactsDir, env.PhaseIndex), []byte(rendered), 0644); err != nil {
		return nil, err
	}

	logFile, err := os.OpenFile(state.LogPath(env.ArtifactsDir, env.PhaseIndex), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
	if err != nil {
		return nil, err
	}
	defer logFile.Close()

	sessionID := uuid.New().String()
	tr, err := runAgentTurn(ctx, phase, env, rendered, sessionID, true, logFile, nil)
	if err != nil {
		return nil, err
	}

	// In unattended mod
dispatch.RunAgentWithPrompt function · go · L145-L168 (24 LOC)
internal/dispatch/agent.go
func RunAgentWithPrompt(ctx context.Context, phase config.Phase, env *Environment, prompt string) (*Result, error) {
	if phase.Timeout > 0 {
		var cancel context.CancelFunc
		ctx, cancel = context.WithTimeout(ctx, time.Duration(phase.Timeout)*time.Minute)
		defer cancel()
	}

	logFile, err := os.OpenFile(state.LogPath(env.ArtifactsDir, env.PhaseIndex), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		return nil, err
	}
	defer logFile.Close()

	tr, err := runAgentTurn(ctx, phase, env, prompt, "", false, logFile, nil)
	if err != nil {
		return nil, err
	}

	output := ""
	if tr.Stream != nil {
		output = tr.Stream.Text
	}
	return &Result{ExitCode: tr.ExitCode, Output: output}, nil
}
dispatch.RunAgentAttended function · go · L175-L247 (73 LOC)
internal/dispatch/agent.go
func RunAgentAttended(ctx context.Context, phase config.Phase, env *Environment) (*Result, error) {
	if phase.Timeout > 0 {
		var cancel context.CancelFunc
		ctx, cancel = context.WithTimeout(ctx, time.Duration(phase.Timeout)*time.Minute)
		defer cancel()
	}

	// Read and render the prompt template
	promptData, err := os.ReadFile(filepath.Join(env.ProjectRoot, phase.Prompt))
	if err != nil {
		return nil, err
	}
	rendered := ExpandVars(string(promptData), env.Vars())

	// Save rendered prompt for inspection
	if err := os.WriteFile(state.PromptPath(env.ArtifactsDir, env.PhaseIndex), []byte(rendered), 0644); err != nil {
		return nil, err
	}

	logFile, err := os.OpenFile(state.LogPath(env.ArtifactsDir, env.PhaseIndex), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
	if err != nil {
		return nil, err
	}
	defer logFile.Close()

	sessionID := uuid.New().String()
	reader := NewStdinReader(os.Stdin)
	defer reader.Stop()

	var extraTools []string
	isFirst := true
	prompt := rendered
	var lastTurn *
Repobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
dispatch.handleDenials function · go · L251-L273 (23 LOC)
internal/dispatch/agent.go
func handleDenials(denials []PermissionDenial) []string {
	var names []string
	for _, d := range denials {
		names = append(names, d.String())
		ux.ToolDenied(d.Tool, d.Input)
	}

	ux.PermissionPrompt(names)
	fmt.Printf("  Retry with these tools approved? [y/n]: ")

	scanner := bufio.NewScanner(os.Stdin)
	if scanner.Scan() {
		answer := strings.TrimSpace(strings.ToLower(scanner.Text()))
		if answer == "y" || answer == "yes" {
			var tools []string
			for _, d := range denials {
				tools = append(tools, d.Tool)
			}
			return tools
		}
	}
	return nil
}
dispatch.Environment.Clone method · go · L26-L39 (14 LOC)
internal/dispatch/dispatch.go
func (e *Environment) Clone() *Environment {
	cp := *e
	if e.CustomVars != nil {
		cp.CustomVars = make(map[string]string, len(e.CustomVars))
		for k, v := range e.CustomVars {
			cp.CustomVars[k] = v
		}
	}
	if e.filteredEnv != nil {
		cp.filteredEnv = make([]string, len(e.filteredEnv))
		copy(cp.filteredEnv, e.filteredEnv)
	}
	return &cp
}
dispatch.Environment.Vars method · go · L43-L53 (11 LOC)
internal/dispatch/dispatch.go
func (e *Environment) Vars() map[string]string {
	m := make(map[string]string, 4+len(e.CustomVars))
	for k, v := range e.CustomVars {
		m[k] = v
	}
	m["TICKET"] = e.Ticket
	m["ARTIFACTS_DIR"] = e.ArtifactsDir
	m["WORK_DIR"] = e.WorkDir
	m["PROJECT_ROOT"] = e.ProjectRoot
	return m
}
dispatch.PhaseWorkDir function · go · L58-L67 (10 LOC)
internal/dispatch/dispatch.go
func PhaseWorkDir(phase config.Phase, env *Environment) string {
	if phase.Cwd != "" {
		expanded := ExpandVars(phase.Cwd, env.Vars())
		if expanded == "" {
			return env.WorkDir
		}
		return expanded
	}
	return env.WorkDir
}
dispatch.BuildEnv function · go · L78-L102 (25 LOC)
internal/dispatch/dispatch.go
func BuildEnv(env *Environment) []string {
	if env.filteredEnv == nil {
		for _, e := range os.Environ() {
			key := strings.SplitN(e, "=", 2)[0]
			if strings.HasPrefix(key, "CLAUDECODE") {
				continue
			}
			env.filteredEnv = append(env.filteredEnv, e)
		}
	}
	result := make([]string, len(env.filteredEnv), len(env.filteredEnv)+6+len(env.CustomVars))
	copy(result, env.filteredEnv)
	for k, v := range env.CustomVars {
		result = append(result, "ORC_"+k+"="+v)
	}
	result = append(result,
		"ORC_TICKET="+env.Ticket,
		"ORC_ARTIFACTS_DIR="+env.ArtifactsDir,
		"ORC_WORK_DIR="+env.WorkDir,
		"ORC_PROJECT_ROOT="+env.ProjectRoot,
		fmt.Sprintf("ORC_PHASE_INDEX=%d", env.PhaseIndex),
		fmt.Sprintf("ORC_PHASE_COUNT=%d", env.PhaseCount),
	)
	return result
}
dispatch.Dispatch function · go · L118-L132 (15 LOC)
internal/dispatch/dispatch.go
func Dispatch(ctx context.Context, phase config.Phase, env *Environment) (*Result, error) {
	switch phase.Type {
	case "script":
		return RunScript(ctx, phase, env)
	case "agent":
		if env.AutoMode {
			return RunAgent(ctx, phase, env)
		}
		return RunAgentAttended(ctx, phase, env)
	case "gate":
		return RunGate(ctx, phase, env)
	default:
		return nil, fmt.Errorf("unknown phase type: %s", phase.Type)
	}
}
dispatch.exitCode function · go · L10-L19 (10 LOC)
internal/dispatch/exitcode.go
func exitCode(err error) (int, error) {
	if err == nil {
		return 0, nil
	}
	var exitErr *exec.ExitError
	if errors.As(err, &exitErr) {
		return exitErr.ExitCode(), nil
	}
	return 0, err
}
dispatch.ExpandVars function · go · L11-L18 (8 LOC)
internal/dispatch/expand.go
func ExpandVars(template string, vars map[string]string) string {
	return os.Expand(template, func(key string) string {
		if v, ok := vars[key]; ok {
			return v
		}
		return os.Getenv(key)
	})
}
Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
dispatch.ExpandConfigVars function · go · L22-L34 (13 LOC)
internal/dispatch/expand.go
func ExpandConfigVars(vars config.OrderedVars, builtins map[string]string) map[string]string {
	result := make(map[string]string, len(vars))
	lookup := make(map[string]string, len(builtins)+len(vars))
	for k, v := range builtins {
		lookup[k] = v
	}
	for _, entry := range vars {
		expanded := ExpandVars(entry.Value, lookup)
		result[entry.Key] = expanded
		lookup[entry.Key] = expanded
	}
	return result
}
dispatch.RunGate function · go · L15-L73 (59 LOC)
internal/dispatch/gate.go
func RunGate(ctx context.Context, phase config.Phase, env *Environment) (*Result, error) {
	logFile, err := os.Create(state.LogPath(env.ArtifactsDir, env.PhaseIndex))
	if err != nil {
		return nil, err
	}
	defer logFile.Close()

	// Auto-approve if --auto mode
	if env.AutoMode {
		msg := fmt.Sprintf("Gate %q auto-approved (--auto mode)\n", phase.Name)
		fmt.Print(msg)
		logFile.WriteString(msg)
		return &Result{ExitCode: 0, Output: msg}, nil
	}

	// Show gate description
	if phase.Description != "" {
		fmt.Printf("\n  %s\n\n", phase.Description)
	}

	// Prompt user
	fmt.Printf("  Approve? [y/n]: ")
	reader := bufio.NewReader(os.Stdin)

	// Use a channel to handle context cancellation during read
	type readResult struct {
		input string
		err   error
	}
	ch := make(chan readResult, 1)
	go func() {
		line, err := reader.ReadString('\n')
		ch <- readResult{input: strings.TrimSpace(line), err: err}
	}()

	select {
	case <-ctx.Done():
		msg := "Gate cancelled\n"
		logFile.WriteString(msg)
	
dispatch.Preflight function · go · L12-L34 (23 LOC)
internal/dispatch/preflight.go
func Preflight(phases []config.Phase) error {
	needed := make(map[string]bool)
	for _, p := range phases {
		switch p.Type {
		case "script":
			needed["bash"] = true
		case "agent":
			needed["claude"] = true
		}
	}

	var missing []string
	for bin := range needed {
		if _, err := exec.LookPath(bin); err != nil {
			missing = append(missing, bin)
		}
	}

	if len(missing) > 0 {
		return fmt.Errorf("required binaries not found in PATH: %s", strings.Join(missing, ", "))
	}
	return nil
}
dispatch.RunScript function · go · L17-L51 (35 LOC)
internal/dispatch/script.go
func RunScript(ctx context.Context, phase config.Phase, env *Environment) (*Result, error) {
	if phase.Timeout > 0 {
		var cancel context.CancelFunc
		ctx, cancel = context.WithTimeout(ctx, time.Duration(phase.Timeout)*time.Minute)
		defer cancel()
	}

	expanded := ExpandVars(phase.Run, env.Vars())

	cmd := exec.CommandContext(ctx, "bash", "-c", expanded)
	cmd.Dir = PhaseWorkDir(phase, env)
	cmd.Env = BuildEnv(env)
	cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
	cmd.Cancel = func() error {
		return syscall.Kill(-cmd.Process.Pid, syscall.SIGTERM)
	}
	cmd.WaitDelay = 5 * time.Second

	logFile, err := os.Create(state.LogPath(env.ArtifactsDir, env.PhaseIndex))
	if err != nil {
		return nil, err
	}
	defer logFile.Close()

	var captured bytes.Buffer
	cmd.Stdout = io.MultiWriter(os.Stdout, logFile, &captured)
	cmd.Stderr = io.MultiWriter(os.Stderr, logFile, &captured)

	code, err := exitCode(cmd.Run())
	if err != nil {
		return nil, err
	}

	return &Result{ExitCode: code, Output: capt
dispatch.NewStdinReader function · go · L17-L24 (8 LOC)
internal/dispatch/stdinreader.go
func NewStdinReader(r io.Reader) *StdinReader {
	sr := &StdinReader{
		lines: make(chan string, 16),
		done:  make(chan struct{}),
	}
	go sr.readLoop(r)
	return sr
}
dispatch.StdinReader.readLoop method · go · L26-L47 (22 LOC)
internal/dispatch/stdinreader.go
func (sr *StdinReader) readLoop(r io.Reader) {
	scanner := bufio.NewScanner(r)
	for {
		select {
		case <-sr.done:
			return
		default:
		}
		if !scanner.Scan() {
			return
		}
		line := scanner.Text()
		if line == "" {
			continue
		}
		select {
		case sr.lines <- line:
		case <-sr.done:
			return
		}
	}
}
dispatch.StdinReader.ReadLine method · go · L51-L58 (8 LOC)
internal/dispatch/stdinreader.go
func (sr *StdinReader) ReadLine() (string, bool) {
	select {
	case line := <-sr.lines:
		return line, true
	default:
		return "", false
	}
}
dispatch.StdinReader.Stop method · go · L63-L70 (8 LOC)
internal/dispatch/stdinreader.go
func (sr *StdinReader) Stop() {
	select {
	case <-sr.done:
		// already stopped
	default:
		close(sr.done)
	}
}
Repobility · open methodology · https://repobility.com/research/
dispatch.PermissionDenial.String method · go · L21-L26 (6 LOC)
internal/dispatch/stream.go
func (d PermissionDenial) String() string {
	if d.Input != "" {
		return fmt.Sprintf("%s(%s)", d.Tool, d.Input)
	}
	return d.Tool
}
dispatch.processStream function · go · L38-L82 (45 LOC)
internal/dispatch/stream.go
func processStream(ctx context.Context, stdout io.Reader, display io.Writer, logFile io.Writer) (*StreamResult, error) {
	scanner := bufio.NewScanner(stdout)
	scanner.Buffer(make([]byte, 0, 256*1024), 1024*1024)

	var result StreamResult
	var textBuf strings.Builder

	for scanner.Scan() {
		if ctx.Err() != nil {
			return &result, ctx.Err()
		}

		line := scanner.Bytes()
		if len(line) == 0 {
			continue
		}

		var event streamEvent
		if err := json.Unmarshal(line, &event); err != nil {
			// Skip malformed lines
			continue
		}

		switch event.Type {
		case "stream_event":
			handleStreamEvent(&event, &textBuf, display, logFile)

		case "assistant":
			handleAssistantEvent(&event)

		case "user":
			handleUserEvent(&event, &result)

		case "result":
			handleResultEvent(&event, &result)
		}
	}

	if err := scanner.Err(); err != nil {
		return &result, fmt.Errorf("reading stream: %w", err)
	}

	result.Text = textBuf.String()
	return &result, nil
}
dispatch.handleStreamEvent function · go · L134-L166 (33 LOC)
internal/dispatch/stream.go
func handleStreamEvent(event *streamEvent, textBuf *strings.Builder, display io.Writer, logFile io.Writer) {
	if event.Event == nil {
		return
	}

	var nested nestedEvent
	if err := json.Unmarshal(event.Event, &nested); err != nil {
		return
	}

	switch nested.Type {
	case "content_block_delta":
		if nested.Delta != nil && nested.Delta.Type == "text_delta" {
			text := nested.Delta.Text
			textBuf.WriteString(text)
			if display != nil {
				fmt.Fprint(display, text)
			}
			if logFile != nil {
				fmt.Fprint(logFile, text)
			}
		}

	case "content_block_start":
		if nested.ContentBlock != nil && nested.ContentBlock.Type == "tool_use" {
			inputStr := ""
			if nested.ContentBlock.Input != nil {
				inputStr = string(nested.ContentBlock.Input)
			}
			ux.ToolUse(nested.ContentBlock.Name, inputStr)
		}
	}
}
dispatch.handleUserEvent function · go · L174-L183 (10 LOC)
internal/dispatch/stream.go
func handleUserEvent(event *streamEvent, result *StreamResult) {
	if event.IsError {
		// Permission denial or other error from the user side
		for _, block := range event.Content {
			if strings.Contains(block.Text, "permission") || strings.Contains(block.Text, "denied") {
				// The actual denials are in the result event; this is just a signal
			}
		}
	}
}
dispatch.handleResultEvent function · go · L185-L209 (25 LOC)
internal/dispatch/stream.go
func handleResultEvent(event *streamEvent, result *StreamResult) {
	// Try to parse the nested result object
	if event.Result != nil {
		var payload resultPayload
		if err := json.Unmarshal(event.Result, &payload); err == nil {
			result.CostUSD = payload.CostUSD
			result.SessionID = payload.SessionID
			for _, d := range payload.PermissionDenials {
				result.PermissionDenials = append(result.PermissionDenials, PermissionDenial{
					Tool:  d.ToolName,
					Input: d.Input,
				})
			}
			return
		}
	}

	// Fallback: cost might be at top level
	if event.CostUSD > 0 {
		result.CostUSD = event.CostUSD
	}
	if event.SessionID != "" {
		result.SessionID = event.SessionID
	}
}
doctor.Run function · go · L38-L70 (33 LOC)
internal/doctor/doctor.go
func Run(ctx context.Context, projectRoot, artifactsDir string, cfg *config.Config, st *state.State) error {
	if st.Status != state.StatusFailed && st.Status != state.StatusInterrupted {
		fmt.Println("No failed run to diagnose.")
		return nil
	}

	if st.PhaseIndex >= len(cfg.Phases) {
		return fmt.Errorf("phase index %d out of range (config has %d phases)", st.PhaseIndex, len(cfg.Phases))
	}

	phase := cfg.Phases[st.PhaseIndex]

	phaseConfig := gatherPhaseConfig(phase)
	log := gatherLog(artifactsDir, st.PhaseIndex)
	prompt := gatherPrompt(artifactsDir, st.PhaseIndex, phase)
	feedback := gatherFeedback(artifactsDir)
	timing := gatherTiming(artifactsDir, phase.Name)
	loops := gatherLoopCounts(artifactsDir)

	diagText := buildPrompt(phaseConfig, log, prompt, feedback, timing, loops)

	// Print header
	fmt.Printf("\n%s%s══ Doctor: diagnosing phase %d/%d (%s) ══%s\n\n",
		ux.Bold, ux.Cyan, st.PhaseIndex+1, len(cfg.Phases), phase.Name, ux.Reset)

	if err := runClaude(ctx, diagText); err != 
doctor.buildPrompt function · go · L72-L93 (22 LOC)
internal/doctor/doctor.go
func buildPrompt(phaseConfig, log, prompt, feedback, timing, loops string) string {
	var promptSection, feedbackSection, timingSection string
	if prompt != "" {
		promptSection = fmt.Sprintf("\n## Agent Prompt\n%s\n", prompt)
	}
	if feedback != "" {
		feedbackSection = fmt.Sprintf("\n## Feedback Files\n%s\n", feedback)
	}

	var extras []string
	if timing != "" {
		extras = append(extras, fmt.Sprintf("Timing: %s", timing))
	}
	if loops != "" {
		extras = append(extras, fmt.Sprintf("Loop counts: %s", loops))
	}
	if len(extras) > 0 {
		timingSection = fmt.Sprintf("\n## Execution Context\n%s\n", strings.Join(extras, "\n"))
	}

	return fmt.Sprintf(diagPrompt, phaseConfig, maxLogLines, log, promptSection, feedbackSection, timingSection)
}
doctor.gatherPhaseConfig function · go · L95-L124 (30 LOC)
internal/doctor/doctor.go
func gatherPhaseConfig(phase config.Phase) string {
	var parts []string
	parts = append(parts, fmt.Sprintf("Name: %s", phase.Name))
	parts = append(parts, fmt.Sprintf("Type: %s", phase.Type))
	if phase.Description != "" {
		parts = append(parts, fmt.Sprintf("Description: %s", phase.Description))
	}
	if phase.Run != "" {
		parts = append(parts, fmt.Sprintf("Run: %s", phase.Run))
	}
	if phase.Prompt != "" {
		parts = append(parts, fmt.Sprintf("Prompt file: %s", phase.Prompt))
	}
	if phase.Model != "" {
		parts = append(parts, fmt.Sprintf("Model: %s", phase.Model))
	}
	if phase.Timeout > 0 {
		parts = append(parts, fmt.Sprintf("Timeout: %ds", phase.Timeout))
	}
	if len(phase.Outputs) > 0 {
		parts = append(parts, fmt.Sprintf("Expected outputs: %s", strings.Join(phase.Outputs, ", ")))
	}
	if phase.Condition != "" {
		parts = append(parts, fmt.Sprintf("Condition: %s", phase.Condition))
	}
	if phase.OnFail != nil {
		parts = append(parts, fmt.Sprintf("On-fail: goto %s (max %d)", phase.OnFail
Repobility — same analyzer, your code, free for public repos · /scan/
doctor.gatherLog function · go · L126-L138 (13 LOC)
internal/doctor/doctor.go
func gatherLog(artifactsDir string, phaseIndex int) string {
	path := state.LogPath(artifactsDir, phaseIndex)
	data, err := os.ReadFile(path)
	if err != nil {
		return "(no log file found)"
	}
	lines := strings.Split(string(data), "\n")
	if len(lines) > maxLogLines {
		lines = lines[len(lines)-maxLogLines:]
		return fmt.Sprintf("... (truncated to last %d lines)\n%s", maxLogLines, strings.Join(lines, "\n"))
	}
	return string(data)
}
doctor.gatherPrompt function · go · L140-L150 (11 LOC)
internal/doctor/doctor.go
func gatherPrompt(artifactsDir string, phaseIndex int, phase config.Phase) string {
	if phase.Type != "agent" {
		return ""
	}
	path := state.PromptPath(artifactsDir, phaseIndex)
	data, err := os.ReadFile(path)
	if err != nil {
		return "(no rendered prompt found)"
	}
	return string(data)
}
doctor.gatherFeedback function · go · L152-L170 (19 LOC)
internal/doctor/doctor.go
func gatherFeedback(artifactsDir string) string {
	dir := filepath.Join(artifactsDir, "feedback")
	entries, err := os.ReadDir(dir)
	if err != nil {
		return ""
	}
	var parts []string
	for _, e := range entries {
		if e.IsDir() {
			continue
		}
		data, err := os.ReadFile(filepath.Join(dir, e.Name()))
		if err != nil {
			continue
		}
		parts = append(parts, fmt.Sprintf("--- %s ---\n%s", e.Name(), string(data)))
	}
	return strings.Join(parts, "\n")
}
page 1 / 2next ›