Skip to content

docs(roadmap): add #457 — --resume --help vs --resume --version parser asymmetry: --version short-circuits, --help is swallowed as session-id#3070

Open
Yeachan-Heo wants to merge 1 commit into
mainfrom
docs/roadmap-457-resume-help-vs-version-short-circuit-asymmetry
Open

docs(roadmap): add #457 — --resume --help vs --resume --version parser asymmetry: --version short-circuits, --help is swallowed as session-id#3070
Yeachan-Heo wants to merge 1 commit into
mainfrom
docs/roadmap-457-resume-help-vs-version-short-circuit-asymmetry

Conversation

@Yeachan-Heo
Copy link
Copy Markdown
Contributor

ROADMAP pinpoint #457--resume --help and --resume --version disagree by parser-arm asymmetry

Dogfooded for the 2026-05-24 08:00 Clawhip pinpoint nudge (message 1508016732986408983).

Repro (clean isolated env, separated streams)

Invocation stdout stderr exit
claw --resume --version (version banner) empty 0
claw --resume --help empty failed to restore session: session not found: --help… 1
claw --resume version empty session not found: version 1
claw --resume help empty session not found: help 1
claw --resume list empty session not found: list 1
claw --resume ls empty session not found: ls 1
claw --resume show empty session not found: show 1

Same parser, same --resume <ARG> shape, only --version short-circuits.

Root cause (traced)

parse_args in rust/crates/rusty-claude-cli/src/main.rs:630-654 has asymmetric arms:

// line 632
"--help" | "-h" if rest.is_empty() => { wants_help = true; index += 1; }

// lines 636-650
"--help" | "-h"
    if !rest.is_empty()
        && matches!(rest[0].as_str(), "prompt" | "commit" | "pr" | "issue") =>
{ wants_help = true; index += 1; }

// lines 651-654 — NO GUARD
"--version" | "-V" => { wants_version = true; index += 1; }

--resume at line 762 pushes "--resume" into rest and advances by one:

"--resume" if rest.is_empty() => { rest.push("--resume".to_string()); index += 1; }

On the next iteration with rest = ["--resume"]:

  • --help fails both guards (rest not empty, rest[0] == "--resume" not in allowlist) → catch-all other => rest.push(...)rest = ["--resume", "--help"] → resume dispatch treats --help as session-id positional.
  • --version matches its unguarded arm → wants_version = true → final if wants_version { return Ok(CliAction::Version { ... }); } (lines 803-805) short-circuits before resume dispatch ever runs.

Why distinct from existing items

Item Tracks
#21 / #55 / #113 REPL-only session verbs (/session list/switch/fork/delete)
#117 -p "test" --help-p's greedy args[index+1..].join(" ") swallows everything
#141 Subcommands handle --help in their own dispatch (the allowlist comment)
#2186 claw --help Resume-safe block lies about which commands work
#457 --help arm has rest.is_empty() guard + 4-name allowlist; --version arm has no guard — under --resume, version works but help does not

#117 is the opposite asymmetry: -p is greedy and absorbs subsequent args. --resume is correctly non-greedy (advances by one and lets the parser continue) — the bug is purely on the --help arm's guards. Fix is one-line scope.

Why it matters

  1. Help discoverability broken for the most common entry point. claw --resume <tab><tab>claw --resume --help is the natural exploration path. Instead users get session not found: --help with no hint that --help is a flag.
  2. <verb> --version / <verb> --help parity contract violated. Every other claw <verb> --version and claw <verb> --help pair returns the corresponding help/version page. --resume uniquely breaks the --help half.
  3. The session not found: --help message is actively misleading. It implies a malformed session id, not a documentation request. Claw orchestrators parsing kind:"session_not_found" won't realize the human typed --help.
  4. Sibling clawability gap. The same arms mean help, list, ls, show are all absorbed as session-id literals. There is no CLI way to enumerate sessions — the hint text in those errors directs to /session list which is REPL-only.

Required fix shape (full detail in ROADMAP entry)

(a) Make --help short-circuit unconditionally, matching --version — drop rest.is_empty() guard and 4-name allowlist on the top-level --help arms; let parse_local_help_action() paths do their own dispatch before parse_args. (b) CLI-side session enumeration: claw session list / claw sessions emitting the same {kind:"session_list", sessions:[…], active:<id>} envelope as the REPL /session list so the hint text has a callable CLI parallel. (c) Better wording when the "session id" looks like a flag (starts with -): emit kind:"flag_swallowed_as_session_id" with explicit hint. (d) Regression tests asserting all eight --help/-h/JSON-mode variants under --resume produce CliAction::Help { … } exit 0.

Acceptance check (one-liner)

claw --resume --help >/dev/null 2>&1; test $? -eq 0

Should pass, and stdout should contain the help text.


[repo owner's gaebal-gajae (clawdbot) 🦞]

…r asymmetry: --version short-circuits but --help is swallowed as session-id
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants