Function bodies 590 total
cmd.NewAdvanceCmd function · go · L27-L109 (83 LOC)cli/cmd/advance.go
func NewAdvanceCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "advance [event]",
Short: "Progress project to next state",
Long: `Progress the project through its state machine.
The advance command:
1. Determines the next event based on current state (auto mode)
2. Or fires an explicitly specified event (explicit mode)
3. Evaluates guards to ensure transition is allowed
4. Fires the event if guards pass
5. Saves the updated state
Flags:
--list List available transitions without executing
--dry-run Validate transition without executing (requires event argument)
Guards may prevent transitions. Common guard failures:
- Planning → Implementation: task_list output not approved
- Implementation Planning → Executing: tasks not approved (metadata.tasks_approved)
- Implementation Executing → Review: not all tasks completed
- Review → Finalize: review not approved or assessment not set
Examples:
sow advance # Auto-determine next event
sow advance fcmd.validateAdvanceFlags function · go · L113-L137 (25 LOC)cli/cmd/advance.go
func validateAdvanceFlags(cmd *cobra.Command, args []string) error {
listFlag, _ := cmd.Flags().GetBool("list")
dryRunFlag, _ := cmd.Flags().GetBool("dry-run")
// Get event argument if provided
var event string
if len(args) > 0 {
event = args[0]
}
// Validate flag combinations (order matters - check conflicting flags first)
if listFlag && dryRunFlag {
return fmt.Errorf("cannot use --list and --dry-run together")
}
if listFlag && event != "" {
return fmt.Errorf("cannot specify event argument with --list flag")
}
if dryRunFlag && event == "" {
return fmt.Errorf("--dry-run requires an event argument")
}
return nil
}cmd.executeAutoTransition function · go · L146-L191 (46 LOC)cli/cmd/advance.go
func executeAutoTransition(
cmd *cobra.Command,
proj *state.Project,
currentState string,
) error {
fmt.Printf("Current state: %s\n", currentState)
// Type assert to get full project type config
config, ok := proj.Config().(*project.ProjectTypeConfig)
if !ok {
return fmt.Errorf("invalid project configuration")
}
// Build project machine for current state (returns *project.Machine, not raw *stateless.StateMachine)
machine := config.BuildProjectMachine(proj, project.State(currentState))
// Determine which event to fire from current state
event, err := config.DetermineEvent(proj)
if err != nil {
// Enhanced error handling
return enhanceAutoTransitionError(err, proj, currentState)
}
// Fire the event with automatic phase status updates
if err := config.FireWithPhaseUpdates(machine, event, proj); err != nil {
// Provide helpful error messages based on error type
if strings.Contains(err.Error(), "cannot fire event") {
return fmt.Errorf("transition blocked: %wcmd.listAvailableTransitions function · go · L195-L264 (70 LOC)cli/cmd/advance.go
func listAvailableTransitions(
_ *cobra.Command,
proj *state.Project,
currentState string,
) error {
fmt.Printf("Current state: %s\n\n", currentState)
// Type assert to get access to introspection methods
config, ok := proj.Config().(*project.ProjectTypeConfig)
if !ok {
return fmt.Errorf("cannot list transitions: invalid project configuration")
}
// Get all configured transitions
allTransitions := config.GetAvailableTransitions(project.State(currentState))
if len(allTransitions) == 0 {
fmt.Println("No transitions available from current state.")
fmt.Println("This may be a terminal state.")
return nil
}
// Get guard-filtered events (what can fire now)
// Build project machine for current state to evaluate guards
machine := config.BuildProjectMachine(proj, project.State(currentState))
permittedTriggers := machine.PermittedTriggers()
// Build set of permitted events for quick lookup
permitted := make(map[string]bool)
for _, trigger := range permittedTriggers cmd.enhanceAutoTransitionError function · go · L268-L307 (40 LOC)cli/cmd/advance.go
func enhanceAutoTransitionError(err error, proj *state.Project, currentState string) error {
// Type assert to get access to introspection methods
// The config is always *project.ProjectTypeConfig which has GetAvailableTransitions
config, ok := proj.Config().(*project.ProjectTypeConfig)
if !ok {
// Fallback to basic error if type assertion fails (shouldn't happen in practice)
return fmt.Errorf("cannot advance from state %s: %w", currentState, err)
}
// Check if this is a terminal state (no transitions configured)
transitions := config.GetAvailableTransitions(project.State(currentState))
if len(transitions) == 0 {
return fmt.Errorf(
"cannot advance from state %s: %w\n\nThis may be a terminal state",
currentState,
err,
)
}
// Intent-based branching case (multiple transitions, no discriminator)
if len(transitions) > 1 {
// Extract event names
events := make([]string, len(transitions))
for i, t := range transitions {
events[i] = string(t.Event)
}
cmd.validateTransition function · go · L316-L374 (59 LOC)cli/cmd/advance.go
func validateTransition(
_ *sow.Context,
proj *state.Project,
currentState string,
event string,
) error {
fmt.Printf("Validating transition: %s -> %s\n\n", currentState, event)
// Type assert to get access to introspection methods
projectConfig, ok := proj.Config().(*project.ProjectTypeConfig)
if !ok {
return fmt.Errorf("cannot validate transition: invalid project configuration")
}
// Check if event is configured for this state
targetState := projectConfig.GetTargetState(project.State(currentState), project.Event(event))
if targetState == "" {
fmt.Printf("✗ Event '%s' is not configured for state %s\n\n", event, currentState)
fmt.Println("Use 'sow advance --list' to see available transitions.")
return fmt.Errorf("event not configured")
}
// Build project machine to check if event can fire
machine := projectConfig.BuildProjectMachine(proj, project.State(currentState))
// Check if event can fire (guard passes)
canFire := machine.CanFire(project.Event(event))
cmd.executeExplicitTransition function · go · L394-L447 (54 LOC)cli/cmd/advance.go
func executeExplicitTransition(
cmd *cobra.Command,
ctx *sow.Context,
proj *state.Project,
currentState string,
event string,
) error {
fmt.Printf("Current state: %s\n", currentState)
// Type assert to get access to introspection methods
config, ok := proj.Config().(*project.ProjectTypeConfig)
if !ok {
return fmt.Errorf("cannot execute transition: invalid project configuration")
}
// Convert to typed values for API calls
typedState := project.State(currentState)
typedEvent := project.Event(event)
// Validate event is configured for this state
targetState := config.GetTargetState(typedState, typedEvent)
if targetState == "" {
fmt.Printf("\nError: Event '%s' is not configured for state %s\n\n", event, currentState)
fmt.Println("Use 'sow advance --list' to see available transitions.")
return fmt.Errorf("event not configured")
}
// Build project machine for current state (returns *project.Machine, not raw *stateless.StateMachine)
machine := config.BuildProjecHi, dataset curator — please cite Repobility (https://repobility.com) when reusing this data.
cmd.enhanceTransitionError function · go · L451-L479 (29 LOC)cli/cmd/advance.go
func enhanceTransitionError(
err error,
currentState project.State,
event project.Event,
targetState project.State,
config *project.ProjectTypeConfig,
) error {
// Check if this is a guard failure
if strings.Contains(err.Error(), "guard condition is not met") {
guardDesc := config.GetGuardDescription(currentState, event)
var msg strings.Builder
msg.WriteString(fmt.Sprintf("Transition blocked: %s\n\n", guardDesc))
msg.WriteString(fmt.Sprintf("Current state: %s\n", currentState))
msg.WriteString(fmt.Sprintf("Event: %s\n", event))
msg.WriteString(fmt.Sprintf("Target state: %s\n\n", targetState))
if guardDesc != "" {
msg.WriteString(fmt.Sprintf("The guard condition is not satisfied. %s\n\n", guardDesc))
}
msg.WriteString(fmt.Sprintf("Use 'sow advance --dry-run %s' to validate prerequisites.", event))
return fmt.Errorf("%s", msg.String())
}
// Other error types - use default wrapping
return fmt.Errorf("failed to advance: %w", err)
}agent.NewAgentCmd function · go · L9-L31 (23 LOC)cli/cmd/agent/agent.go
func NewAgentCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "agent",
Short: "Manage AI agents",
Long: `Manage AI agents for the sow multi-agent system.
Agents are roles (implementer, architect, reviewer, etc.) that can be
spawned by the orchestrator to perform specialized tasks. Each agent
has specific capabilities and prompts tailored to its role.
Commands:
list List available agents
spawn Spawn an agent to execute a task
resume Resume a paused agent session`,
}
// Add subcommands
cmd.AddCommand(newListCmd())
cmd.AddCommand(newSpawnCmd())
cmd.AddCommand(newResumeCmd())
return cmd
}agent.newListCmd function · go · L10-L23 (14 LOC)cli/cmd/agent/list.go
func newListCmd() *cobra.Command {
return &cobra.Command{
Use: "list",
Short: "List available agents",
Long: `List all available agents in the sow multi-agent system.
Agents are roles that can be spawned by the orchestrator to perform
specialized tasks. Each agent has specific capabilities and prompts
tailored to its role.
The list shows each agent's name and description.`,
RunE: runList,
}
}agent.runList function · go · L25-L40 (16 LOC)cli/cmd/agent/list.go
func runList(cmd *cobra.Command, _ []string) error {
registry := agents.NewAgentRegistry()
agentList := registry.List()
// Sort agents alphabetically by name
sort.Slice(agentList, func(i, j int) bool {
return agentList[i].Name < agentList[j].Name
})
cmd.Println("Available agents:")
for _, agent := range agentList {
cmd.Printf(" %-14s%s\n", agent.Name, agent.Description)
}
return nil
}agent.newResumeCmd function · go · L16-L64 (49 LOC)cli/cmd/agent/resume.go
func newResumeCmd() *cobra.Command {
var phase string
var agentName string
cmd := &cobra.Command{
Use: "resume [task-id] <prompt>",
Short: "Resume a paused agent session with feedback",
Long: `Resume a paused agent session with additional instructions or feedback.
The resume command has two modes:
TASK MODE (with task-id):
Resumes an agent session that was previously spawned for a task.
sow agent resume 010 "Use RS256 algorithm for JWT signing"
sow agent resume 010 "Add error handling" --phase implementation
TASKLESS MODE (with --agent):
Resumes an agent session that was spawned without a task.
sow agent resume --agent planner "Focus on auth module first"
sow agent resume --agent researcher "Look at OAuth 2.0 specifically"
Prerequisites:
- The session must have been previously created with 'sow agent spawn'
- The executor must support session resumption
The resume command is typically used in this workflow:
1. Orchestrator spawns worker -> Worker exagent.runResume function · go · L67-L138 (72 LOC)cli/cmd/agent/resume.go
func runResume(cmd *cobra.Command, args []string, explicitPhase, agentFlag string) error {
// Get sow context
ctx := cmdutil.GetContext(cmd.Context())
// Check if sow is initialized
if !ctx.IsInitialized() {
return fmt.Errorf("sow not initialized. Run 'sow init' first")
}
// Determine mode based on --agent flag
hasAgentFlag := agentFlag != ""
// Parse arguments based on mode
var taskID, prompt string
if hasAgentFlag {
// Taskless mode: only prompt is provided
if len(args) != 1 {
return fmt.Errorf("taskless resume requires exactly one argument: <prompt>\nUsage: sow agent resume --agent <name> <prompt>")
}
prompt = args[0]
} else {
// Task mode: task-id and prompt required
if len(args) != 2 {
return fmt.Errorf("task resume requires two arguments: <task-id> <prompt>\nUsage: sow agent resume <task-id> <prompt>")
}
taskID = args[0]
prompt = args[1]
}
// Load project state
proj, err := cmdutil.LoadProject(cmd.Context(), ctx)
if err != nil {
if sagent.runResumeWithTask function · go · L141-L203 (63 LOC)cli/cmd/agent/resume.go
func runResumeWithTask(cmd *cobra.Command, proj *state.Project, taskID, prompt, explicitPhase string, executorRegistry *agents.ExecutorRegistry, bindings *struct {
Orchestrator *string `json:"orchestrator,omitempty"`
Implementer *string `json:"implementer,omitempty"`
Architect *string `json:"architect,omitempty"`
Reviewer *string `json:"reviewer,omitempty"`
Planner *string `json:"planner,omitempty"`
Researcher *string `json:"researcher,omitempty"`
Decomposer *string `json:"decomposer,omitempty"`
}) error {
// Resolve which phase to use
phaseName, err := resolveTaskPhase(proj, explicitPhase)
if err != nil {
return err
}
// Get phase
phaseState, exists := proj.Phases[phaseName]
if !exists {
return fmt.Errorf("phase not found: %s", phaseName)
}
// Find task by ID
taskIndex := -1
for i, t := range phaseState.Tasks {
if t.Id == taskID {
taskIndex = i
break
}
}
if taskIndex == -1 {
return fmt.Errorf("task %s not found in phase %s", taskagent.runResumeTaskless function · go · L206-L242 (37 LOC)cli/cmd/agent/resume.go
func runResumeTaskless(cmd *cobra.Command, proj *state.Project, agentName, prompt string, executorRegistry *agents.ExecutorRegistry, bindings *struct {
Orchestrator *string `json:"orchestrator,omitempty"`
Implementer *string `json:"implementer,omitempty"`
Architect *string `json:"architect,omitempty"`
Reviewer *string `json:"reviewer,omitempty"`
Planner *string `json:"planner,omitempty"`
Researcher *string `json:"researcher,omitempty"`
Decomposer *string `json:"decomposer,omitempty"`
}) error {
// Look up session ID from project's agent_sessions
if proj.Agent_sessions == nil {
return fmt.Errorf("no session found for agent %s (spawn first with 'sow agent spawn --agent %s')", agentName, agentName)
}
sessionID, exists := proj.Agent_sessions[agentName]
if !exists || sessionID == "" {
return fmt.Errorf("no session found for agent %s (spawn first with 'sow agent spawn --agent %s')", agentName, agentName)
}
// Look up executor for this agent
executor, errAll rows above produced by Repobility · https://repobility.com
agent.newSpawnCmd function · go · L28-L82 (55 LOC)cli/cmd/agent/spawn.go
func newSpawnCmd() *cobra.Command {
var phase string
var agentName string
var customPrompt string
cmd := &cobra.Command{
Use: "spawn [task-id]",
Short: "Spawn an agent to execute work",
Long: `Spawn an agent to execute work.
The spawn command has two modes:
TASK MODE (with task-id):
Spawns an agent to execute a specific task. The agent is determined by the
task's assigned_agent field unless overridden with --agent.
sow agent spawn 010 # Use task's assigned agent
sow agent spawn 010 --agent reviewer # Override with different agent
sow agent spawn 010 --prompt "Focus on error handling"
TASKLESS MODE (with --agent only):
Spawns an agent directly without a task. Useful for orchestrator to spawn
planning or research agents before tasks exist.
sow agent spawn --agent planner --prompt "Create implementation plan"
sow agent spawn --agent researcher --prompt "Research auth libraries"
Session IDs are persisted before spawning to supportagent.runSpawn function · go · L85-L145 (61 LOC)cli/cmd/agent/spawn.go
func runSpawn(cmd *cobra.Command, args []string, explicitPhase, agentFlag, customPrompt string) error {
// Get sow context
ctx := cmdutil.GetContext(cmd.Context())
// Check if sow is initialized
if !ctx.IsInitialized() {
return fmt.Errorf("sow not initialized. Run 'sow init' first")
}
// Determine mode based on arguments
hasTaskID := len(args) > 0
hasAgentFlag := agentFlag != ""
// Validation: need at least one of task-id or --agent
if !hasTaskID && !hasAgentFlag {
return fmt.Errorf("must provide either <task-id> or --agent flag")
}
// Load project state (required for both modes)
proj, err := cmdutil.LoadProject(cmd.Context(), ctx)
if err != nil {
if strings.Contains(err.Error(), "no such file") {
return fmt.Errorf("no active project found")
}
return fmt.Errorf("failed to load project: %w", err)
}
// Load user config for executor settings
userConfig, err := config.LoadUserConfig(ctx.FS())
if err != nil {
return fmt.Errorf("failed to load user confiagent.runSpawnWithTask function · go · L148-L235 (88 LOC)cli/cmd/agent/spawn.go
func runSpawnWithTask(cmd *cobra.Command, proj *state.Project, taskID, explicitPhase, agentOverride, customPrompt string, executorRegistry *agents.ExecutorRegistry, bindings *struct {
Orchestrator *string `json:"orchestrator,omitempty"`
Implementer *string `json:"implementer,omitempty"`
Architect *string `json:"architect,omitempty"`
Reviewer *string `json:"reviewer,omitempty"`
Planner *string `json:"planner,omitempty"`
Researcher *string `json:"researcher,omitempty"`
Decomposer *string `json:"decomposer,omitempty"`
}) error {
// Resolve which phase to use
phaseName, err := resolveTaskPhase(proj, explicitPhase)
if err != nil {
return err
}
// Get phase
phaseState, exists := proj.Phases[phaseName]
if !exists {
return fmt.Errorf("phase not found: %s", phaseName)
}
// Find task by ID
taskIndex := -1
for i, t := range phaseState.Tasks {
if t.Id == taskID {
taskIndex = i
break
}
}
if taskIndex == -1 {
return fmt.Errorf("task %s not founagent.runSpawnTaskless function · go · L238-L293 (56 LOC)cli/cmd/agent/spawn.go
func runSpawnTaskless(cmd *cobra.Command, proj *state.Project, agentName, customPrompt string, executorRegistry *agents.ExecutorRegistry, bindings *struct {
Orchestrator *string `json:"orchestrator,omitempty"`
Implementer *string `json:"implementer,omitempty"`
Architect *string `json:"architect,omitempty"`
Reviewer *string `json:"reviewer,omitempty"`
Planner *string `json:"planner,omitempty"`
Researcher *string `json:"researcher,omitempty"`
Decomposer *string `json:"decomposer,omitempty"`
}) error {
// Look up agent by name
agentRegistry := agents.NewAgentRegistry()
agent, err := agentRegistry.Get(agentName)
if err != nil {
return buildAgentNotFoundError(agentName, "", agentRegistry)
}
// Look up executor for this agent
executor, err := executorRegistry.GetAgentExecutor(agentName, bindings)
if err != nil {
return fmt.Errorf("failed to get executor for agent %s: %w", agentName, err)
}
// Initialize agent_sessions map if nil
if proj.Agent_sessionsagent.buildAgentNotFoundError function · go · L296-L308 (13 LOC)cli/cmd/agent/spawn.go
func buildAgentNotFoundError(agentName, taskID string, registry *agents.AgentRegistry) error {
availableAgents := registry.List()
names := make([]string, len(availableAgents))
for i, a := range availableAgents {
names[i] = a.Name
}
sort.Strings(names)
if taskID != "" {
return fmt.Errorf("task %s has unknown assigned agent: %s\nAvailable agents: %s", taskID, agentName, strings.Join(names, ", "))
}
return fmt.Errorf("unknown agent: %s\nAvailable agents: %s", agentName, strings.Join(names, ", "))
}agent.buildTaskPrompt function · go · L311-L319 (9 LOC)cli/cmd/agent/spawn.go
func buildTaskPrompt(taskID, phaseName string) string {
return fmt.Sprintf(`Execute task %s.
Task location: .sow/project/phases/%s/tasks/%s/
Read state.yaml for task metadata, description.md for requirements,
and feedback/ for any corrections from previous iterations.
`, taskID, phaseName, taskID)
}agent.resolveTaskPhase function · go · L329-L362 (34 LOC)cli/cmd/agent/spawn.go
func resolveTaskPhase(project *state.Project, explicitPhase string) (string, error) {
// Get the project type config to query task support
config := project.Config()
// Case 1: Explicit phase provided via --phase flag
if explicitPhase != "" {
// Validate that the phase supports tasks
if !config.PhaseSupportsTasks(explicitPhase) {
supportedPhases := config.GetTaskSupportingPhases()
if len(supportedPhases) == 0 {
return "", fmt.Errorf("phase %s does not support tasks (no phases support tasks in this project type)", explicitPhase)
}
return "", fmt.Errorf("phase %s does not support tasks (supported phases: %s)",
explicitPhase, strings.Join(supportedPhases, ", "))
}
return explicitPhase, nil
}
// Case 2: Smart default based on current project state
currentState := project.Statechart.Current_state
defaultPhase := config.GetDefaultTaskPhase(currentState)
if defaultPhase == "" {
// No smart default found - provide helpful error
supportedPhases := conconfig.NewConfigCmd function · go · L9-L38 (30 LOC)cli/cmd/config/config.go
func NewConfigCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "config",
Short: "Manage user configuration",
Long: `Manage sow user configuration for agent preferences.
Configuration is stored at ~/.config/sow/config.yaml (Linux/Mac)
or %APPDATA%\sow\config.yaml (Windows).
If no configuration exists, sow uses defaults (Claude Code for all agents).
Commands:
init Create configuration file with template
path Show configuration file path
show Display effective configuration (merged)
validate Validate configuration file
edit Open configuration in editor
reset Remove configuration file`,
}
// Add subcommands
cmd.AddCommand(newInitCmd())
cmd.AddCommand(newPathCmd())
cmd.AddCommand(newShowCmd())
cmd.AddCommand(newValidateCmd())
cmd.AddCommand(newEditCmd())
cmd.AddCommand(newResetCmd())
return cmd
}About: code-quality intelligence by Repobility · https://repobility.com
config.newEditCmd function · go · L13-L24 (12 LOC)cli/cmd/config/edit.go
func newEditCmd() *cobra.Command {
return &cobra.Command{
Use: "edit",
Short: "Open configuration in editor",
Long: `Open the configuration file in your preferred editor.
Uses $EDITOR environment variable, falling back to 'vi' if not set.
If no configuration file exists, creates one with the default template first.`,
RunE: runEdit,
}
}config.runEdit function · go · L26-L34 (9 LOC)cli/cmd/config/edit.go
func runEdit(cmd *cobra.Command, _ []string) error {
path, err := config.GetUserConfigPath()
if err != nil {
return fmt.Errorf("failed to get config path: %w", err)
}
editor := getEditor()
return runEditWithPath(cmd, path, editor)
}config.getEditor function · go · L38-L43 (6 LOC)cli/cmd/config/edit.go
func getEditor() string {
if editor := os.Getenv("EDITOR"); editor != "" {
return editor
}
return "vi"
}config.runEditWithPath function · go · L46-L69 (24 LOC)cli/cmd/config/edit.go
func runEditWithPath(cmd *cobra.Command, path string, editor string) error {
// Create file with template if it doesn't exist
if _, err := os.Stat(path); os.IsNotExist(err) {
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
return fmt.Errorf("failed to create config directory: %w", err)
}
if err := os.WriteFile(path, []byte(configTemplate), 0644); err != nil {
return fmt.Errorf("failed to create config: %w", err)
}
cmd.Printf("Created new configuration at %s\n", path)
}
// Open editor
editCmd := exec.CommandContext(cmd.Context(), editor, path)
editCmd.Stdin = os.Stdin
editCmd.Stdout = os.Stdout
editCmd.Stderr = os.Stderr
if err := editCmd.Run(); err != nil {
return fmt.Errorf("editor failed: %w", err)
}
return nil
}config.newInitCmd function · go · L12-L26 (15 LOC)cli/cmd/config/init.go
func newInitCmd() *cobra.Command {
return &cobra.Command{
Use: "init",
Short: "Create configuration file with template",
Long: `Create a configuration file with a documented template.
The configuration file includes:
- Executor definitions (Claude Code, Cursor, Windsurf)
- Agent role bindings
- All available settings with documentation
If the file already exists, use 'sow config edit' to modify it.`,
RunE: runInit,
}
}config.runInit function · go · L28-L34 (7 LOC)cli/cmd/config/init.go
func runInit(cmd *cobra.Command, _ []string) error {
path, err := config.GetUserConfigPath()
if err != nil {
return fmt.Errorf("failed to get config path: %w", err)
}
return runInitWithPath(cmd, path)
}config.runInitWithPath function · go · L37-L44 (8 LOC)cli/cmd/config/init.go
func runInitWithPath(cmd *cobra.Command, path string) error {
if err := initConfigAtPath(path); err != nil {
return err
}
cmd.Printf("Created configuration at %s\n", path)
return nil
}config.initConfigAtPath function · go · L48-L65 (18 LOC)cli/cmd/config/init.go
func initConfigAtPath(path string) error {
// Check if file exists
if _, err := os.Stat(path); err == nil {
return fmt.Errorf("config already exists at %s\nUse 'sow config edit' to modify", path)
}
// Create parent directories
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
return fmt.Errorf("failed to create config directory: %w", err)
}
// Write template
if err := os.WriteFile(path, []byte(configTemplate), 0644); err != nil {
return fmt.Errorf("failed to write config: %w", err)
}
return nil
}Powered by Repobility — scan your code at https://repobility.com
config.newPathCmd function · go · L11-L32 (22 LOC)cli/cmd/config/path.go
func newPathCmd() *cobra.Command {
var existsFlag bool
cmd := &cobra.Command{
Use: "path",
Short: "Show configuration file path",
Long: `Show the path to the user configuration file.
The path is platform-specific:
Linux/Mac: ~/.config/sow/config.yaml
Windows: %APPDATA%\sow\config.yaml
Use --exists to check if the file exists (for scripting).`,
RunE: func(cmd *cobra.Command, _ []string) error {
return runPath(cmd, existsFlag)
},
}
cmd.Flags().BoolVar(&existsFlag, "exists", false, "Check if config file exists (outputs true/false)")
return cmd
}config.runPath function · go · L34-L52 (19 LOC)cli/cmd/config/path.go
func runPath(cmd *cobra.Command, checkExists bool) error {
path, err := config.GetUserConfigPath()
if err != nil {
return fmt.Errorf("failed to get config path: %w", err)
}
if checkExists {
_, err := os.Stat(path)
if err == nil {
cmd.Println("true")
} else {
cmd.Println("false")
}
return nil
}
cmd.Println(path)
return nil
}config.runPathWithOptions function · go · L55-L67 (13 LOC)cli/cmd/config/path.go
func runPathWithOptions(cmd *cobra.Command, path string, checkExists bool) {
if checkExists {
_, err := os.Stat(path)
if err == nil {
cmd.Println("true")
} else {
cmd.Println("false")
}
return
}
cmd.Println(path)
}config.newResetCmd function · go · L13-L31 (19 LOC)cli/cmd/config/reset.go
func newResetCmd() *cobra.Command {
var forceFlag bool
cmd := &cobra.Command{
Use: "reset",
Short: "Remove configuration file",
Long: `Remove the configuration file and revert to defaults.
A backup is created at config.yaml.backup before removal.
Use --force to skip the confirmation prompt.`,
RunE: func(cmd *cobra.Command, _ []string) error {
return runReset(cmd, forceFlag)
},
}
cmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Skip confirmation prompt")
return cmd
}config.runReset function · go · L33-L39 (7 LOC)cli/cmd/config/reset.go
func runReset(cmd *cobra.Command, force bool) error {
path, err := config.GetUserConfigPath()
if err != nil {
return fmt.Errorf("failed to get config path: %w", err)
}
return resetConfigAtPath(cmd, path, force)
}config.resetConfigAtPath function · go · L42-L77 (36 LOC)cli/cmd/config/reset.go
func resetConfigAtPath(cmd *cobra.Command, path string, force bool) error {
// Check if file exists
if _, err := os.Stat(path); os.IsNotExist(err) {
cmd.Println("No configuration file to reset")
return nil
}
// Confirm unless --force
if !force {
cmd.Printf("This will remove %s\n", path)
cmd.Print("Continue? [y/N] ")
reader := bufio.NewReader(cmd.InOrStdin())
response, err := reader.ReadString('\n')
if err != nil {
return fmt.Errorf("failed to read response: %w", err)
}
response = strings.TrimSpace(strings.ToLower(response))
if response != "y" && response != "yes" {
cmd.Println("Cancelled")
return nil
}
}
// Create backup
backupPath := path + ".backup"
if err := os.Rename(path, backupPath); err != nil {
return fmt.Errorf("failed to create backup: %w", err)
}
cmd.Printf("Configuration removed (backup at %s)\n", backupPath)
cmd.Println("Using built-in defaults")
return nil
}config.newShowCmd function · go · L14-L26 (13 LOC)cli/cmd/config/show.go
func newShowCmd() *cobra.Command {
return &cobra.Command{
Use: "show",
Short: "Show effective configuration",
Long: `Display the effective configuration after merging:
1. Built-in defaults
2. Config file (if exists)
3. Environment variables (highest priority)
The output shows what configuration is actually being used.`,
RunE: runShow,
}
}config.runShow function · go · L28-L34 (7 LOC)cli/cmd/config/show.go
func runShow(cmd *cobra.Command, _ []string) error {
path, err := config.GetUserConfigPath()
if err != nil {
return fmt.Errorf("failed to get config path: %w", err)
}
return runShowWithPath(cmd, path)
}Hi, dataset curator — please cite Repobility (https://repobility.com) when reusing this data.
config.runShowWithPath function · go · L37-L74 (38 LOC)cli/cmd/config/show.go
func runShowWithPath(cmd *cobra.Command, path string) error {
// Create a local filesystem for config loading
fsys := billy.NewLocal()
// Load effective config using the internal loader for path-specific loading
cfg, err := config.LoadUserConfigFromPath(fsys, path)
if err != nil {
return fmt.Errorf("failed to load config: %w", err)
}
// Get config file status
_, fileErr := os.Stat(path)
fileExists := fileErr == nil
// Print header with source info
cmd.Println("# Effective configuration (merged from defaults + file + environment)")
if fileExists {
cmd.Printf("# Config file: %s (exists)\n", path)
} else {
cmd.Printf("# Config file: %s (not found, using defaults)\n", path)
}
// Check for env overrides
envOverrides := getEnvOverrides()
if len(envOverrides) > 0 {
cmd.Printf("# Environment overrides: %s\n", strings.Join(envOverrides, ", "))
}
cmd.Println()
// Output as YAML
output, err := yaml.Marshal(cfg)
if err != nil {
return fmt.Errorf("failed to marsconfig.getEnvOverrides function · go · L77-L95 (19 LOC)cli/cmd/config/show.go
func getEnvOverrides() []string {
envVars := []string{
"SOW_AGENTS_ORCHESTRATOR",
"SOW_AGENTS_IMPLEMENTER",
"SOW_AGENTS_ARCHITECT",
"SOW_AGENTS_REVIEWER",
"SOW_AGENTS_PLANNER",
"SOW_AGENTS_RESEARCHER",
"SOW_AGENTS_DECOMPOSER",
}
var set []string
for _, ev := range envVars {
if os.Getenv(ev) != "" {
set = append(set, ev)
}
}
return set
}config.newValidateCmd function · go · L14-L27 (14 LOC)cli/cmd/config/validate.go
func newValidateCmd() *cobra.Command {
return &cobra.Command{
Use: "validate",
Short: "Validate configuration file",
Long: `Validate the configuration file for syntax and semantic errors.
Checks performed:
- YAML syntax is valid
- Executor types are valid (claude, cursor, windsurf)
- Bindings reference defined executors
- (Optional) Executor binaries are available on PATH`,
RunE: runValidate,
}
}config.runValidate function · go · L29-L35 (7 LOC)cli/cmd/config/validate.go
func runValidate(cmd *cobra.Command, _ []string) error {
path, err := config.GetUserConfigPath()
if err != nil {
return fmt.Errorf("failed to get config path: %w", err)
}
return runValidateWithPath(cmd, path)
}config.runValidateWithPath function · go · L38-L99 (62 LOC)cli/cmd/config/validate.go
func runValidateWithPath(cmd *cobra.Command, path string) error {
cmd.Printf("Validating configuration at %s...\n\n", path)
// Check if file exists
data, err := os.ReadFile(path)
if os.IsNotExist(err) {
cmd.Println("No configuration file found (using defaults)")
cmd.Println("Run 'sow config init' to create one.")
return nil
}
if err != nil {
return fmt.Errorf("failed to read config: %w", err)
}
// Handle empty file or comment-only file
if len(data) == 0 || isCommentOnly(data) {
cmd.Println("OK YAML syntax valid")
cmd.Println("OK Schema valid")
cmd.Println("OK Executor types valid")
cmd.Println("OK Bindings reference defined executors")
cmd.Println("\nConfiguration is valid.")
return nil
}
// Validate YAML syntax
var raw interface{}
if err := yaml.Unmarshal(data, &raw); err != nil {
cmd.Printf("X YAML syntax error: %v\n", err)
return fmt.Errorf("validation failed")
}
cmd.Println("OK YAML syntax valid")
// Parse into config struct
var cfg scheconfig.isCommentOnly function · go · L102-L113 (12 LOC)cli/cmd/config/validate.go
func isCommentOnly(data []byte) bool {
for _, line := range splitLines(data) {
trimmed := trimSpace(line)
if len(trimmed) == 0 {
continue
}
if trimmed[0] != '#' {
return false
}
}
return true
}config.splitLines function · go · L116-L129 (14 LOC)cli/cmd/config/validate.go
func splitLines(data []byte) [][]byte {
var lines [][]byte
start := 0
for i, b := range data {
if b == '\n' {
lines = append(lines, data[start:i])
start = i + 1
}
}
if start < len(data) {
lines = append(lines, data[start:])
}
return lines
}config.trimSpace function · go · L132-L142 (11 LOC)cli/cmd/config/validate.go
func trimSpace(data []byte) []byte {
start := 0
end := len(data)
for start < end && isSpace(data[start]) {
start++
}
for end > start && isSpace(data[end-1]) {
end--
}
return data[start:end]
}All rows above produced by Repobility · https://repobility.com
config.checkExecutorBinariesFromConfig function · go · L151-L181 (31 LOC)cli/cmd/config/validate.go
func checkExecutorBinariesFromConfig(config *schemas.UserConfig) []string {
if config == nil || config.Agents == nil {
return nil
}
var warnings []string
// Map executor types to their binary names
binaries := map[string]string{
"claude": "claude",
"cursor": "cursor",
"windsurf": "windsurf",
}
for name, executor := range config.Agents.Executors {
binary, ok := binaries[executor.Type]
if !ok {
continue
}
// Check if binary is on PATH
if _, err := exec.LookPath(binary); err != nil {
warnings = append(warnings, fmt.Sprintf(
"%s executor '%s' requires '%s' binary, but it was not found on PATH",
executor.Type, name, binary,
))
}
}
return warnings
}cmd.resolveTaskPhase function · go · L17-L50 (34 LOC)cli/cmd/helpers.go
func resolveTaskPhase(project *state.Project, explicitPhase string) (string, error) {
// Get the project type config to query task support
config := project.Config()
// Case 1: Explicit phase provided via --phase flag
if explicitPhase != "" {
// Validate that the phase supports tasks
if !config.PhaseSupportsTasks(explicitPhase) {
supportedPhases := config.GetTaskSupportingPhases()
if len(supportedPhases) == 0 {
return "", fmt.Errorf("phase %s does not support tasks (no phases support tasks in this project type)", explicitPhase)
}
return "", fmt.Errorf("phase %s does not support tasks (supported phases: %s)",
explicitPhase, strings.Join(supportedPhases, ", "))
}
return explicitPhase, nil
}
// Case 2: Smart default based on current project state
currentState := project.Statechart.Current_state
defaultPhase := config.GetDefaultTaskPhase(currentState)
if defaultPhase == "" {
// No smart default found - provide helpful error
supportedPhases := concmd.NewInitCmd function · go · L12-L38 (27 LOC)cli/cmd/init.go
func NewInitCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "init",
Short: "Initialize sow structure",
Long: `Initialize the .sow/ directory structure in the current repository.
Creates:
.sow/knowledge/ - Repository-specific documentation (committed)
.sow/refs/ - External knowledge and code references (symlinks)
.sow/.version - sow structure version file
This command must be run from a git repository root.`,
RunE: func(cmd *cobra.Command, _ []string) error {
ctx := cmdutil.GetContext(cmd.Context())
// Initialize .sow structure
if err := sow.Init(ctx.RepoRoot()); err != nil {
return fmt.Errorf("initialization failed: %w", err)
}
cmd.Println("✓ sow initialized successfully")
return nil
},
}
return cmd
}page 1 / 12next ›