# pi-julia

A [pi](https://github.com/earendil-works/pi) extension that eliminates Julia's TTFX
(time-to-first-execution) problem and brings full code intelligence to LLM-driven Julia
workflows.

It runs two background services:

- **[DaemonMode.jl](https://github.com/dmolina/DaemonMode.jl)** — a persistent warm Julia
  process so the agent can execute code without paying compilation cost on every call.
- **[LanguageServer.jl](https://github.com/julia-vscode/LanguageServer.jl)** — a full LSP
  server for hover docs, diagnostics, completions, and go-to-definition.

## Requirements

- Julia ≥ 1.9
- [pi](https://github.com/earendil-works/pi) installed

## Installation

```bash
pi install pi-julia
```

On first use, `pi-julia` will automatically install DaemonMode.jl into Julia's global
environment. This is a one-time step and does not touch your project's `Project.toml`.
LanguageServer.jl is resolved from your VS Code Julia extension if installed, or installed
into the global environment otherwise.

## Usage

Start both servers for a project:

```
/julia-start /path/to/project
```

Or pass no path to auto-detect the nearest `Project.toml`, falling back to Julia's global
environment if none is found:

```
/julia-start
```

Stop both servers:

```
/julia-stop
```

Once started, the agent has access to these tools:

| Tool | Description |
|---|---|
| `julia_start` | Start (or restart) both servers |
| `julia_stop` | Stop both servers |
| `julia_run_file` | Execute a `.jl` file via DaemonMode (no TTFX) |
| `julia_run_expr` | Execute a Julia code block via DaemonMode (no TTFX) |
| `julia_doc` | Fetch a docstring by symbol name via LSP |
| `julia_hover` | Docstring and type at a file position via LSP |
| `julia_diagnostics` | Errors and warnings for a file (or all open files) via LSP |
| `julia_complete` | Completion suggestions at a file position via LSP |
| `julia_definition` | Go-to-definition for a symbol via LSP |

## Configuration

Persist a project path and enable auto-start in `~/.pi/agent/settings.json`:

```json
{
  "pi-julia": {
    "projectPath": "/path/to/your/julia/project",
    "autoStart": true
  }
}
```

## How it works

```
pi-julia
  │
  ├─ DaemonMode server
  │     julia --project=<path> -e 'using Revise; using DaemonMode; serve(<port>)'
  │     port is deterministic per project path — multiple projects run simultaneously
  │
  └─ LanguageServer.jl
        julia --project=<ls-env> -e 'using LanguageServer; runserver(stdin, stdout, <path>)'
        resolves env from VS Code extension, global env, or installs automatically
```

[Revise.jl](https://github.com/timholy/Revise.jl) is loaded on the DaemonMode server so
source edits are hot-reloaded without a restart. It is expected to be in your global Julia
environment (standard for Julia development).

## Limitations

- ~400 ms overhead per `julia_run_*` call (Julia client process startup), independent of
  what the code does.
- Adding a new package requires restarting the server (`/julia-start` again), since
  DaemonMode cannot load new packages into a running process.
- LanguageServer.jl on Julia 1.12 has a known upstream stability issue
  ([#1366](https://github.com/julia-vscode/LanguageServer.jl/issues/1366)).
