Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ builds:
env:
- CGO_ENABLED=0
ldflags:
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser -X main.uptraceDsn={{.Env.UPTRACE_DSN}} -X main.ppEndpoint={{.Env.PP_ENDPOINT}} -X main.ppToken={{.Env.PP_TOKEN}}
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser -X main.uptraceDsn={{.Env.UPTRACE_DSN}}
- binary: "shelltime"
id: mt-mac
goos:
Expand All @@ -26,7 +26,7 @@ builds:
env:
- CGO_ENABLED=0
ldflags:
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser -X main.uptraceDsn={{.Env.UPTRACE_DSN}} -X main.ppEndpoint={{.Env.PP_ENDPOINT}} -X main.ppToken={{.Env.PP_TOKEN}}
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser -X main.uptraceDsn={{.Env.UPTRACE_DSN}}
- binary: "shelltime-daemon"
id: mt-daemon-linux
goos:
Expand All @@ -38,7 +38,7 @@ builds:
env:
- CGO_ENABLED=0
ldflags:
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser -X main.uptraceDsn={{.Env.UPTRACE_DSN}} -X main.ppEndpoint={{.Env.PP_ENDPOINT}} -X main.ppToken={{.Env.PP_TOKEN}}
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser -X main.uptraceDsn={{.Env.UPTRACE_DSN}}
- binary: "shelltime-daemon"
id: mt-daemon-mac
goos:
Expand All @@ -50,7 +50,7 @@ builds:
env:
- CGO_ENABLED=0
ldflags:
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser -X main.uptraceDsn={{.Env.UPTRACE_DSN}} -X main.ppEndpoint={{.Env.PP_ENDPOINT}} -X main.ppToken={{.Env.PP_TOKEN}}
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser -X main.uptraceDsn={{.Env.UPTRACE_DSN}}
archives:
- format: tar.gz
id: mt-common
Expand Down
14 changes: 3 additions & 11 deletions cmd/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ var (
commit = "none"
date = "unknown"
uptraceDsn = ""

ppEndpoint = ""
ppToken = ""
)

func main() {
Expand Down Expand Up @@ -64,14 +61,9 @@ func main() {
model.InjectVar(version)
commands.InjectVar(version, configService)

// Initialize AI service if configured
if ppEndpoint != "" && ppToken != "" {
aiService := model.NewAIService(model.AIServiceConfig{
Endpoint: ppEndpoint,
Token: ppToken,
Timeout: 60 * time.Second,
UserToken: cfg.Token,
})
// Initialize AI service if user has a token configured
if cfg.Token != "" {
aiService := model.NewAIService()
commands.InjectAIService(aiService)
}
app := cli.NewApp()
Expand Down
3 changes: 0 additions & 3 deletions cmd/daemon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ var (
commit = "none"
date = "unknown"
uptraceDsn = ""

ppEndpoint = ""
ppToken = ""
)

func main() {
Expand Down
87 changes: 46 additions & 41 deletions commands/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,31 @@ func commandQuery(c *cli.Context) error {

// Check if AI service is initialized
if aiService == nil {
color.Red.Println("AI service is not configured")
color.Red.Println("AI service is not configured")
return fmt.Errorf("AI service is not available")
}

// Get the query from command arguments
args := c.Args().Slice()
if len(args) == 0 {
color.Red.Println("Please provide a query")
color.Red.Println("Please provide a query")
return fmt.Errorf("query is required")
}

query := strings.Join(args, " ")

// Read config to get endpoint/token
cfg, err := configService.ReadConfigFile(ctx)
if err != nil {
color.Red.Printf("Failed to read config: %v\n", err)
return fmt.Errorf("failed to read config: %w", err)
}

endpoint := model.Endpoint{
APIEndpoint: cfg.APIEndpoint,
Token: cfg.Token,
}

// Get system context
systemContext, err := getSystemContext(query)
if err != nil {
Expand All @@ -59,34 +71,40 @@ func commandQuery(c *cli.Context) error {
BaseColor: stloader.RGB{R: 100, G: 180, B: 255},
})
l.Start()
defer l.Stop()

// skip userId for now
userId := ""
var result strings.Builder
firstToken := true

// Query the AI
newCommand, err := aiService.QueryCommand(ctx, systemContext, userId)
if err != nil {
// Stream the AI response
err = aiService.QueryCommandStream(ctx, systemContext, endpoint, func(token string) {
if firstToken {
l.Stop()
color.Green.Printf("Suggested command:\n")
firstToken = false
}
fmt.Print(token)
result.WriteString(token)
})

if firstToken {
// No tokens received, stop loader
l.Stop()
color.Red.Printf("❌ Failed to query AI: %v\n", err)
}

if err != nil {
if !firstToken {
fmt.Println()
}
color.Red.Printf("Failed to query AI: %v\n", err)
return err
}

l.Stop()
// Print newline after streaming
fmt.Println()

// Trim the command
newCommand = strings.TrimSpace(newCommand)
newCommand := strings.TrimSpace(result.String())

// Check auto-run configuration
cfg, err := configService.ReadConfigFile(ctx)
if err != nil {
slog.Warn("Failed to read config for auto-run check", slog.Any("err", err))
// If can't read config, just display the command
displayCommand(newCommand)
return nil
}

// Check if AI auto-run is configured
if cfg.AI != nil && (cfg.AI.Agent.View || cfg.AI.Agent.Edit || cfg.AI.Agent.Delete) {
// Classify the command
actionType := model.ClassifyCommand(newCommand)
Expand All @@ -105,9 +123,7 @@ func commandQuery(c *cli.Context) error {
if canAutoRun {
// For delete commands, add an extra confirmation
if actionType == model.ActionDelete {
color.Green.Printf("💡 Suggested command:\n")
color.Cyan.Printf("%s\n\n", newCommand)
color.Yellow.Printf("⚠️ This is a DELETE command. Are you sure you want to run it? (y/N): ")
color.Yellow.Printf("This is a DELETE command. Are you sure you want to run it? (y/N): ")

var response string
fmt.Scanln(&response)
Expand All @@ -116,26 +132,20 @@ func commandQuery(c *cli.Context) error {
return nil
}
} else {
// Display the command and auto-run it
color.Green.Printf("💡 Auto-running command:\n")
color.Cyan.Printf("%s\n\n", newCommand)
color.Green.Printf("Auto-running command...\n")
}

// Execute the command
return executeCommand(ctx, newCommand)
} else {
// Display command with info about why it's not auto-running
displayCommand(newCommand)
if shouldShowTips(cfg) && actionType != model.ActionOther {
color.Yellow.Printf("\n💡 Tip: This is a %s command. Enable 'ai.agent.%s' in your config to auto-run it.\n",
color.Yellow.Printf("\nTip: This is a %s command. Enable 'ai.agent.%s' in your config to auto-run it.\n",
actionType, actionType)
}
}
} else {
// No auto-run configured, display the command and tip
displayCommand(newCommand)
if shouldShowTips(cfg) {
color.Yellow.Printf("\n💡 Tip: You can enable AI auto-run in your config file:\n")
color.Yellow.Printf("\nTip: You can enable AI auto-run in your config file:\n")
color.Yellow.Printf(" [ai.agent]\n")
color.Yellow.Printf(" view = true # Auto-run view commands\n")
color.Yellow.Printf(" edit = true # Auto-run edit commands\n")
Expand All @@ -146,11 +156,6 @@ func commandQuery(c *cli.Context) error {
return nil
}

func displayCommand(command string) {
color.Green.Printf("💡 Suggested command:\n")
color.Cyan.Printf("%s\n", command)
}

func shouldShowTips(cfg model.ShellTimeConfig) bool {
// If ShowTips is not set (nil), default to true
if cfg.AI == nil || cfg.AI.ShowTips == nil {
Expand All @@ -176,14 +181,14 @@ func executeCommand(ctx context.Context, command string) error {

// Run the command
if err := cmd.Run(); err != nil {
color.Red.Printf("\n❌ Command failed: %v\n", err)
color.Red.Printf("\nCommand failed: %v\n", err)
return err
}

return nil
}

func getSystemContext(query string) (model.PPPromptGuessNextPromptVariables, error) {
func getSystemContext(query string) (model.CommandSuggestVariables, error) {
// Get shell information
shell := os.Getenv("SHELL")
if shell == "" {
Expand All @@ -198,7 +203,7 @@ func getSystemContext(query string) (model.PPPromptGuessNextPromptVariables, err
// Get OS information
osInfo := runtime.GOOS

return model.PPPromptGuessNextPromptVariables{
return model.CommandSuggestVariables{
Shell: shell,
Os: osInfo,
Query: query,
Expand Down
Loading