diff --git a/plugins/cohere/co.go b/plugins/cohere/co.go new file mode 100644 index 000000000..3bdcf2e6d --- /dev/null +++ b/plugins/cohere/co.go @@ -0,0 +1,27 @@ +package cohere + +import ( + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/needsauth" + "github.com/1Password/shell-plugins/sdk/schema" + "github.com/1Password/shell-plugins/sdk/schema/credname" +) + +func CohereCLI() schema.Executable { + return schema.Executable{ + Name: "Cohere CLI", + Runs: []string{"co"}, + DocsURL: sdk.URL("https://docs.cohere.com/reference/command"), + NeedsAuth: needsauth.IfAll( + needsauth.NotForHelpOrVersion(), + needsauth.NotWithoutArgs(), + needsauth.NotWhenContainsArgs("config"), + needsauth.NotWhenContainsArgs("ping"), + ), + Uses: []schema.CredentialUsage{ + { + Name: credname.Credentials, + }, + }, + } +} diff --git a/plugins/cohere/credentials.go b/plugins/cohere/credentials.go new file mode 100644 index 000000000..ff4c1256c --- /dev/null +++ b/plugins/cohere/credentials.go @@ -0,0 +1,110 @@ +package cohere + +import ( + "context" + "encoding/json" + + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/importer" + "github.com/1Password/shell-plugins/sdk/provision" + "github.com/1Password/shell-plugins/sdk/schema" + "github.com/1Password/shell-plugins/sdk/schema/credname" + "github.com/1Password/shell-plugins/sdk/schema/fieldname" +) + +func Credentials() schema.CredentialType { + return schema.CredentialType{ + Name: credname.Credentials, + DocsURL: sdk.URL("https://docs.cohere.com/reference/config"), + ManagementURL: sdk.URL("https://dashboard.cohere.ai/"), + Fields: []schema.CredentialField{ + { + Name: fieldname.JWT, + MarkdownDescription: "JWT used to authenticate to Cohere stored in disk.", + Secret: true, + }, + { + Name: fieldname.Email, + MarkdownDescription: "Email used to authenticate to Cohere.", + Optional: true, + }, + { + Name: fieldname.URL, + MarkdownDescription: "URL of the operator server", + Optional: true, + }, + }, + DefaultProvisioner: provision.TempFile( + cohereJSON, + provision.AtFixedPath("~/.command/config")), + Importer: importer.TryAll( + TryCohereConfigFile(), + )} +} + +func TryCohereConfigFile() sdk.Importer { + return importer.TryFile("~/.command/config", func(ctx context.Context, contents importer.FileContents, in sdk.ImportInput, out *sdk.ImportAttempt) { + var config Config + if err := contents.ToJSON(&config); err != nil { + out.AddError(err) + return + } + + if config.Contexts[config.CurrentURL].JWT == "" { + return + } + + out.AddCandidate(sdk.ImportCandidate{ + Fields: map[sdk.FieldName]string{ + fieldname.URL: config.CurrentURL, + fieldname.JWT: config.Contexts[config.CurrentURL].JWT, + fieldname.Email: config.Contexts[config.CurrentURL].Email, + }, + }) + }) +} + +func cohereJSON(in sdk.ProvisionInput) ([]byte, error) { + var currentURL, jwt, email string + + if value, ok := in.ItemFields[fieldname.JWT]; ok { + jwt = value + } else { + return nil, nil + } + + if value, ok := in.ItemFields[fieldname.URL]; ok { + currentURL = value + } + + if value, ok := in.ItemFields[fieldname.Email]; ok { + email = value + } + + data := Config{ + CurrentURL: currentURL, + Contexts: map[string]APISettings{ + currentURL: { + JWT: jwt, + Email: email, + }, + }, + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, err + + } + return []byte(jsonData), nil +} + +type Config struct { + CurrentURL string `json:"CurrentURL"` + Contexts map[string]APISettings `json:"Contexts"` +} + +type APISettings struct { + JWT string `json:"JWT"` + Email string `json:"Email"` +} diff --git a/plugins/cohere/credentials_test.go b/plugins/cohere/credentials_test.go new file mode 100644 index 000000000..b8ab23bfd --- /dev/null +++ b/plugins/cohere/credentials_test.go @@ -0,0 +1,48 @@ +package cohere + +import ( + "testing" + + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/plugintest" + "github.com/1Password/shell-plugins/sdk/schema/fieldname" +) + +func TestCredentialsProvisioner(t *testing.T) { + plugintest.TestProvisioner(t, Credentials().DefaultProvisioner, map[string]plugintest.ProvisionCase{ + "temp file": { + ItemFields: map[sdk.FieldName]string{ + fieldname.JWT: "PLEzI1N--EXAMPLE", + fieldname.URL: "https://api.os.cohere.ai", + fieldname.Email: "wendy@appleseed.com", + }, + ExpectedOutput: sdk.ProvisionOutput{ + Files: map[string]sdk.OutputFile{ + "~/.command/config": { + Contents: []byte(plugintest.LoadFixture(t, "config")), + }, + }, + }, + }, + }) +} + +func TestCredentialsImporter(t *testing.T) { + plugintest.TestImporter(t, Credentials().Importer, map[string]plugintest.ImportCase{ + + "config file": { + Files: map[string]string{ + "~/.command/config": plugintest.LoadFixture(t, "config"), + }, + ExpectedCandidates: []sdk.ImportCandidate{ + { + Fields: map[sdk.FieldName]string{ + fieldname.JWT: "PLEzI1N--EXAMPLE", + fieldname.URL: "https://api.os.cohere.ai", + fieldname.Email: "wendy@appleseed.com", + }, + }, + }, + }, + }) +} diff --git a/plugins/cohere/plugin.go b/plugins/cohere/plugin.go new file mode 100644 index 000000000..bccfa2cbb --- /dev/null +++ b/plugins/cohere/plugin.go @@ -0,0 +1,22 @@ +package cohere + +import ( + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/schema" +) + +func New() schema.Plugin { + return schema.Plugin{ + Name: "cohere", + Platform: schema.PlatformInfo{ + Name: "Cohere", + Homepage: sdk.URL("https://cohere.com"), + }, + Credentials: []schema.CredentialType{ + Credentials(), + }, + Executables: []schema.Executable{ + CohereCLI(), + }, + } +} diff --git a/plugins/cohere/test-fixtures/config b/plugins/cohere/test-fixtures/config new file mode 100644 index 000000000..b0ebe4809 --- /dev/null +++ b/plugins/cohere/test-fixtures/config @@ -0,0 +1 @@ +{"CurrentURL":"https://api.os.cohere.ai","Contexts":{"https://api.os.cohere.ai":{"JWT":"PLEzI1N--EXAMPLE","Email":"wendy@appleseed.com"}}} \ No newline at end of file