developing-reef
Skill84 starsChanged 17 days agoApache-2.0View on GitHub
REQUIRED before any non-test code change in Reef. Load this skill before modifying Reef runtime architecture, `App` state, tabs/panels, rendering code, input dispatch (`crates/reef-tui/src/input.rs`, any picker overlay, the commit textarea, any new text-input field), background work, git/file-tree/diff/graph loading, performance-sensitive paths, or when the user asks about "how Reef is structured", "render blocking", "heavy tasks", "new tab", "new feature architecture", "input handling", "text input", "picker", "PickerCore", "input_edit", or "project conventions". Do NOT start editing Reef source without loading this skill first — the architecture has non-obvious invariants (render-pure, async generation tokens, three-layer text-input stack) whose violation has been re-introduced and re-fixed across multiple PRs. Pair with `testing-reef` whenever adding or changing tests.
- Commits and pushes
In this repository5 other files it gives its agents.
- releasing-reefSkill
- rust-best-practicesSkill
- rust-testingSkill
- testing-reefSkill
- testing-strategySkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
22 rules. About 0 are common, 7 are distinctive, and 15 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈7
Distinctive · estimate
This author's own choices. Worth a look.
15
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Very specific: line 8
Use this skill as the project onboarding guide for non-test Reef changes.
- Very specific: line 14
Keep ui::*::render on cached state only.
- Very specific: line 15
Treat input handlers as intent dispatchers.
- Very specific: line 18
Put UI-independent logic in crates/reef-core.
- Very specific: line 19
Put renderer-neutral app state, async scheduling, worker-result merge, settings state, nav/history, preview/search/git/graph orchestration …
- Very specific: line 26
Keep terminal-only state in crates/reef-tui: ratatui layout caches, hit-test registry, terminal image protocol, text-selection geometry, …
- Very specific: line 28
Prefer stale cached UI over blocking.
- Distinctive: line 29
Use generation tokens for async results.
- Distinctive: line 30
Keep each tab/panel independently refreshable.
- Very specific: line 31
When a renderer needs preview content beyond the bounded display projection, expose that content through a typed, renderer-neutral …
- Very specific: line 66
Read references/runtime-architecture.md before changing crates/reef-app/src/, crates/reef-tui/src/app/mod.rs, crates/reef-tui/src/input.rs, …
- Very specific: line 136
Every text input in Reef routes through one of three layers — L0 input_edit (single-line readline/VSCode vocabulary), L1 input_edit_multi …
- Distinctive: line 159
Keep user-facing behavior stable when possible.
- Very specific: line 163
Use $testing-reef before adding or modifying tests.
- Distinctive: line 164
Add unit tests for pure helpers and state transitions when practical.
- Distinctive: line 165
Update snapshot tests only when rendered text/layout intentionally changes.
- Very specific: line 171
Treat this Skill and references/runtime-architecture.md as part of the architecture, not as optional prose.
- Very specific: line 173
When a change alters crate ownership, the ReefApp public boundary, command/snapshot/event flow, task scheduling, wake/deadline behavior, …
- Very specific: line 176
When a public Reef change alters the contract consumed by another renderer or bridge, update the renderer-facing contract here and notify …
- Distinctive: line 179
Do not merge an architecture change with knowingly stale Skill guidance.
- Distinctive: line 184
Run these locally before git push.
- Very specific: line 199
cargo fmtedits in place;--checkonly verifies: Run the first to fix, the second to gate.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Developing Reef
Use this skill as the project onboarding guide for non-test Reef changes. The workspace contains a renderer-neutral Rust app engine plus the Reef TUI frontend. Every host must stay responsive, and expensive work must not run from a renderer.
Core Architecture Rules
- Keep
ui::*::renderon cached state only. Do not call git, filesystem walks, diff generation, syntax highlighting, external processes, or long formatting from render. Renderer-specific media geometry may be cached during render; decoder open/rebuild work starts from the host tick. - Treat input handlers as intent dispatchers. They decode terminal input and dispatch
reef_app::AppCommand; they must not directly own business state or do blocking host work. - Route expensive work through
reef-app's task coordinator; merge worker results fromReefApp::step. - Put UI-independent logic in
crates/reef-core; shared host filesystem services such as the unified preference store belong incrates/reef-io; keep ratatui/crossterm rendering and input orchestration incrates/reef-tui. - Put renderer-neutral app state, async scheduling, worker-result merge, settings state, nav/history, preview/search/git/graph orchestration in
crates/reef-app. - Renderer hosts dispatch preview definition requests with a typed source cursor and viewport budget. For local backends,
reef-appmarks the initial workspace index stale and schedules its build fromstep; remote backends keep that unsupported work idle.reef-appowns enrichment- and workspace-index-bound retry, definition/reference resolution, candidate state, selected-candidate preview, history, and committed jumps; hosts own only coordinate mapping and popup geometry. - Navigation locations retain the exact source line and UTF-8 byte range for jumps and highlights. Their bounded display snippets are cropped around that target range so every renderer can keep the matched identifier visible without reading candidate files or reconstructing source lines.
- Location history is renderer-neutral and stores the active surface, path, UTF-8 cursor, and vertical/horizontal scroll. Hosts sample their current native position only when dispatching an explicit navigation and pass it to the shared back/forward commands; ordinary cursor movement and scrolling do not create history entries.
- Graph Changed-files selection is renderer-neutral. Hosts dispatch file-navigation commands;
reef-appfollows the visible list/tree order, skips collapsed descendants, updates selection immediately, and schedules the matching commit diff without moving focus away from the Changed-files panel. - Hosts construct
ReefAppfromAppConfig;AppStateand its construction details stay private toreef-app. - Keep terminal-only state in
crates/reef-tui: ratatui layout caches, hit-test registry, terminal image protocol, text-selection geometry, mouse row/column mapping, scroll pacing, leader/chord timers, popup rects, and the live TUI theme object. - Keep inline-video decode and terminal protocol encoding off the TUI loop. Bound decoded frame dimensions and playback FPS by terminal wire cost before starting ffmpeg; playback ticks may drain decoded frames, submit only the newest due frame to a bounded encoder, and merge completed protocol payloads without waiting.
- Prefer stale cached UI over blocking. Show old data plus loading/stale/error status instead of waiting during tab switches or hover/mouse movement.
- Use generation tokens for async results. Late results from older requests must not overwrite newer selections or newer snapshots.
- Keep each tab/panel independently refreshable. Adding a feature should not require another tab to render before data can update.
- When a renderer needs preview content beyond the bounded display projection, expose that content through a typed, renderer-neutral
PreviewBodySnapshot; do not make a host reparse source content while selecting or rendering a preview. - Preserve complete structured source separately from its bounded visible-line projection. Reef must not identify or name third-party formats; renderer-specific recognition belongs to the renderer that consumes this generic source.
Spreadsheet previews
reef-core::preview::spreadsheetparses xlsx/xls/xlsm/xlsb/ods into a typed workbook on the preview worker. Local and remote backends use the same parser; remote reads request complete workbook bytes within the 10 MiB input limit.- xlsx/xlsm/xlsb use two streaming cell passes: determine the actual nonempty used range, then fill only the bounded projection. Never construct a dense range from distant cell coordinates. xls/ods retain Calamine's eager readers; their input and projection limits do not bound parser memory.
- Each worksheet preserves its used-range origin, original dimensions, column addresses, and display values. Preview data is bounded to 10,000 rows, 256 columns and 100,000 cells per sheet, with explicit truncation. Formula values are the file's cached results; formulas and macros are never executed.
reef-appownsSelectSpreadsheetSheetand the selected sheet index. Its preview snapshot contains worksheet names and only the selected worksheet. Switching sheets changes the presentation revision and resets preview scroll, while the source revision stays stable.- Hosts own native/terminal cell selection and geometry. TUI uses the spreadsheet keymap scope and virtualized visible cells; spreadsheet parsing and source I/O stay off render.
Runtime Data Flow
- User input in
reef-tuibecomes anAppCommand. ReefApp::dispatchmutates renderer-neutral state or requests work.- The request method marks an
AsyncState, increments its generation, and sends a worker request throughTaskCoordinator. - Workers do git/filesystem/diff/highlight work off the render path and send
WorkerResult. - The host calls
ReefApp::stepafter input, a coalesced worker wake notification, a filesystem watcher notification, or the reportednext_deadline. stepdrains results, accepts only matching generations, updates state, emits runtime events, and reports the next deadline.- Render reads
AppSnapshotplus explicit read-only accessors. It must never be required for progress beyond drawing.
Read references/runtime-architecture.md before changing crates/reef-app/src/**, crates/reef-tui/src/app/mod.rs, crates/reef-tui/src/input.rs, or any tab/panel render path.
File/Module Habits
- Startup CLI parsing lives in
crates/reef-tui/src/cli.rs;main.rsdispatches non-interactive commands before installing terminal hooks or probing the terminal.update.rsverifies Homebrew ownership and delegates to the owning package manager. The npm launcher'sbin/update.jshandles global npm updates before starting the native executable, allowing Windows to replace it. These commands do not use app state. crates/reef-app/src/engine.rsowns the public mutable app boundary. New mutable business entry points must be represented asAppCommand; if a new public&mut selfmethod is truly needed, updatescripts/check-architecture.shand explain why in the PR.crates/reef-app/src/app/**owns renderer-neutral app state orchestration: tab state, async state, result merging, and command side effects.crates/reef-core/src/**owns UI-independent git, diff, highlight, markdown, nav/LSP, preview loading, file-op, host parsing, and history logic.crates/reef-app/src/tasks.rsowns background worker definitions and should stay free of UI concerns.crates/reef-tui/src/app/mod.rsowns the terminal adapter: image protocol, terminal-local selections, hit-test/layout cache, and effect handling.crates/reef-tui/src/ui/**owns rendering and local panel command dispatch; keep it pure except transient hit-test registration.crates/reef-tui/src/ui/preview/**owns the TUI preview renderers; core preview models must stay free of ratatui/crossterm types.crates/reef-tui/src/input.rsowns key/mouse routing; useAppCommand/TuiApp::set_active_tabinstead of assigningactive_tabdirectly.crates/reef-tui/src/input_edit{,_multi}.rsandcrates/reef-tui/src/picker_core.rsown the shared text-input vocabulary. Don't hand-roll a key table; embed one of the three layers (see "Text Input Stack" below).crates/reef-core/src/file_tree.rsowns pure file-tree ordering/navigation helpers;crates/reef-app/src/features/file_tree.rsowns renderer-neutral file-tree state.reef-tuirenders snapshots and dispatches commands only.SetFileTreeSortowns sibling ordering at every tree depth. The coreFileTreeSortcomparator supports name, extension-based kind, and modification time with an independent direction and default-enabled folders-first setting. When enabled, directories precede files and both groups follow the selected ordering; otherwise siblings sort together. Directory timestamps are their own filesystem modification times. Full-tree and subtree workers capture the same typed settings. Sort changes invalidate older rebuild/subtree requests and preserve expansion and selection. Hosts seedAppPrefs.file_tree_sortfrom the sharedfile_tree.sortpreference. Backend directory entries carry optional modification timestamps; unavailable timestamps sort last. The TUI exposes these settings through the file-tree context menu'sSort Bysubmenu, including checked field/direction and Folders First rows. Menu navigation stays inContextMenuState; TUI keyboard/mouse adapters dispatch commands, and render only lays out the parent/submenu and hit regions. Sort choices dispatch the sharedSetFileTreeSortcommand.- Grouped menus use
reef_core::menu::MenuEntry<T>with explicitItemandSeparatorentries. Features declare their order and grouping in one list;menu_itemsandnavigate_menushare item-only selection semantics across file-tree and text menus.reef-tui/src/ui/context_menu.rsowns reusable drawing, placement, scrolling, and hit regions. The file-tree and text-menu panels adapt labels, enabled/checked state, and typed actions. Separators consume layout height and capture clicks while remaining outside keyboard selection. - File-tree row splices carry
base_revision(the preceding structure change) andrevision(the resulting change). Intermediate revisions only change presentation. Retain the latest splice across content updates and clear it on structure reset, so hosts can apply an exact delta after coalescing content events without replaying skipped structure changes. crates/reef-tui/src/keymap.rsowns shortcut bindings by scope; handlers should dispatch commands, not duplicate key matching tables.
App Boundary Guardrails
reef-tuimust not directly own business state that belongs inreef-app. Settings, preview/search/git/graph/nav/history state should flow throughReefAppcommands, snapshots, or read-only accessors.- SQLite hosts dispatch the shared database commands and read
DbPreviewStateplus its page/detail/cell load status throughReefApp. Paginated rows keep bounded TEXT values and bounded row locators; oversized primary keys use an offset plus fingerprint. Opening a cell requests its complete value throughDbLoadCellusing the locator returned with its page. Remote TEXT delivery streams frame-bounded chunks from that one read and validates the terminal full-cell revision. A newer cell selection cancels the previous local or remote read; cell work runs separately from ordinary file and database-page previews. The opened cell is also the grid's cell cursor: hosts move it, close it, and scroll its value through commands, and report the grid's body height soreef-appcan keep the cursor row on screen. Laying the value out — pane width, wrapping, JSON coloring — is renderer-owned derived layout and must stay out ofreef-app. Table row counts provide a known last page; views keep an unknown last page until a short or empty follow-up page establishes the boundary. Schema expansion, object selection, paging, typed rows, and details must not be reimplemented by a renderer adapter. reef-appmust not depend onratatui,crossterm, orratatui-image.- Trusted interactive hosts construct
LocalBackendwithopen_at_with_external_previews, allowing preview-only reads to follow a workspace entry's symlink target outside the workspace.reef-agentand other untrusted request boundaries useopen_at; all non-preview reads and every write remain workspace-bound. - Worker result merge paths belong in
reef-app; TUI may adapt terminal-only payloads such as image protocol state before dispatching the merge command. scripts/check-architecture.shis the cheap CI tripwire. If it blocks a legitimate change, prefer changing the whitelist with a short explanation over adding another bypass.
Text Input Stack
Every text input in Reef routes through one of three layers — L0
input_edit (single-line readline/VSCode vocabulary), L1
input_edit_multi (textarea: Enter→\n, line-aware Up/Down/Home/End),
or L2 picker_core::PickerCore (overlay scaffold: filter + cursor +
selected_idx + dispatch). 12+ input sites are already migrated; net
~700 lines of duplicated key dispatch was removed.
Do NOT add a new text input without reading
references/text-input-stack.md first. It documents the canonical
example for each layer plus seven mandatory invariants whose
violation has been re-introduced and re-fixed across multiple
review rounds (strict-bare-Enter, Ctrl+letter swallow in textareas,
close-on-confirm-None, edit-derived work on Edited-only, UTF-8
cursor boundary, exhaustive InputOutcome match, protocol bump
discipline).
Adding or Changing Features
- For a new tab or expensive panel, define: UI state, cached data snapshot,
AsyncState, worker request/result, request method, result merge path, and render fallback for stale/loading/error. - For a cheap UI-only feature, keep it local and synchronous, but verify it never calls host I/O through helpers.
- For actions that move HEAD/refs or change index/worktree, mark the affected snapshots stale and
let the next
steprefresh them. - For selections that load content, request async work immediately and rely on generations to drop stale responses.
- Keep user-facing behavior stable when possible; avoid broad rewrites of keybindings, file layout, or visual style while solving performance/architecture issues.
Testing Expectations
- Use
$testing-reefbefore adding or modifying tests. - Add unit tests for pure helpers and state transitions when practical.
- Update snapshot tests only when rendered text/layout intentionally changes.
- For async UI behavior, tests should drive
stepafter worker wake notifications or due deadlines instead of assuming synchronous state.
Architecture Documentation Contract
- Treat this Skill and
references/runtime-architecture.mdas part of the architecture, not as optional prose. - When a change alters crate ownership, the
ReefApppublic boundary, command/snapshot/event flow, task scheduling, wake/deadline behavior, module responsibilities, validation commands, or a documented invariant, update the affected Skill/reference in the same change. - When a public Reef change alters the contract consumed by another renderer or bridge, update the renderer-facing contract here and notify the downstream repository in the same development cycle.
- Do not merge an architecture change with knowingly stale Skill guidance. The implementation, architecture checks, tests, and Skills must describe one current path.
Pre-PR Checks
Run these locally before git push. CI runs exactly these commands — mirroring them avoids the "commit → push → CI red → fmt fix → force push" round-trip on every PR.
cargo fmt --all
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace --all-features
cargo test --workspace --doc
node --test npm/cli/test/update.test.jsFailure modes that keep catching people:
cargo test --libis not enough. It skips integration tests (crates/reef-app/tests/*.rs,crates/reef-io/tests/*.rs,crates/reef-tui/tests/*.rs), snapshot tests (crates/reef-tui/tests/ui_snapshots.rs), and doctests. CI runs--workspace --all-features— so must you.- Clippy without
--workspacemissestest-support. The scope flag is load-bearing; drop it and a broken lint in a helper crate sails through locally then trips CI. cargo fmtedits in place;--checkonly verifies. Run the first to fix, the second to gate. Omit the first and every stylebot nit becomes a second commit on your PR.
Coverage (cargo llvm-cov) is advisory and doesn't block PRs; no need to run it locally unless you're inspecting coverage deltas.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

