# Lux Project Notes ## Development Environment This is a **Nix environment**. Tools like `cargo`, `rustc`, `clippy`, etc. are not available in the base shell. To run Rust/Cargo commands, use one of: ```bash nix develop --command cargo test nix develop --command cargo build nix develop --command cargo clippy nix develop --command cargo fmt ``` Or enter the development shell first: ```bash nix develop # then run commands normally cargo test ``` The `lux` binary can be run directly if already built: ```bash ./target/debug/lux test ./target/release/lux ``` For additional tools not in the dev shell: ```bash nix-shell -p ``` ## Development Workflow When making changes: 1. **Always run tests**: `cargo check && cargo test` - fix all errors and warnings 2. **Lint the Lux code**: `./target/release/lux lint` - fix warnings 3. **Check Lux code**: `./target/release/lux check` - type check + lint in one pass 4. **Format Lux code**: `./target/release/lux fmt` - auto-format all .lux files 5. **Write tests**: Add tests to cover new code 6. **Document features**: Provide documentation and tutorials for new features/frameworks 7. **Fix language limitations**: If you encounter parser/type system limitations, fix them (without regressions on guarantees or speed) 8. **Git commits**: Always use `--no-gpg-sign` flag ### Post-work checklist (run after each committable change) **MANDATORY: Run the full validation script after every committable change:** ```bash ./scripts/validate.sh ``` This script runs ALL of the following checks and will fail if any regress: 1. `cargo check` — no Rust compilation errors 2. `cargo test` — all Rust tests pass (currently 387) 3. `cargo build --release` — release binary builds 4. `lux test` on every package (path, frontmatter, xml, rss, markdown) — all 286 package tests pass 5. `lux check` on every package — type checking + lint passes If `validate.sh` is not available or you need to run manually: ```bash nix develop --command cargo check # No Rust errors nix develop --command cargo test # All Rust tests pass nix develop --command cargo build --release # Build release binary cd ../packages/path && ../../lang/target/release/lux test # Package tests cd ../packages/frontmatter && ../../lang/target/release/lux test cd ../packages/xml && ../../lang/target/release/lux test cd ../packages/rss && ../../lang/target/release/lux test cd ../packages/markdown && ../../lang/target/release/lux test ``` **Do NOT commit if any check fails.** Fix the issue first. ### Commit after every piece of work **After completing each logical unit of work, commit immediately.** This is NOT optional — every fix, feature, or change MUST be committed right away. Do not let changes accumulate uncommitted across multiple features. Each commit should be a single logical change (one feature, one bugfix, etc.). Use `--no-gpg-sign` flag for all commits. **Commit workflow:** 1. Make the change 2. Run `./scripts/validate.sh` (all 13 checks must pass) 3. `git add` the relevant files 4. `git commit --no-gpg-sign -m "type: description"` (use conventional commits: fix/feat/chore/docs) 5. Move on to the next task **Never skip committing.** If you fixed a bug, commit it. If you added a feature, commit it. If you updated docs, commit it. Do not batch unrelated changes into one commit. **IMPORTANT: Always verify Lux code you write:** - Run with interpreter: `./target/release/lux file.lux` - Compile to binary: `./target/release/lux compile file.lux` - Both must work before claiming code is functional - The C backend has limited effect support (Console, File only - no HttpServer, Http, etc.) ## CLI Commands & Aliases | Command | Alias | Description | |---------|-------|-------------| | `lux fmt` | `lux f` | Format .lux files | | `lux test` | `lux t` | Run test suite | | `lux check` | `lux k` | Type check + lint | | `lux lint` | `lux l` | Lint only (with `--explain` for detailed help) | | `lux serve` | `lux s` | Static file server | | `lux compile` | `lux c` | Compile to binary | ## Documenting Lux Language Errors When working on any major task that involves writing Lux code, **document every language error, limitation, or surprising behavior** you encounter. This log is optimized for LLM consumption so future sessions can avoid repeating mistakes. **File:** Maintain an `ISSUES.md` in the relevant project directory (e.g., `~/src/blu-site/ISSUES.md`). **Format for each entry:** ```markdown ## Issue N: **Category**: Parser limitation | Type checker gap | Missing feature | Runtime error | Documentation gap **Severity**: High | Medium | Low **Status**: Open | **Fixed** (commit hash or version) <1-2 sentence description of the problem> **Reproduction:** ```lux // Minimal code that triggers the issue ``` **Error message:** `` **Workaround:** **Fix:** ``` **Rules:** - Add new issues as you encounter them during any task - When a previously documented issue gets fixed, update its status to **Fixed** and note the commit/version - Remove entries that are no longer relevant (e.g., the feature was redesigned entirely) - Keep the summary table at the bottom of ISSUES.md in sync with the entries - Do NOT duplicate issues already documented -- check existing entries first ## Code Quality - Fix all compiler warnings before committing - Ensure all tests pass (currently 387 tests) - Add new tests when adding features - Keep examples and documentation in sync ## Lux Language Notes ### Top-level expressions Bare `run` expressions are not allowed at top-level. You must wrap them in a `let` binding: ```lux // WRONG: parse error run main() with {} // CORRECT let output = run main() with {} ``` ### String methods Lux uses module-qualified function calls, not method syntax on primitives: ```lux // WRONG: not valid syntax path.endsWith(".html") // CORRECT String.endsWith(path, ".html") ``` ### Available String functions Key string functions (all in `String.` namespace): - `String.length(s)` - get length - `String.startsWith(s, prefix)` - check prefix - `String.endsWith(s, suffix)` - check suffix - `String.split(s, delimiter)` - split into list - `String.join(list, delimiter)` - join list - `String.substring(s, start, end)` - extract substring - `String.indexOf(s, needle)` - find position (returns Option) - `String.replace(s, old, new)` - replace occurrences - `String.trim(s)` - trim whitespace - `String.toLower(s)` / `String.toUpper(s)` - case conversion