e09919b679
- Add 'reminder' to glyph CHECK constraint (was accepted by parser but
rejected by DB)
- Default serve bind to 127.0.0.1, add --host flag for LAN access
- Validate card_data as JSON in Store.Create/Update/Promote
- Return pagination envelope {data,total,limit,offset} from list endpoint
- Append absorb breadcrumb to source entity before soft-delete
- Add Levenshtein fuzzy match to catch command typos before routing to add
- Replace DDL string-matching migrations with versioned schema_version table
- Update web UI and API tests for envelope response format
109 lines
2.0 KiB
Go
109 lines
2.0 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var rootCmd = &cobra.Command{
|
|
Use: "nib",
|
|
Short: "capture and crystallize notes, todos, and events",
|
|
Args: cobra.ArbitraryArgs,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
if len(args) == 0 {
|
|
return cmd.Help()
|
|
}
|
|
return runAdd(cmd, args)
|
|
},
|
|
SilenceUsage: true,
|
|
}
|
|
|
|
func Execute() error {
|
|
if len(os.Args) > 1 {
|
|
first := os.Args[1]
|
|
isFlag := strings.HasPrefix(first, "-") && !strings.Contains(first, " ")
|
|
if first != "help" && first != "completion" &&
|
|
!isFlag && !isSubcommand(first) {
|
|
if near := nearSubcommand(first); near != "" {
|
|
fmt.Fprintf(os.Stderr, "unknown command %q — did you mean %q?\n", first, near)
|
|
os.Exit(1)
|
|
}
|
|
// "--" stops cobra from parsing glyph prefixes like "-" as flags
|
|
rootCmd.SetArgs(append([]string{"add", "--"}, os.Args[1:]...))
|
|
}
|
|
}
|
|
return rootCmd.Execute()
|
|
}
|
|
|
|
func isSubcommand(name string) bool {
|
|
for _, c := range rootCmd.Commands() {
|
|
if c.Name() == name {
|
|
return true
|
|
}
|
|
for _, alias := range c.Aliases {
|
|
if alias == name {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func nearSubcommand(name string) string {
|
|
for _, c := range rootCmd.Commands() {
|
|
if d := editDist(name, c.Name()); d > 0 && d <= 2 {
|
|
return c.Name()
|
|
}
|
|
for _, alias := range c.Aliases {
|
|
if d := editDist(name, alias); d > 0 && d <= 2 {
|
|
return alias
|
|
}
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func editDist(a, b string) int {
|
|
la, lb := len(a), len(b)
|
|
if la == 0 {
|
|
return lb
|
|
}
|
|
if lb == 0 {
|
|
return la
|
|
}
|
|
prev := make([]int, lb+1)
|
|
for j := range prev {
|
|
prev[j] = j
|
|
}
|
|
for i := 1; i <= la; i++ {
|
|
curr := make([]int, lb+1)
|
|
curr[0] = i
|
|
for j := 1; j <= lb; j++ {
|
|
cost := 1
|
|
if a[i-1] == b[j-1] {
|
|
cost = 0
|
|
}
|
|
ins := curr[j-1] + 1
|
|
del := prev[j] + 1
|
|
sub := prev[j-1] + cost
|
|
curr[j] = ins
|
|
if del < curr[j] {
|
|
curr[j] = del
|
|
}
|
|
if sub < curr[j] {
|
|
curr[j] = sub
|
|
}
|
|
}
|
|
prev = curr
|
|
}
|
|
return prev[lb]
|
|
}
|
|
|
|
func init() {
|
|
rootCmd.AddCommand(addCmd)
|
|
rootCmd.AddCommand(lsCmd)
|
|
}
|