package cmd import ( "fmt" "net/http" "os" "github.com/kb-search/kb/internal/api" "github.com/kb-search/kb/internal/output" "github.com/spf13/cobra" ) var addnoteCmd = &cobra.Command{ Use: "addnote ", Short: "Add a text note to the knowledge base", Args: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { return fmt.Errorf("requires a note text argument\n\n Usage: kb addnote \"your note text here\"") } if len(args) > 1 { return fmt.Errorf("accepts 1 arg but received %d — quote your note text, e.g. kb addnote \"your note text here\"", len(args)) } return nil }, RunE: runAddnote, } func init() { addnoteCmd.Flags().String("tags", "", "tags (comma-separated)") rootCmd.AddCommand(addnoteCmd) } func runAddnote(cmd *cobra.Command, args []string) error { tags, _ := cmd.Flags().GetString("tags") client := api.NewClient() return submitNote(client, args[0], tags) } func submitNote(client *api.Client, note, tags string) error { fields := map[string]string{ "note": note, } if tags != "" { fields["tags"] = tags } resp, err := client.PostMultipart("/api/v1/jobs", fields, nil) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } if resp.StatusCode == http.StatusConflict { var result interface{} if err := api.DecodeJSON(resp, &result); err != nil { return fmt.Errorf("failed to decode response: %w", err) } if output.IsJSON() { output.PrintJSON(result) } else { if m, ok := result.(map[string]interface{}); ok { if docID, ok := m["document_id"].(float64); ok { fmt.Printf("Already imported: %s (doc ID: %.0f)\n", m["title"], docID) } else if jobID, ok := m["job_id"].(float64); ok { fmt.Printf("Already queued: %s (job ID: %.0f)\n", m["title"], jobID) } } } return nil } if err := api.CheckError(resp); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } var result interface{} if err := api.DecodeJSON(resp, &result); err != nil { return fmt.Errorf("failed to decode response: %w", err) } if output.IsJSON() { output.PrintJSON(result) } else { fmt.Println("Queued: note") } return nil }