Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude/codebase/structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
## Directory Layout

```
cmd/micasa/main.go CLI entry (kong). runCmd, backupCmd, configCmd
cmd/micasa/main.go CLI entry (cobra). runOpts, backupOpts, newRootCmd
internal/
app/ TUI package (~30K lines, largest package)
model.go Model struct, Init/Update/View, key dispatch
Expand Down Expand Up @@ -119,5 +119,5 @@ internal/
- `lrstanley/bubblezone` - Mouse zone tracking
- `rmhubbert/bubbletea-overlay` - Overlay compositing
- `brianvoe/gofakeit` - Random data generation
- `alecthomas/kong` - CLI parsing
- `spf13/cobra` - CLI parsing
- `stretchr/testify` - Test assertions
2 changes: 1 addition & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ New status or season-like enum values require updates in four places:
| `mozilla-ai/any-llm-go` | Multi-provider LLM client |
| `lrstanley/bubblezone` | Mouse zone tracking |
| `stretchr/testify` | Test assertions |
| `alecthomas/kong` | CLI parsing |
| `spf13/cobra` | CLI parsing |

## Nix Development Environment

Expand Down
52 changes: 52 additions & 0 deletions cmd/micasa/completion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2026 Phillip Cloud
// Licensed under the Apache License, Version 2.0

package main

import (
"github.com/spf13/cobra"
)

func newCompletionCmd(root *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "completion [bash|zsh|fish]",
Short: "Generate shell completion scripts",
SilenceErrors: true,
SilenceUsage: true,
}

cmd.AddCommand(
&cobra.Command{
Use: "bash",
Short: "Generate bash completion script",
SilenceErrors: true,
SilenceUsage: true,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
return root.GenBashCompletionV2(cmd.OutOrStdout(), true)
},
},
&cobra.Command{
Use: "zsh",
Short: "Generate zsh completion script",
SilenceErrors: true,
SilenceUsage: true,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
return root.GenZshCompletion(cmd.OutOrStdout())
},
},
&cobra.Command{
Use: "fish",
Short: "Generate fish completion script",
SilenceErrors: true,
SilenceUsage: true,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
return root.GenFishCompletion(cmd.OutOrStdout(), true)
},
},
)

return cmd
}
111 changes: 111 additions & 0 deletions cmd/micasa/help.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Copyright 2026 Phillip Cloud
// Licensed under the Apache License, Version 2.0

package main

import (
"fmt"
"strings"

"github.com/charmbracelet/lipgloss"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)

// Wong palette colors (duplicated from internal/app/styles.go so the CLI
// binary does not import the full TUI package).
var (
helpAccent = lipgloss.AdaptiveColor{Light: "#0072B2", Dark: "#56B4E9"}
helpSecondary = lipgloss.AdaptiveColor{Light: "#D55E00", Dark: "#E69F00"}
helpDim = lipgloss.AdaptiveColor{Light: "#4B5563", Dark: "#6B7280"}
helpMid = lipgloss.AdaptiveColor{Light: "#4B5563", Dark: "#9CA3AF"}
)

var (
helpHeading = lipgloss.NewStyle().
Foreground(helpAccent).
Bold(true)
helpCmd = lipgloss.NewStyle().
Foreground(helpSecondary)
helpFlag = lipgloss.NewStyle().
Foreground(helpSecondary)
helpDesc = lipgloss.NewStyle().
Foreground(helpMid)
helpDimStyle = lipgloss.NewStyle().
Foreground(helpDim)
)

func styledHelp(cmd *cobra.Command, _ []string) {
var b strings.Builder

if cmd.Long != "" {
fmt.Fprintln(&b, helpDesc.Render(cmd.Long))
fmt.Fprintln(&b)
} else if cmd.Short != "" {
fmt.Fprintln(&b, helpDesc.Render(cmd.Short))
fmt.Fprintln(&b)
}

if cmd.Runnable() {
fmt.Fprintln(&b, helpHeading.Render("Usage"))
fmt.Fprintf(&b, " %s\n\n", helpDimStyle.Render(cmd.UseLine()))
}

if cmd.HasAvailableSubCommands() {
fmt.Fprintln(&b, helpHeading.Render("Commands"))
maxLen := 0
for _, c := range cmd.Commands() {
if !c.IsAvailableCommand() && c.Name() != "help" {
continue
}
if n := len(c.Name()); n > maxLen {
maxLen = n
}
}
for _, c := range cmd.Commands() {
if !c.IsAvailableCommand() && c.Name() != "help" {
continue
}
name := helpCmd.Render(c.Name())
pad := strings.Repeat(" ", maxLen-len(c.Name()))
fmt.Fprintf(&b, " %s%s %s\n", name, pad, helpDesc.Render(c.Short))
}
fmt.Fprintln(&b)
}

if cmd.HasAvailableLocalFlags() {
fmt.Fprintln(&b, helpHeading.Render("Flags"))
cmd.LocalFlags().VisitAll(func(f *pflag.Flag) {
if f.Hidden {
return
}
var names string
if f.Shorthand != "" {
names = fmt.Sprintf("-%s, --%s", f.Shorthand, f.Name)
} else {
names = fmt.Sprintf(" --%s", f.Name)
}
fmt.Fprintf(&b, " %s %s\n", helpFlag.Render(names), helpDesc.Render(f.Usage))
})
fmt.Fprintln(&b)
}

if cmd.HasAvailableInheritedFlags() {
fmt.Fprintln(&b, helpHeading.Render("Global Flags"))
cmd.InheritedFlags().VisitAll(func(f *pflag.Flag) {
if f.Hidden {
return
}
var names string
if f.Shorthand != "" {
names = fmt.Sprintf("-%s, --%s", f.Shorthand, f.Name)
} else {
names = fmt.Sprintf(" --%s", f.Name)
}
fmt.Fprintf(&b, " %s %s\n", helpFlag.Render(names), helpDesc.Render(f.Usage))
})
fmt.Fprintln(&b)
}

_, _ = fmt.Fprint(cmd.OutOrStdout(), b.String())
}
Loading
Loading