package cmd import ( "flag" "fmt" "strings" "git.noodles.cam/claude-skills/marketplace/cli/internal/config" "git.noodles.cam/claude-skills/marketplace/cli/internal/issue" "git.noodles.cam/claude-skills/marketplace/cli/internal/project" ) func init() { register(&Command{ Name: "config", Group: GroupProject, Short: "show what this project resolved to", Long: `Every path and every setting, with the overrides already applied, so a run that went somewhere unexpected can be explained without guessing. The token is never printed — only whether one was found. This is the command to reach for when the store looks empty, when a push says 401, or when two directories disagree about which project they are in.`, Examples: []Example{ {"kettle config", "resolved paths and settings"}, }, Setup: func(fs *flag.FlagSet) func([]string) error { return func(args []string) error { root := project.Root("") if root == "" { return project.NotFoundError("") } fmt.Printf("project %s\n", root) fmt.Printf("store %s\n", issue.Root("")) fmt.Printf("payload %s\n", project.PayloadRoot("")) fmt.Printf("config %s\n", config.ProjectPath("")) fmt.Printf("logins %s\n", config.LoginsPath()) printScaffold() r, err := config.Resolve("") if err != nil { fmt.Println() return err } red := r.Redacted() fmt.Println() fmt.Printf("login %s\n", orNone(red.Login)) fmt.Printf("url %s\n", orNone(red.URL)) fmt.Printf("token %s\n", orNone(red.Token)) // What the login says its token can do, which is a note somebody // wrote and not an answer from the instance — a 403 out of // `kettle api` is read against this line. scopes := "(not recorded)" if len(red.Scopes) > 0 { scopes = strings.Join(red.Scopes, ", ") } fmt.Printf("scopes %s\n", scopes) if r.Owner != "" { fmt.Printf("repo %s\n", r.Slug()) } else { fmt.Printf("repo none\n") } return nil } }, }) } // printScaffold says where the agent-harness tree went and whether the build // that wrote it is the build that is running now. // // The mismatch is worth a line because these documents are generated whole: // there is nothing inside one that tells an operator how old it is, and a skill // four releases behind describes flags that have since been renamed. It is a // note, never a failure — `kettle gen scaffold` is the fix and the operator // decides when to run it. func printScaffold() { rec, existed, err := config.ReadScaffoldFile(config.ScaffoldPath("")) if err != nil || !existed { fmt.Printf("scaffold (none written — `kettle gen scaffold`)\n") return } out := rec.Out if out == "" { out = "(unrecorded)" } switch { case rec.Version == Version: fmt.Printf("scaffold %s (kettle %s)\n", out, rec.Version) default: fmt.Printf("scaffold %s (written by kettle %s; this is %s — run `kettle gen scaffold`)\n", out, rec.Version, Version) } }