# Coming from ansi-escapes

> An ansi-escapes alternative for the OSC half — hyperlinks, images, title, clipboard, notifications, bell — where every capability has a static projection for pipes and agents. Graded 1 / 4 by ansi-escapes' own suite, the ceiling for an OSC-only package; no drop-in is claimed.

Source: https://paratext.interlace.tools/docs/coming-from/ansi-escapes

**paratext** is an **ansi-escapes alternative** for its OSC half: the escapes that address
the terminal *program* — hyperlinks, inline images, the window title, the clipboard, desktop
notifications, the working directory and the bell. The CSI half — the cursor, erasing,
scrolling, the alternate screen — is out of scope. paratext does **not** claim to be an
ansi-escapes drop-in.

## Migrate from ansi-escapes: the OSC members only

The root is call-compatible with ansi-escapes for the four OSC members of its surface:

```diff
- import ansiEscapes, { link, image, setCwd, beep } from 'ansi-escapes';
+ import ansiEscapes, { link, image, setCwd, beep } from 'paratext';
```

The CSI names are still *declared*, as `undefined`, so a module that imports them loads
rather than dying on an ESM named import — and TypeScript types them so that calling one is
a compile error. If your program moves the cursor or erases lines with ansi-escapes, keep
ansi-escapes for those calls; in the burgee family that half belongs to flagstaff, which
draws the grid, and closeout, which puts it back.

## Is paratext compatible with ansi-escapes?

For the OSC half only, and the grade shows the boundary. ansi-escapes' own suite, vendored
and unmodified apart from the import specifier, runs against `paratext` beside a control that
runs it against the real package:

| | passing | rate |
| :-- | --: | --: |
| `paratext` | 1 / 4 | 25.0% |
| ansi-escapes itself (control) | 4 / 4 | 100.0% |

From [Compatibility](https://burgee.interlace.tools/docs/compatibility), which `npm run compat:page` generates from the
oracle's last run; that page is the authority. Three of the suite's four cases assert CSI,
which paratext does not implement, so **1 / 4 is the ceiling on this row** — complete for the
OSC half, and not a compatibility claim. The same page grades the `paratext/terminal-link`
and `paratext/term-img` paths against those packages' suites.

## What you gain over ansi-escapes

No terminal answers "do you support OSC 1337", so emitting the bytes and hoping is what puts
`\u001B]1337;File=inline=1;…` across the screen of anyone who piped your output to a file.
paratext never hopes:

- **Every capability has a static projection.** `emit()` returns it whenever support is absent
  or unknown: an image becomes its caption, a notification a printed line, a hyperlink
  `text (url)`. On a pipe, that projection is what an agent reads.
- **The fallback is required.** A capability without one is refused at registration; there is
  no opt-out.
- **A capability is data.** Plain objects, no functions, so a capability travels through
  JSON, is diffable, and is validated against `paratext/schema.json` without running its
  author's code.

```js
import { emit, processRuntime } from 'paratext';

emit(processRuntime(), 'link', { text: 'Docs', url: 'https://x.dev' });
// a terminal that supports it: the OSC 8 hyperlink
// a pipe:                      Docs (https://x.dev)
```

## When to switch from ansi-escapes

- Your CLI emits hyperlinks, images or notifications, and its output is ever piped, logged or
  read by an agent.
- You want new terminal capabilities registered as data rather than waiting for a release.

The registry, the schema and the plugin host are on [paratext](/docs).
