Skip to content

Commit 40d5bfb

Browse files
author
Build Tools
committed
permissions issue in claude settigns
1 parent 1b8dcbd commit 40d5bfb

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

CLAUDE.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# er_build_tools
2+
3+
Public build tools and CI utilities for Extend Robotics ROS1 repositories. The main component is `ci_tool`, an interactive CLI that reproduces CI failures locally in Docker and uses Claude Code to fix them.
4+
5+
## Project Structure
6+
7+
```
8+
bin/
9+
ci_tool/ # Main Python package
10+
__main__.py # Entry point (auto-installs missing deps)
11+
cli.py # Menu dispatch router
12+
ci_fix.py # Core workflow: reproduce -> Claude analysis -> fix -> shell
13+
ci_reproduce.py # Docker container setup for CI reproduction
14+
claude_setup.py # Install Claude + copy credentials/config into container
15+
claude_session.py # Interactive Claude session launcher
16+
containers.py # Docker lifecycle (create, exec, cp, remove)
17+
preflight.py # Auth/setup validation (fail-fast)
18+
display_progress.py # Stream-json output processor for Claude
19+
ci_context/
20+
CLAUDE.md # CI-specific instructions for Claude inside containers
21+
setup.sh # User-facing setup script
22+
reproduce_ci.sh # Public wrapper for CI reproduction
23+
.helper_bash_functions # Sourced by users; provides colcon/rosdep helpers + ci_tool alias
24+
pylintrc # Pylint config (strict: fail-under=10.0, max-line-length=140)
25+
```
26+
27+
## Code Style
28+
29+
- Python 3.6+, `from __future__ import annotations` in all modules
30+
- snake_case everywhere; PascalCase for classes only
31+
- 4-space indentation, max 140 char line length
32+
- Pylint must pass at 10.0 (`pylintrc` at repo root)
33+
- Use `# pylint: disable=...` pragmas only when essential, with justification
34+
- Interactive prompts via `InquirerPy`; terminal UI via `rich`
35+
36+
## Conventions
37+
38+
- **Fail fast**: `PreflightError` for expected failures, `RuntimeError` for unexpected. No silent defaults, no fallback behaviour.
39+
- **Minimal diffs**: Only change what's requested. No cosmetic cleanups, no "while I'm here" changes.
40+
- **Self-documenting code**: Verbose variable names. Comments only for maths or external doc links.
41+
- **Subprocess calls**: Use `docker_exec()` / `run_command()` from `containers.py`. Pass `check=False` when non-zero is expected; `quiet=True` to suppress echo.
42+
- **State files**: `/ros_ws/.ci_fix_state.json` inside containers (session_id, phase, attempt_count)
43+
- **Learnings persistence**: `~/.ci_tool/learnings/{org}_{repo}.md` on host, `/ros_ws/.ci_learnings.md` in container
44+
45+
## Environment Variables
46+
47+
- `GH_TOKEN` or `ER_SETUP_TOKEN` — GitHub token (checked in preflight)
48+
- `CI_TOOL_SCRIPTS_BRANCH` — branch of er_build_tools_internal to fetch scripts from
49+
- `IS_SANDBOX=1` — injected into all docker exec calls for Claude
50+
51+
## Running
52+
53+
```bash
54+
# From host
55+
source ~/.helper_bash_functions
56+
ci_tool # interactive menu
57+
ci_fix # shortcut for ci_tool fix
58+
59+
# Lint
60+
pylint --rcfile=pylintrc bin/ci_tool/
61+
```
62+
63+
## Testing
64+
65+
No unit tests yet. Test manually by running `ci_tool` workflows end-to-end.
66+
67+
## Common Pitfalls
68+
69+
- Container Claude settings must use valid `defaultMode` values: `"acceptEdits"`, `"bypassPermissions"`, `"default"`, `"dontAsk"`, `"plan"`. The old `"dangerouslySkipPermissions"` is invalid.
70+
- `docker_cp_to_container` requires the container to be running.
71+
- Claude inside containers runs with `--dangerously-skip-permissions` flag (separate from the settings.json mode).

bin/ci_tool/claude_setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def copy_claude_config(container_name):
8787
with open(settings_path, encoding="utf-8") as settings_file:
8888
settings = json.load(settings_file)
8989

90-
settings.setdefault("permissions", {})["defaultMode"] = "dangerouslySkipPermissions"
90+
settings.setdefault("permissions", {})["defaultMode"] = "bypassPermissions"
9191

9292
with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as tmp:
9393
json.dump(settings, tmp, indent=2)

0 commit comments

Comments
 (0)