From 5fd727b1f18ad57f35256ea82490d2b3b640da77 Mon Sep 17 00:00:00 2001 From: DTTerastar Date: Sat, 25 Apr 2026 17:59:10 -0400 Subject: [PATCH] feat: add 'auth status' subcommand MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per the quantcli shared contract §5, every CLI exposes 'auth status' that prints a one-line readiness summary and exits 0 if usable, non-zero otherwise. https://github.com/quantcli/common/blob/main/CONTRACT.md#5-auth For crono, this introduces an 'auth' parent command (previously absent because credentials are entirely env-var driven) with one child: crono-export auth status Logic is a local env-var check — no network call. Validates that both CRONOMETER_USERNAME and CRONOMETER_PASSWORD are set, with a clear "missing X" message when not. Updated prime AUTH section to mention the new subcommand. Co-Authored-By: Claude Opus 4.7 (1M context) --- cmd/auth.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ cmd/prime.go | 3 +++ 2 files changed, 50 insertions(+) create mode 100644 cmd/auth.go diff --git a/cmd/auth.go b/cmd/auth.go new file mode 100644 index 0000000..7ccfc71 --- /dev/null +++ b/cmd/auth.go @@ -0,0 +1,47 @@ +package cmd + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" +) + +var authCmd = &cobra.Command{ + Use: "auth", + Short: "Authentication commands", +} + +var authStatusCmd = &cobra.Command{ + Use: "status", + Short: "Print one-line auth readiness state and exit 0 if usable", + Long: `Print a one-line summary of whether the CLI has the credentials it needs +to talk to Cronometer. Exit code 0 if usable, 1 if missing. + +This is a local check — no network call. It only verifies the +CRONOMETER_USERNAME and CRONOMETER_PASSWORD environment variables are set. +The CLI logs in fresh on every invocation, so a successful status here is +necessary but not sufficient: a wrong password will still fail at run time. + +Per the quantcli shared contract: +https://github.com/quantcli/common/blob/main/CONTRACT.md#5-auth`, + RunE: func(cmd *cobra.Command, _ []string) error { + user := os.Getenv("CRONOMETER_USERNAME") + pass := os.Getenv("CRONOMETER_PASSWORD") + switch { + case user == "" && pass == "": + return fmt.Errorf("missing CRONOMETER_USERNAME and CRONOMETER_PASSWORD") + case user == "": + return fmt.Errorf("missing CRONOMETER_USERNAME") + case pass == "": + return fmt.Errorf("missing CRONOMETER_PASSWORD") + } + fmt.Fprintf(cmd.OutOrStdout(), "credentials present for %s (env-var auth, no token cache)\n", user) + return nil + }, +} + +func init() { + authCmd.AddCommand(authStatusCmd) + rootCmd.AddCommand(authCmd) +} diff --git a/cmd/prime.go b/cmd/prime.go index 8441816..3910157 100644 --- a/cmd/prime.go +++ b/cmd/prime.go @@ -33,6 +33,9 @@ AUTH CRONOMETER_USERNAME your Cronometer email CRONOMETER_PASSWORD your Cronometer password + 'crono-export auth status' is a fast local check that exits 0 when both + vars are set, 1 with a clear "missing X" message otherwise. + DATE FLAGS (every export subcommand accepts these) --since VALUE inclusive lower bound --until VALUE inclusive upper bound; defaults to today