]> git.giacomolli.uk - onechat/blob - main.go
Stamp daemon log lines only outside the journal
[onechat] / main.go
1 package main
2
3 import (
4 "context"
5 "fmt"
6 "os"
7 "os/signal"
8 "strings"
9 "syscall"
10 )
11
12 // usage is the help text of the command.
13 const usage = `Usage: onechat [COMMAND]
14
15 Commands:
16 chat talk to the agent in this terminal (default)
17 daemon run the agent, Telegram, and WhatsApp
18 login log in to ChatGPT with a device code
19 probe LOG COUNT [BUILDS] measure the compactor on a log, with real calls
20 help show this help
21
22 Chat needs a running daemon. ONECHAT_DIR sets the data directory.
23 `
24
25 func main() {
26 err := run()
27 if err != nil {
28 fmt.Fprintln(os.Stderr, "onechat:", err)
29 os.Exit(1)
30 }
31 }
32
33 func run() error {
34 ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
35 defer cancel()
36
37 args := os.Args[1:]
38 switch {
39 case len(args) == 1 && (args[0] == "help" || args[0] == "--help" || args[0] == "-h"):
40 _, err := fmt.Print(usage)
41 if err != nil {
42 return err
43 }
44 case len(args) == 1 && args[0] == "login":
45 err := chatgptLogin(ctx, os.Stdout)
46 if err != nil {
47 return err
48 }
49 // A signal is the normal stop of the daemon and the client, so their
50 // result does not include ctx.Err().
51 case len(args) == 1 && args[0] == "daemon":
52 return daemon(ctx, os.Stdout)
53 case len(args) == 0 || len(args) == 1 && args[0] == "chat":
54 return terminal(ctx, os.Stdin, os.Stdout)
55 case len(args) > 0 && args[0] == "probe":
56 err := probe(ctx, args[1:], os.Stdout)
57 if err != nil {
58 return err
59 }
60 default:
61 return fmt.Errorf("unknown command %q\n\n%s", strings.Join(args, " "), strings.TrimSuffix(usage, "\n"))
62 }
63
64 return ctx.Err()
65 }