]> git.giacomolli.uk - onechat/blob - command.go
fefb662da21039a37d44f0ccaca750abe2d6c0f7
[onechat] / command.go
1 package main
2
3 import (
4 "context"
5 "fmt"
6 "os"
7 "strings"
8 )
9
10 // usage is the help text of the command.
11 const usage = `Usage: onechat [COMMAND]
12
13 Commands:
14 backup FILE archive the running daemon data
15 restore FILE restore into an empty data directory
16 chat talk to the agent in this terminal (default)
17 daemon run the agent, Telegram, and WhatsApp
18 import [-n] [--agent NAME] ZIP...
19 import WhatsApp history (stop the daemon first)
20 -n print the plan without model calls
21 --agent NAME import into an existing direct child (default: root)
22 login log in to ChatGPT with a device code
23 probe LOG COUNT [BUILDS] measure the compactor on a log, with real calls
24 version show the build version
25 help show this help
26
27 Chat needs a running daemon. ONECHAT_DIR sets the data directory.
28 In chat, /image PATH [caption] sends a JPEG, PNG, or WebP image up to 20 MB.
29 Quote PATH with single or double quotes when it contains spaces.
30 `
31
32 // version is set by the package build and stays dev for direct Go builds.
33 var version = "dev"
34
35 // parseCommand dispatches args with ctx and prints command output.
36 func parseCommand(ctx context.Context, args []string) error {
37 switch {
38 case len(args) == 1 && (args[0] == "help" || args[0] == "--help" || args[0] == "-h"):
39 _, err := fmt.Print(usage)
40 if err != nil {
41 return fmt.Errorf("write command help: %w", err)
42 }
43 case len(args) == 1 && args[0] == "version":
44 _, err := fmt.Println(version)
45 if err != nil {
46 return fmt.Errorf("write build version: %w", err)
47 }
48 case len(args) == 1 && args[0] == "login":
49 err := chatgptLogin(ctx, os.Stdout)
50 if err != nil {
51 return fmt.Errorf("log in: %w", err)
52 }
53
54 // A signal is the normal stop of the daemon and the client, so their
55 // result does not include ctx.Err().
56 case len(args) == 1 && args[0] == "daemon":
57 err := daemon(ctx, os.Stdout)
58 if err != nil {
59 return fmt.Errorf("run daemon: %w", err)
60 }
61
62 return nil
63 case len(args) == 0 || len(args) == 1 && args[0] == "chat":
64 err := terminal(ctx, os.Stdin, os.Stdout)
65 if err != nil {
66 return fmt.Errorf("run terminal: %w", err)
67 }
68
69 return nil
70 case len(args) == 2 && args[0] == "backup":
71 err := backup(ctx, args[1], os.Stdout)
72 if err != nil {
73 return fmt.Errorf("run backup: %w", err)
74 }
75
76 return nil
77 case len(args) == 2 && args[0] == "restore":
78 err := restore(ctx, args[1], os.Stdout)
79 if err != nil {
80 return fmt.Errorf("run restore: %w", err)
81 }
82
83 return nil
84 case len(args) > 0 && args[0] == "import":
85 err := whatsappImport(ctx, args[1:], os.Stdout)
86 if err != nil {
87 return fmt.Errorf("import WhatsApp history: %w", err)
88 }
89
90 return nil
91 case len(args) > 0 && args[0] == "probe":
92 err := probe(ctx, args[1:], os.Stdout)
93 if err != nil {
94 return fmt.Errorf("run probe: %w", err)
95 }
96 default:
97 return fmt.Errorf("unknown command %q\n\n%s", strings.Join(args, " "), strings.TrimSuffix(usage, "\n"))
98 }
99
100 return ctx.Err()
101 }