Metadata-Version: 2.4
Name: rime-code
Version: 0.1.0
Summary: A model-native compiler pipeline for Rime source files
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: openai>=1.30.0
Requires-Dist: rich>=13.7.1
Requires-Dist: rich-argparse>=1.5.2
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == "dev"
Dynamic: license-file

# Rime

> Code-prompting for code-generation models.

You write the shape. The model writes the code.

---

## The Problem

Prompting a code model in natural language is fast but loose:

```
"build a Student records service with add, get, update, and list operations"
```

The model decides the architecture. The model decides the types. The model decides how much state to introduce, what errors to raise, and what to do when the prompt is ambiguous.

You get code back, but not necessarily the code shape you intended.

Rime gives you a way to declare that shape up front without writing the implementation yourself.

---

## Example

This is the canonical example in the repository:

```rime
desc: "Build a student records service that stores students, fetches individual records, updates grades, and lists all known students."

types {
  StudentRecord = struct(student_id: string, name: string, grade: int)
}

state {
  students: list[StudentRecord] = []
}

contracts {
  contract add_student(student_id: string, name: string, grade: int) -> StudentRecord {
    desc: "Add a new student record to the system and return the created record"
    raises: DuplicateStudentID, InvalidGrade
  }

  contract get_student(student_id: string) -> StudentRecord | null {
    desc: "Return the student record matching the given identifier, or null if not found"
    requires: valid_student_id
  }

  contract update_grade(student_id: string, new_grade: int) -> StudentRecord {
    desc: "Update the grade for an existing student and return the updated record"
    raises: StudentNotFound, InvalidGrade
  }

  contract list_students() -> list[StudentRecord] {
    desc: "Return a list of all student records currently in the system"
    requires: non_empty_student_list
  }
}
```

That is the whole source input. Rime compiles it into an intermediate representation and then into validated Python.

---

## The Pipeline

Rime runs a model-native compiler pipeline:

```text
Students.rime -> Students.ir -> Students.py
source          IR            output
```

The current repository exposes three main commands:

1. `rime lint <input.rime>` reports non-fatal authoring warnings.
2. `rime ir <input.rime>` generates the textual IR.
3. `rime build <input.rime>` generates final Python.

You can also keep the intermediate artifact during build:

```bash
rime build examples/Students.rime --emit-ir
```

The pipeline validates three boundaries:

- `.rime` source structure and grounded syntax
- IR structure and semantic consistency
- generated Python syntax and contract-shape compliance against the IR

When IR or code validation fails, Rime performs corrective regeneration and feeds the validation diagnostic back into the next model attempt.

Example IR output:

```text
RIME-IR v0.1
entity: Students
language: python

[STATE]
students: list[StudentRecord] = []

[CONTRACTS]
add_student(student_id: string, name: string, grade: int) -> StudentRecord
  hint: Add a new student record to the system and return the created record
  raises: DuplicateStudentID, InvalidGrade
get_student(student_id: string) -> StudentRecord | null
  hint: Return the student record matching the given identifier, or null if not found
  requires: valid_student_id
update_grade(student_id: string, new_grade: int) -> StudentRecord
  hint: Update the grade for an existing student and return the updated record
  raises: StudentNotFound, InvalidGrade
list_students() -> list[StudentRecord]
  hint: Return a list of all student records currently in the system
  requires: non_empty_student_list

[ERRORS]
DuplicateStudentID: Declared failure mode from Rime source
InvalidGrade: Declared failure mode from Rime source
StudentNotFound: Declared failure mode from Rime source
```

The IR is not meant to be written by hand. It is the compiler-visible artifact that keeps the model workflow inspectable and correctable.

---

## What Rime Is

Rime is:

- a declaration language
- a contract surface for model-generated code
- a compiler-style control layer for code generation

Rime is not:

- a runtime language
- a general-purpose programming language
- a replacement for Python or other implementation languages

The implementation still ends up in Python or another target language. Rime exists one level above that.

---

## Why Not Just Use Natural Language?

|               | Natural language | Rime          |
| ------------- | ---------------- | ------------- |
| Architecture  | Model decides    | You decide    |
| Types         | Model infers     | You declare   |
| Failure modes | Model guesses    | You name them |
| Diffable      | No               | Yes           |
| Validatable   | No               | Yes           |
| Reproducible  | Rarely           | By design     |

Rime does not replace the model. It gives the model a better brief.

---

## Authoring Workflow

The recommended workflow is now:

1. start a new `.rime` file from the VS Code scaffold
2. let live editor diagnostics catch structural and modeling mistakes while you type
3. run `rime lint` for non-fatal authoring warnings
4. run `rime build` once the source shape is clean

This matters because many Rime mistakes are not raw syntax errors. They are modeling mistakes that are structurally valid but still likely to cause drift during generation.

---

## Quick Start

1. Create and activate a Python environment.
2. Install the project in editable mode: `pip install -e .[dev]`
3. Run `rime init` to configure your API key and model globally.
4. If you use VS Code, start a new `.rime` file from the built-in scaffold.
5. Lint the source: `rime lint examples/Students.rime`
6. Inspect the IR: `rime ir examples/Students.rime`
7. Build Python: `rime build examples/Students.rime --emit-ir`
8. Run the generated program: `python examples/Students.py`

---

## CLI

```text
rime                          opens interactive Rime shell
rime lint <file.rime>         shows non-fatal authoring warnings
rime build <file.rime>        compiles to validated Python
rime ir <file.rime>           emits IR only
rime shell                    opens shell explicitly
rime version                  shows installed version
```

Optional environment variables:

- `RIME_API_BASE_URL` for any OpenAI-compatible endpoint

---

## Syntax At A Glance

```rime
desc: "what this entity does"

types {
  TypeName = struct(field: type, ...)
  TypeName = enum(Variant1, Variant2, ...)
}

state {
  field: type = default
}

contracts {
  contract name(param: type) -> ReturnType {
    desc: "what this contract does"
    requires: ConditionName
    raises: ErrorName
  }
}
```

Rules that matter immediately:

- one entity per file
- the filename is the canonical entity name
- `desc` and `types` live in the preamble
- `types {`, `state {`, and `contracts {` are explicit block openers
- contract metadata lives inside `contract ... { ... }` blocks
- `requires:` and `raises:` are symbolic names, not quoted strings

Full syntax reference: `docs/rime-syntax.md`

For practical authoring guidance, see [guide.md](guide.md).

---

## Repository Layout

- `docs/ir-dsl.md` defines the current IR contract
- `docs/rime-syntax.md` defines the current Rime source surface
- `guide.md` explains how to write stronger Rime source and avoid common modeling mistakes
- `examples/Students.rime` is the canonical example input
- `src/rime/` contains the CLI, prompt builders, validators, and pipeline orchestration
- `tests/` covers the non-LLM seams with mocked model responses

---

## VS Code Support

The extension in `vscode-extension/` now provides:

- `.rime` file association
- auto-inserted scaffold for new empty `.rime` files
- manual scaffold snippet for existing files
- syntax highlighting
- live editor diagnostics for high-signal authoring mistakes
- semantic warnings for command/query mismatch, missing sibling IDs, and nested relationship objects

Useful settings:

- `rime.fileScaffold.enabled`
- `rime.liveLint.enabled`
- `rime.liveLint.debounceMs`

Install the `.vsix` locally or load the extension folder directly in VS Code.

---

## Status

**v0.1: working pipeline, intentionally small surface.**

Included now:

- single-file `.rime` input
- grounded source parsing and structural validation
- OpenAI-compatible model integration
- textual IR DSL
- Python code generation
- IR and Python contract validation
- automatic corrective regeneration
- CLI entrypoints for full build and IR-only output

Deferred for later:

- multi-file composition
- imports and richer type semantics
- behavioral guarantees

---

## Contributing

Issues and PRs are welcome. If you write a `.rime` file that breaks the pipeline or produces the wrong output, that is a bug worth filing.

---

## Developer Journey

If you want to use Rime to build something, the workflow is as follows:

### 1. Installation & Environment Setup
First, install Rime and set up your environment variables for whatever LLM provider you want to use:

```bash
pip install rime-code
rime init
```

### 2. Creating the Shape
Let's say you want to build a simple `Inventory` system. Instead of opening a Python file and starting from scratch, you create an `Inventory.rime` file and define the "shape" of your system. 

You write the **types**, the **state** you want to track, and the **contracts** (functions, what they require, and what errors they can throw):

```rime
desc: "A system to track store inventory, add stock, and purchase items."

types {
  Item = struct(id: string, name: string, price: float, quantity: int)
}

state {
  stock: list[Item] = []
}

contracts {
  contract add_stock(item_id: string, name: string, price: float, quantity: int) -> Item {
    desc: "Adds a new item to inventory or increases quantity if it exists"
    raises: InvalidPrice
  }

  contract purchase(item_id: string, amount: int) -> Item {
    desc: "Reduces inventory stock by amount for the given item"
    raises: ItemNotFound, InsufficientStock
  }
}
```

### 3. Linting (The Gut Check)
Instead of just guessing if you wrote it right, you can use Rime's CLI to check your work.
```bash
rime lint Inventory.rime
```
*If you are using the VS Code extension, you won't even need to do this manually—you'll see diagnostics directly in the editor.*

### 4. Let the Model Build It
Once the contract is clean, hand it over to Rime to compile it into an intermediate representation and generate the final Python code.
```bash
rime build Inventory.rime
```

### 5. Using the Output
Rime validates that the LLM didn't "hallucinate" anything outside of your defined bounds. Once `rime build` finishes successfully, you will have a newly minted `Inventory.py` file. You can immediately import that file into your core application and use the robust, error-checked logic exactly as you defined it. 

```python
# main.py
from Inventory import Inventory, InvalidPrice, InsufficientStock

store = Inventory()
store.add_stock("1", "Apple", 0.50, 100)

try:
    store.purchase("1", 50)
except InsufficientStock:
    print("Not enough stock!")
```

---

_Rime is syntax-inspired by Python and C#, owned by neither._
