# Claude.ai Slash Command Skills Picker Parity Report

Capture date: 2026-07-04 18:03:44Z / 22:03:44 Asia-Tbilisi
Claude surface: authenticated claude.ai new chat in RocketMinds org
Viewport: 1091 x 818 CSS px, devicePixelRatio 1.1
Issues: https://github.com/Rocket-Minds/tegy-io/issues/708 and https://github.com/Rocket-Minds/tegy-io/issues/710

## Executive Summary

Claude's slash-command skills picker is a client-side composer feature backed by server-loaded organization catalogs. The catalog is loaded during normal page bootstrap, then slash typing, filtering, keyboard movement, escape, and chip insertion happen locally in the ProseMirror composer.

The important parity point for Tegy: do not call the server for every slash keystroke. Fetch the skill/plugin catalog up front, keep a local filtered candidate list, render a popover anchored above the composer, and insert a structured non-editable skill chip when the user selects a command. Server involvement resumes only when the eventual chat message is submitted. Follow-up edge-case captures confirm that no-match, deletion, recovery, Escape suppression, and chip deletion are also local composer behavior.

## Evidence Bundle

- Frame samples: `evidence/json/*-frame-samples.json`
- State snapshots: `evidence/json/00-idle-loaded.json` through `99-after-clear.json`
- Edge-case final states: `evidence/json/edge-06-middle-delete-from-biz.json` through `edge-11-chip-backspace-removal.json`
- Edge-case per-character timelines: `evidence/json/edge-timeline-*.json`
- Network logs: `evidence/json/network-events.redacted.json`, `edge-case-capture-summary.redacted.json`, and `edge-timeline-summary.redacted.json`
- API schema summary: `evidence/json/catalog-schema-summary.redacted.json`
- Contact sheets: `evidence/frames/*contact-sheet.png`
- Final screenshots: `evidence/screenshots/*.png`

## Full State Graph

```mermaid
stateDiagram-v2
  [*] --> S0_Idle
  S0_Idle --> S1_SlashTextPending: user types '/'
  S1_SlashTextPending --> S2_MenuOpenAllCommands: local TipTap suggestion plugin mounts menu
  S2_MenuOpenAllCommands --> S3_Filtering: user types query chars after slash
  S3_Filtering --> S3a_MenuTemporarilyUnmounted: filter/remount cycle during some keystrokes
  S3a_MenuTemporarilyUnmounted --> S3b_FilteredMenuOpen: local candidate list recalculated
  S3b_FilteredMenuOpen --> S4_HighlightedCandidate: arrow keys or default first candidate
  S4_HighlightedCandidate --> S5_SelectedSkillChip: click/enter candidate
  S5_SelectedSkillChip --> S0_Idle: composer clear/backspace
  S3b_FilteredMenuOpen --> S6_EscapeClosed: Escape
  S6_EscapeClosed --> S3b_FilteredMenuOpen: type/delete while slash token remains
  S6_EscapeClosed --> S0_Idle: clear composer
  S2_MenuOpenAllCommands --> S0_Idle: clear composer or blur
```

## State Details

### S0 - Idle Composer

- Composer is a ProseMirror contenteditable with role textbox and aria-label `Write your prompt to Claude`.
- No menu exists in DOM.
- Composer rect in capture: left 250.2, top 336.5, width 636.2, height 22.4.
- No slash command localStorage entry existed before selection.

### S1/S2 - Slash Typed and Menu Opens

Frame facts from `01-type-slash-open-frame-samples.json`:

| Time | Composer | Menu | Notes |
| ---: | --- | --- | --- |
| 14.6ms | empty | absent | baseline sample before keyboard mutation |
| 167.6ms | `/` | absent | typed slash is in composer before menu mount |
| 250.4ms | `/` | present at 0,0 | first observed mount before placement settles |
| 1101.3ms | `/` | present at x 234.5, y 23.6 | final stable popover above composer |

Final menu facts:

- Element role: `menu`.
- Position: absolute.
- Final rect: x 234.5, y 23.6, width 267.4, height 303.4.
- Gap above composer: about 9.5px. Menu bottom 327.0, composer top 336.5.
- Menu is horizontally offset left of composer by about 15.7px.
- CSS: white background, 12px border radius, z-index 50, max-height 303.415px, overflow-y auto.
- Shadow: 0 2px 8px rgba(0,0,0,0.08).
- Computed transition/animation: transitionDuration 0s, animationName none.

Candidate content for `/` is broad: file picker, custom org skills, StrategyOS/Tegy plugin skills, and domain command groups such as Operations, Brand Voice, HR, Design, Engineering, Sales, Legal, Product Management, Productivity, Marketing, Finance, Enterprise Search, and Data.

### S3 - Filtering to /biz

Frame facts from `02-type-biz-filter-frame-samples.json`:

| Time | Composer | Menu | Notes |
| ---: | --- | --- | --- |
| 15.4ms | `/` | full menu | inherited from slash-open state |
| 86.0ms | `/` | absent | menu temporarily unmounted during query update |
| 148.9ms | `/b` | absent | typed query exists before menu remount |
| 249.2ms | `/bi` | absent | still remounting/filtering |
| 303.7ms | `/bi` | present at y -56.4 | intermediate popover placement above viewport |
| 364.5ms | `/biz` | present at x 234.5, y 23.6 | stable filtered list |
| 1301.1ms | `/biz` | stable | final state |

Final `/biz` candidate list, in observed order:

1. biz-storyline
2. biz-meeting-prep
3. biz-project-init
4. biz-rigor-review
5. biz-market-sizing
6. biz-mece-structure
7. biz-executive-comms
8. biz-stakeholder-map
9. biz-workshop-design
10. biz-framework-toolkit
11. biz-north-star-alignment
12. biz-off-ramp-recommender
13. biz-checkpoint-discipline
14. biz-trusted-repos-scanner
15. biz-hypothesis-driven-analysis

DOM detail:

- The typed slash token is wrapped as `<span class="suggestion">/biz</span>` with a `data-decoration-id`.
- Each row is a `div role="menuitem"`.
- Row height is about 32px.
- Row border radius is 8px.
- First item is highlighted by class `bg-bg-200`, not by `aria-selected`.
- Highlight background in light mode: rgb(244, 244, 241).

### S4 - Keyboard Highlight

After pressing ArrowDown twice from `/biz`, the visual highlight moved to index 2, `biz-project-init`.

Important accessibility/implementation observation: the active row did not expose `aria-selected="true"` in the captured DOM. The visible state was class/background driven:

- highlighted row class includes `bg-bg-200 text-text-300`
- non-highlighted rows have transparent background
- composer remains the active document element, not the menu

For Tegy parity, keep focus in the composer and move an internal activeIndex; do not move DOM focus into the menu on ArrowDown.

### S5 - Escape Closes Menu

Frame facts from `04-escape-close-frame-samples.json`:

- At 16.6ms after Escape, menu is already absent.
- Composer text remains `/biz`.
- No close animation was observed. The menu is removed from the DOM immediately.

### S6 - Selecting a Skill

Selection test used `/biz-mece`, then clicked `biz-mece-structure`.

Frame facts from `05-select-skill-frame-samples.json`:

| Time | Composer | Menu | Notes |
| ---: | --- | --- | --- |
| 5.1ms | empty | absent | baseline |
| 170.8ms | `/` | absent | slash text precedes menu |
| 225.0ms | `/` | present at 0,0 | first mount placement |
| 286.7ms | `/b` | present | fuzzy matches include non-biz commands |
| 362.6ms | `/bi` | present | narrowed but not final |
| 432.2ms | `/biz` | present | StrategyOS biz set visible |
| 510.1ms | `/biz-` | present | prefix-ish narrowing |
| 588.2ms | `/biz-m` | present | fewer candidates |
| 705.5ms | `/biz-me` | present, height 141.8 | small filtered popover |
| 784.9ms | `/biz-mec` | present, height 173.8 | candidate set changes again |
| 872.6ms | `/biz-mece` | present, height 109.8 | final target visible |
| 1256.3ms | chip inserted | absent | selection complete |

After click, the composer text reads `/biz-mece-structure `, but the DOM is not plain text. It is a non-editable TipTap node:

- `span.react-renderer.node-skillChip`
- `contenteditable="false"`
- visible chip text is `/biz-mece-structure`
- trailing editable space follows the chip
- menu is absent

LocalStorage changed after selection:

- New key: `LSS-slash-command-skill-usage:<uuid>`
- Shape: `{ value: { "tegy:biz-mece-structure": { usageCount, lastUsedAt } }, tabId, timestamp }`
- This appears to support recency/ranking only. It is not the source catalog.

## Animation and Transition Model

The popover does not use a meaningful CSS open/close tween in this capture. Computed menu style on stable states:

- transitionDuration: 0s
- transitionProperty: all
- animationName: none
- animationDuration: 0s
- opacity: 1 immediately when mounted

The perceived transition comes from these mechanics instead:

1. Keystroke updates ProseMirror text immediately.
2. Suggestion plugin conditionally mounts/unmounts a menu.
3. Floating/Popper placement runs after mount. One frame can appear at 0,0 or temporarily out of viewport before final placement.
4. Candidate list is recalculated locally and rows remount/reflow.
5. Menu height changes with candidate count but is clamped by max-height around 303px.
6. Selection removes the menu immediately and replaces the suggestion span with a skill chip node.

For Tegy parity, match the behavior rather than adding decorative transitions: instant mount, stable anchored placement, a subtle shadow, row hover/highlight state, and no delayed close animation.

## API and Local/Server Boundary

### Server-bound on page load

Captured page load made the usual Claude bootstrap requests. Relevant endpoints for slash commands:

| Endpoint | Role | Evidence |
| --- | --- | --- |
| `GET /api/organizations/<uuid>/plugins/list-plugins?enabled_only=true` | Loads enabled organization plugins. The Tegy/StrategyOS plugin appears here with its skills/commands. | 200, top-level keys `plugins, has_more, next_page`, 14 plugins, plugin item includes `skills`, `commands`, `agents`, `mcp_servers`. Regex found 52 StrategyOS-like skill names. |
| `GET /api/organizations/<uuid>/skills/list-skills` | Loads standalone/org/user skills. | 200, top-level key `skills`, 13 skills. Includes `rocketminds-slide-generator`, `rocketminds-brand-voice`, `skill-creator`. |
| `GET /edge-api/bootstrap/<uuid>/app_start?...` | Main app bootstrap/config and feature data. | Large bootstrap response, not the specific filtered interaction. |
| `GET /api/organizations/<uuid>/mcp/v2/bootstrap` and `/v1/toolbox/shttp/mcp/<uuid>` | MCP/toolbox bootstrap. | Loaded after page boot; not involved in slash filtering keystrokes. |

### Local after page load

| User action | API calls observed | Local behavior |
| --- | --- | --- |
| Type `/` | Only analytics/RUM: `POST /api/event_logging/v2/batch`, Datadog intake. | ProseMirror text changes, menu mounts, full command list uses preloaded catalogs. |
| Type `biz` | No skill/plugin/search API request. | Local fuzzy filtering over existing candidate list. |
| ArrowDown twice | No relevant API request. | Local activeIndex changes; highlighted row background moves. |
| Escape | No relevant API request. | Menu unmounts, slash text remains. |
| Click `biz-mece-structure` | One `POST https://a-api.anthropic.com/v1/b` beacon-like request. No chat/conversation API. | Local skill chip inserted; localStorage usage counter updated. |

No WebSocket traffic was observed for this feature capture.

## Data Model Inference

Claude appears to merge at least three command sources into one menu:

1. Built-in composer commands such as `add-files`.
2. Standalone skills from `/skills/list-skills`, for example `rocketminds-brand-voice`, `rocketminds-slide-generator`, and `skill-creator`.
3. Enabled plugin commands/skills from `/plugins/list-plugins?enabled_only=true`, especially the required `tegy` plugin carrying StrategyOS `biz-*`, `gtm-*`, `prod-*`, and `ma-*` skills.

The `tegy` plugin object schema includes:

- `id`
- `name`
- `display_name`
- `description`
- `enabled`
- `installation_preference` observed as `required`
- `marketplace_id`, `marketplace_name`
- `plugin_version_id`, `version`
- `skills`
- `commands`
- `agents`
- `mcp_servers`
- `hooks`
- `content_scan`

The standalone skill object schema includes:

- `id`
- `name`
- `description`
- `enabled`
- `user_invocable`
- `creator_type`
- `partition_by`
- `source`
- `owner`
- sharing/public fields

## Edge-Case Slash Keyword Timelines

Follow-up capture date: 2026-07-04, authenticated Claude.ai RocketMinds org, same slash-command surface. The second capture recorded per-character timelines for typing, deleting, recovering from no-match, Escape suppression, and skill chip deletion. All screenshots were cropped around the composer/dropdown.

### Type From Slash To No-Match

```text
/                 -> menu open, 145 rows, first rows: add-files, rocketminds-brand-voice, rocketminds-slide-generator
/b                -> menu open, 103 rows, first rows: brief, brand-review, biz-storyline
/bi               -> menu open, 27 rows, first rows: biz-storyline, biz-meeting-prep, biz-project-init
/biz              -> menu open, 15 rows, first rows: biz-storyline, biz-meeting-prep, biz-project-init
/bizz             -> menu open, 15 rows, first rows rerank to biz-mece-structure, biz-checkpoint-discipline, biz-executive-comms
/bizzz            -> no menu
/bizzz-n          -> menu reappears, 1 row: biz-north-star-alignment
/bizzz-no         -> menu remains open, 1 row: biz-north-star-alignment
/bizzz-no-        -> no menu
/bizzz-no-match-x -> no menu through final /bizzz-no-match-xyz
```

Important behavior: no-match does not render an empty dropdown or a "no results" row. The menu is absent. Filtering is fuzzy rather than strict prefix matching, so a query can temporarily lose all candidates and then regain one candidate when more characters are typed.

### Recover From No-Match By Backspacing

Starting at `/bizzz-no-match-xyz`, repeated Backspace kept the menu absent until the query again matched candidates:

| Step | Composer text | Menu state | Candidate result |
| --- | --- | --- | --- |
| final bad query | `/bizzz-no-match-xyz` | closed | no candidates |
| backspace to `/bizzz-no` | open | 1 row | `biz-north-star-alignment` |
| backspace to `/bizzz-` | closed | no rows | no candidates |
| backspace to `/bizz` | open | 15 rows | first row `biz-mece-structure` |
| backspace to `/biz` | open | 15 rows | first row `biz-storyline` |

Answer to the implementation question: yes, if the user makes a bad slash query and then backspaces into a query with candidates, the dropdown reappears. This only applied while the suggestion session was still naturally active.

### Delete Or Edit Characters In The Middle

Observed sequence: type `/biz`, move the caret before `z`, press Backspace so the token becomes `/bz`, then type `i` in the middle to recover `/biz`.

| Step | Composer text | Menu state |
| --- | --- | --- |
| before edit | `/biz` | open, 15 rows |
| middle Backspace deletes `i` | `/bz` | closed |
| type `i` back in the middle | `/biz` | stayed closed in this capture |

This is different from suffix backspacing. Arbitrary mid-token edits can end or suppress the active suggestion session even if the resulting text would otherwise match. For Tegy parity, the slash picker should be driven by an active suggestion-session state, not merely by scanning the whole composer text after every edit.

### Escape Suppression And Reopen Rules

Observed sequence: type `/biz`, press Escape, then continue editing the same slash token.

| Step | Composer text | Menu state |
| --- | --- | --- |
| before Escape | `/biz` | open, 15 rows |
| Escape | `/biz` | closed immediately |
| type `m` after Escape | `/bizm` | stayed closed |
| Backspace after Escape | `/biz` | stayed closed |
| clear composer, type fresh `/` | `/` | open, 145 rows |

Escape is a deliberate dismissal for the current slash token. It does not clear the text, but subsequent edits to that same token did not reopen the menu. A new slash trigger after clearing the token opens normally.

### Skill Chip Selection And Deletion

Observed sequence: type `/biz-mece`, click `biz-mece-structure`, press Backspace.

| Step | Composer text | Menu state | Storage |
| --- | --- | --- | --- |
| `/biz-mece` | menu open, 3 rows | no mutation while typing | existing usage key unchanged |
| click `biz-mece-structure` | chip text `/biz-mece-structure `, menu closed | usage key updated | `usageCount` changed from 2 to 3 in capture |
| Backspace | only trailing space remained, menu closed | no rollback | usage key stayed at 3 |

The localStorage key was `LSS-slash-command-skill-usage:<uuid>`. The value shape remained `{ value: { "tegy:biz-mece-structure": { usageCount, lastUsedAt } }, tabId, timestamp }`. Deleting the chip does not undo recency/usage tracking.

## Edge-Case API, Storage, And Animation Findings

### API Calls

The per-character timeline capture included normal page bootstrap calls before baseline, including `/plugins/list-plugins?enabled_only=true` and `/skills/list-skills`. After the baseline empty-composer state, none of the slash interactions made catalog, skill, plugin, search, conversation, completion, or chat-message API calls.

Checked interactions with zero catalog/search/chat calls after baseline:

- type `/bizzz-no-match-xyz`
- backspace from `/bizzz-no-match-xyz` back to `/biz`
- middle delete `/biz` -> `/bz` and middle recovery `/biz`
- Escape `/biz`, then type/backspace inside the same token
- select `biz-mece-structure` and Backspace-delete the chip

Only telemetry/beacon-style traffic appeared during some steps: Datadog RUM, `https://a-api.anthropic.com/v1/b`, and `https://api.anthropic.com/v1/m`. No WebSocket traffic was observed.

### LocalStorage And SessionStorage

- Typing `/`, filtering, no-match, deletion, recovery, and Escape did not mutate slash-related localStorage or sessionStorage.
- The slash usage key already existed from a prior skill selection in the same browser profile.
- Clicking `biz-mece-structure` incremented `tegy:biz-mece-structure.usageCount` from 2 to 3 and updated `lastUsedAt`/`timestamp`.
- Backspace-removing the chip did not decrement usage and did not remove the usage key.
- No sessionStorage slash-command mutations were observed.

### Animation And Geometry

Across 36 menu-visible timeline samples:

- `transitionDuration: 0s`
- `transitionDelay: 0s`
- `animationName: none`
- `animationDuration: 0s`
- `opacity: 1`

There is still no fade, slide, scale, or delayed close animation. The visible change is discrete state replacement:

1. Query text changes in ProseMirror.
2. Candidate rows recompute locally.
3. Menu mounts or unmounts depending on candidate count and suggestion-session state.
4. Floating placement recalculates geometry.
5. Menu height changes instantly with row count.

Geometry observations from the edge capture:

| Candidate count | Example query | Menu width | Menu height | Top y |
| ---: | --- | ---: | ---: | ---: |
| 145 | `/` | about 267px | about 287px | 23.6px |
| 15 | `/biz` | about 268px | about 287px | 23.6px |
| 5 | `/biz-mec` | about 240px | about 173.8px | 137.3px |
| 4 | `/biz-me` | about 240px | about 141.8px | 169.1px |
| 3 | `/biz-mece` | about 240px | about 109.8px | 200.9px |
| 1 | `/bizzz-no` | about 240px | about 45.8px | 265.5px |

The dropdown appears anchored above the composer, with its bottom staying near the composer as height shrinks. This makes the top y move down for smaller result sets.

## Edge-Case State Machine Additions

```mermaid
stateDiagram-v2
  S3_Filtering --> S7_NoMatchClosed: candidate count becomes 0
  S7_NoMatchClosed --> S3b_FilteredMenuOpen: same active slash token edited to candidate count > 0
  S3b_FilteredMenuOpen --> S8_MidTokenEditClosed: arbitrary middle edit invalidates/suppresses suggestion session
  S8_MidTokenEditClosed --> S0_Idle: clear token
  S3b_FilteredMenuOpen --> S6_EscapeClosed: Escape
  S6_EscapeClosed --> S6_EscapeClosed: type/delete same token, menu remains closed
  S6_EscapeClosed --> S2_MenuOpenAllCommands: clear token and type fresh slash
  S5_SelectedSkillChip --> S9_ChipDeleted: Backspace deletes chip, usage recency remains
  S9_ChipDeleted --> S0_Idle: clear remaining whitespace
```

## Tegy Parity Implementation Notes

### Required UI behavior

- Detect slash command trigger inside the active composer token, not globally.
- Keep keyboard focus in composer while menu is open.
- Open a `role="menu"` popover above the composer.
- Width: about 240-268px depending candidate content.
- Max height: about 303px, scrollable.
- Menu radius: 12px. Item radius: 8px. Item height: about 32px.
- Row layout: icon/label horizontal flex, compact padding.
- Highlight first candidate on open and move internal activeIndex with arrows.
- Escape closes only the menu; it does not clear the slash text. Continued edits to the same escaped token stayed closed in the capture.
- No-match renders as no menu, not as an empty result panel. If suffix backspacing returns to a matching query, the menu reappears.
- Middle-of-token edits can suppress the active suggestion session even when the resulting text matches again.
- Selection inserts a non-editable skill chip plus trailing space, not only raw text.
- Clearing the composer removes both chip and text.

### Required data behavior

- Load skill/plugin catalog once per session/org bootstrap.
- Do local filtering. Do not hit the server for `/b`, `/bi`, `/biz`, etc.
- Persist local usage/recency after selection. Use a key equivalent to `slash-command-skill-usage`; do not use it as canonical catalog data.
- Do not mutate usage/recency for typing, no-match, Escape, or chip deletion. Selection increments usage; deletion does not roll it back.
- Treat selected chip as structured composer content. When submitting, serialize it explicitly and audibly into the AI boundary. This needs operator approval before implementation because it changes what Claude sees.

### Suggested Tegy state machine

- `idle`: no slash token, menu closed.
- `slash-token`: active token starts with `/`, menu may be mounting.
- `menu-open`: candidate list rendered; activeIndex default 0 if candidates exist.
- `filtering`: query changes; recompute candidates locally; clamp menu height; reposition.
- `keyboard-navigation`: update activeIndex; keep focus in composer.
- `escaped`: menu closed, slash text preserved.
- `selected`: replace slash token with `SkillChipNode`, trailing space, menu closed.
- `submitted`: convert chip(s) into approved runtime instruction/message representation.

## Parity Risks

- The chip-to-runtime serialization is an AI boundary. Do not silently inject skill instructions without explicit design approval.
- Claude's dropdown includes multiple command sources. If Tegy only lists StrategyOS skills, it will miss parity for file picker, built-ins, runtime document skills, and future org skills.
- Do not add over-smooth animation. Claude's menu is effectively instant; added fades/slides would drift visually. Height and y-position changes are discrete reflow/reposition effects, not tweens.
- Do not rely on aria-selected for active item parity; Claude uses visual classes while focus remains in the composer. Tegy can improve accessibility, but visual parity should still keep composer focus.
- Do not make filtering server-bound. Networked search would add latency and diverge from Claude's local feel.

## Evidence Links

### Contact Sheets

- [Slash open frames](evidence/frames/01-type-slash-open-contact-sheet.png)
- [Biz filter frames](evidence/frames/02-type-biz-filter-contact-sheet.png)
- [Keyboard navigation frames](evidence/frames/03-keyboard-nav-contact-sheet.png)
- [Escape close frames](evidence/frames/04-escape-close-contact-sheet.png)
- [Skill selection frames](evidence/frames/05-select-skill-contact-sheet.png)
- [Edge: type to no-match timeline](evidence/frames/edge-timeline-type-to-no-match-contact-sheet.png)
- [Edge: recover from no-match timeline](evidence/frames/edge-timeline-recover-from-no-match-contact-sheet.png)
- [Edge: middle delete and recover timeline](evidence/frames/edge-timeline-middle-delete-and-recover-contact-sheet.png)
- [Edge: Escape suppression timeline](evidence/frames/edge-timeline-escape-suppression-contact-sheet.png)
- [Edge: chip select and delete timeline](evidence/frames/edge-timeline-chip-select-and-delete-contact-sheet.png)

### JSON

- [Capture summary](evidence/json/capture-summary.json)
- [Frame transition summary](evidence/json/frame-transition-summary.json)
- [Catalog schema summary](evidence/json/catalog-schema-summary.redacted.json)
- [Network events](evidence/json/network-events.redacted.json)
- [Response summaries](evidence/json/response-summaries.redacted.json)
- [Edge final-state summary](evidence/json/edge-case-capture-summary.redacted.json)
- [Edge timeline summary](evidence/json/edge-timeline-summary.redacted.json)
- [Edge type to no-match timeline](evidence/json/edge-timeline-type-to-no-match.json)
- [Edge recover from no-match timeline](evidence/json/edge-timeline-recover-from-no-match.json)
- [Edge middle delete and recover timeline](evidence/json/edge-timeline-middle-delete-and-recover.json)
- [Edge Escape suppression timeline](evidence/json/edge-timeline-escape-suppression.json)
- [Edge chip select and delete timeline](evidence/json/edge-timeline-chip-select-and-delete.json)
