From 5410482e1450367d38afd9f7ee5f2f2296810421 Mon Sep 17 00:00:00 2001 From: Ben Firestone Date: Thu, 30 Apr 2026 16:23:09 -0700 Subject: [PATCH 1/2] feat(share): add --force flag to share delete for cleaning up orphans MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `arc share delete ` previously had no recovery path for entries in ~/.arc/shares.json that had become unusable — either the edit_token was missing locally, or the server returned 404/403/network errors. Both cases left a dead row in the registry with no way to prune it. Add a --force / -f flag that turns delete into a best-effort cleanup: warn instead of erroring when the edit_token is missing (skip server call), warn instead of erroring when the server delete fails, and always remove the local registry entry. Default behavior is unchanged. Also set SilenceUsage on shareDeleteCmd so runtime errors no longer dump the cobra help block — usage should only print for actual usage errors (wrong arg count, bad flag), matching the existing pattern in self.go. --- cmd/arc/share.go | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/cmd/arc/share.go b/cmd/arc/share.go index 6ebb91f..7ea6c38 100644 --- a/cmd/arc/share.go +++ b/cmd/arc/share.go @@ -181,10 +181,11 @@ const ( const defaultShareServer = "https://arcplanner.sentiolabs.io" var shareDeleteCmd = &cobra.Command{ - Use: "delete ", - Short: "Delete a share (uses edit_token from shares.json)", - Args: cobra.ExactArgs(1), - RunE: runShareDelete, + Use: "delete ", + Short: "Delete a share (uses edit_token from shares.json)", + Args: cobra.ExactArgs(1), + SilenceUsage: true, + RunE: runShareDelete, } var ( @@ -196,6 +197,7 @@ var ( shareCommentsAccepted bool shareCommentsJSON bool shareShowAuthorURL bool + shareDeleteForce bool ) func init() { @@ -216,6 +218,8 @@ func init() { shareCommentsCmd.Flags().BoolVar(&shareCommentsJSON, "json", false, "Output as JSON") shareShowCmd.Flags().BoolVar(&shareShowAuthorURL, "author-url", false, "Print the author URL (includes edit_token) instead of the plan content") + shareDeleteCmd.Flags().BoolVarP(&shareDeleteForce, "force", "f", false, + "Remove the local registry entry even if the edit token is missing or the server delete fails") shareCmd.AddCommand(shareCreateCmd, shareListCmd, shareShowCmd, shareCommentsCmd, sharePullCmd, shareApproveCmd, shareUpdateCmd, shareDeleteCmd) @@ -401,10 +405,15 @@ func runShareDelete(cmd *cobra.Command, args []string) error { } s, _ := sharesconfig.Find(id) if s == nil || s.EditToken == "" { - return fmt.Errorf("no edit_token for share %s in ~/.arc/shares.json", id) - } - if err := deleteShare(server, id, s.EditToken); err != nil { - return err + if !shareDeleteForce { + return fmt.Errorf("no edit_token for share %s in ~/.arc/shares.json (use --force to remove the local entry)", id) + } + fmt.Fprintf(cmd.ErrOrStderr(), "warning: no edit_token for %s; skipping server delete\n", id) + } else if err := deleteShare(server, id, s.EditToken); err != nil { + if !shareDeleteForce { + return err + } + fmt.Fprintf(cmd.ErrOrStderr(), "warning: server delete failed: %v; removing local entry anyway\n", err) } return sharesconfig.Remove(id) } From 7a4c8731686eb5eab225c3126bf31e75919838a5 Mon Sep 17 00:00:00 2001 From: Ben Firestone Date: Thu, 30 Apr 2026 16:25:41 -0700 Subject: [PATCH 2/2] chore(lint): fix golangci-lint findings on share delete --force - Wrap long error message to satisfy revive line-length-limit (120) - Discard fmt.Fprintf return values via _, _ = ... and use os.Stderr directly to match the existing pattern in share.go / self.go / docs.go (revive unhandled-error) --- cmd/arc/share.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmd/arc/share.go b/cmd/arc/share.go index 7ea6c38..7f42231 100644 --- a/cmd/arc/share.go +++ b/cmd/arc/share.go @@ -406,14 +406,15 @@ func runShareDelete(cmd *cobra.Command, args []string) error { s, _ := sharesconfig.Find(id) if s == nil || s.EditToken == "" { if !shareDeleteForce { - return fmt.Errorf("no edit_token for share %s in ~/.arc/shares.json (use --force to remove the local entry)", id) + return fmt.Errorf("no edit_token for share %s in ~/.arc/shares.json "+ + "(use --force to remove the local entry)", id) } - fmt.Fprintf(cmd.ErrOrStderr(), "warning: no edit_token for %s; skipping server delete\n", id) + _, _ = fmt.Fprintf(os.Stderr, "warning: no edit_token for %s; skipping server delete\n", id) } else if err := deleteShare(server, id, s.EditToken); err != nil { if !shareDeleteForce { return err } - fmt.Fprintf(cmd.ErrOrStderr(), "warning: server delete failed: %v; removing local entry anyway\n", err) + _, _ = fmt.Fprintf(os.Stderr, "warning: server delete failed: %v; removing local entry anyway\n", err) } return sharesconfig.Remove(id) }