YoRHa-HexFlow is a visual tool for designing binary protocols and orchestrating hexadecimal instructions. It uses block-based editing to define frame structures, configure fields, calculate values, and export or dispatch assembled data. The interface is inspired by NieR: Automata.
The project uses React 19 and Vite for the frontend, FastAPI for the backend, and SQLite for local storage.
- Drag and Drop Blocks: Uses
@dnd-kitfor dragging and sorting nested blocks. - Dynamic Swimlanes: Automatically generates hierarchical swimlane views based on data structure.
- Reference Connections: Displays relationships between blocks, including checksum and length calculation references.
- Real-time Formula Calculation: Supports dynamic formulas like
([FieldA] + 10) / 2, with real-time preview of calculation results on the frontend. - Counters and Time Accumulation: Includes
AUTO_COUNTERandTIME_ACCUMULATORblocks. - Bitfield Editor: The
BITFIELDoperator ships with a dedicated bit layout editor (start_bit/bit_len/default_val), persisted to thebit_fieldstable and packed by the encoder. - Multi-base Support: Property panels support hexadecimal, decimal, and binary input.
- Hex File Export:
POST /export/hexturns the assembled stream into a downloadable.hexfile (Instruction Processing page). - Binary File Export:
POST /export/binarycompiles the merged block forest server-side via the Orchestrator and returns a.binfile (Orchestration page). - Dispatch and Transport:
POST /dispatch/sends frames and retains up to 100 raw, response, and error events in memory. The default transport is an in-process loopback channel. UsePOST /transport/configto configure TCP or serial communication andGET /transport/statusto inspect connection-state events.
- Environment Status Panel:
GET /datahub/statusreports the DB path / size / mtime, row counts for seven tracked tables (instructions / fields / bit fields / protocols / operator templates / bindings / response specs), and the backend version. - Aggregate Export:
GET /datahub/export/bundlepackages instruction definitions, protocol bindings, response specifications, a manifest, and per-instruction skeleton frames into one ZIP. - Relations Import:
POST /datahub/import/relationsre-imports the ZIP'srelations.json— upsert byidwith a per-row report (missing parent → skipped with reason, danglingslot_id→ cleared with a warning,definition_hashpreserved as-is), partial success is kept instead of rolling back the whole batch. - Backup & Restore:
POST /datahub/backupcopiesyorha.dbintobackend/db/backups/(gitignored);POST /datahub/restoretakes an automaticpre-restore-*snapshot, releases the pool, clears WAL/SHM leftovers, and atomically replaces the file (filename traversal is rejected).
Frontend tests use Vitest and React Testing Library for components, hooks, and smoke tests. Backend tests use Python's unittest. See Running Tests for commands.
- Protocol definitions: The protocol tree describes frame structure: headers, fields, lengths, checksums, and slots. Transport settings, including channel, address, timeouts, reconnect behavior, and device profiles, are managed on the Communication Terminal page through
/transport/config. - Device-agnostic protocols: Protocols carry no
device_code. Each slot'sacceptswhitelist determines which instruction device codes it accepts, with validation performed by the backend at bind time. - Governance view: the Data Hub page hosts the read-only binding matrix (instruction → default protocol → slot) plus
relations.jsonexport/import; dangling slots, deleted protocols, and staledefinition_hashfingerprints are flagged rather than silently dropped.
Page implementation status is maintained in docs/PAGE_STATUS.md, generated from frontend/src/config/pageStatus.json. Update the source JSON and regenerate the document rather than editing the generated file:
node scripts/generate-page-status.mjs # after editing pageStatus.jsonPlanned work is tracked in docs/PLAN_Backlog.md. Development context and the file map are documented in PROJECT_HANDOVER.md.
The project now defaults to the repository-local SQLite database at backend/db/yorha.db. Tables, operator templates, and sample instructions are created automatically on first startup.
No external database service is required.
On Windows, use the root script to boot both backend and frontend.
.\start-dev.ps1The script will:
- install missing Python dependencies for the backend
- install missing Node dependencies for the frontend
- start the FastAPI backend on
http://127.0.0.1:8000 - start the Vite frontend on
http://127.0.0.1:5173when available, otherwise another free port
Run the backend from the repository root:
python -m pip install -r backend/requirements.txt
python -m uvicorn backend.main:app --reloadIn a separate terminal, start the frontend:
cd frontend
npm install
npm run devRun frontend tests from frontend/:
cd frontend
npm run test -- --runRun backend tests from the repository root:
python -m unittest discover -s backend/tests -t backend/testsgraph TD
UI[Frontend UI] -->|Ref/Select| Hooks[Custom Hooks]
Hooks -->|Data Flow| Logic[Business Logic]
Logic -->|REST API| API[Backend FastAPI]
subgraph Frontend [React Layer]
Hooks --> useInstructionData
Hooks --> useSelectionSystem
Hooks --> useInstructionLanes
Hooks --> useCanvasConnections
end
subgraph Utils [Shared Utilities]
Logic --> formula.js[Formula Engine]
Logic --> constants.js[Constants]
end
For detailed technical specifications, please refer to: SPECIFICATION.md
/backend
main.py # FastAPI entry (lifespan: create_all + ensure_* self-heal + versioned migrations + seeds)
requirements.txt # Python deps (includes pymysql, used only by debug_db.py)
/routers # HTTP routes (instruction, protocol, operator, compile, export, dispatch, datahub)
/handlers # Range logic (length, checksum)
/core # orchestrator.py (wired); processor.py / graph.py (legacy, unwired)
/db # SQLAlchemy models + SQLite file backend/db/yorha.db (migrations/*.sql = non-authoritative)
# migrate.py = versioned upgrade runner (schema_migrations table)
# runtime backups land in /db/backups (gitignored)
debug_db.py # Standalone MySQL debug script (only pymysql consumer)
/frontend
/src
/components
/ui # Generic UI (NieRModal, NieRDatePicker)
/editor # Editor domain (Canvas, Block, BlockPropertiesPanel, ComponentPalette, ...)
/InstructionForm # Dynamic send form (InstructionRunner + extracted field tree/log)
/hooks # Business logic hooks (useInstructionData + instructionDataOptions contract, useInstructionForm, ...)
/pages # Page containers (Protocol, Instruction, InstructionProcessor, Orchestration, DataHub)
/utils # Pure utilities (InstructionEncoder.js = encoding core, formula.js, normalizeInstruction.js, blockMerge.js)
/config # pageStatus.json (page status SoT) + blockTypes.js / runnerRenderRules.js (testable render-rule configs)
/api # All HTTP calls, split by domain (client/protocols/instructions/export/dispatch/datahub + index)
constants.js # Global constants (OP_CODES, categories)
/src/**/__tests__ # Vitest suites
/scripts
generate-page-status.mjs # Regenerates docs/PAGE_STATUS.md from pageStatus.json
inspect_db.py # SQLite debug script (path resolved relative to script)
backend/core/processor.py and backend/core/graph.py are retained legacy modules outside the active execution path. Avoid adding new dependencies to them. See PROJECT_HANDOVER.md for maintenance details.
- Single Responsibility: No single file should exceed 400 lines; complex logic must be extracted into Hooks.
- Test-Driven:
npm run testmust be run after modifying core logic. - DRY Principle: Avoid Magic Strings; use
constants.js.

