Skip to content

feat: add Claude Code project settings (.claude/settings.json)#37

Open
martinydeAI wants to merge 1 commit into
developfrom
feature/issue-6-claude-settings
Open

feat: add Claude Code project settings (.claude/settings.json)#37
martinydeAI wants to merge 1 commit into
developfrom
feature/issue-6-claude-settings

Conversation

@martinydeAI

Copy link
Copy Markdown
Collaborator

Summary

Adds a committed .claude/settings.json so the whole team shares the same Claude Code harness configuration for this repo (#6). The configuration is taken from itk-dev/devops_itksites#62 and includes a permission allowlist, deny/ask rules, hooks, and a set of enabled plugins.

Features Added

  • Permission allowlist — auto-approves common read-only commands (cat, ls, grep, find, head, tail, wc, tree, diff, which, pwd, echo), git, gh, task, and read-only docker compose subcommands (exec, run, up, ps, logs, top, config, pull, images) plus docker network.
  • Deny list — hard-blocks rm -rf, gh issue/release/repo/label delete, and reads of .env.local, .env.local.*, config/secrets/*.
  • Ask list — requires explicit confirmation for state-changing git operations (push, reset, rebase, merge, commit, branch delete, tag, stash drop, clean, checkout --, restore), GitHub PR/issue/release/label actions (create, close, merge, edit, comment, review), and Docker lifecycle commands (down, stop, rm, restart).
  • Hooks
    • SessionStart: runs docker compose up --detach so the dev stack is ready.
    • PreToolUse: blocks Edit/Write to composer.lock, yarn.lock, and .env.local*.
    • PostToolUse: runs php-cs-fixer and phpstan on *.php, twig-cs-fixer on *.twig, composer normalize on composer.json, and prettier on *.{js,css,scss,yaml,yml,md} — all inside the container.
    • Stop: runs bin/console lint:container to validate Symfony DI wiring at end of session.
  • Enabled pluginsphp-lsp, code-simplifier, context7, code-review, security-guidance, playwright, feature-dev, and itkdev-skills.
  • Local overrides.claude/settings.local.json is gitignored so per-user tweaks/secrets stay out of version control.

Files Changed

  • .claude/settings.json (new) — committed, team-shared Claude Code harness configuration.
  • .gitignore — ignore .claude/settings.local.json.
  • CHANGELOG.md — note the addition under [Unreleased] / Added.

Test Plan

  • Open the repo in Claude Code and confirm the settings file is picked up (no JSON parse errors at startup).
  • Run an allowlisted command (e.g. git status, task --list) — should execute without a permission prompt.
  • Attempt a denied command (e.g. rm -rf some/path) — should be refused.
  • Attempt an ask-listed command (e.g. git push, gh pr create) — should prompt for confirmation.
  • Edit a *.php file and verify php-cs-fixer / phpstan run via the phpfpm service.
  • Edit a *.md file and verify prettier runs via the node service.
  • Try to Edit composer.lock — should be blocked by the PreToolUse hook.
  • Verify .claude/settings.local.json is ignored by git (create the file, run git status).

Closes #6

Adds .claude/settings.json so the team shares the same Claude Code
harness configuration: a permission allowlist for common safe commands,
a deny list for destructive actions and secrets, an ask list for
state-changing git/gh/docker operations, project hooks (auto-start
Docker, block lock-file edits, run php-cs-fixer/phpstan/twig-cs-fixer/
composer normalize/prettier after edits, lint Symfony DI container on
stop), and a set of enabled Claude plugins.

Adds .claude/settings.local.json to .gitignore so local-only overrides
stay out of version control.

Closes #6
@martinyde martinyde requested review from martinyde, tuj and yepzdk June 8, 2026 11:31

@yepzdk yepzdk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How often does the "PostToolUse" run? Match on Write/Edit sounds excessive for running commands that check coding standards etc.
I have not used it, so can't say how it is in real life, just flagging it, as a potential burn of time/tokens.

Comment thread .claude/settings.json
"Bash(diff:*)",
"Bash(echo:*)",
"Bash(find:*)",
"Bash(gh:*)",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should just allow all from gh or git

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have also worked on a settings.json in economics:
https://github.com/itk-dev/economics/pull/317/changes

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that the rules for deny, ask, allow are evaluated in that order. So when we also have say gh repo deleteunder deny that will always trigger before the broader rule under allow

Rules are evaluated in order: deny, then ask, then allow. The first match in that order determines the outcome, and rule specificity does not change the order. A matching ask rule prompts even when a more specific allow rule also matches the same call.

https://code.claude.com/docs/en/permissions#manage-permissions

That said, I agree with @tuj that we shouldn't default to allow like this. Allow rules should be scoped to non-commands of "view" or "list" in nature.

@martinyde martinyde requested a review from tuj June 10, 2026 06:14
@martinyde

Copy link
Copy Markdown
Contributor

How often does the "PostToolUse" run? Match on Write/Edit sounds excessive for running commands that check coding standards etc. I have not used it, so can't say how it is in real life, just flagging it, as a potential burn of time/tokens.

Yeah i asked @turegjorup about that in a different project. If i understand correctly they run on every prompt, so quite often, but he mentioned he didn't experience much overhead, so i allowed it in. But i'm also a bit iffy about it. I guess we can just try it and see how it works.

@martinyde martinyde requested a review from turegjorup June 10, 2026 06:20
@turegjorup

Copy link
Copy Markdown

How often does the "PostToolUse" run? Match on Write/Edit sounds excessive for running commands that check coding standards etc. I have not used it, so can't say how it is in real life, just flagging it, as a potential burn of time/tokens.

Example from Claude Code docs:

This example runs a linting script only when Claude writes or edits a file:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "/path/to/lint-check.sh"
          }
        ]
      }
    ]
  }
}

https://code.claude.com/docs/en/hooks documents what is currently available PostToolUse seems like the best candidate for adding quality checks in settings, but obviously needs to be balanced against performance.

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.

Add Claude Code project settings (.claude/settings.json)

5 participants