Skip to content

Commit

Permalink
chore: initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Ugochukwu Onyebuchi committed Mar 24, 2023
0 parents commit e2c45cf
Show file tree
Hide file tree
Showing 8 changed files with 721 additions and 0 deletions.
22 changes: 22 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/

# Go workspace file
go.work
.vscode
Empty file added LICENSE
Empty file.
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# ChatShell

ChatShell is a CLI tool that helps you find shell commands for specific tasks. It uses OpenAI's GPT-3.5 language model to generate commands based on user input.

## Installation

To use ChatShell, you will need to have Golang installed on your machine. Once you have installed Golang, you can install ChatShell using the following command:

go get github.com/yourusername/chatshell

## Configuration

ChatShell reads your OpenAI API key from a JSON configuration file named config.json. By default, it looks for this file in the $HOME/.chatshell/ directory.

Here's an example of what your configuration file should look like:

`{
"OPENAI_AUTH_TOKEN": "your_api_key_here"
}`

## Usage

To use ChatShell, simply run the ask command followed by your query. For example:

`bash
chatshell ask "How do I list all files in a directory?"`


This will return a shell command that you can use to list all files in a directory.

You can also enter chat mode by using the -c flag:


chatshell ask -c "Hello, how are you?"


This will enter chat mode and allow you to have a normal conversation with ChatGPT.

## Releases

Releases of ChatShell will be generated periodically and added to the repository. These releases will be available for download in the Releases section of this repository. To use a release, simply download the binary for your operating system and place it in a directory that is in your system's PATH.

## Contributing

If you encounter any bugs or issues with ChatShell, please feel free to create an issue in the repository. Pull requests are also welcome if you would like to contribute to the development of ChatShell.
83 changes: 83 additions & 0 deletions cmd/chat.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
Copyright © 2023 Ugochukwu Onyebuchi <[email protected]>
*/
package cmd

import (
"context"
"fmt"
"os"
"runtime"

"github.com/spf13/cobra"
"github.com/spf13/viper"
openai "github.com/sashabaranov/go-openai"
)

// askCmd represents the ask command
var askCmd = &cobra.Command{
Use: "ask [text]",
Short: "ask ChatGPT",
Long: `ask is used to ask for shell commands for a particular task`,
Args: cobra.ExactArgs(1),
Run: runAsk,
}
var authToken string

func init() {
rootCmd.AddCommand(askCmd)

askCmd.PersistentFlags().BoolP("chat", "c", false, "Chat with ChatGPT")

// Read the auth token from a configuration file
viper.SetConfigName("config")
viper.AddConfigPath("$HOME/.chatshell")
viper.SetEnvPrefix("OPENAI")
viper.AutomaticEnv()


if err := viper.ReadInConfig(); err == nil {
authToken = viper.GetString("OPENAI_AUTH_TOKEN")
} else {
fmt.Printf("Error reading configuration file: %v\n", err)
}

if authToken == "" {
fmt.Println("Error: OPENAI_AUTH_TOKEN environment variable not set")
os.Exit(1)
}
}

func runAsk(cmd *cobra.Command, args []string) {
client := openai.NewClient(authToken)
osType := runtime.GOOS
shell := os.Getenv("SHELL")
content := ""

chatMode, _ := cmd.Flags().GetBool("chat")

if !chatMode {
content = fmt.Sprintf(`You are a very helpful shell assistant that gives users only shell commands to achieve a task, just give out only the shell command(s), and nothing else, no preamble, greetings or explanation please, just the shell command. When you can't find a command for a query/prompt/greeting respond strictly with "Sorry I can't seem to find a command for that". Start now: "%v in %v os using %v shell"`, args[0], osType, shell)
} else {
content = args[0]
}

resp, err := client.CreateChatCompletion(
context.Background(),
openai.ChatCompletionRequest{
Model: openai.GPT3Dot5Turbo,
Messages: []openai.ChatCompletionMessage{
{
Role: openai.ChatMessageRoleUser,
Content: content,
},
},
},
)

if err != nil {
fmt.Printf("ChatCompletion error: %v\n", err)
}

fmt.Println(resp.Choices[0].Message.Content)
}
47 changes: 47 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
Copyright © 2023 Ugochukwu Onyebuchi <[email protected]>
*/
package cmd

import (
"os"

"github.com/spf13/cobra"
)



// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "chatshell",
Short: "ChatGPT in the shell",
Long: `Access the power of ChatGPT right in the shell,
ask for shell commands or just a normal chat`,
// Uncomment the following line if your bare application
// has an action associated with it:
// Run: func(cmd *cobra.Command, args []string) { },
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
}

func init() {
// Here you will define your flags and configuration settings.
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.

// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.chatshell.json)")

// Cobra also supports local flags, which will only run
// when this action is called directly.
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}


27 changes: 27 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module github.com/coledrain/chatshell

go 1.19

require (
github.com/sashabaranov/go-openai v1.5.7
github.com/spf13/cobra v1.6.1
github.com/spf13/viper v1.15.0
)

require (
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/spf13/afero v1.9.3 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/text v0.5.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading

0 comments on commit e2c45cf

Please sign in to comment.