Skip to content

claude-code-settings: add if, shell, once to hookCommand#5583

Closed
sarahdeaton wants to merge 3 commits intoSchemaStore:masterfrom
sarahdeaton:claude-code-hook-if-shell-once
Closed

claude-code-settings: add if, shell, once to hookCommand#5583
sarahdeaton wants to merge 3 commits intoSchemaStore:masterfrom
sarahdeaton:claude-code-hook-if-shell-once

Conversation

@sarahdeaton
Copy link
Copy Markdown

Adds three hook fields that ship in current Claude Code releases but are missing from the schema, causing editors to flag valid settings.json files when $schema is set.

  • if (string, all hook types): permission-rule pattern that gates whether the hook runs for a given tool call. Shipped in v2.1.85. Docs: https://code.claude.com/docs/en/hooks-guide#filter-hooks-with-if
  • once (boolean, all hook types): run the hook once per session then remove it.
  • shell (enum bash|powershell, command hooks only): selects the interpreter for command.

Validated locally with jsonschema against the example from the Claude Code hooks docs that users reported as failing.

@github-actions
Copy link
Copy Markdown
Contributor

Thanks for the PR!

This section of the codebase is owned by @domdomegg, @bogini, and @ant-kurt - if they write a comment saying "LGTM" then it will be merged.

miteshashar added a commit to miteshashar/schemastore that referenced this pull request Apr 17, 2026
Subsumes open PRs SchemaStore#5483 and SchemaStore#5583 (credited; coverage.js changes
deferred to a separate follow-up PR).

Schema:
- Add hookCommand fields: asyncRewake (command-only), shell (command-only,
  enum bash|powershell), if (filter on tool-related events). Omit `once`
  since docs scope it to skill frontmatter, not settings.json.
- Add hook events: StopFailure (API-error matcher values documented)
- Add 17 top-level properties: agent, allowedChannelPlugins, autoMemoryDirectory,
  autoMode (with allow/soft_deny/environment classifier customization),
  channelsEnabled, defaultShell, disableDeepLinkRegistration,
  disableSkillShellExecution, forceRemoteSettingsRefresh, minimumVersion,
  showClearContextOnPlanAccept, showThinkingSummaries,
  skipDangerousModePermissionPrompt, strictPluginOnlyCustomization, tui,
  useAutoModeDuringPlan, viewMode, voiceEnabled
- Add permissions.disableAutoMode (nested, mirrors disableBypassPermissionsMode)
- Add sandbox.network.allowMachLookup (macOS XPC/Mach service allowlist)
- Add sandbox.ripgrep custom-binary configuration
- Add statusLine.refreshInterval (min 1)
- Add pluginConfigs.*.options (non-sensitive plugin userConfig values)
- Extend effortLevel enum with xhigh (Opus 4.7) and max
- Extend permissionRule pattern with Monitor and PowerShell tools
- Tighten cleanupPeriodDays minimum from 0 to 1 (v2.1.89 validator rejects 0)
- Fix stale doc anchors: hooks-guide#filter-hooks-with-matchers,
  hooks#http-hook-fields, memory#exclude-specific-claude-md-files,
  tools-reference (canonical page for tool list)

Tests:
- modern-complete-config.json: cover all new properties
- complete-config.json: cover effortLevel medium and viewMode default
- edge-cases.json: update cleanupPeriodDays 0 -> 1
- New enum-coverage.json: cover alternate enum values (bash, fullscreen,
  xhigh, verbose) for full positive coverage across new enums

Negative tests:
- invalid-enum-values.json: add invalid values for defaultShell,
  disableDeepLinkRegistration, permissions.disableAutoMode, tui, viewMode
- New invalid-hook-shell.json: exercise hookCommand.shell invalid enum

Excluded:
- coverage.js \$defs-path fix from SchemaStore#5483 (scheduled for a separate PR
  crediting @r-johnv). Consequence: the #\$defs/hookCommand.shell enum
  coverage gate fails here; will be resolved when that PR lands.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@miteshashar
Copy link
Copy Markdown
Contributor

Hi @sarahdeaton — just a heads-up: I opened #5585 to sync the schema to v2.1.112 and it subsumes your if/shell additions. I initially included once as well, but removed it after cross-checking the hooks documentation — the docs scope once to skill frontmatter YAML (hooks declared inside a skill), not to hookCommand entries in settings.json. if and shell are explicitly called out as hookCommand fields on that page, but once appears only under the skills/frontmatter section.

If that's an incorrect reading and once is in fact valid in settings.json hooks (e.g., via a docs source I missed or empirical CLI behavior), please do let me know.

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