github manuelschipper/nah v0.8.0

latest releases: v0.8.1, claude-plugin-v0.8.1
3 hours ago

Breaking

  • Target-first install/update/uninstall commandsnah install, nah update, and nah uninstall now require an explicit target instead of defaulting to Claude Code. Use nah install claude, nah update claude, and nah uninstall claude for direct Claude hooks; shell and provider targets use the same shape. Bare nah install exits nonzero with a guided target list, and the old --agent lifecycle shape is no longer the documented product surface. (nah-882)

Added

  • Human-friendly safety explanations — terminal guard prompts, Claude Code permission reasons, nah test, and compact nah log output now show short nah paused: / nah blocked: messages such as “this can rewrite Git history” while preserving the technical reason, action type, hints, and JSON/log diagnostics alongside a new human_reason field. (nah-884)
  • Opt-in bash and zsh terminal guard — added nah install bash and nah install zsh to protect interactive shell sessions with managed rc-file snippets that classify complete single-line commands before execution. The guard supports status/doctor diagnostics, prompt-on-ask behavior, fail-closed handling for unsupported multiline/here-doc/continuation input, explicit bypass via nah-bypass <command> or NAH_TERMINAL_BYPASS=1, and terminal decision logging for blocks, denied asks, confirmed asks, bypasses, and errors while keeping allowed terminal commands out of the nah log by default. (nah-882)
  • Target-aware dry runs and config overrides — added nah test --target <target> and --json, plus target-scoped config under targets.<target> for runtime-specific policies. Bash and zsh targets default to LLM mode off even when a global provider is configured, unless explicitly enabled under their target override. (nah-882)
  • Codex native hook support — added nah run codex for local interactive Codex sessions using Codex PermissionRequest hooks instead of shell-wrapper prompts. The runner injects nah-owned hook, sandbox, approval, and dynamic-MCP-disabling overrides, rejects unsafe Codex launch modes, routes Bash and MCP permission requests through nah classification, and adds nah codex doctor / nah codex repair to block and repair remembered Codex approvals or MCP approval modes that could bypass nah. (nah-897, nah-898)
  • Guarded Codex edit auto-allow — added nah run codex --auto-edits to auto-allow safe project-local apply_patch add/update edits after nah path, content, and LLM checks, while default sessions still ask and dangerous patches remain blocked or ask-only. (nah-904)
  • Codex flow mode — added nah run codex --flow as a shortcut for no Codex filesystem sandbox plus safe apply_patch auto-allow. Use --no-sandbox separately when you want to remove the Codex sandbox without also auto-accepting edits. (nah-906)
  • MCP threat-model audit coverage — added mcp_permissions to nah audit-threat-model, covering core MCP permission/runtime tests for Claude Code matcher registration, global-only MCP classification, wildcard safety, database/browser MCP action typing, Codex MCP PermissionRequest hooks, and Codex MCP approval-mode preflight/repair. README and public docs now report 1,807 category coverage hits across 13 tested danger classes. (nah-905)
  • OS keyring-backed LLM secrets — added nah key set, nah key status, nah key import-env, and nah key rm for storing optional LLM
    provider keys outside the process environment. Keyring support remains an
    optional keys extra, with env-var fallback for existing setups. Thanks
    @ZhangJiaLong90524 for the initial PR and direction.
    (#65, nah-889)

Changed

  • License transition for future releases — future source snapshots and
    releases are fair-source under FSL-1.1-MIT and convert to MIT two years after
    they are made available. Versions and source snapshots made available under
    MIT before this transition, including v0.7.1 and earlier tagged releases,
    remain MIT.
  • Agent session launchers use nah run — the one-shot Claude Code launcher
    is now nah run claude, matching nah run codex. Legacy nah claude exits
    with a pointer to the new command.
  • README and public docs rebranded for coding agents — refreshed README, site install/CLI/privacy/how-it-works/getting-started docs, and package metadata around “Context aware safety guard for coding agents” instead of a Claude-only positioning, with the user terminal guard treated as an optional bonus. Updated examples to current nah paused: / nah blocked: copy and documented Codex doctor/repair plus nah log --llm. (nah-899)
  • Terminal guard documented as opt-in shell protection — README, install docs, configuration docs, privacy copy, and lifecycle target help now describe bash/zsh terminal protection as opt-in per shell without preview labeling.
  • Minimal taxonomy profile deprecatedprofile: minimal now warns and behaves like profile: full, leaving full and none as the two supported profile shapes. The old minimal classification data has been removed so custom classifiers are not evaluated against a weaker built-in baseline.
  • Install lifecycle targets stay runtime-only — removed the unreleased nah install openrouter / nah uninstall openrouter convenience path so lifecycle commands only install or remove nah from guarded runtimes (claude, bash, zsh). LLM providers remain configured through global config. (nah-882 follow-up)
  • Install docs now start with a chooser — README and site install docs now separate the Claude Code plugin, PyPI CLI/direct-hook, terminal guard, config extra, and LLM provider configuration more clearly, and stale setup examples now use explicit target-first lifecycle commands instead of bare nah install. (nah-885)

Fixed

  • Windows drive-letter paths route through trusted pathsnah trust C:/Projects and nah trust D:\work now write to trusted_paths instead of
    being mistaken for network hosts in known_registries. Thanks @enermark.
    (#69)
  • Sparse environments keep useful log user attribution — structured
    decision logs now fall back from USER to LOGNAME, USERNAME, and finally
    getpass.getuser() before leaving the user field empty.
  • Codex flow edit approval race — safe apply_patch edits in nah run codex --flow now trust direct Codex patch payloads and retry the Codex transcript briefly when direct patch text is unavailable, fixing cases where the PermissionRequest hook fell back to the native edit prompt before nah could inspect the patch. (nah-907)
  • Quoted output text no longer becomes a fake redirect — Bash classification
    now preserves > characters that appear inside quoted or backslash-escaped
    printf / echo text before redirect decomposition, so prose such as
    <key> or -> no longer prompts as a filesystem write while real unquoted
    redirects to sensitive paths still block. (nah-902)
  • Claude launcher rejects unsafe bypass modesnah run claude now refuses
    --dangerously-skip-permissions, --enable-auto-mode, and
    --permission-mode bypassPermissions because those modes can run tool calls
    outside the guarded permission path.
  • Shell control-flow bodies are classified by payloadfor ...; do ...; done, while ...; do ...; done, and if ...; then ...; fi now expose their executable inner commands to the classifier instead of stopping at reserved words like for, do, and done. Literal for item lists are expanded into the loop body so safe batch GitHub/GitLab CLI API reads can allow while sensitive paths still block; dynamic loop values and control-flow body command substitutions fail closed. Tracks #78.
  • Unwrapped shell bodies mirror top-level variable expansionbash -c 'BAD=/etc/shadow; rm "$BAD"' and control-flow variants now apply the same intra-chain $VAR expansion used for top-level Bash commands, closing a sensitive-path bypass inside shell wrappers.
  • GitLab API form writes ask cleanlyglab api --form ... now classifies as network_write, including multipart file-upload forms, and gh / glab API prompt copy no longer mistakes field values such as file=@image.png for network hosts.
  • Bash terminal ask denials clear the prompt line — denied ask decisions now cancel and return to an empty prompt instead of restoring the same command line and making the shell look stuck. (nah-882 follow-up)
  • Terminal guard reload hint replaces active snippetsnah install bash / nah update bash now print a reload command that clears terminal guard environment and replaces the shell, so an already-running shell can load the updated guard without running startup files inside the old in-memory Readline hook. (nah-882 follow-up)
  • Bash terminal guard preserves normal prompt redraws — bash now filters the Readline buffer and lets Bash execute accepted commands normally, instead of running commands inside the Readline callback. Confirmed commands run through normal Bash execution, preserving shell state such as cd and source. (nah-882 follow-up)
  • nah update no longer looks like a project file writenah install / nah update now classify as nah lifecycle commands instead of treating target names such as bash or update as filesystem paths like ~/bash or ~/update when the terminal guard runs outside a Git project. (nah-882 follow-up)
  • Bash rc reloads replace the active guard — sourcing .bashrc in an already-guarded bash shell now refreshes nah's active function and key bindings instead of skipping the snippet because NAH_TERMINAL_GUARD_ACTIVE was already set. The original pre-nah binding metadata is still captured only once for diagnostics. (nah-882 follow-up)
  • Bash ask prompts use the hidden decision helper — bash ask decisions now prompt through nah _terminal-decision --confirm instead of shell read inside the Readline callback or a pending y / n command line. This keeps normal Run anyway? [y/N] prompts responsive without leaking helper commands into the prompt or history. (nah-882 follow-up)
  • Bash ask confirmations read raw terminal keys — the hidden terminal prompt now reads a single y, n, Enter, or Ctrl-C key so confirmation works while Bash Readline has the tty in raw mode. (nah-882 follow-up)
  • Bash accept-line newlines are normalized — the terminal guard now trims the single trailing newline that Bash Readline can pass to the hidden helper, so commands like nah test '...' --json are classified normally instead of being mistaken for multiline input. (nah-882 follow-up)
  • LLM provider setup warnings stay out of guard prompts — missing LLM API keys no longer create noisy standalone stderr lines in terminal guard prompts or Codex permission hook output; expected provider/key misses are logged as quiet review metadata instead. (nah-897)

Don't miss a new nah release

NewReleases is sending notifications on new releases.