]> git.giacomolli.uk - onechat/blobdiff - main.go
Keep time limits with their operations
[onechat] / main.go
diff --git a/main.go b/main.go
index 04b06770977eac566ca0599a0766f4864b095bbb..10ac995a9555b2885070e2d8baf77a1eed30fa4f 100644 (file)
--- a/main.go
+++ b/main.go
@@ -1,3 +1,4 @@
+// Command onechat runs the agent daemon and its terminal client.
 package main
 
 import (
 package main
 
 import (
@@ -13,15 +14,27 @@ import (
 const usage = `Usage: onechat [COMMAND]
 
 Commands:
 const usage = `Usage: onechat [COMMAND]
 
 Commands:
+  backup FILE              archive the running daemon data
+  restore FILE             restore into an empty data directory
   chat                     talk to the agent in this terminal (default)
   daemon                   run the agent, Telegram, and WhatsApp
   chat                     talk to the agent in this terminal (default)
   daemon                   run the agent, Telegram, and WhatsApp
+  import [-n] [--agent NAME] ZIP...
+                           import WhatsApp history (stop the daemon first)
+    -n                     print the plan without model calls
+    --agent NAME           import into an existing direct child (default: root)
   login                    log in to ChatGPT with a device code
   probe LOG COUNT [BUILDS] measure the compactor on a log, with real calls
   login                    log in to ChatGPT with a device code
   probe LOG COUNT [BUILDS] measure the compactor on a log, with real calls
+  version                  show the build version
   help                     show this help
 
 Chat needs a running daemon. ONECHAT_DIR sets the data directory.
   help                     show this help
 
 Chat needs a running daemon. ONECHAT_DIR sets the data directory.
+In chat, /image PATH [caption] sends a JPEG, PNG, or WebP image up to 20 MB.
+Quote PATH with single or double quotes when it contains spaces.
 `
 
 `
 
+// version is set by the package build and stays dev for direct Go builds.
+var version = "dev"
+
 func main() {
        err := run()
        if err != nil {
 func main() {
        err := run()
        if err != nil {
@@ -39,19 +52,31 @@ func run() error {
        case len(args) == 1 && (args[0] == "help" || args[0] == "--help" || args[0] == "-h"):
                _, err := fmt.Print(usage)
                if err != nil {
        case len(args) == 1 && (args[0] == "help" || args[0] == "--help" || args[0] == "-h"):
                _, err := fmt.Print(usage)
                if err != nil {
-                       return err
+                       return fmt.Errorf("write command help: %w", err)
+               }
+       case len(args) == 1 && args[0] == "version":
+               _, err := fmt.Println(version)
+               if err != nil {
+                       return fmt.Errorf("write build version: %w", err)
                }
        case len(args) == 1 && args[0] == "login":
                err := chatgptLogin(ctx, os.Stdout)
                if err != nil {
                        return err
                }
                }
        case len(args) == 1 && args[0] == "login":
                err := chatgptLogin(ctx, os.Stdout)
                if err != nil {
                        return err
                }
+
        // A signal is the normal stop of the daemon and the client, so their
        // result does not include ctx.Err().
        case len(args) == 1 && args[0] == "daemon":
                return daemon(ctx, os.Stdout)
        case len(args) == 0 || len(args) == 1 && args[0] == "chat":
                return terminal(ctx, os.Stdin, os.Stdout)
        // A signal is the normal stop of the daemon and the client, so their
        // result does not include ctx.Err().
        case len(args) == 1 && args[0] == "daemon":
                return daemon(ctx, os.Stdout)
        case len(args) == 0 || len(args) == 1 && args[0] == "chat":
                return terminal(ctx, os.Stdin, os.Stdout)
+       case len(args) == 2 && args[0] == "backup":
+               return backup(ctx, args[1], os.Stdout)
+       case len(args) == 2 && args[0] == "restore":
+               return restore(ctx, args[1], os.Stdout)
+       case len(args) > 0 && args[0] == "import":
+               return whatsappImport(ctx, args[1:], os.Stdout)
        case len(args) > 0 && args[0] == "probe":
                err := probe(ctx, args[1:], os.Stdout)
                if err != nil {
        case len(args) > 0 && args[0] == "probe":
                err := probe(ctx, args[1:], os.Stdout)
                if err != nil {