]> git.giacomolli.uk - onechat/commitdiff
Open the chat when no command is given
authorAnderson A. Giacomolli <redacted>
Mon, 9 Nov 2026 13:13:51 +0000 (10:13 -0300)
committerAnderson A. Giacomolli <redacted>
Mon, 9 Nov 2026 13:13:51 +0000 (10:13 -0300)
onechat with no command opens the terminal chat, as onechat chat does,
because the chat is the command of daily use once the daemon runs as a
service. A start of the daemon stays explicit, so a second daemon does
not start by accident. onechat help, --help, and -h print the commands,
and an unknown command prints the error and the same help. The install
check runs onechat help in place of the bare command.

README.rst
main.go
nix/package.nix
terminal.go

index 09e048cd2f951d1b5f52379ec6f277190d8d5a72..9b9c4890b866441e48686c5d0602060031c34964 100644 (file)
@@ -73,7 +73,10 @@ Start the daemon, and then the client in another terminal:
 .. code:: console
 
    onechat daemon
-   onechat chat
+   onechat
+
+``onechat`` with no command is the same as ``onechat chat``. ``onechat
+help`` lists the commands.
 
 The daemon owns the root agent in ``agent/`` in the data directory and
 listens on the Unix socket ``onechat.sock`` there. In the client, each
@@ -192,7 +195,7 @@ the service:
    systemctl --user daemon-reload
    systemctl --user enable --now onechat.service
    systemctl --user status onechat.service
-   ONECHAT_DIR=DATA_DIR ./result-service/bin/onechat chat
+   ONECHAT_DIR=DATA_DIR ./result-service/bin/onechat
    journalctl --user -u onechat.service -f
 
 After a pull, update the package and unit with:
diff --git a/main.go b/main.go
index f2c263dc9600d83153c8424d0f34310e29abc9ea..04b06770977eac566ca0599a0766f4864b095bbb 100644 (file)
--- a/main.go
+++ b/main.go
@@ -9,6 +9,19 @@ import (
        "syscall"
 )
 
+// usage is the help text of the command.
+const usage = `Usage: onechat [COMMAND]
+
+Commands:
+  chat                     talk to the agent in this terminal (default)
+  daemon                   run the agent, Telegram, and WhatsApp
+  login                    log in to ChatGPT with a device code
+  probe LOG COUNT [BUILDS] measure the compactor on a log, with real calls
+  help                     show this help
+
+Chat needs a running daemon. ONECHAT_DIR sets the data directory.
+`
+
 func main() {
        err := run()
        if err != nil {
@@ -23,8 +36,8 @@ func run() error {
 
        args := os.Args[1:]
        switch {
-       case len(args) == 0:
-               _, err := fmt.Println("onechat")
+       case len(args) == 1 && (args[0] == "help" || args[0] == "--help" || args[0] == "-h"):
+               _, err := fmt.Print(usage)
                if err != nil {
                        return err
                }
@@ -37,7 +50,7 @@ func run() error {
        // result does not include ctx.Err().
        case len(args) == 1 && args[0] == "daemon":
                return daemon(ctx, os.Stdout)
-       case len(args) == 1 && args[0] == "chat":
+       case len(args) == 0 || len(args) == 1 && args[0] == "chat":
                return terminal(ctx, os.Stdin, os.Stdout)
        case len(args) > 0 && args[0] == "probe":
                err := probe(ctx, args[1:], os.Stdout)
@@ -45,7 +58,7 @@ func run() error {
                        return err
                }
        default:
-               return fmt.Errorf("unknown command %q", strings.Join(args, " "))
+               return fmt.Errorf("unknown command %q\n\n%s", strings.Join(args, " "), strings.TrimSuffix(usage, "\n"))
        }
 
        return ctx.Err()
index 729cf5347375056d2b6b91e13ac29ac713adf86d..b38dcc05783e8b2c95b41c0bbfe28b647346d1e7 100644 (file)
@@ -23,7 +23,7 @@ buildGoModule {
   doInstallCheck = true;
   installCheckPhase = ''
     runHook preInstallCheck
-    test "$("$out/bin/onechat")" = onechat
+    [[ "$("$out/bin/onechat" help)" == "Usage: onechat "* ]]
     runHook postInstallCheck
   '';
 
index 45a1a69dec7cef489dabead041b4f1e6a6ac51fa..876986a4479f38a679d9d2dc586be8a85164ac15 100644 (file)
@@ -18,12 +18,12 @@ const terminalResultLines = 10
 // errTerminalDaemonClosed tells that the daemon closed the connection.
 var errTerminalDaemonClosed = errors.New("the daemon closed the connection")
 
-// terminal runs "onechat chat": the terminal client of the daemon. Each line of
-// input is a user message, the line /stop interrupts the running turn, the line
-// /stop NAME stops the subagent NAME, and a line that starts with /whatsapp is
-// a WhatsApp command. The client shows the replies, the tool calls, and their
-// results as they happen. It ends at the end of the input or when the daemon
-// closes the connection.
+// terminal runs "onechat" and "onechat chat": the terminal client of the
+// daemon. Each line of input is a user message, the line /stop interrupts the
+// running turn, the line /stop NAME stops the subagent NAME, and a line that
+// starts with /whatsapp is a WhatsApp command. The client shows the replies,
+// the tool calls, and their results as they happen. It ends at the end of the
+// input or when the daemon closes the connection.
 func terminal(ctx context.Context, in io.Reader, out io.Writer) error {
        dir, err := dataDir()
        if err != nil {