57 lines
2.5 KiB
Markdown
57 lines
2.5 KiB
Markdown
|
|
# 10. Universal package mapping via project-relative path
|
||
|
|
|
||
|
|
**Date:** 2026-07-03
|
||
|
|
|
||
|
|
**Status:** Accepted
|
||
|
|
|
||
|
|
## Context
|
||
|
|
|
||
|
|
Each detected behavioral convention needs a "package" or "module" label so the LLM knows where to place generated code. Options:
|
||
|
|
|
||
|
|
- **No package info**: LLM guesses wrong directory, generates code at project root.
|
||
|
|
- **Per-language directory lookup**: Hardcode `kotlin`/`java`/`python` source root names. Breeds per-language branches — violates the zero-adapters constraint.
|
||
|
|
- **Full file path**: Too verbose, exposes absolute system paths (/home/user/project/...).
|
||
|
|
- **Project-relative path**: Pure path arithmetic, no language assumptions.
|
||
|
|
|
||
|
|
## Decision
|
||
|
|
|
||
|
|
Derive the package from the file's directory relative to the project root:
|
||
|
|
|
||
|
|
```python
|
||
|
|
def _file_to_package(fp, project_root):
|
||
|
|
rel = os.path.relpath(os.path.dirname(fp), project_root)
|
||
|
|
if rel == ".":
|
||
|
|
return "" # file at project root
|
||
|
|
return rel
|
||
|
|
```
|
||
|
|
|
||
|
|
No source root markers. No per-language directory names. Just `relpath` from the root the user passed to `analyze_directory`.
|
||
|
|
|
||
|
|
Examples:
|
||
|
|
```
|
||
|
|
/project/src/main/kotlin/org/app/User.kt → src/main/kotlin/org/app
|
||
|
|
/project/mypackage/module.py → mypackage
|
||
|
|
/project/lib/core/helper.rb → lib/core
|
||
|
|
/project/src/main.rs → src
|
||
|
|
/flat/project/file.py → flat
|
||
|
|
```
|
||
|
|
|
||
|
|
The project root is the directory passed to `analyze_directory(...)` and threaded down through `analyze_clusters` → `_top_packages`.
|
||
|
|
|
||
|
|
## Consequences
|
||
|
|
|
||
|
|
**Positive:**
|
||
|
|
- Zero per-language branches. Works identically for all 10 languages.
|
||
|
|
- No configuration or convention list to maintain.
|
||
|
|
- LLM sees the exact directory structure it should mirror in generated code.
|
||
|
|
|
||
|
|
**Negative:**
|
||
|
|
- `relpath` assumes the project root is the scan root. Scanning a subdirectory gives partial paths (still correct, but missing context).
|
||
|
|
- Files at the root of deeply nested projects get empty package strings. Mitigation: users should scan from the project root.
|
||
|
|
|
||
|
|
## Alternatives Considered
|
||
|
|
|
||
|
|
- **Per-language source root list (reverted)**: Hardcoded `kotlin`/`java`/`python` directory names. Brittle, violated zero-adapters constraint. Reverted to `feature/kotlin-specific-extras`.
|
||
|
|
- **Source root markers (`src`/`lib`/`pkg`/`app`)**: Broader than per-language but still assumes project layout conventions. Broke for flat repos, non-standard layouts.
|
||
|
|
- **No package mapping**: Simpler but useless — LLM can't locate generated code. The package label is essential for file placement.
|