diff --git a/internal/agent/hermes/command.go b/internal/agent/hermes/command.go index b7e9423..d906715 100644 --- a/internal/agent/hermes/command.go +++ b/internal/agent/hermes/command.go @@ -15,14 +15,17 @@ func shellQuote(s string) string { // // agentSessionID is the hermes session ID (Session.AgentSessionID). On // resume: -// - if non-empty: `hermes --resume ` -// - if empty: `hermes -c` (continue most-recent) +// - if non-empty: `hermes --tui --resume ` +// - if empty: `hermes --tui -c` (continue most-recent) // -// In both resume branches the command falls back to a fresh `hermes` on -// non-zero exit — matches codex's pattern for crash/Ctrl-C parity. +// In both resume branches the command falls back to a fresh `hermes --tui` +// on non-zero exit — matches codex's pattern for crash/Ctrl-C parity. // (Hermes itself exits 0 even on bad ID, so this fallback is purely // defensive against crashes during resume.) // +// --tui is always passed: ctm only ever drives hermes through its TUI +// surface. +// // envExports, when non-empty, is prepended verbatim as a shell prelude. func BuildCommand(agentSessionID, mode string, resume bool, envExports string) string { var yoloFlag string @@ -30,17 +33,17 @@ func BuildCommand(agentSessionID, mode string, resume bool, envExports string) s yoloFlag = " --yolo" } - freshCmd := "hermes" + yoloFlag + freshCmd := "hermes --tui" + yoloFlag var core string switch { case !resume: core = freshCmd case agentSessionID != "": - core = fmt.Sprintf("hermes --resume %s%s || %s", + core = fmt.Sprintf("hermes --tui --resume %s%s || %s", shellQuote(agentSessionID), yoloFlag, freshCmd) default: - core = "hermes -c" + yoloFlag + " || " + freshCmd + core = "hermes --tui -c" + yoloFlag + " || " + freshCmd } if envExports != "" { diff --git a/internal/agent/hermes/command_test.go b/internal/agent/hermes/command_test.go index 6e865e7..5ed2f3a 100644 --- a/internal/agent/hermes/command_test.go +++ b/internal/agent/hermes/command_test.go @@ -14,53 +14,53 @@ func TestBuildCommand(t *testing.T) { { name: "fresh-safe", mode: "safe", resume: false, - want: "hermes", + want: "hermes --tui", }, { name: "fresh-yolo", mode: "yolo", resume: false, - want: "hermes --yolo", + want: "hermes --tui --yolo", }, { name: "resume-with-id-safe", agentSessionID: "20260515_152727_9da209", mode: "safe", resume: true, - want: "hermes --resume '20260515_152727_9da209' || hermes", + want: "hermes --tui --resume '20260515_152727_9da209' || hermes --tui", }, { name: "resume-with-id-yolo", agentSessionID: "20260515_152727_9da209", mode: "yolo", resume: true, - want: "hermes --resume '20260515_152727_9da209' --yolo || hermes --yolo", + want: "hermes --tui --resume '20260515_152727_9da209' --yolo || hermes --tui --yolo", }, { name: "resume-no-id-safe", mode: "safe", resume: true, - want: "hermes -c || hermes", + want: "hermes --tui -c || hermes --tui", }, { name: "resume-no-id-yolo", mode: "yolo", resume: true, - want: "hermes -c --yolo || hermes --yolo", + want: "hermes --tui -c --yolo || hermes --tui --yolo", }, { name: "env-prelude-fresh-safe", mode: "safe", resume: false, envExports: "export FOO='bar'", - want: "export FOO='bar'; hermes", + want: "export FOO='bar'; hermes --tui", }, { name: "env-prelude-resume-yolo", agentSessionID: "id1", mode: "yolo", resume: true, envExports: "export FOO='bar'", - want: "export FOO='bar'; hermes --resume 'id1' --yolo || hermes --yolo", + want: "export FOO='bar'; hermes --tui --resume 'id1' --yolo || hermes --tui --yolo", }, { name: "shell-quote-escapes-single-quote", agentSessionID: `weird'id`, mode: "safe", resume: true, - want: `hermes --resume 'weird'\''id' || hermes`, + want: `hermes --tui --resume 'weird'\''id' || hermes --tui`, }, } for _, tt := range tests {