# Workspace

The Workspace is the user's current UI context — what they are looking at, what is selected, and what persistent state belongs to their session. It is a collection of named **stores** that are kept in sync between the web client, the gateway, and the user's sandbox container.

Use `WorkspaceRead(store_name)` to read any store and `WorkspacePatch(store_name, patch)` to update it. Patches use JSON Patch (RFC 6902) format.

---

## Stores

### `chartState` — Current chart view (persistent)

Tracks what the user is currently looking at on the TradingView chart.

| Field | Type | Description |
|---|---|---|
| `symbol` | string | Active trading pair in `SYMBOL.EXCHANGE` format (e.g. `BTC/USDT.BINANCE`) |
| `period` | number | OHLC bar period in seconds (e.g. `900` = 15 min, `3600` = 1 h) |
| `start_time` | number \| null | Unix timestamp of left edge of visible range, or null for auto |
| `end_time` | number \| null | Unix timestamp of right edge of visible range, or null for auto |
| `selected_shapes` | string[] | IDs of currently selected drawing/annotation shapes |

When the user says "the current chart" or "what's selected", read `chartState` first.

---

### `indicators` — Active indicators on the chart (persistent)

A flat map of `indicator_id → IndicatorInstance`. Each entry represents one study currently plotted on the TradingView chart.

**`IndicatorInstance` fields:**

| Field | Type | Description |
|---|---|---|
| `id` | string | Unique ID for this instance |
| `pandas_ta_name` | string | Internal name used in strategy/indicator scripts (e.g. `RSI_14`, `custom_MyIndicator`) |
| `instance_name` | string | Human-readable label shown on chart |
| `parameters` | object | Key/value parameter map (e.g. `{ length: 14 }`) |
| `tv_study_id` | string? | TradingView study ID (assigned by TV after the study is added) |
| `tv_indicator_name` | string? | TradingView indicator name for built-in studies |
| `tv_inputs` | object? | TradingView input overrides keyed by TV input name |
| `visible` | boolean | Whether the study is visible on the chart |
| `pane` | string | `"price"` to overlay on price pane, `"separate"` for its own panel |
| `symbol` | string? | Override symbol if different from `chartState.symbol` |
| `created_at` | number? | Unix timestamp when added |
| `modified_at` | number? | Unix timestamp when last changed |
| `custom_metadata` | object? | Present only for `custom_*` indicators; drives TradingView custom study construction (see below) |

**`custom_metadata` sub-fields** (for custom indicators only):

| Field | Type | Description |
|---|---|---|
| `display_name` | string | Human-readable indicator title shown in TV |
| `parameters` | object | Parameter schema: `{ name: { type, default, description, min?, max? } }` |
| `input_series` | string[] | Input price series required (e.g. `["close"]`) |
| `output_columns` | array | Each entry: `{ name, display_name?, description?, plot? }` where `plot` has `{ style, color?, linewidth?, visible? }` |
| `pane` | `"price"` \| `"separate"` | Default pane placement |
| `filled_areas` | array? | Shaded regions between two plots or hlines |
| `bands` | array? | Horizontal reference lines (e.g. RSI 70/30) |

---

### `shapes` — Chart drawings and annotations (persistent)

```json
{ "shapes": { "<shape_id>": Shape } }
```

Each `Shape` has:

| Field | Type | Description |
|---|---|---|
| `id` | string | Unique shape ID |
| `type` | string | Drawing type (e.g. `"trend_line"`, `"horizontal_line"`, `"rectangle"`) |
| `points` | array | Control points: `{ time: unix_ts, price: number, channel?: string }` |
| `color` | string? | Hex color |
| `line_width` | number? | Line thickness |
| `line_style` | string? | `"solid"`, `"dotted"`, `"dashed"` |
| `properties` | object? | Additional type-specific properties |
| `symbol` | string? | Symbol the shape belongs to |
| `created_at` | number? | Unix timestamp |
| `modified_at` | number? | Unix timestamp |

---

### `indicator_types` — Custom indicator registry (persistent)

```json
{ "types": { "<script_name>": CustomIndicatorMetadata } }
```

Maps custom indicator script names to their `CustomIndicatorMetadata` (same structure as `custom_metadata` above). Populated when a custom indicator is created or updated by the indicator agent. The web client uses this to register custom TradingView studies.

---

### `strategy_types` — Strategy registry (persistent)

```json
{ "types": { "<script_name>": StrategyMetadata } }
```

Maps strategy script names to their metadata. Used by the web client to know which strategies are available.

---

### `research_types` — Research script registry (persistent)

```json
{ "types": { "<script_name>": ResearchMetadata } }
```

Maps research script names to their metadata.

---

### `channelState` — Connected channels (transient, gateway-only)

Tracks which communication channels (WebSocket, Telegram, etc.) are connected to the current session. **Not synced to web clients.**

```json
{ "connected": { "<channel_id>": { type, connectedAt, capabilities } } }
```

---

## Sync Protocol

Stores are kept in sync using JSON Patch (RFC 6902) messages:
- **snapshot** — full state dump sent on connect or after missed patches
- **patch** — incremental change with a monotonic sequence number

Stores marked `persistent` are saved to the user's container at `/data/workspace/{store_name}.json` and survive session reconnects.
