Skip to content

Commit 7031ae2

Browse files
committed
add CLAUDE.md file and common CC settings
1 parent d9c0b54 commit 7031ae2

2 files changed

Lines changed: 254 additions & 0 deletions

File tree

.claude/settings.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"includeCoAuthoredBy": false,
3+
"attribution": { "commit": "", "pr": "" },
4+
"permissions": {
5+
"allow": [
6+
"Read",
7+
"Bash(pytest *)",
8+
"Bash(black *)",
9+
"Bash(isort *)",
10+
"Bash(flake8 *)",
11+
"Bash(mypy *)",
12+
"Bash(coverage *)",
13+
"Bash(git status*)",
14+
"Bash(git diff*)",
15+
"Bash(git log*)",
16+
"Bash(ls *)",
17+
"Bash(cat *)",
18+
"Bash(grep *)",
19+
"Bash(find *)",
20+
"Bash(head *)",
21+
"Bash(tail *)",
22+
"Bash(conda *)",
23+
"Bash(.venv/bin/python *)",
24+
"Bash(python plain2code.py *)"
25+
]
26+
}
27+
}

CLAUDE.md

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Overview
6+
7+
This is **codeplain**, a Python CLI tool that renders code from `***plain` specification files using the Codeplain API. The tool acts as a client that:
8+
1. Parses `***plain` spec files (a domain-specific language for software specifications)
9+
2. Sends specs to the Codeplain API (LLM-based code generation service)
10+
3. Manages an iterative state-machine-driven render process with testing and refactoring cycles
11+
4. Outputs generated code to a build folder
12+
13+
The codebase serves two audiences:
14+
- **End users**: developers who write `***plain` specs and run `plain2code.py` to generate code
15+
- **Internal devs**: maintaining the renderer itself (this codebase)
16+
17+
### Related Repository: plain2code_rest_api
18+
19+
This repository has a sibling repository **`plain2code_rest_api`** which contains the backend API service that this client communicates with. The two repositories are typically cloned as siblings:
20+
21+
```
22+
parent-directory/
23+
├── codeplain/ # This repository (client)
24+
└── plain2code_rest_api/ # Backend API service
25+
```
26+
27+
**When to work across both repositories:**
28+
- API contract changes (request/response formats)
29+
- Adding new endpoints or modifying existing ones
30+
- Debugging communication issues between client and server
31+
- End-to-end feature development that requires both client and server changes
32+
33+
When working on features that span both repositories, coordinate changes carefully to maintain backward compatibility or plan coordinated deployments.
34+
35+
## Development Setup
36+
37+
### Prerequisites
38+
- Python 3.11+
39+
- `CODEPLAIN_API_KEY` environment variable set
40+
41+
### Installation
42+
```bash
43+
python -m venv .venv
44+
source .venv/bin/activate # On Windows: .venv\Scripts\activate
45+
pip install -r requirements.txt
46+
```
47+
48+
### Git Hooks
49+
A pre-push hook runs automatically on `git push` and executes:
50+
- Black formatting check
51+
- isort import sorting check
52+
- Flake8 linting
53+
- Mypy type checking
54+
- Full test suite with coverage
55+
56+
Hook is located at `.git/hooks/pre-push`.
57+
58+
## Common Commands
59+
60+
### Running the Tool
61+
```bash
62+
# Basic usage - render a .plain file
63+
python plain2code.py path/to/file.plain
64+
65+
# Dry run (parse and validate .plain files without rendering code)
66+
# This parses the spec files, resolves imports/requires, but doesn't generate code
67+
python plain2code.py path/to/file.plain --dry-run
68+
69+
# Enable file logging (writes to codeplain.log in same dir as .plain file)
70+
python plain2code.py path/to/file.plain --log-to-file
71+
72+
# Headless mode (no TUI, logs to file only)
73+
python plain2code.py path/to/file.plain --headless
74+
75+
# Render specific functionality range
76+
python plain2code.py file.plain --render-range 1,3 # Render functionalities 1-3
77+
python plain2code.py file.plain --render-from 2 # Resume from functionality 2
78+
79+
# Run with examples
80+
cd examples/example_hello_world_python
81+
python ../../plain2code.py hello_world_python.plain
82+
cd build && python hello_world.py
83+
```
84+
85+
### Testing
86+
```bash
87+
# Run all tests
88+
pytest tests/ -v
89+
90+
# Run specific test file
91+
pytest tests/test_plain_modules.py -v
92+
93+
# Run specific test
94+
pytest tests/test_plain_modules.py::test_get_next_frid_within_same_module -v
95+
96+
# Run with coverage
97+
coverage run -m pytest tests/ -v
98+
coverage report
99+
coverage html # Generates htmlcov/index.html
100+
```
101+
102+
### Code Quality
103+
```bash
104+
# Format code
105+
black .
106+
107+
# Sort imports
108+
isort .
109+
110+
# Lint
111+
flake8 .
112+
113+
# Type check
114+
mypy . --check-untyped-defs
115+
116+
# Run all checks (same as pre-push hook)
117+
black . --check && isort . --check-only && flake8 . && mypy . --check-untyped-defs && coverage run -m pytest tests/ -v && coverage report
118+
```
119+
120+
## Architecture
121+
122+
### High-Level Flow
123+
1. **Entry Point** (`plain2code.py`): CLI argument parsing, logging setup, TUI initialization
124+
2. **Module Loading** (`plain_modules.py`, `plain_file.py`): Parse `.plain` files into `PlainModule` objects with dependency trees
125+
3. **Rendering Orchestration** (`module_renderer.py`): Coordinates render process across modules
126+
4. **State Machine** (`render_machine/`): Hierarchical state machine drives the render lifecycle
127+
5. **API Communication** (`codeplain_REST_api.py`): HTTP client for Codeplain API
128+
6. **Code Generation** (`render_machine/code_renderer.py`): Main code renderer class that orchestrates the code generation workflow using a hierarchical state machine.
129+
7. **TUI** (`tui/`): Textual-based terminal UI showing render progress
130+
131+
### Key Concepts
132+
133+
**Plain Modules**: A `.plain` file can `import` other `.plain` files, creating a module dependency tree. The renderer processes required modules first (depth-first), then the top module.
134+
135+
**Functionalities (FRIDs)**: Each functional requirement in a `.plain` file has a unique ID (FRID). The renderer processes them sequentially. State is checkpointed after each FRID.
136+
137+
**Render State Machine** (`render_machine/states.py`): Hierarchical FSM with states like:
138+
- `IMPLEMENTING_FRID``PROCESSING_UNIT_TESTS``REFACTORING_CODE``PROCESSING_CONFORMANCE_TESTS`
139+
- Transitions handled by triggers in `render_machine/triggers.py`
140+
- Config in `render_machine/state_machine_config.py`
141+
142+
**Memory Management** (`memory_management.py`): Tracks previously rendered code to provide context to the LLM for incremental changes. Uses git commits to persist checkpoints.
143+
144+
**Partial Rendering** (`partial_rendering.py`): Detects when specs or code changed and determines the optimal starting point to resume rendering (avoids full re-renders).
145+
146+
**Event Bus** (`event_bus.py`): Pub/sub for UI updates. Events defined in `plain2code_events.py` (e.g., `LogMessageEmitted`, `RenderCompleted`).
147+
148+
### Directory Structure
149+
150+
- `plain2code.py` - Main CLI entry point
151+
- `plain_modules.py` - Module dependency resolution
152+
- `plain_file.py` - `.plain` file parser
153+
- `plain_spec.py` - Spec extraction and FRID utilities
154+
- `module_renderer.py` - Orchestrates render for a module
155+
- `render_machine/` - State machine implementation
156+
- `code_renderer.py` - Generates code via templates
157+
- `states.py` - State name constants
158+
- `triggers.py` - State transition logic
159+
- `render_context.py` - Shared context across states
160+
- `conformance_tests.py` - Test generation and execution
161+
- `tui/` - Terminal UI (Textual framework)
162+
- `plain2code_tui.py` - Main TUI app
163+
- `components.py` - Custom UI widgets
164+
- `codeplain_REST_api.py` - API client
165+
- `memory_management.py` - Context tracking
166+
- `git_utils.py` - Git operations for checkpointing
167+
- `file_utils.py` - File I/O utilities
168+
- `concept_utils.py` - Concept validation (***plain language feature)
169+
- `plain2code_logger.py` - Custom logging with elapsed time timestamps
170+
- `plain2code_state.py` - Runtime state (render ID, counters, timing)
171+
- `standard_template_library/` - Built-in code templates
172+
- `examples/` - Sample `.plain` projects
173+
174+
### Testing Architecture
175+
176+
Tests are in `tests/` and cover:
177+
- `test_plain_modules.py` - Module loading, dependency resolution, metadata
178+
- `test_plainfileparser.py` - `.plain` syntax parsing
179+
- `test_partial_rendering.py` - Render resumption logic
180+
- `test_git_utils.py` - Git checkpoint/restore operations
181+
- `test_imports.py`, `test_requires.py` - Module dependency resolution
182+
183+
No integration tests hit the actual Codeplain API (would require API key + network). Testing focuses on parser, state management, and file operations.
184+
185+
### Logging
186+
187+
Two logging modes:
188+
1. **Console (TUI)**: Logs displayed in TUI with relative timestamps `[HH:MM:SS]` (elapsed since render start, accounts for pauses)
189+
2. **File**: Same format as TUI, written to `codeplain.log` in the `.plain` file's directory
190+
191+
`ElapsedTimeFormatter` (in `plain2code_logger.py`) uses `RunState` to calculate elapsed time. Format: `[HH:MM:SS] LEVEL logger_name: message`
192+
193+
## Important Notes
194+
195+
### Plain Specification Language
196+
- `***plain` is a Markdown-like DSL for software specs
197+
- Docs at https://www.plainlang.org/docs/
198+
- Parser handles sections: definitions, functional specs, implementation reqs, test reqs, acceptance tests
199+
- Concepts (domain terms) validated across modules via `concept_utils.py`
200+
201+
### Code Generation Process
202+
- Templates in `standard_template_library/` use Liquid2 syntax
203+
- Template search order: (1) `.plain` file dir, (2) `--template-dir`, (3) built-in standard lib
204+
- Generated code written to `build/` (configurable via `--build-folder`)
205+
- Each FRID render produces a git commit in build folder for rollback capability
206+
207+
### Configuration
208+
- `config.yaml` can be placed in `.plain` file dir or CWD
209+
- Specifies test scripts, template dirs, build paths
210+
- CLI args override config file values
211+
212+
### Running Plain2Code from Another Directory
213+
The tool can be run from any directory by providing an absolute or relative path to the `.plain` file. All paths (build folder, log file, templates) are resolved relative to the `.plain` file's directory, not the current working directory, unless explicitly overridden via CLI arguments.
214+
215+
### Windows Support
216+
Windows users must use WSL (Windows Subsystem for Linux). The codebase has some platform-specific script handling (`.ps1` for Windows, `.sh` for Unix).
217+
218+
### CRITICAL: No User-Specific Paths in Version Control
219+
**Never commit files containing user-specific absolute paths** (e.g., `/Users/username/...`, `/home/username/...`, `C:\Users\...`) to version-controlled files like:
220+
- `.claude/settings.json` - Use relative paths (`.venv/bin/python`) instead of absolute paths
221+
- `config.yaml` or any config files
222+
- Any documentation or scripts
223+
224+
User-specific paths should only exist in:
225+
- `.claude/settings.local.json` (gitignored)
226+
- Personal `.env` files (gitignored)
227+
- User's global `~/.claude/settings.json`

0 commit comments

Comments
 (0)