rdev/cmd/sdlc/cmd_config.go
jordan 425ef0f806 feat: add SDLC orchestration - library, CLI, and API integration
Implements deterministic feature lifecycle management for agent-driven
development. Agents use the CLI in pods; operators control via REST API.

Library (internal/sdlc/):
- Feature lifecycle with 10 phases (draft → released)
- Classifier engine with priority-ordered rules
- Artifact tracking with approval workflow
- Task management within features
- YAML-based state persistence

CLI (cmd/sdlc/):
- init, state, next, feature, artifact, task, query commands
- --json flag for machine-readable output
- Runs inside project pods

API (21 endpoints under /projects/{id}/sdlc/):
- State: GET /state, GET /next
- Features: CRUD + transition/block/unblock
- Artifacts: approve/reject per type
- Tasks: add/start/complete/block
- Queries: blocked/ready/needs-approval

Architecture:
- Port: SDLCExecutor interface (internal/port/)
- Adapter: kubectl exec into pods (internal/adapter/kubernetes/)
- Service: pod resolution + logging (internal/service/)
- Handlers: 5 files under 500-line limit (internal/handlers/)

Also includes template upgrades (chassis framework, UI components,
OpenAPI helpers, backend/frontend guides) and component improvements.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 09:57:05 -07:00

105 lines
2.4 KiB
Go

package main
import (
"fmt"
"github.com/orchard9/rdev/internal/sdlc"
"github.com/spf13/cobra"
)
var configCmd = &cobra.Command{
Use: "config",
Short: "Manage SDLC configuration",
}
var configShowCmd = &cobra.Command{
Use: "show",
Short: "Show current configuration",
RunE: func(_ *cobra.Command, _ []string) error {
root := mustResolveRoot()
cfg, err := sdlc.LoadConfig(root)
if err != nil {
return err
}
if jsonOutput {
printJSON(cfg)
return nil
}
fmt.Printf("SDLC Config (v%d)\n", cfg.Version)
fmt.Printf(" Project: %s\n", cfg.Project.Name)
if cfg.Project.Type != "" {
fmt.Printf(" Type: %s\n", cfg.Project.Type)
}
fmt.Printf(" Main: %s\n", cfg.Branches.Main)
fmt.Printf(" Prefix: %s\n", cfg.Branches.FeaturePrefix)
fmt.Println()
fmt.Println("Enabled Phases:")
for _, p := range cfg.Phases.Enabled {
fmt.Printf(" - %s\n", p)
}
fmt.Println()
fmt.Println("Compliance:")
fmt.Printf(" Require Approvals: %v\n", cfg.Compliance.RequireApprovals)
fmt.Printf(" Require Branch: %v\n", cfg.Compliance.RequireBranch)
fmt.Printf(" Require QA: %v\n", cfg.Compliance.RequireQA)
return nil
},
}
var configSetCmd = &cobra.Command{
Use: "set <key> <value>",
Short: "Set a configuration value",
Args: cobra.ExactArgs(2),
RunE: func(_ *cobra.Command, args []string) error {
root := mustResolveRoot()
cfg, err := sdlc.LoadConfig(root)
if err != nil {
return err
}
key, value := args[0], args[1]
switch key {
case "project.name":
cfg.Project.Name = value
case "project.type":
cfg.Project.Type = value
case "branches.main":
cfg.Branches.Main = value
case "branches.feature_prefix":
cfg.Branches.FeaturePrefix = value
case "compliance.require_approvals":
cfg.Compliance.RequireApprovals = value == "true"
case "compliance.require_branch":
cfg.Compliance.RequireBranch = value == "true"
case "compliance.require_qa":
cfg.Compliance.RequireQA = value == "true"
default:
return fmt.Errorf("unknown config key: %s", key)
}
if err := cfg.Save(root); err != nil {
return err
}
if jsonOutput {
printJSON(map[string]string{"key": key, "value": value, "status": "set"})
return nil
}
fmt.Printf("Set %s = %s\n", key, value)
return nil
},
}
func init() {
configCmd.AddCommand(configShowCmd, configSetCmd)
rootCmd.AddCommand(configCmd)
}