@@ -11,9 +11,10 @@ import (
1111
1212// AppsCmd is the `onecli apps` command group.
1313type AppsCmd struct {
14- List AppsListCmd `cmd:"" help:"List all app connections."`
15- Connect AppsConnectCmd `cmd:"" help:"Connect an OAuth app (e.g. Google)."`
16- Disconnect AppsDisconnectCmd `cmd:"" help:"Disconnect an app."`
14+ List AppsListCmd `cmd:"" help:"List all apps with config and connection status."`
15+ Configure AppsConfigureCmd `cmd:"" help:"Save OAuth credentials (BYOC) for a provider."`
16+ Remove AppsRemoveCmd `cmd:"" help:"Remove OAuth credentials for a provider."`
17+ Disconnect AppsDisconnectCmd `cmd:"" help:"Disconnect an app connection."`
1718}
1819
1920// AppsListCmd is `onecli apps list`.
@@ -41,87 +42,97 @@ func (c *AppsListCmd) Run(out *output.Writer) error {
4142 return out .WriteFiltered (apps , c .Fields )
4243}
4344
44- // AppsConnectCmd is `onecli apps connect `.
45- type AppsConnectCmd struct {
46- Provider string `required:"" help:"Provider name (e.g. 'google ')."`
45+ // AppsConfigureCmd is `onecli apps configure `.
46+ type AppsConfigureCmd struct {
47+ Provider string `required:"" help:"Provider name (e.g. 'github', 'gmail ')."`
4748 ClientID string `required:"" name:"client-id" help:"OAuth client ID."`
4849 ClientSecret string `required:"" name:"client-secret" help:"OAuth client secret."`
4950 Json string `optional:"" help:"Raw JSON payload. Overrides individual flags."`
5051 DryRun bool `optional:"" name:"dry-run" help:"Validate the request without executing it."`
5152}
5253
53- const docsBaseURL = "https://onecli.sh/docs/guides/credential-stubs"
54-
55- // connectResult wraps the API response with onboarding guidance as structured fields.
56- type connectResult struct {
57- api.App
58- NextSteps string `json:"next_steps"`
59- DocsURL string `json:"docs_url"`
60- }
61-
62- func (c * AppsConnectCmd ) Run (out * output.Writer ) error {
63- var input api.ConnectAppInput
54+ func (c * AppsConfigureCmd ) Run (out * output.Writer ) error {
55+ var input api.ConfigAppInput
6456 if c .Json != "" {
6557 if err := json .Unmarshal ([]byte (c .Json ), & input ); err != nil {
6658 return fmt .Errorf ("invalid JSON payload: %w" , err )
6759 }
6860 } else {
69- input = api.ConnectAppInput {
70- Provider : c .Provider ,
61+ input = api.ConfigAppInput {
7162 ClientID : c .ClientID ,
7263 ClientSecret : c .ClientSecret ,
7364 }
7465 }
7566
76- if err := validate .ResourceID (input .Provider ); err != nil {
67+ if err := validate .ResourceID (c .Provider ); err != nil {
7768 return fmt .Errorf ("invalid provider: %w" , err )
7869 }
7970
8071 if c .DryRun {
8172 preview := map [string ]string {
82- "provider" : input .Provider ,
73+ "provider" : c .Provider ,
8374 "clientId" : input .ClientID ,
8475 "clientSecret" : "***" ,
8576 }
86- return out .WriteDryRun ("Would connect app" , preview )
77+ return out .WriteDryRun ("Would configure app" , preview )
8778 }
8879
8980 client , err := newClient ()
9081 if err != nil {
9182 return err
9283 }
93- app , err := client .ConnectApp (newContext (), input )
94- if err != nil {
84+ if err := client .ConfigureApp (newContext (), c .Provider , input ); err != nil {
9585 return err
9686 }
9787
98- result := connectResult {
99- App : * app ,
100- NextSteps : "Create local credential stub files using 'onecli-managed' as placeholder for all secrets. The OneCLI gateway handles real OAuth token exchange at request time." ,
101- DocsURL : docsBaseURL + "/" + input .Provider + ".md" ,
88+ return out .Write (map [string ]string {
89+ "status" : "configured" ,
90+ "provider" : c .Provider ,
91+ })
92+ }
93+
94+ // AppsRemoveCmd is `onecli apps remove`.
95+ type AppsRemoveCmd struct {
96+ Provider string `required:"" help:"Provider name (e.g. 'github', 'gmail')."`
97+ DryRun bool `optional:"" name:"dry-run" help:"Validate the request without executing it."`
98+ }
99+
100+ func (c * AppsRemoveCmd ) Run (out * output.Writer ) error {
101+ if err := validate .ResourceID (c .Provider ); err != nil {
102+ return fmt .Errorf ("invalid provider: %w" , err )
102103 }
103- return out .Write (result )
104+ if c .DryRun {
105+ return out .WriteDryRun ("Would remove app config" , map [string ]string {"provider" : c .Provider })
106+ }
107+ client , err := newClient ()
108+ if err != nil {
109+ return err
110+ }
111+ if err := client .UnconfigureApp (newContext (), c .Provider ); err != nil {
112+ return err
113+ }
114+ return out .Write (map [string ]string {"status" : "removed" , "provider" : c .Provider })
104115}
105116
106117// AppsDisconnectCmd is `onecli apps disconnect`.
107118type AppsDisconnectCmd struct {
108- ID string `required:"" help:"ID of the app connection to disconnect ."`
109- DryRun bool `optional:"" name:"dry-run" help:"Validate the request without executing it."`
119+ Provider string `required:"" help:"Provider name (e.g. 'github', 'gmail') ."`
120+ DryRun bool `optional:"" name:"dry-run" help:"Validate the request without executing it."`
110121}
111122
112123func (c * AppsDisconnectCmd ) Run (out * output.Writer ) error {
113- if err := validate .ResourceID (c .ID ); err != nil {
114- return fmt .Errorf ("invalid app ID : %w" , err )
124+ if err := validate .ResourceID (c .Provider ); err != nil {
125+ return fmt .Errorf ("invalid provider : %w" , err )
115126 }
116127 if c .DryRun {
117- return out .WriteDryRun ("Would disconnect app" , map [string ]string {"id " : c .ID })
128+ return out .WriteDryRun ("Would disconnect app" , map [string ]string {"provider " : c .Provider })
118129 }
119130 client , err := newClient ()
120131 if err != nil {
121132 return err
122133 }
123- if err := client .DisconnectApp (newContext (), c .ID ); err != nil {
134+ if err := client .DisconnectApp (newContext (), c .Provider ); err != nil {
124135 return err
125136 }
126- return out .Write (map [string ]string {"status" : "disconnected" , "id " : c .ID })
137+ return out .Write (map [string ]string {"status" : "disconnected" , "provider " : c .Provider })
127138}
0 commit comments