Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ black . --check && isort . --check-only && flake8 . && mypy . --check-untyped-de
- `plain2code_logger.py` - Custom logging with elapsed time timestamps
- `plain2code_console.py` - Rich console wrapper with custom styles
- `plain2code_state.py` - Runtime state (render ID, counters, timing)
- `standard_template_library/` - Built-in code templates
- `standard_template_library/` - Built-in `.plain` templates (git subtree from `plainlang-examples`)
- `examples/` - Sample `.plain` projects

### Testing Architecture
Expand Down Expand Up @@ -223,6 +223,16 @@ Two logging modes:
### Running Plain2Code from Another Directory
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.

### Standard Template Library

`standard_template_library/` is a git subtree sourced from the `plainlang-examples` repository. It is **not** updated automatically — you must pull changes manually when the templates change upstream:

```bash
git subtree pull --prefix=standard_template_library git@github.com:Codeplain-ai/plainlang-examples.git main --squash
```

The subtree does not track a branch pointer. The branch (`main` above) is just an argument passed at pull time — git uses the `git-subtree-split` hash embedded in the commit history to determine what's new since the last sync.

### Windows Support
Windows users must use WSL (Windows Subsystem for Linux). The codebase has some platform-specific script handling (`.ps1` for Windows, `.sh` for Unix).

Expand Down
3 changes: 1 addition & 2 deletions plain2code.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import importlib.resources
import logging
import logging.config
import os
Expand Down Expand Up @@ -52,7 +51,7 @@
from tui.plain2code_tui import Plain2CodeTUI
from tui.plain_module_render_choice_tui import PlainModuleRenderChoiceTUI

DEFAULT_TEMPLATE_DIRS = importlib.resources.files("standard_template_library")
DEFAULT_TEMPLATE_DIRS = "standard_template_library"
RENDER_THREAD_SHUTDOWN_TIMEOUT = 0.7


Expand Down
1 change: 0 additions & 1 deletion standard_template_library/__init__.py

This file was deleted.

14 changes: 7 additions & 7 deletions tests/test_cli_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@ def test_display_active_free_trial(self, mock_console):
"type": "free",
"total": 50,
"remaining": 4,
"period_end": "2026-06-01T00:00:00+00:00",
"period_end": "2028-12-01T00:00:00+00:00",
}
_display_credit_line(plan_credits)

mock_console.print.assert_called_once()
call_args = mock_console.print.call_args[0][0]
assert "Free trial" in call_args
assert "4 of 50 remaining" in call_args
assert "expires Jun 1, 2026" in call_args
assert "expires Dec 1, 2028" in call_args

@patch("cli_output.status.console")
def test_display_active_pro_plan(self, mock_console):
Expand Down Expand Up @@ -110,13 +110,13 @@ def test_display_exhausted_credits(self, mock_console):
"type": "free",
"total": 50,
"remaining": 0,
"period_end": "2026-06-01T00:00:00+00:00",
"period_end": "2028-12-01T00:00:00+00:00",
}
_display_credit_line(plan_credits)

call_args = mock_console.print.call_args[0][0]
assert "0 of 50 remaining" in call_args
assert "expires Jun 1, 2026" in call_args
assert "expires Dec 1, 2028" in call_args

@patch("cli_output.status.console")
def test_timezone_naive_datetime(self, mock_console):
Expand Down Expand Up @@ -185,7 +185,7 @@ def test_has_active_plan_credits(self, mock_console):
"""Test when user has active plan credits."""
plan_credits = {
"remaining": 10,
"period_end": "2026-06-01T00:00:00+00:00",
"period_end": "2028-12-01T00:00:00+00:00",
}
_display_status_message(plan_credits, [])

Expand All @@ -211,7 +211,7 @@ def test_no_credits_remaining(self, mock_console):
"""Test when user has no credits remaining."""
plan_credits = {
"remaining": 0,
"period_end": "2026-06-01T00:00:00+00:00",
"period_end": "2028-12-01T00:00:00+00:00",
}
_display_status_message(plan_credits, [])

Expand Down Expand Up @@ -268,7 +268,7 @@ def test_valid_client_version(self, mock_console, mock_api_class):
"type": "free",
"total": 50,
"remaining": 10,
"period_end": "2026-06-01T00:00:00+00:00",
"period_end": "2028-12-01T00:00:00+00:00",
},
"purchased_credits": [],
}
Expand Down
Loading