# Project workspace

A project gets a tab. Run `tern` anywhere inside a directory with `elide.pkl`, choose **Open project workspace**, and
the tab opens with Files, an editor on `elide.pkl`, a terminal in the project root and the Elide toolbar. Everything
the toolbar opens lands beside the editor, and the test runs it starts are visible to every view of the project,
Tern's agent included.

## Open a workspace

Run `tern` in the project directory or any directory below it, then use one of:

| From | Action |
| --- | --- |
| Command palette | **Open project workspace** |
| Status bar | **Workspace** |
| Command palette | Choose the project's `elide.pkl` file. |
| Project menu | **Open project workspace** |

The editor starts on `elide.pkl`, and files you click in Files open in it. Opening the workspace again refreshes its
toolbar and keeps your layout. Actions keep acting on the project they were opened for when focus moves elsewhere.

## Toolbar

| Button | Action |
| --- | --- |
| **Build project** | Opens the full Build page (`elide build --surface=screen`). |
| **Run tests** | Opens the project Tests page. |
| **Run project** | Runs `elide run` in a terminal in the project root. |
| **Debug** *file* | Debugs the file in the editor when it is JavaScript, TypeScript or Python; otherwise **Open debugger** opens the target picker. |
| **Source** | Opens the editor's file in the [source editor](#source-editor). Shown for supported files only. |
| **Open REPL** | Opens a [notebook](#repl-notebook). |
| **Serve project files** | Opens the Server page for the project directory. |
| **Show project files** | Reveals the project in Files. |

Results open beside the editor; pressing a button again focuses the pane it opened.

## Status bar and project menu

Inside a project, tabs take the project's name unless you named them, and the status bar shows:

| Segment | Click opens |
| --- | --- |
| The project's name | The project menu. |
| **Workspace** | The project workspace. |
| The pane's last `elide test`, `build` or `run` | The project's test runs for `elide test`; the project menu otherwise. |

The outcome reads `Tests passed` or `Tests failed`, `Built` or `Build failed`, `Ran` or `Run failed`, and
`… interrupted` after Ctrl+C or another signal. A build adds its counts: `Build failed · 3 errors, 1 warning`.

A failing `elide test` typed in a terminal also shows a **Tests failed** notification.

The project menu (status bar, palette **Project actions**, or the button in Files) lists **Run tests**, **Open
debugger**, **Open Elide source…**, **Open REPL**, **Serve static files**, **Serve a script…**, **Open manifest**,
**Open project workspace**, and **View test runs** once the project has test reports.

## Project Tests page

**Run tests** in a project opens the Tests page on the project's shared session. It shows the same tabs and keys as
[`elide test --surface=screen`](/docs/tern-terminal#elide-test-in-tern), plus:

| Feature | Behavior |
| --- | --- |
| Shared runs | Every Tests view of the project, and Tern's agent, see the same runs. Opening a second view does not start the tests again. |
| Run lifetime | Closing a view leaves its run going. **Cancel** (`x`) stops it. |
| Recent runs | The session keeps four runs; pick one to view it without rerunning. **View project test runs** reopens them. |
| **Debug this test** (`d`) | Launches the [debugger](/docs/tern-debugging) in test mode on a JavaScript or TypeScript test, with a breakpoint at the failure line. |
| Coverage | **Run with coverage** (`c`) adds the Coverage tab; see [Coverage](/docs/tern-coverage). |
| JVM tests | A whole-project run includes JVM tests; a path runs only the tests under it. |

Each test run has a five-minute deadline. A project session with no open view and no active run closes after two
minutes.

## Shared sessions with Tern's agent

Tern's built-in agent reaches the same project session through exports under `plugins.elide`. Runs it starts appear
in the Tests views, and a retried command with the same id does not start a second run.

| Export | Does |
| --- | --- |
| `project_open(root)` | Attaches to a project root and returns a binding. Focus changes never retarget it. |
| `project_read(binding)` | Reads run handles, counts, report paths and failure previews, and renews the attachment. |
| `test_run(binding, subject, command)` | Starts tests. `command` is a new UUID per intended run. |
| `test_cover(binding, subject, command)` | Starts tests with coverage. |
| `coverage_read(binding, run, query)` | Pages measured files (`{}`) or one file's lines (`{file = N}`), at most 100 per page. |
| `test_cancel(binding, run)` | Cancels a run. |
| `debug_launch`, `debug_read`, `debug_control`, `debug_takeover` | Drive the [debugger](/docs/tern-debugging#shared-control). |
| `project_close(binding)` | Releases the attachment; running tests continue. |

An attachment lapses after 60 seconds without a request.

## Source editor

The source editor is Elide's own editor block for JavaScript, TypeScript, Python, Kotlin and Java files in a project.
It adds the coverage, debug and diagnostics overlays to Tern's highlighting and editing.

| Open it from | Action |
| --- | --- |
| A file's menu | **Open with Elide source** |
| Workspace toolbar | **Source** |
| Project menu | **Open Elide source…** |
| Command palette | **Open Elide source view** |
| An `elide://source` link | Opens at the linked line. |

| Key | Action |
| --- | --- |
| `⌘S` | Save. A file changed on disk since it loaded asks before it is overwritten. |
| `⌘Z`, `⌘⇧Z` | Undo and redo. |
| `⌃F` | Find; `Enter` and `⇧Enter` select the next and previous match. |
| `⌃G` | Go to `line` or `line:column`. |
| `⌥Z` | Soft wrap. |
| `⌘/` | Toggle line comments. |
| `Tab`, `⇧Tab` | Indent and outdent. |
| `Esc` | Close find or go to line, then the overlay, then the editor. |

Enter keeps the line's indentation, and the indent unit is the file's own. A clean file reloads when it changes on
disk; a modified one asks first. Files over 600 lines show without highlighting, and files over 512 KiB show a notice instead of their text.

### Overlays

The overlay switch shows only the overlays that can act. Switching overlays changes only line tints: no text moves.

| Overlay | Shows | Keys |
| --- | --- | --- |
| **Coverage** | Covered, partly covered and uncovered rows from the newest coverage run. | `F5` runs coverage, `F6` refreshes. |
| **Debug** | Breakpoints and the paused line, with run and step controls while a target exists. | `F9` breakpoint, `F5` launch or resume; see [Debugging](/docs/tern-debugging#source-editor). |
| **Diagnostics** | Errors and warnings from the newest build report. | `F8`, `⇧F8` next and previous. |

Running coverage or launching the debugger with unsaved changes asks to save first. Details:
[Coverage](/docs/tern-coverage#source-editor), [Build diagnostics](/docs/tern-build#source-editor).

## `elide://` links

Elide puts `elide://` links on file names and locations in its Tern views. Any program can print them as OSC 8
hyperlinks; the plugin opens them.

| URL | Opens |
| --- | --- |
| `elide://source?path=<abs>[&root=<abs>][&line=<n>[&col=<n>]]` | The file at `line`: in the source editor for a supported file in a project, else in Tern's editor. |
| `elide://debug?root=<abs>&path=<abs>[&line=<n>]` | The project debugger with `path` as its target. |
| `elide://tests?root=<abs>` | The project's test runs. |
| `elide://help?topic=<slug>` | `elide help` at that topic, in a new pane beside the link. |

| Rule | Result |
| --- | --- |
| A malformed URL, a repeated key, a fragment, or `path` outside `root` | Dropped with a notification. |
| A `root` without `elide.pkl`, or a file that does not exist | Dropped with a notification. |
| A link without `root` to a file outside every detected project | Dropped with a notification. |
| A `root` this window has not detected | A prompt names the root and acts only when you choose to open it. |
| A remote host's pane | Dropped with a notification. |
| `+` in a value | A literal plus; encode spaces as `%20`. |

Paths are compared as written: use canonical, symlink-resolved paths.

## Output lenses

The plugin renders the output of these commands as structured blocks in the terminal. Output over 20,000 lines or
4 MiB, or with nothing to parse, stays raw.

| Lens | Commands | Shows |
| --- | --- | --- |
| Build | `elide javac …`, `elide kotlinc …`, `elide build` when it prints plain output | Diagnostics as cards grouped by file, with counts and an **Open** link per location. |
| TAP | `elide test --reporter=tap` | A pass and fail summary and a table of results, with each failure's message. |
| JSON | `elide project …`, any `elide … --json` | The JSON as an expandable tree. |

## REPL notebook

**Open REPL** opens a notebook backed by the embedded SDK; it works without a project. Cells take JavaScript, Python,
Kotlin, CEL and Pkl; **Open js REPL** and **Open python REPL** start in that language.

| Key | Action |
| --- | --- |
| `Enter` | Evaluate the cell. |
| `Shift+Enter` | New line. |
| `Ctrl+L` | Open the language picker; arrows choose and `Enter` switches. |

JavaScript and Python share live values: enter `const y = {"hi": 5}` in JavaScript, switch to Python, and `y.hi`
returns `5`. Changes to a shared object show in both languages. Declarations print nothing, objects render as
expandable JSON trees, and a language heading appears when the cell language changes. Each language keeps its own
draft and history. CEL evaluates expressions over the shared data, and Pkl evaluates modules and binds the result as
`_`. **Clear** clears the transcript and keeps the session's values.

## Serving from the plugin

**Serve directory or script**, **Serve static files**, **Serve a script…** and the toolbar's **Serve project files**
open the [Server page](/docs/tern-terminal#elide-serve-in-tern) in a new pane. Closing the pane stops the server.

## Next

A test fails on the Tests page. Press `d`: the [debugger](/docs/tern-debugging) launches it and stops at the failing line.
