# Bidi

JSON text with each bidi control written as its JSON escape, U+202E as the six characters `\u202E`, for a field where a person edits JSON a model or a tool wrote (a tool call's input before allowing it). The escape is visible and reorders nothing, and it parses back to the same character, so the input that's sent is still exactly the one proposed. In JSON text a control can only stand inside a string, where the escape means the same.

- Registry name: `bidi` (`@candor/bidi`)
- Tier: Free (MIT). No licence key needed.
- Docs: https://candor.themethodic.com/docs/bidi

## Install

```bash
npx candor-ui add bidi
```

Run `npx candor-ui@latest init` once first (https://candor.themethodic.com/get-started.md). Without the CLI: `npx shadcn@latest add @candor/bidi`.
It brings in: tokens.

## Functions

### neutralizeBidi

```ts
neutralizeBidi(text: string | undefined)
```

### escapeBidiJson

```ts
escapeBidiJson(json: string)
```

### hasBidiControls

```ts
hasBidiControls(text: string)
```

Whether `text` holds a bidi control character that `neutralizeBidi` would mark.

## Rules for using Candor UI

- Components take plain typed data. Never pass model output as HTML or render it as a link; messages are typed blocks.
- A control that can't be used says why: wrap it in `<Locked reason="…">`, don't just disable it.
- Don't show a value you don't have: leave it out (it renders as —) rather than guess. An estimate is labelled as one.
- Nothing is pre-selected in a decision a person makes, and the agent is named from your app's data, never from model output.
- Your app's words go in `LocaleProvider`: its fixed strings in `strings`, its nouns in `nouns`; entity kinds and agent roles in `EntityKindsProvider` and `AgentRolesProvider`.
