Skip to content

Model the permission modes CLI 2.1.291 accepts - #3

Open
mariuszs wants to merge 2 commits into
markpollack:mainfrom
mariuszs:add-cli-permission-modes
Open

mariuszs wants to merge 2 commits into
markpollack:mainfrom
mariuszs:add-cli-permission-modes

Conversation

@mariuszs

@mariuszs mariuszs commented Oct 6, 2026

Copy link
Copy Markdown

Summary

claude --help (2.1.291) lists --permission-mode choices acceptEdits, auto, bypassPermissions, manual, dontAsk, plan. Four of them had no PermissionMode constant.

 public enum PermissionMode {
   DEFAULT("default"),            // no longer listed, still accepted
   ACCEPT_EDITS("acceptEdits"),
   BYPASS_PERMISSIONS("bypassPermissions"),
   DANGEROUSLY_SKIP_PERMISSIONS("dangerously-skip-permissions"),
+  MANUAL("manual"),              // new name for default
+  AUTO("auto"),                  // falls back to default on models without auto
+  DONT_ASK("dontAsk"),
+  PLAN("plan");

The new constants are appended, so existing ordinals do not change. CLIFlagParityIT now reads the --permission-mode choices from --help:

sdkPermissionModesShouldBeCliChoices                 gate: every SDK mode is a CLI choice
                                                     (DEFAULT recorded as accepted-but-unlisted)
cliPermissionModeChoicesShouldHaveSdkConstants       warning: a CLI choice with no constant
permissionModeChoicesShouldBeParseable               the choices list was found

The second check is a warning rather than a gate, for the same reason the existing unmodelled-flag check is. A missing mode is still reachable, because extraArgs is emitted after the SDK's own --permission-mode and the CLI applies the last one.

Evidence

Init-message permissionMode with CLI 2.1.291, claude -p … --output-format stream-json --verbose:

Flags Model Reported
--permission-mode manual haiku default
--permission-mode default haiku default
--permission-mode auto sonnet auto
--permission-mode acceptEdits --permission-mode plan haiku plan
--permission-mode plan --permission-mode acceptEdits haiku acceptEdits
--permission-mode default --permission-mode auto sonnet auto

The auto fallback to default on a model that doesn't support it was observed on Haiku. It is documented on AUTO.

Tests:

  • Before: against the old enum, cliPermissionModeChoicesShouldHaveSdkConstants reports auto, dontAsk, manual, plan.
  • After: nothing to report. CLIFlagParityTest.permissionModeValues checks that every mode emits --permission-mode <value> exactly once and round-trips through fromValue.

./mvnw clean verify passes.

Merge Danger

Door: two-way

Blast Radius: additive

Only new enum constants were added. Defaults and the emitted command are unchanged for the existing modes. A consumer with an exhaustive switch over PermissionMode will need to handle the new cases.

claude --help (2.1.291) lists the --permission-mode choices acceptEdits,
auto, bypassPermissions, manual, dontAsk and plan. PermissionMode had
only DEFAULT, ACCEPT_EDITS and BYPASS_PERMISSIONS, plus
DANGEROUSLY_SKIP_PERMISSIONS, which is a separate flag.

Add AUTO, DONT_ASK, PLAN and MANUAL after the existing constants, so
the existing ordinals stay the same. DEFAULT stays: the CLI no longer
lists "default" but still accepts it, and reports a "manual" session
as "default" in its init message. On a model that does not support
"auto" (Haiku), the CLI silently falls back to "default" instead of
failing; the AUTO javadoc says so.

CLIFlagParityIT now reads the --permission-mode choices from --help.
It gates on every SDK mode being one of them, with DEFAULT recorded as
accepted but unlisted, and it warns about a choice that has no constant.
Like the unmodelled-flag check, that is a warning rather than a gate,
because the mode stays reachable: extraArgs is emitted after the SDK's
own --permission-mode, and the CLI applies the last one. Against the old
enum it reports auto, dontAsk, manual and plan.
The gate compared PermissionMode values with the choices claude --help
lists, so it could not cover DEFAULT, which the SDK sends by default and
the CLI still accepts without listing it, and it would fail on any other
mode the CLI hides but keeps accepting. It now runs
claude --permission-mode <value> --version for every value, which the
CLI validates while parsing arguments, without starting a session.

PermissionMode.isPermissionModeValue() replaces the three separate
special cases for DANGEROUSLY_SKIP_PERMISSIONS. The help choices are
parsed once, and the parse stops at the next option.
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.

1 participant