From f232effe69cda81b5955b7fe72d6d2c718c906e3 Mon Sep 17 00:00:00 2001 From: Alex Dunmow Date: Wed, 3 Jun 2026 06:56:07 +0800 Subject: [PATCH] feat(cli): init prompts for kind and categories --- cmd/ninja/cmd/plugin.go | 74 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/cmd/ninja/cmd/plugin.go b/cmd/ninja/cmd/plugin.go index 09eaf99..c75455e 100644 --- a/cmd/ninja/cmd/plugin.go +++ b/cmd/ninja/cmd/plugin.go @@ -76,14 +76,30 @@ func newPluginInitCmd() *cobra.Command { } } + kind, err := promptKind(scanner) + if err != nil { + return err + } + var cats []string + if kind == "plugin" { + cats, err = promptCategories(ctx, cli, scanner) + if err != nil { + return err + } + } + if _, err := cli.Reg.CreatePlugin(ctx, connect.NewRequest(&v1.CreatePluginRequest{ - ScopeSlug: scopeAPISlug(scope), Name: name, Description: "", + ScopeSlug: scopeAPISlug(scope), + Name: name, + Description: "", + Kind: kind, + Categories: cats, })); err != nil { return err } fmt.Printf("\nCreated %s/%s\n", scope, name) - if err := upsertPluginMod(scope, name); err != nil { + if err := upsertPluginMod(scope, name, kind, cats); err != nil { return err } fmt.Println("plugin.mod updated") @@ -198,6 +214,56 @@ func createScopeInline(ctx context.Context, cli *orchclient.Client, scanner *buf return slug, nil } +func promptKind(scanner *bufio.Scanner) (string, error) { + fmt.Println("Kind: 1) plugin 2) theme") + fmt.Print("Select [1]: ") + if !scanner.Scan() { + return "", fmt.Errorf("cancelled") + } + v := strings.TrimSpace(scanner.Text()) + switch v { + case "", "1", "plugin": + return "plugin", nil + case "2", "theme": + return "theme", nil + default: + return "", fmt.Errorf("invalid kind: %s", v) + } +} + +func promptCategories(ctx context.Context, cli *orchclient.Client, scanner *bufio.Scanner) ([]string, error) { + resp, err := cli.Reg.ListCategories(ctx, connect.NewRequest(&v1.ListCategoriesRequest{})) + if err != nil { + return nil, fmt.Errorf("list categories: %w", err) + } + cats := resp.Msg.Categories + if len(cats) == 0 { + return nil, nil + } + fmt.Println("Categories (comma-separated numbers, or blank to skip):") + for i, c := range cats { + fmt.Printf(" %d. %s — %s\n", i+1, c.Slug, c.DisplayName) + } + fmt.Print("Select: ") + if !scanner.Scan() { + return nil, fmt.Errorf("cancelled") + } + raw := strings.TrimSpace(scanner.Text()) + if raw == "" { + return nil, nil + } + parts := strings.Split(raw, ",") + out := make([]string, 0, len(parts)) + for _, p := range parts { + n, err := strconv.Atoi(strings.TrimSpace(p)) + if err != nil || n < 1 || n > len(cats) { + return nil, fmt.Errorf("invalid category selection: %s", p) + } + out = append(out, cats[n-1].Slug) + } + return out, nil +} + func newPluginPublishCmd() *cobra.Command { var channel string var allowDirty bool @@ -482,7 +548,7 @@ func runCmd(name string, args ...string) error { return c.Run() } -func upsertPluginMod(scope, name string) error { +func upsertPluginMod(scope, name, kind string, categories []string) error { const file = "plugin.mod" existing, _ := os.ReadFile(file) mod, _ := core.ParseModFull(existing) @@ -494,6 +560,8 @@ func upsertPluginMod(scope, name string) error { } mod.Plugin.Scope = scope mod.Plugin.Name = name + mod.Plugin.Kind = kind + mod.Plugin.Categories = categories return writeMod(file, mod) }