Skip to content

dcd live <subcommand> prints the parent help menu after every subcommand #15

@riglar

Description

@riglar

Summary

Every dcd live subcommand (start, status, install, exec, stop) prints the generic "Live Session Commands" menu after its own output. The menu is the parent liveCommand.run() body leaking into successful subcommand invocations.

Reproduction

$ dcd live status --session bouncy-green-hawk --api-url https://api.dev.devicecloud.dev

Live Session
────────────────────────────────────────────────
   Session:    bouncy-green-hawk
   Platform:   android
   Status:     RUNNING
   Created:    6/16/2026, 10:57:30 AM

Live Session Commands          <-- spurious, should not be here
────────────────────────────────────────────────
   start    Start a new live device session
   install  Install a binary on the device
   exec     Execute Maestro YAML commands
   stop     Stop a live session
   status   Get session status

   Run dcd live <command> --help for details

Same trailing menu appears after live start and live install (verified on dev).

Root cause

citty's runCommand does not early-return after dispatching to a subcommand — after running the matched subcommand it falls through and also invokes the parent command's run if one is defined:

// node_modules/citty/dist/index.mjs (runCommand)
if (subCommand) { await runCommand(subCommand, {...}); }
...
if (typeof cmd.run === "function") { result = await cmd.run(context); }  // parent run still fires

liveCommand (src/commands/live.ts) defines both subCommands and a run() that prints the menu, so the menu prints on every subcommand. The top-level main command is unaffected because it has no run.

Suggested fix

Have liveCommand.run() only print the menu when no subcommand was matched — e.g. detect whether the first positional in rawArgs/ctx.args._ is one of the subcommand names and return early otherwise. (Alternatively restructure so the menu lives in a default sub-command.)

Side note (low priority)

dcd live exec wraps server errors as Failed to execute test failed: <message> — the doubled "test failed" reads awkwardly (e.g. Failed to execute test failed: Session not ready (HTTP 425)). Worth tidying the error-prefix wording while in this area.

Found during a full feature sweep of v5.0.0 against the dev environment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions