🛟 Updated.
d56bc20 parent: a38f300 modified
.tickets/issues/0117-make-possible-the-usage-of-mm-tui-like-mm-tui-an.yaml +30 -4 | @@ -1,14 +1,40 @@ | ||
| 1 | 1 | # Managed by IssueSpec. Hand edits are welcome; keep the schema valid. |
| 2 | 2 | id: 117 |
| 3 | 3 | title: make possible the usage of mm tui like mm --tui and mm acp like mm --acp |
| 4 | -state: open | |
| 4 | +state: closed | |
| 5 | 5 | author: |
| 6 | 6 | name: k33g |
| 7 | 7 | email: ph.charriere@gmail.com |
| 8 | 8 | createdAt: 2026-10-21T11:39:39.289Z |
| 9 | -updatedAt: 2026-10-21T11:44:38.778Z | |
| 9 | +updatedAt: 2026-10-21T23:45:00.000Z | |
| 10 | 10 | labels: [] |
| 11 | 11 | milestone: v0.9.0 |
| 12 | -body: "" | |
| 12 | +body: | | |
| 13 | + `mm tui` should do what `mm -tui` does, and `mm acp` what `mm -acp` does — | |
| 14 | + the modes as words, like `mm init`. | |
| 13 | 15 | tasks: [] |
| 14 | -comments: [] | |
| 16 | +comments: | |
| 17 | + - id: 1 | |
| 18 | + author: | |
| 19 | + name: k33g | |
| 20 | + email: ph.charriere@gmail.com | |
| 21 | + createdAt: 2026-10-21T23:30:00.000Z | |
| 22 | + body: | | |
| 23 | + Done (2026-10-21, on main, uncommitted). | |
| 24 | + - `mm --tui` and `mm --acp` already worked: Go's flag package takes | |
| 25 | + `-x` and `--x` alike. What was missing was the words. | |
| 26 | + - main.go: modeWordAsFlag rewrites a FIRST argument `tui` / `acp` into | |
| 27 | + `-tui` / `-acp` before the flags are read, so the rest of main is | |
| 28 | + unchanged and every other flag still works (`mm tui -config a.yaml`, | |
| 29 | + `mm acp agent.yaml`). Anywhere else the word is not special: | |
| 30 | + `mm agent.yaml tui` still names two config files. A config file | |
| 31 | + called tui or acp is now reached as ./tui or with -config (same | |
| 32 | + rule as init since ticket 97). | |
| 33 | + - -h: both flags say "(same as: mm tui)" / "(same as: mm acp)" | |
| 34 | + (backticks would have been read by the flag package as the | |
| 35 | + argument's name). | |
| 36 | + - Test: TestModeWordAsFlag (init_assemble_test.go). Live: `mm acp` | |
| 37 | + and `mm -acp` give the same initialize answer; `mm tui` piped falls | |
| 38 | + back to the line mode like `mm -tui`. | |
| 39 | + - Docs EN+FR: reference/cli (invocation lines, -acp, -tui and <path> | |
| 40 | + rows). | |
| @@ -1,14 +1,40 @@ | |||
| 1 | # Managed by IssueSpec. Hand edits are welcome; keep the schema valid. | 1 | # Managed by IssueSpec. Hand edits are welcome; keep the schema valid. |
| 2 | id: 117 | 2 | id: 117 |
| 3 | title: make possible the usage of mm tui like mm --tui and mm acp like mm --acp | 3 | title: make possible the usage of mm tui like mm --tui and mm acp like mm --acp |
| 4 | -state: open | 4 | +state: closed |
| 5 | author: | 5 | author: |
| 6 | name: k33g | 6 | name: k33g |
| 7 | email: ph.charriere@gmail.com | 7 | email: ph.charriere@gmail.com |
| 8 | createdAt: 2026-10-21T11:39:39.289Z | 8 | createdAt: 2026-10-21T11:39:39.289Z |
| 9 | -updatedAt: 2026-10-21T11:44:38.778Z | 9 | +updatedAt: 2026-10-21T23:45:00.000Z |
| 10 | labels: [] | 10 | labels: [] |
| 11 | milestone: v0.9.0 | 11 | milestone: v0.9.0 |
| 12 | -body: "" | 12 | +body: | |
| 13 | + `mm tui` should do what `mm -tui` does, and `mm acp` what `mm -acp` does — | ||
| 14 | + the modes as words, like `mm init`. | ||
| 13 | tasks: [] | 15 | tasks: [] |
| 14 | -comments: [] | 16 | +comments: |
| 17 | + - id: 1 | ||
| 18 | + author: | ||
| 19 | + name: k33g | ||
| 20 | + email: ph.charriere@gmail.com | ||
| 21 | + createdAt: 2026-10-21T23:30:00.000Z | ||
| 22 | + body: | | ||
| 23 | + Done (2026-10-21, on main, uncommitted). | ||
| 24 | + - `mm --tui` and `mm --acp` already worked: Go's flag package takes | ||
| 25 | + `-x` and `--x` alike. What was missing was the words. | ||
| 26 | + - main.go: modeWordAsFlag rewrites a FIRST argument `tui` / `acp` into | ||
| 27 | + `-tui` / `-acp` before the flags are read, so the rest of main is | ||
| 28 | + unchanged and every other flag still works (`mm tui -config a.yaml`, | ||
| 29 | + `mm acp agent.yaml`). Anywhere else the word is not special: | ||
| 30 | + `mm agent.yaml tui` still names two config files. A config file | ||
| 31 | + called tui or acp is now reached as ./tui or with -config (same | ||
| 32 | + rule as init since ticket 97). | ||
| 33 | + - -h: both flags say "(same as: mm tui)" / "(same as: mm acp)" | ||
| 34 | + (backticks would have been read by the flag package as the | ||
| 35 | + argument's name). | ||
| 36 | + - Test: TestModeWordAsFlag (init_assemble_test.go). Live: `mm acp` | ||
| 37 | + and `mm -acp` give the same initialize answer; `mm tui` piped falls | ||
| 38 | + back to the line mode like `mm -tui`. | ||
| 39 | + - Docs EN+FR: reference/cli (invocation lines, -acp, -tui and <path> | ||
| 40 | + rows). | ||
modified
docs/en/reference/cli.md +5 -3 | @@ -9,14 +9,16 @@ mm [-config <path>] [-acp] [-tui] [-prompt <text>|-p <text>] [--version] [--abou | ||
| 9 | 9 | mm [-config <path>] --ask <agent> [-p <question>] (question on stdin when -p is absent) |
| 10 | 10 | mm [-config <path>] --ask-with-context <agent> [-p <question>] (context on stdin) |
| 11 | 11 | mm init [flags] (write a new agent.yaml; also mm --init) |
| 12 | +mm tui [<path>] [flags] (same as mm -tui) | |
| 13 | +mm acp [<path>] [flags] (same as mm -acp) | |
| 12 | 14 | ``` |
| 13 | 15 | |
| 14 | 16 | | Element | Type | Default | Description | |
| 15 | 17 | |---------|------|---------|-------------| |
| 16 | 18 | | `-config <path>` | string | `""` | Path of the YAML configuration file. | |
| 17 | -| `<path>` | positional | none | Same as `-config`, when `-config` is not given. A second positional argument is an error. | | |
| 18 | -| `-acp` | bool | `false` | Serve the Agent Client Protocol on stdin/stdout instead of the terminal REPL. | | |
| 19 | -| `-tui` | bool | `false` | Open the single-window mode (conversation above, input box below). Same effect as `tui: true` in the YAML; ignored with `-acp`. Falls back to the line mode when stdin or stdout is not a terminal. | | |
| 19 | +| `<path>` | positional | none | Same as `-config`, when `-config` is not given. A second positional argument is an error. A first argument `init`, `tui` or `acp` is a mode word, not a path: a configuration file with one of these names is given as `./tui` or with `-config`. | | |
| 20 | +| `-acp` | bool | `false` | Serve the Agent Client Protocol on stdin/stdout instead of the terminal REPL. Also written `--acp`, or `acp` as the first argument (`mm acp agent.yaml`). | | |
| 21 | +| `-tui` | bool | `false` | Open the single-window mode (conversation above, input box below). Same effect as `tui: true` in the YAML; ignored with `-acp`. Falls back to the line mode when stdin or stdout is not a terminal. Also written `--tui`, or `tui` as the first argument (`mm tui agent.yaml`). | | |
| 20 | 22 | | `-prompt <text>` / `-p <text>` | string | `""` | Run a single prompt and exit. The prompt text is required. Works with the config file before or after: `mm -p "hello" config.yaml` and `mm config.yaml -p "hello"` are both valid. No banner, no session persistence, no TUI/ACP. | |
| 21 | 23 | | `--version` | bool | `false` | Print the version and exit, before the configuration is read. `-version` is the same flag. | |
| 22 | 24 | | `--about` | bool | `false` | Print what `mm` is — one screen: version, the three front ends, the tools, the model servers, where the project and the docs live — and exit, before the configuration is read. | |
| @@ -9,14 +9,16 @@ mm [-config <path>] [-acp] [-tui] [-prompt <text>|-p <text>] [--version] [--abou | |||
| 9 | mm [-config <path>] --ask <agent> [-p <question>] (question on stdin when -p is absent) | 9 | mm [-config <path>] --ask <agent> [-p <question>] (question on stdin when -p is absent) |
| 10 | mm [-config <path>] --ask-with-context <agent> [-p <question>] (context on stdin) | 10 | mm [-config <path>] --ask-with-context <agent> [-p <question>] (context on stdin) |
| 11 | mm init [flags] (write a new agent.yaml; also mm --init) | 11 | mm init [flags] (write a new agent.yaml; also mm --init) |
| 12 | +mm tui [<path>] [flags] (same as mm -tui) | ||
| 13 | +mm acp [<path>] [flags] (same as mm -acp) | ||
| 12 | ``` | 14 | ``` |
| 13 | 15 | ||
| 14 | | Element | Type | Default | Description | | 16 | | Element | Type | Default | Description | |
| 15 | |---------|------|---------|-------------| | 17 | |---------|------|---------|-------------| |
| 16 | | `-config <path>` | string | `""` | Path of the YAML configuration file. | | 18 | | `-config <path>` | string | `""` | Path of the YAML configuration file. | |
| 17 | -| `<path>` | positional | none | Same as `-config`, when `-config` is not given. A second positional argument is an error. | | 19 | +| `<path>` | positional | none | Same as `-config`, when `-config` is not given. A second positional argument is an error. A first argument `init`, `tui` or `acp` is a mode word, not a path: a configuration file with one of these names is given as `./tui` or with `-config`. | |
| 18 | -| `-acp` | bool | `false` | Serve the Agent Client Protocol on stdin/stdout instead of the terminal REPL. | | 20 | +| `-acp` | bool | `false` | Serve the Agent Client Protocol on stdin/stdout instead of the terminal REPL. Also written `--acp`, or `acp` as the first argument (`mm acp agent.yaml`). | |
| 19 | -| `-tui` | bool | `false` | Open the single-window mode (conversation above, input box below). Same effect as `tui: true` in the YAML; ignored with `-acp`. Falls back to the line mode when stdin or stdout is not a terminal. | | 21 | +| `-tui` | bool | `false` | Open the single-window mode (conversation above, input box below). Same effect as `tui: true` in the YAML; ignored with `-acp`. Falls back to the line mode when stdin or stdout is not a terminal. Also written `--tui`, or `tui` as the first argument (`mm tui agent.yaml`). | |
| 20 | | `-prompt <text>` / `-p <text>` | string | `""` | Run a single prompt and exit. The prompt text is required. Works with the config file before or after: `mm -p "hello" config.yaml` and `mm config.yaml -p "hello"` are both valid. No banner, no session persistence, no TUI/ACP. | | 22 | | `-prompt <text>` / `-p <text>` | string | `""` | Run a single prompt and exit. The prompt text is required. Works with the config file before or after: `mm -p "hello" config.yaml` and `mm config.yaml -p "hello"` are both valid. No banner, no session persistence, no TUI/ACP. | |
| 21 | | `--version` | bool | `false` | Print the version and exit, before the configuration is read. `-version` is the same flag. | | 23 | | `--version` | bool | `false` | Print the version and exit, before the configuration is read. `-version` is the same flag. | |
| 22 | | `--about` | bool | `false` | Print what `mm` is — one screen: version, the three front ends, the tools, the model servers, where the project and the docs live — and exit, before the configuration is read. | | 24 | | `--about` | bool | `false` | Print what `mm` is — one screen: version, the three front ends, the tools, the model servers, where the project and the docs live — and exit, before the configuration is read. | |
modified
docs/fr/reference/cli.md +5 -3 | @@ -9,14 +9,16 @@ mm [-config <chemin>] [-acp] [-tui] [-prompt <texte>|-p <texte>] [--version] [-- | ||
| 9 | 9 | mm [-config <chemin>] --ask <agent> [-p <question>] (question sur stdin sans -p) |
| 10 | 10 | mm [-config <chemin>] --ask-with-context <agent> [-p <question>] (contexte sur stdin) |
| 11 | 11 | mm init [options] (écrire un nouvel agent.yaml ; aussi mm --init) |
| 12 | +mm tui [<chemin>] [options] (identique à mm -tui) | |
| 13 | +mm acp [<chemin>] [options] (identique à mm -acp) | |
| 12 | 14 | ``` |
| 13 | 15 | |
| 14 | 16 | | Élément | Type | Défaut | Description | |
| 15 | 17 | |---------|------|--------|-------------| |
| 16 | 18 | | `-config <chemin>` | chaîne | `""` | Chemin du fichier de configuration YAML. | |
| 17 | -| `<chemin>` | positionnel | aucun | Équivalent de `-config` quand `-config` n'est pas donné. Un second argument positionnel est une erreur. | | |
| 18 | -| `-acp` | booléen | `false` | Sert l'Agent Client Protocol sur stdin/stdout au lieu du REPL du terminal. | | |
| 19 | -| `-tui` | booléen | `false` | Ouvre le mode fenêtre unique (conversation en haut, zone de saisie en bas). Même effet que `tui: true` dans le YAML ; ignoré avec `-acp`. Retombe sur le mode ligne quand stdin ou stdout n'est pas un terminal. | | |
| 19 | +| `<chemin>` | positionnel | aucun | Équivalent de `-config` quand `-config` n'est pas donné. Un second argument positionnel est une erreur. Un premier argument `init`, `tui` ou `acp` est un mot de mode, pas un chemin : un fichier de configuration portant l'un de ces noms se donne en `./tui` ou avec `-config`. | | |
| 20 | +| `-acp` | booléen | `false` | Sert l'Agent Client Protocol sur stdin/stdout au lieu du REPL du terminal. S'écrit aussi `--acp`, ou `acp` en premier argument (`mm acp agent.yaml`). | | |
| 21 | +| `-tui` | booléen | `false` | Ouvre le mode fenêtre unique (conversation en haut, zone de saisie en bas). Même effet que `tui: true` dans le YAML ; ignoré avec `-acp`. Retombe sur le mode ligne quand stdin ou stdout n'est pas un terminal. S'écrit aussi `--tui`, ou `tui` en premier argument (`mm tui agent.yaml`). | | |
| 20 | 22 | | `-prompt <texte>` / `-p <texte>` | chaîne | `""` | Exécute une seule invite et quitte. Le texte de l'invite est obligatoire. Fonctionne avec le fichier de config avant ou après : `mm -p "bonjour" config.yaml` et `mm config.yaml -p "bonjour"` sont tous deux valides. Pas de bannière, pas de persistance de session, pas de TUI/ACP. | |
| 21 | 23 | | `--version` | bool | `false` | Affiche la version et quitte, avant la lecture de la configuration. `-version` est la même option. | |
| 22 | 24 | | `--about` | bool | `false` | Affiche ce qu'est `mm` — un écran : version, les trois façades, les outils, les serveurs de modèles, où vivent le projet et la documentation — puis quitte, avant la lecture de la configuration. | |
| @@ -9,14 +9,16 @@ mm [-config <chemin>] [-acp] [-tui] [-prompt <texte>|-p <texte>] [--version] [-- | |||
| 9 | mm [-config <chemin>] --ask <agent> [-p <question>] (question sur stdin sans -p) | 9 | mm [-config <chemin>] --ask <agent> [-p <question>] (question sur stdin sans -p) |
| 10 | mm [-config <chemin>] --ask-with-context <agent> [-p <question>] (contexte sur stdin) | 10 | mm [-config <chemin>] --ask-with-context <agent> [-p <question>] (contexte sur stdin) |
| 11 | mm init [options] (écrire un nouvel agent.yaml ; aussi mm --init) | 11 | mm init [options] (écrire un nouvel agent.yaml ; aussi mm --init) |
| 12 | +mm tui [<chemin>] [options] (identique à mm -tui) | ||
| 13 | +mm acp [<chemin>] [options] (identique à mm -acp) | ||
| 12 | ``` | 14 | ``` |
| 13 | 15 | ||
| 14 | | Élément | Type | Défaut | Description | | 16 | | Élément | Type | Défaut | Description | |
| 15 | |---------|------|--------|-------------| | 17 | |---------|------|--------|-------------| |
| 16 | | `-config <chemin>` | chaîne | `""` | Chemin du fichier de configuration YAML. | | 18 | | `-config <chemin>` | chaîne | `""` | Chemin du fichier de configuration YAML. | |
| 17 | -| `<chemin>` | positionnel | aucun | Équivalent de `-config` quand `-config` n'est pas donné. Un second argument positionnel est une erreur. | | 19 | +| `<chemin>` | positionnel | aucun | Équivalent de `-config` quand `-config` n'est pas donné. Un second argument positionnel est une erreur. Un premier argument `init`, `tui` ou `acp` est un mot de mode, pas un chemin : un fichier de configuration portant l'un de ces noms se donne en `./tui` ou avec `-config`. | |
| 18 | -| `-acp` | booléen | `false` | Sert l'Agent Client Protocol sur stdin/stdout au lieu du REPL du terminal. | | 20 | +| `-acp` | booléen | `false` | Sert l'Agent Client Protocol sur stdin/stdout au lieu du REPL du terminal. S'écrit aussi `--acp`, ou `acp` en premier argument (`mm acp agent.yaml`). | |
| 19 | -| `-tui` | booléen | `false` | Ouvre le mode fenêtre unique (conversation en haut, zone de saisie en bas). Même effet que `tui: true` dans le YAML ; ignoré avec `-acp`. Retombe sur le mode ligne quand stdin ou stdout n'est pas un terminal. | | 21 | +| `-tui` | booléen | `false` | Ouvre le mode fenêtre unique (conversation en haut, zone de saisie en bas). Même effet que `tui: true` dans le YAML ; ignoré avec `-acp`. Retombe sur le mode ligne quand stdin ou stdout n'est pas un terminal. S'écrit aussi `--tui`, ou `tui` en premier argument (`mm tui agent.yaml`). | |
| 20 | | `-prompt <texte>` / `-p <texte>` | chaîne | `""` | Exécute une seule invite et quitte. Le texte de l'invite est obligatoire. Fonctionne avec le fichier de config avant ou après : `mm -p "bonjour" config.yaml` et `mm config.yaml -p "bonjour"` sont tous deux valides. Pas de bannière, pas de persistance de session, pas de TUI/ACP. | | 22 | | `-prompt <texte>` / `-p <texte>` | chaîne | `""` | Exécute une seule invite et quitte. Le texte de l'invite est obligatoire. Fonctionne avec le fichier de config avant ou après : `mm -p "bonjour" config.yaml` et `mm config.yaml -p "bonjour"` sont tous deux valides. Pas de bannière, pas de persistance de session, pas de TUI/ACP. | |
| 21 | | `--version` | bool | `false` | Affiche la version et quitte, avant la lecture de la configuration. `-version` est la même option. | | 23 | | `--version` | bool | `false` | Affiche la version et quitte, avant la lecture de la configuration. `-version` est la même option. | |
| 22 | | `--about` | bool | `false` | Affiche ce qu'est `mm` — un écran : version, les trois façades, les outils, les serveurs de modèles, où vivent le projet et la documentation — puis quitte, avant la lecture de la configuration. | | 24 | | `--about` | bool | `false` | Affiche ce qu'est `mm` — un écran : version, les trois façades, les outils, les serveurs de modèles, où vivent le projet et la documentation — puis quitte, avant la lecture de la configuration. | |
modified
init_assemble_test.go +18 -0 | @@ -4,6 +4,7 @@ import ( | ||
| 4 | 4 | "context" |
| 5 | 5 | "os" |
| 6 | 6 | "path/filepath" |
| 7 | + "slices" | |
| 7 | 8 | "testing" |
| 8 | 9 | |
| 9 | 10 | "mm/internal/agentinit" |
| @@ -23,6 +24,23 @@ func TestIsInit(t *testing.T) { | ||
| 23 | 24 | } |
| 24 | 25 | } |
| 25 | 26 | |
| 27 | +// `mm tui …` and `mm acp …` become their flags; a mode word anywhere else, | |
| 28 | +// or a path, is left alone. | |
| 29 | +func TestModeWordAsFlag(t *testing.T) { | |
| 30 | + for _, c := range []struct{ in, want []string }{ | |
| 31 | + {[]string{"mm", "tui"}, []string{"mm", "-tui"}}, | |
| 32 | + {[]string{"mm", "acp", "agent.yaml"}, []string{"mm", "-acp", "agent.yaml"}}, | |
| 33 | + {[]string{"mm", "tui", "-config", "a.yaml"}, []string{"mm", "-tui", "-config", "a.yaml"}}, | |
| 34 | + {[]string{"mm", "agent.yaml", "tui"}, []string{"mm", "agent.yaml", "tui"}}, | |
| 35 | + {[]string{"mm", "./tui"}, []string{"mm", "./tui"}}, | |
| 36 | + {[]string{"mm"}, []string{"mm"}}, | |
| 37 | + } { | |
| 38 | + if got := modeWordAsFlag(c.in); !slices.Equal(got, c.want) { | |
| 39 | + t.Errorf("modeWordAsFlag(%q) = %q, want %q", c.in, got, c.want) | |
| 40 | + } | |
| 41 | + } | |
| 42 | +} | |
| 43 | + | |
| 26 | 44 | // A JSON agent written by `mm init` starts: structuredOutput forbids every |
| 27 | 45 | // tool, and the generated file turns them all off — main is where that rule |
| 28 | 46 | // is checked (config.StructuredOutputConflict), not config.Load. |
| @@ -4,6 +4,7 @@ import ( | |||
| 4 | "context" | 4 | "context" |
| 5 | "os" | 5 | "os" |
| 6 | "path/filepath" | 6 | "path/filepath" |
| 7 | + "slices" | ||
| 7 | "testing" | 8 | "testing" |
| 8 | 9 | ||
| 9 | "mm/internal/agentinit" | 10 | "mm/internal/agentinit" |
| @@ -23,6 +24,23 @@ func TestIsInit(t *testing.T) { | |||
| 23 | } | 24 | } |
| 24 | } | 25 | } |
| 25 | 26 | ||
| 27 | +// `mm tui …` and `mm acp …` become their flags; a mode word anywhere else, | ||
| 28 | +// or a path, is left alone. | ||
| 29 | +func TestModeWordAsFlag(t *testing.T) { | ||
| 30 | + for _, c := range []struct{ in, want []string }{ | ||
| 31 | + {[]string{"mm", "tui"}, []string{"mm", "-tui"}}, | ||
| 32 | + {[]string{"mm", "acp", "agent.yaml"}, []string{"mm", "-acp", "agent.yaml"}}, | ||
| 33 | + {[]string{"mm", "tui", "-config", "a.yaml"}, []string{"mm", "-tui", "-config", "a.yaml"}}, | ||
| 34 | + {[]string{"mm", "agent.yaml", "tui"}, []string{"mm", "agent.yaml", "tui"}}, | ||
| 35 | + {[]string{"mm", "./tui"}, []string{"mm", "./tui"}}, | ||
| 36 | + {[]string{"mm"}, []string{"mm"}}, | ||
| 37 | + } { | ||
| 38 | + if got := modeWordAsFlag(c.in); !slices.Equal(got, c.want) { | ||
| 39 | + t.Errorf("modeWordAsFlag(%q) = %q, want %q", c.in, got, c.want) | ||
| 40 | + } | ||
| 41 | + } | ||
| 42 | +} | ||
| 43 | + | ||
| 26 | // A JSON agent written by `mm init` starts: structuredOutput forbids every | 44 | // A JSON agent written by `mm init` starts: structuredOutput forbids every |
| 27 | // tool, and the generated file turns them all off — main is where that rule | 45 | // tool, and the generated file turns them all off — main is where that rule |
| 28 | // is checked (config.StructuredOutputConflict), not config.Load. | 46 | // is checked (config.StructuredOutputConflict), not config.Load. |
modified
main.go +19 -2 | @@ -80,6 +80,9 @@ func main() { | ||
| 80 | 80 | if len(os.Args) > 1 && isInit(os.Args[1]) { |
| 81 | 81 | os.Exit(agentinit.Main(os.Args[2:], os.Stdin, os.Stdout, agentinit.Options{Window: tui.RunInit, Terminal: tui.Terminal})) |
| 82 | 82 | } |
| 83 | + // `mm tui` and `mm acp` (ticket 117): the modes as words too, like | |
| 84 | + // `mm init` — `mm tui agent.yaml` is `mm -tui agent.yaml`. | |
| 85 | + os.Args = modeWordAsFlag(os.Args) | |
| 83 | 86 | |
| 84 | 87 | // Handle --prompt/-p flag which can appear after the config file argument |
| 85 | 88 | // We manually extract it before flag.Parse() so both orders work: |
| @@ -112,8 +115,8 @@ func main() { | ||
| 112 | 115 | os.Args = append([]string{os.Args[0]}, remainingArgs...) |
| 113 | 116 | |
| 114 | 117 | configPath := flag.String("config", "", "path to the YAML config file (default: $AGENT_CONFIG, then ./agent.yaml)") |
| 115 | - acpMode := flag.Bool("acp", false, "serve the Agent Client Protocol on stdio (for Zed, JetBrains, Neovim…) instead of the terminal REPL") | |
| 116 | - tuiMode := flag.Bool("tui", false, "open the single-window mode (conversation above, input box below); falls back to the line mode when stdout is not a terminal") | |
| 118 | + acpMode := flag.Bool("acp", false, "serve the Agent Client Protocol on stdio (for Zed, JetBrains, Neovim…) instead of the terminal REPL (same as: mm acp)") | |
| 119 | + tuiMode := flag.Bool("tui", false, "open the single-window mode (conversation above, input box below); falls back to the line mode when stdout is not a terminal (same as: mm tui)") | |
| 117 | 120 | promptMode := flag.String("prompt", "", "run a single prompt and exit") |
| 118 | 121 | flag.StringVar(promptMode, "p", "", "shorthand for --prompt") |
| 119 | 122 | showVersion := flag.Bool("version", false, "print the version and exit") |
| @@ -824,3 +827,17 @@ func runAsk(ctx context.Context, name string, withContext bool, prompt string) i | ||
| 824 | 827 | func isInit(arg string) bool { |
| 825 | 828 | return arg == "init" || arg == "--init" || arg == "-init" |
| 826 | 829 | } |
| 830 | + | |
| 831 | +// modeWordAsFlag turns a first argument `tui` or `acp` into its flag, so the | |
| 832 | +// rest of main sees one spelling: | |
| 833 | +// | |
| 834 | +// modeWordAsFlag([]string{"mm", "tui", "agent.yaml"}) // → mm -tui agent.yaml | |
| 835 | +// | |
| 836 | +// Only the first argument is a mode word: `mm agent.yaml tui` still names two | |
| 837 | +// config files, and a config file called tui is reached as ./tui. | |
| 838 | +func modeWordAsFlag(args []string) []string { | |
| 839 | + if len(args) < 2 || (args[1] != "tui" && args[1] != "acp") { | |
| 840 | + return args | |
| 841 | + } | |
| 842 | + return append([]string{args[0], "-" + args[1]}, args[2:]...) | |
| 843 | +} | |
| @@ -80,6 +80,9 @@ func main() { | |||
| 80 | if len(os.Args) > 1 && isInit(os.Args[1]) { | 80 | if len(os.Args) > 1 && isInit(os.Args[1]) { |
| 81 | os.Exit(agentinit.Main(os.Args[2:], os.Stdin, os.Stdout, agentinit.Options{Window: tui.RunInit, Terminal: tui.Terminal})) | 81 | os.Exit(agentinit.Main(os.Args[2:], os.Stdin, os.Stdout, agentinit.Options{Window: tui.RunInit, Terminal: tui.Terminal})) |
| 82 | } | 82 | } |
| 83 | + // `mm tui` and `mm acp` (ticket 117): the modes as words too, like | ||
| 84 | + // `mm init` — `mm tui agent.yaml` is `mm -tui agent.yaml`. | ||
| 85 | + os.Args = modeWordAsFlag(os.Args) | ||
| 83 | 86 | ||
| 84 | // Handle --prompt/-p flag which can appear after the config file argument | 87 | // Handle --prompt/-p flag which can appear after the config file argument |
| 85 | // We manually extract it before flag.Parse() so both orders work: | 88 | // We manually extract it before flag.Parse() so both orders work: |
| @@ -112,8 +115,8 @@ func main() { | |||
| 112 | os.Args = append([]string{os.Args[0]}, remainingArgs...) | 115 | os.Args = append([]string{os.Args[0]}, remainingArgs...) |
| 113 | 116 | ||
| 114 | configPath := flag.String("config", "", "path to the YAML config file (default: $AGENT_CONFIG, then ./agent.yaml)") | 117 | configPath := flag.String("config", "", "path to the YAML config file (default: $AGENT_CONFIG, then ./agent.yaml)") |
| 115 | - acpMode := flag.Bool("acp", false, "serve the Agent Client Protocol on stdio (for Zed, JetBrains, Neovim…) instead of the terminal REPL") | 118 | + acpMode := flag.Bool("acp", false, "serve the Agent Client Protocol on stdio (for Zed, JetBrains, Neovim…) instead of the terminal REPL (same as: mm acp)") |
| 116 | - tuiMode := flag.Bool("tui", false, "open the single-window mode (conversation above, input box below); falls back to the line mode when stdout is not a terminal") | 119 | + tuiMode := flag.Bool("tui", false, "open the single-window mode (conversation above, input box below); falls back to the line mode when stdout is not a terminal (same as: mm tui)") |
| 117 | promptMode := flag.String("prompt", "", "run a single prompt and exit") | 120 | promptMode := flag.String("prompt", "", "run a single prompt and exit") |
| 118 | flag.StringVar(promptMode, "p", "", "shorthand for --prompt") | 121 | flag.StringVar(promptMode, "p", "", "shorthand for --prompt") |
| 119 | showVersion := flag.Bool("version", false, "print the version and exit") | 122 | showVersion := flag.Bool("version", false, "print the version and exit") |
| @@ -824,3 +827,17 @@ func runAsk(ctx context.Context, name string, withContext bool, prompt string) i | |||
| 824 | func isInit(arg string) bool { | 827 | func isInit(arg string) bool { |
| 825 | return arg == "init" || arg == "--init" || arg == "-init" | 828 | return arg == "init" || arg == "--init" || arg == "-init" |
| 826 | } | 829 | } |
| 830 | + | ||
| 831 | +// modeWordAsFlag turns a first argument `tui` or `acp` into its flag, so the | ||
| 832 | +// rest of main sees one spelling: | ||
| 833 | +// | ||
| 834 | +// modeWordAsFlag([]string{"mm", "tui", "agent.yaml"}) // → mm -tui agent.yaml | ||
| 835 | +// | ||
| 836 | +// Only the first argument is a mode word: `mm agent.yaml tui` still names two | ||
| 837 | +// config files, and a config file called tui is reached as ./tui. | ||
| 838 | +func modeWordAsFlag(args []string) []string { | ||
| 839 | + if len(args) < 2 || (args[1] != "tui" && args[1] != "acp") { | ||
| 840 | + return args | ||
| 841 | + } | ||
| 842 | + return append([]string{args[0], "-" + args[1]}, args[2:]...) | ||
| 843 | +} | ||