arcane-agents 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +528 -0
- package/assets/characters/README.md +114 -0
- package/assets/characters/assassin-shadow/animations/walk/east/0.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/east/1.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/east/2.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/east/3.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/east/4.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/east/5.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/east/6.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/east/7.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/north/0.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/north/1.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/north/2.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/north/3.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/north/4.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/north/5.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/north/6.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/north/7.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/south/0.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/south/1.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/south/2.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/south/3.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/south/4.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/south/5.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/south/6.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/south/7.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/west/0.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/west/1.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/west/2.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/west/3.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/west/4.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/west/5.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/west/6.png +0 -0
- package/assets/characters/assassin-shadow/animations/walk/west/7.png +0 -0
- package/assets/characters/assassin-shadow/animations/working/0.png +0 -0
- package/assets/characters/assassin-shadow/animations/working/1.png +0 -0
- package/assets/characters/assassin-shadow/animations/working/10.png +0 -0
- package/assets/characters/assassin-shadow/animations/working/11.png +0 -0
- package/assets/characters/assassin-shadow/animations/working/12.png +0 -0
- package/assets/characters/assassin-shadow/animations/working/13.png +0 -0
- package/assets/characters/assassin-shadow/animations/working/14.png +0 -0
- package/assets/characters/assassin-shadow/animations/working/15.png +0 -0
- package/assets/characters/assassin-shadow/animations/working/2.png +0 -0
- package/assets/characters/assassin-shadow/animations/working/3.png +0 -0
- package/assets/characters/assassin-shadow/animations/working/4.png +0 -0
- package/assets/characters/assassin-shadow/animations/working/5.png +0 -0
- package/assets/characters/assassin-shadow/animations/working/6.png +0 -0
- package/assets/characters/assassin-shadow/animations/working/7.png +0 -0
- package/assets/characters/assassin-shadow/animations/working/8.png +0 -0
- package/assets/characters/assassin-shadow/animations/working/9.png +0 -0
- package/assets/characters/assassin-shadow/rotations/east.png +0 -0
- package/assets/characters/assassin-shadow/rotations/north.png +0 -0
- package/assets/characters/assassin-shadow/rotations/south.png +0 -0
- package/assets/characters/assassin-shadow/rotations/west.png +0 -0
- package/assets/characters/assassin-shadow/voice-lines/arrive.mp3 +0 -0
- package/assets/characters/assassin-shadow/voice-lines/attention.mp3 +0 -0
- package/assets/characters/assassin-shadow/voice-lines/complete.mp3 +0 -0
- package/assets/characters/assassin-shadow/voice-lines/death.mp3 +0 -0
- package/assets/characters/assassin-shadow/voice-lines/move_variant_1.mp3 +0 -0
- package/assets/characters/assassin-shadow/voice-lines/move_variant_2.mp3 +0 -0
- package/assets/characters/assassin-shadow/voice-lines/move_variant_3.mp3 +0 -0
- package/assets/characters/assassin-shadow/voice-lines/selected_variant_1.mp3 +0 -0
- package/assets/characters/assassin-shadow/voice-lines/selected_variant_2.mp3 +0 -0
- package/assets/characters/assassin-shadow/voice-lines/selected_variant_3.mp3 +0 -0
- package/assets/characters/barbarian-wild/animations/walk/east/0.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/east/1.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/east/2.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/east/3.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/east/4.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/east/5.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/east/6.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/east/7.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/north/0.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/north/1.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/north/2.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/north/3.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/north/4.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/north/5.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/north/6.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/north/7.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/south/0.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/south/1.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/south/2.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/south/3.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/south/4.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/south/5.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/south/6.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/south/7.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/west/0.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/west/1.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/west/2.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/west/3.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/west/4.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/west/5.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/west/6.png +0 -0
- package/assets/characters/barbarian-wild/animations/walk/west/7.png +0 -0
- package/assets/characters/barbarian-wild/animations/working/0.png +0 -0
- package/assets/characters/barbarian-wild/animations/working/1.png +0 -0
- package/assets/characters/barbarian-wild/animations/working/10.png +0 -0
- package/assets/characters/barbarian-wild/animations/working/11.png +0 -0
- package/assets/characters/barbarian-wild/animations/working/12.png +0 -0
- package/assets/characters/barbarian-wild/animations/working/13.png +0 -0
- package/assets/characters/barbarian-wild/animations/working/14.png +0 -0
- package/assets/characters/barbarian-wild/animations/working/15.png +0 -0
- package/assets/characters/barbarian-wild/animations/working/2.png +0 -0
- package/assets/characters/barbarian-wild/animations/working/3.png +0 -0
- package/assets/characters/barbarian-wild/animations/working/4.png +0 -0
- package/assets/characters/barbarian-wild/animations/working/5.png +0 -0
- package/assets/characters/barbarian-wild/animations/working/6.png +0 -0
- package/assets/characters/barbarian-wild/animations/working/7.png +0 -0
- package/assets/characters/barbarian-wild/animations/working/8.png +0 -0
- package/assets/characters/barbarian-wild/animations/working/9.png +0 -0
- package/assets/characters/barbarian-wild/rotations/east.png +0 -0
- package/assets/characters/barbarian-wild/rotations/north.png +0 -0
- package/assets/characters/barbarian-wild/rotations/south.png +0 -0
- package/assets/characters/barbarian-wild/rotations/west.png +0 -0
- package/assets/characters/barbarian-wild/voice-lines/arrive.mp3 +0 -0
- package/assets/characters/barbarian-wild/voice-lines/attention.mp3 +0 -0
- package/assets/characters/barbarian-wild/voice-lines/complete.mp3 +0 -0
- package/assets/characters/barbarian-wild/voice-lines/death.mp3 +0 -0
- package/assets/characters/barbarian-wild/voice-lines/move_variant_1.mp3 +0 -0
- package/assets/characters/barbarian-wild/voice-lines/move_variant_2.mp3 +0 -0
- package/assets/characters/barbarian-wild/voice-lines/move_variant_3.mp3 +0 -0
- package/assets/characters/barbarian-wild/voice-lines/selected_variant_1.mp3 +0 -0
- package/assets/characters/barbarian-wild/voice-lines/selected_variant_2.mp3 +0 -0
- package/assets/characters/barbarian-wild/voice-lines/selected_variant_3.mp3 +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/east/0.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/east/1.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/east/2.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/east/3.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/east/4.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/east/5.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/east/6.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/east/7.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/north/0.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/north/1.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/north/2.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/north/3.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/north/4.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/north/5.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/north/6.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/north/7.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/south/0.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/south/1.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/south/2.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/south/3.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/south/4.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/south/5.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/south/6.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/south/7.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/west/0.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/west/1.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/west/2.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/west/3.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/west/4.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/west/5.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/west/6.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/walk/west/7.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/working/0.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/working/1.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/working/10.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/working/11.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/working/12.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/working/13.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/working/14.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/working/15.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/working/2.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/working/3.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/working/4.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/working/5.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/working/6.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/working/7.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/working/8.png +0 -0
- package/assets/characters/blood-elf-spellarcher/animations/working/9.png +0 -0
- package/assets/characters/blood-elf-spellarcher/rotations/east.png +0 -0
- package/assets/characters/blood-elf-spellarcher/rotations/north.png +0 -0
- package/assets/characters/blood-elf-spellarcher/rotations/south.png +0 -0
- package/assets/characters/blood-elf-spellarcher/rotations/west.png +0 -0
- package/assets/characters/blood-elf-spellarcher/voice-lines/arrive.mp3 +0 -0
- package/assets/characters/blood-elf-spellarcher/voice-lines/attention.mp3 +0 -0
- package/assets/characters/blood-elf-spellarcher/voice-lines/complete.mp3 +0 -0
- package/assets/characters/blood-elf-spellarcher/voice-lines/death.mp3 +0 -0
- package/assets/characters/blood-elf-spellarcher/voice-lines/move_variant_1.mp3 +0 -0
- package/assets/characters/blood-elf-spellarcher/voice-lines/move_variant_2.mp3 +0 -0
- package/assets/characters/blood-elf-spellarcher/voice-lines/move_variant_3.mp3 +0 -0
- package/assets/characters/blood-elf-spellarcher/voice-lines/selected_variant_1.mp3 +0 -0
- package/assets/characters/blood-elf-spellarcher/voice-lines/selected_variant_2.mp3 +0 -0
- package/assets/characters/blood-elf-spellarcher/voice-lines/selected_variant_3.mp3 +0 -0
- package/assets/characters/chronomancer/animations/walk/east/0.png +0 -0
- package/assets/characters/chronomancer/animations/walk/east/1.png +0 -0
- package/assets/characters/chronomancer/animations/walk/east/2.png +0 -0
- package/assets/characters/chronomancer/animations/walk/east/3.png +0 -0
- package/assets/characters/chronomancer/animations/walk/east/4.png +0 -0
- package/assets/characters/chronomancer/animations/walk/east/5.png +0 -0
- package/assets/characters/chronomancer/animations/walk/east/6.png +0 -0
- package/assets/characters/chronomancer/animations/walk/east/7.png +0 -0
- package/assets/characters/chronomancer/animations/walk/north/0.png +0 -0
- package/assets/characters/chronomancer/animations/walk/north/1.png +0 -0
- package/assets/characters/chronomancer/animations/walk/north/2.png +0 -0
- package/assets/characters/chronomancer/animations/walk/north/3.png +0 -0
- package/assets/characters/chronomancer/animations/walk/north/4.png +0 -0
- package/assets/characters/chronomancer/animations/walk/north/5.png +0 -0
- package/assets/characters/chronomancer/animations/walk/north/6.png +0 -0
- package/assets/characters/chronomancer/animations/walk/north/7.png +0 -0
- package/assets/characters/chronomancer/animations/walk/south/0.png +0 -0
- package/assets/characters/chronomancer/animations/walk/south/1.png +0 -0
- package/assets/characters/chronomancer/animations/walk/south/2.png +0 -0
- package/assets/characters/chronomancer/animations/walk/south/3.png +0 -0
- package/assets/characters/chronomancer/animations/walk/south/4.png +0 -0
- package/assets/characters/chronomancer/animations/walk/south/5.png +0 -0
- package/assets/characters/chronomancer/animations/walk/south/6.png +0 -0
- package/assets/characters/chronomancer/animations/walk/south/7.png +0 -0
- package/assets/characters/chronomancer/animations/walk/west/0.png +0 -0
- package/assets/characters/chronomancer/animations/walk/west/1.png +0 -0
- package/assets/characters/chronomancer/animations/walk/west/2.png +0 -0
- package/assets/characters/chronomancer/animations/walk/west/3.png +0 -0
- package/assets/characters/chronomancer/animations/walk/west/4.png +0 -0
- package/assets/characters/chronomancer/animations/walk/west/5.png +0 -0
- package/assets/characters/chronomancer/animations/walk/west/6.png +0 -0
- package/assets/characters/chronomancer/animations/walk/west/7.png +0 -0
- package/assets/characters/chronomancer/animations/working/0.png +0 -0
- package/assets/characters/chronomancer/animations/working/1.png +0 -0
- package/assets/characters/chronomancer/animations/working/10.png +0 -0
- package/assets/characters/chronomancer/animations/working/11.png +0 -0
- package/assets/characters/chronomancer/animations/working/12.png +0 -0
- package/assets/characters/chronomancer/animations/working/13.png +0 -0
- package/assets/characters/chronomancer/animations/working/14.png +0 -0
- package/assets/characters/chronomancer/animations/working/15.png +0 -0
- package/assets/characters/chronomancer/animations/working/2.png +0 -0
- package/assets/characters/chronomancer/animations/working/3.png +0 -0
- package/assets/characters/chronomancer/animations/working/4.png +0 -0
- package/assets/characters/chronomancer/animations/working/5.png +0 -0
- package/assets/characters/chronomancer/animations/working/6.png +0 -0
- package/assets/characters/chronomancer/animations/working/7.png +0 -0
- package/assets/characters/chronomancer/animations/working/8.png +0 -0
- package/assets/characters/chronomancer/animations/working/9.png +0 -0
- package/assets/characters/chronomancer/rotations/east.png +0 -0
- package/assets/characters/chronomancer/rotations/north.png +0 -0
- package/assets/characters/chronomancer/rotations/south.png +0 -0
- package/assets/characters/chronomancer/rotations/west.png +0 -0
- package/assets/characters/chronomancer/voice-lines/arrive.mp3 +0 -0
- package/assets/characters/chronomancer/voice-lines/attention.mp3 +0 -0
- package/assets/characters/chronomancer/voice-lines/complete.mp3 +0 -0
- package/assets/characters/chronomancer/voice-lines/death.mp3 +0 -0
- package/assets/characters/chronomancer/voice-lines/move_variant_1.mp3 +0 -0
- package/assets/characters/chronomancer/voice-lines/move_variant_2.mp3 +0 -0
- package/assets/characters/chronomancer/voice-lines/move_variant_3.mp3 +0 -0
- package/assets/characters/chronomancer/voice-lines/selected_variant_1.mp3 +0 -0
- package/assets/characters/chronomancer/voice-lines/selected_variant_2.mp3 +0 -0
- package/assets/characters/chronomancer/voice-lines/selected_variant_3.mp3 +0 -0
- package/assets/characters/crystal-mage/animations/walk/east/0.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/east/1.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/east/2.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/east/3.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/east/4.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/east/5.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/east/6.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/east/7.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/north/0.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/north/1.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/north/2.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/north/3.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/north/4.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/north/5.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/north/6.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/north/7.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/south/0.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/south/1.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/south/2.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/south/3.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/south/4.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/south/5.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/south/6.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/south/7.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/west/0.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/west/1.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/west/2.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/west/3.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/west/4.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/west/5.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/west/6.png +0 -0
- package/assets/characters/crystal-mage/animations/walk/west/7.png +0 -0
- package/assets/characters/crystal-mage/animations/working/0.png +0 -0
- package/assets/characters/crystal-mage/animations/working/1.png +0 -0
- package/assets/characters/crystal-mage/animations/working/10.png +0 -0
- package/assets/characters/crystal-mage/animations/working/11.png +0 -0
- package/assets/characters/crystal-mage/animations/working/12.png +0 -0
- package/assets/characters/crystal-mage/animations/working/13.png +0 -0
- package/assets/characters/crystal-mage/animations/working/14.png +0 -0
- package/assets/characters/crystal-mage/animations/working/15.png +0 -0
- package/assets/characters/crystal-mage/animations/working/2.png +0 -0
- package/assets/characters/crystal-mage/animations/working/3.png +0 -0
- package/assets/characters/crystal-mage/animations/working/4.png +0 -0
- package/assets/characters/crystal-mage/animations/working/5.png +0 -0
- package/assets/characters/crystal-mage/animations/working/6.png +0 -0
- package/assets/characters/crystal-mage/animations/working/7.png +0 -0
- package/assets/characters/crystal-mage/animations/working/8.png +0 -0
- package/assets/characters/crystal-mage/animations/working/9.png +0 -0
- package/assets/characters/crystal-mage/rotations/east.png +0 -0
- package/assets/characters/crystal-mage/rotations/north.png +0 -0
- package/assets/characters/crystal-mage/rotations/south.png +0 -0
- package/assets/characters/crystal-mage/rotations/west.png +0 -0
- package/assets/characters/crystal-mage/voice-lines/arrive.mp3 +0 -0
- package/assets/characters/crystal-mage/voice-lines/attention.mp3 +0 -0
- package/assets/characters/crystal-mage/voice-lines/complete.mp3 +0 -0
- package/assets/characters/crystal-mage/voice-lines/death.mp3 +0 -0
- package/assets/characters/crystal-mage/voice-lines/move_variant_1.mp3 +0 -0
- package/assets/characters/crystal-mage/voice-lines/move_variant_2.mp3 +0 -0
- package/assets/characters/crystal-mage/voice-lines/move_variant_3.mp3 +0 -0
- package/assets/characters/crystal-mage/voice-lines/selected_variant_1.mp3 +0 -0
- package/assets/characters/crystal-mage/voice-lines/selected_variant_2.mp3 +0 -0
- package/assets/characters/crystal-mage/voice-lines/selected_variant_3.mp3 +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/east/0.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/east/1.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/east/2.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/east/3.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/east/4.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/east/5.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/east/6.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/east/7.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/north/0.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/north/1.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/north/2.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/north/3.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/north/4.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/north/5.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/north/6.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/north/7.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/south/0.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/south/1.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/south/2.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/south/3.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/south/4.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/south/5.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/south/6.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/south/7.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/west/0.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/west/1.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/west/2.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/west/3.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/west/4.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/west/5.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/west/6.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/walk/west/7.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/working/0.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/working/1.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/working/10.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/working/11.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/working/12.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/working/13.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/working/14.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/working/15.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/working/2.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/working/3.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/working/4.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/working/5.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/working/6.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/working/7.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/working/8.png +0 -0
- package/assets/characters/dwarf-warrior-short/animations/working/9.png +0 -0
- package/assets/characters/dwarf-warrior-short/rotations/east.png +0 -0
- package/assets/characters/dwarf-warrior-short/rotations/north.png +0 -0
- package/assets/characters/dwarf-warrior-short/rotations/south.png +0 -0
- package/assets/characters/dwarf-warrior-short/rotations/west.png +0 -0
- package/assets/characters/dwarf-warrior-short/voice-lines/arrive.mp3 +0 -0
- package/assets/characters/dwarf-warrior-short/voice-lines/attention.mp3 +0 -0
- package/assets/characters/dwarf-warrior-short/voice-lines/complete.mp3 +0 -0
- package/assets/characters/dwarf-warrior-short/voice-lines/death.mp3 +0 -0
- package/assets/characters/dwarf-warrior-short/voice-lines/move_variant_1.mp3 +0 -0
- package/assets/characters/dwarf-warrior-short/voice-lines/move_variant_2.mp3 +0 -0
- package/assets/characters/dwarf-warrior-short/voice-lines/move_variant_3.mp3 +0 -0
- package/assets/characters/dwarf-warrior-short/voice-lines/selected_variant_1.mp3 +0 -0
- package/assets/characters/dwarf-warrior-short/voice-lines/selected_variant_2.mp3 +0 -0
- package/assets/characters/dwarf-warrior-short/voice-lines/selected_variant_3.mp3 +0 -0
- package/assets/characters/elder-wizard/animations/walk/east/0.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/east/1.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/east/2.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/east/3.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/east/4.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/east/5.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/east/6.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/east/7.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/north/0.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/north/1.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/north/2.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/north/3.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/north/4.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/north/5.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/north/6.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/north/7.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/south/0.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/south/1.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/south/2.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/south/3.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/south/4.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/south/5.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/south/6.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/south/7.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/west/0.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/west/1.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/west/2.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/west/3.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/west/4.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/west/5.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/west/6.png +0 -0
- package/assets/characters/elder-wizard/animations/walk/west/7.png +0 -0
- package/assets/characters/elder-wizard/animations/working/0.png +0 -0
- package/assets/characters/elder-wizard/animations/working/1.png +0 -0
- package/assets/characters/elder-wizard/animations/working/10.png +0 -0
- package/assets/characters/elder-wizard/animations/working/11.png +0 -0
- package/assets/characters/elder-wizard/animations/working/12.png +0 -0
- package/assets/characters/elder-wizard/animations/working/13.png +0 -0
- package/assets/characters/elder-wizard/animations/working/14.png +0 -0
- package/assets/characters/elder-wizard/animations/working/15.png +0 -0
- package/assets/characters/elder-wizard/animations/working/2.png +0 -0
- package/assets/characters/elder-wizard/animations/working/3.png +0 -0
- package/assets/characters/elder-wizard/animations/working/4.png +0 -0
- package/assets/characters/elder-wizard/animations/working/5.png +0 -0
- package/assets/characters/elder-wizard/animations/working/6.png +0 -0
- package/assets/characters/elder-wizard/animations/working/7.png +0 -0
- package/assets/characters/elder-wizard/animations/working/8.png +0 -0
- package/assets/characters/elder-wizard/animations/working/9.png +0 -0
- package/assets/characters/elder-wizard/rotations/east.png +0 -0
- package/assets/characters/elder-wizard/rotations/north.png +0 -0
- package/assets/characters/elder-wizard/rotations/south.png +0 -0
- package/assets/characters/elder-wizard/rotations/west.png +0 -0
- package/assets/characters/elder-wizard/voice-lines/arrive.mp3 +0 -0
- package/assets/characters/elder-wizard/voice-lines/attention.mp3 +0 -0
- package/assets/characters/elder-wizard/voice-lines/complete.mp3 +0 -0
- package/assets/characters/elder-wizard/voice-lines/death.mp3 +0 -0
- package/assets/characters/elder-wizard/voice-lines/move_variant_1.mp3 +0 -0
- package/assets/characters/elder-wizard/voice-lines/move_variant_2.mp3 +0 -0
- package/assets/characters/elder-wizard/voice-lines/move_variant_3.mp3 +0 -0
- package/assets/characters/elder-wizard/voice-lines/selected_variant_1.mp3 +0 -0
- package/assets/characters/elder-wizard/voice-lines/selected_variant_2.mp3 +0 -0
- package/assets/characters/elder-wizard/voice-lines/selected_variant_3.mp3 +0 -0
- package/assets/characters/gothic-witch/animations/walk/east/0.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/east/1.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/east/2.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/east/3.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/east/4.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/east/5.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/east/6.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/east/7.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/north/0.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/north/1.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/north/2.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/north/3.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/north/4.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/north/5.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/north/6.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/north/7.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/south/0.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/south/1.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/south/2.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/south/3.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/south/4.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/south/5.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/south/6.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/south/7.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/west/0.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/west/1.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/west/2.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/west/3.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/west/4.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/west/5.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/west/6.png +0 -0
- package/assets/characters/gothic-witch/animations/walk/west/7.png +0 -0
- package/assets/characters/gothic-witch/animations/working/0.png +0 -0
- package/assets/characters/gothic-witch/animations/working/1.png +0 -0
- package/assets/characters/gothic-witch/animations/working/10.png +0 -0
- package/assets/characters/gothic-witch/animations/working/11.png +0 -0
- package/assets/characters/gothic-witch/animations/working/12.png +0 -0
- package/assets/characters/gothic-witch/animations/working/13.png +0 -0
- package/assets/characters/gothic-witch/animations/working/14.png +0 -0
- package/assets/characters/gothic-witch/animations/working/15.png +0 -0
- package/assets/characters/gothic-witch/animations/working/2.png +0 -0
- package/assets/characters/gothic-witch/animations/working/3.png +0 -0
- package/assets/characters/gothic-witch/animations/working/4.png +0 -0
- package/assets/characters/gothic-witch/animations/working/5.png +0 -0
- package/assets/characters/gothic-witch/animations/working/6.png +0 -0
- package/assets/characters/gothic-witch/animations/working/7.png +0 -0
- package/assets/characters/gothic-witch/animations/working/8.png +0 -0
- package/assets/characters/gothic-witch/animations/working/9.png +0 -0
- package/assets/characters/gothic-witch/rotations/east.png +0 -0
- package/assets/characters/gothic-witch/rotations/north.png +0 -0
- package/assets/characters/gothic-witch/rotations/south.png +0 -0
- package/assets/characters/gothic-witch/rotations/west.png +0 -0
- package/assets/characters/gothic-witch/voice-lines/arrive.mp3 +0 -0
- package/assets/characters/gothic-witch/voice-lines/attention.mp3 +0 -0
- package/assets/characters/gothic-witch/voice-lines/complete.mp3 +0 -0
- package/assets/characters/gothic-witch/voice-lines/death.mp3 +0 -0
- package/assets/characters/gothic-witch/voice-lines/move_variant_1.mp3 +0 -0
- package/assets/characters/gothic-witch/voice-lines/move_variant_2.mp3 +0 -0
- package/assets/characters/gothic-witch/voice-lines/move_variant_3.mp3 +0 -0
- package/assets/characters/gothic-witch/voice-lines/selected_variant_1.mp3 +0 -0
- package/assets/characters/gothic-witch/voice-lines/selected_variant_2.mp3 +0 -0
- package/assets/characters/gothic-witch/voice-lines/selected_variant_3.mp3 +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/east/0.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/east/1.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/east/2.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/east/3.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/east/4.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/east/5.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/east/6.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/east/7.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/north/0.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/north/1.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/north/2.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/north/3.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/north/4.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/north/5.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/north/6.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/north/7.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/south/0.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/south/1.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/south/2.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/south/3.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/south/4.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/south/5.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/south/6.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/south/7.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/west/0.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/west/1.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/west/2.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/west/3.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/west/4.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/west/5.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/west/6.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/walk/west/7.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/working/0.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/working/1.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/working/10.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/working/11.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/working/12.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/working/13.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/working/14.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/working/15.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/working/2.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/working/3.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/working/4.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/working/5.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/working/6.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/working/7.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/working/8.png +0 -0
- package/assets/characters/horned-helm-fighter/animations/working/9.png +0 -0
- package/assets/characters/horned-helm-fighter/rotations/east.png +0 -0
- package/assets/characters/horned-helm-fighter/rotations/north.png +0 -0
- package/assets/characters/horned-helm-fighter/rotations/south.png +0 -0
- package/assets/characters/horned-helm-fighter/rotations/west.png +0 -0
- package/assets/characters/horned-helm-fighter/voice-lines/arrive.mp3 +0 -0
- package/assets/characters/horned-helm-fighter/voice-lines/attention.mp3 +0 -0
- package/assets/characters/horned-helm-fighter/voice-lines/complete.mp3 +0 -0
- package/assets/characters/horned-helm-fighter/voice-lines/death.mp3 +0 -0
- package/assets/characters/horned-helm-fighter/voice-lines/move_variant_1.mp3 +0 -0
- package/assets/characters/horned-helm-fighter/voice-lines/move_variant_2.mp3 +0 -0
- package/assets/characters/horned-helm-fighter/voice-lines/move_variant_3.mp3 +0 -0
- package/assets/characters/horned-helm-fighter/voice-lines/selected_variant_1.mp3 +0 -0
- package/assets/characters/horned-helm-fighter/voice-lines/selected_variant_2.mp3 +0 -0
- package/assets/characters/horned-helm-fighter/voice-lines/selected_variant_3.mp3 +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/east/0.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/east/1.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/east/2.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/east/3.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/east/4.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/east/5.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/east/6.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/east/7.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/north/0.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/north/1.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/north/2.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/north/3.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/north/4.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/north/5.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/north/6.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/north/7.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/south/0.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/south/1.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/south/2.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/south/3.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/south/4.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/south/5.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/south/6.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/south/7.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/west/0.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/west/1.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/west/2.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/west/3.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/west/4.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/west/5.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/west/6.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/walk/west/7.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/working/0.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/working/1.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/working/10.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/working/11.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/working/12.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/working/13.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/working/14.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/working/15.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/working/2.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/working/3.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/working/4.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/working/5.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/working/6.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/working/7.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/working/8.png +0 -0
- package/assets/characters/knight-blue-guardian/animations/working/9.png +0 -0
- package/assets/characters/knight-blue-guardian/rotations/east.png +0 -0
- package/assets/characters/knight-blue-guardian/rotations/north.png +0 -0
- package/assets/characters/knight-blue-guardian/rotations/south.png +0 -0
- package/assets/characters/knight-blue-guardian/rotations/west.png +0 -0
- package/assets/characters/knight-blue-guardian/voice-lines/arrive.mp3 +0 -0
- package/assets/characters/knight-blue-guardian/voice-lines/attention.mp3 +0 -0
- package/assets/characters/knight-blue-guardian/voice-lines/complete.mp3 +0 -0
- package/assets/characters/knight-blue-guardian/voice-lines/death.mp3 +0 -0
- package/assets/characters/knight-blue-guardian/voice-lines/move_variant_1.mp3 +0 -0
- package/assets/characters/knight-blue-guardian/voice-lines/move_variant_2.mp3 +0 -0
- package/assets/characters/knight-blue-guardian/voice-lines/move_variant_3.mp3 +0 -0
- package/assets/characters/knight-blue-guardian/voice-lines/selected_variant_1.mp3 +0 -0
- package/assets/characters/knight-blue-guardian/voice-lines/selected_variant_2.mp3 +0 -0
- package/assets/characters/knight-blue-guardian/voice-lines/selected_variant_3.mp3 +0 -0
- package/assets/characters/launch-preview.html +298 -0
- package/assets/characters/minotaur-strategist/animations/walk/east/0.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/east/1.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/east/2.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/east/3.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/east/4.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/east/5.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/east/6.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/east/7.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/north/0.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/north/1.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/north/2.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/north/3.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/north/4.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/north/5.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/north/6.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/north/7.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/south/0.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/south/1.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/south/2.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/south/3.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/south/4.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/south/5.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/south/6.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/south/7.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/west/0.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/west/1.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/west/2.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/west/3.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/west/4.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/west/5.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/west/6.png +0 -0
- package/assets/characters/minotaur-strategist/animations/walk/west/7.png +0 -0
- package/assets/characters/minotaur-strategist/animations/working/0.png +0 -0
- package/assets/characters/minotaur-strategist/animations/working/1.png +0 -0
- package/assets/characters/minotaur-strategist/animations/working/10.png +0 -0
- package/assets/characters/minotaur-strategist/animations/working/11.png +0 -0
- package/assets/characters/minotaur-strategist/animations/working/12.png +0 -0
- package/assets/characters/minotaur-strategist/animations/working/13.png +0 -0
- package/assets/characters/minotaur-strategist/animations/working/14.png +0 -0
- package/assets/characters/minotaur-strategist/animations/working/15.png +0 -0
- package/assets/characters/minotaur-strategist/animations/working/2.png +0 -0
- package/assets/characters/minotaur-strategist/animations/working/3.png +0 -0
- package/assets/characters/minotaur-strategist/animations/working/4.png +0 -0
- package/assets/characters/minotaur-strategist/animations/working/5.png +0 -0
- package/assets/characters/minotaur-strategist/animations/working/6.png +0 -0
- package/assets/characters/minotaur-strategist/animations/working/7.png +0 -0
- package/assets/characters/minotaur-strategist/animations/working/8.png +0 -0
- package/assets/characters/minotaur-strategist/animations/working/9.png +0 -0
- package/assets/characters/minotaur-strategist/rotations/east.png +0 -0
- package/assets/characters/minotaur-strategist/rotations/north.png +0 -0
- package/assets/characters/minotaur-strategist/rotations/south.png +0 -0
- package/assets/characters/minotaur-strategist/rotations/west.png +0 -0
- package/assets/characters/minotaur-strategist/voice-lines/arrive.mp3 +0 -0
- package/assets/characters/minotaur-strategist/voice-lines/attention.mp3 +0 -0
- package/assets/characters/minotaur-strategist/voice-lines/complete.mp3 +0 -0
- package/assets/characters/minotaur-strategist/voice-lines/death.mp3 +0 -0
- package/assets/characters/minotaur-strategist/voice-lines/move_variant_1.mp3 +0 -0
- package/assets/characters/minotaur-strategist/voice-lines/move_variant_2.mp3 +0 -0
- package/assets/characters/minotaur-strategist/voice-lines/move_variant_3.mp3 +0 -0
- package/assets/characters/minotaur-strategist/voice-lines/selected_variant_1.mp3 +0 -0
- package/assets/characters/minotaur-strategist/voice-lines/selected_variant_2.mp3 +0 -0
- package/assets/characters/minotaur-strategist/voice-lines/selected_variant_3.mp3 +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/east/0.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/east/1.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/east/2.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/east/3.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/east/4.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/east/5.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/east/6.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/east/7.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/north/0.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/north/1.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/north/2.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/north/3.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/north/4.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/north/5.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/north/6.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/north/7.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/south/0.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/south/1.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/south/2.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/south/3.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/south/4.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/south/5.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/south/6.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/south/7.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/west/0.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/west/1.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/west/2.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/west/3.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/west/4.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/west/5.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/west/6.png +0 -0
- package/assets/characters/moon-grove-druid/animations/walk/west/7.png +0 -0
- package/assets/characters/moon-grove-druid/animations/working/0.png +0 -0
- package/assets/characters/moon-grove-druid/animations/working/1.png +0 -0
- package/assets/characters/moon-grove-druid/animations/working/10.png +0 -0
- package/assets/characters/moon-grove-druid/animations/working/11.png +0 -0
- package/assets/characters/moon-grove-druid/animations/working/12.png +0 -0
- package/assets/characters/moon-grove-druid/animations/working/13.png +0 -0
- package/assets/characters/moon-grove-druid/animations/working/14.png +0 -0
- package/assets/characters/moon-grove-druid/animations/working/15.png +0 -0
- package/assets/characters/moon-grove-druid/animations/working/2.png +0 -0
- package/assets/characters/moon-grove-druid/animations/working/3.png +0 -0
- package/assets/characters/moon-grove-druid/animations/working/4.png +0 -0
- package/assets/characters/moon-grove-druid/animations/working/5.png +0 -0
- package/assets/characters/moon-grove-druid/animations/working/6.png +0 -0
- package/assets/characters/moon-grove-druid/animations/working/7.png +0 -0
- package/assets/characters/moon-grove-druid/animations/working/8.png +0 -0
- package/assets/characters/moon-grove-druid/animations/working/9.png +0 -0
- package/assets/characters/moon-grove-druid/rotations/east.png +0 -0
- package/assets/characters/moon-grove-druid/rotations/north.png +0 -0
- package/assets/characters/moon-grove-druid/rotations/south.png +0 -0
- package/assets/characters/moon-grove-druid/rotations/west.png +0 -0
- package/assets/characters/moon-grove-druid/voice-lines/arrive.mp3 +0 -0
- package/assets/characters/moon-grove-druid/voice-lines/attention.mp3 +0 -0
- package/assets/characters/moon-grove-druid/voice-lines/complete.mp3 +0 -0
- package/assets/characters/moon-grove-druid/voice-lines/death.mp3 +0 -0
- package/assets/characters/moon-grove-druid/voice-lines/move_variant_1.mp3 +0 -0
- package/assets/characters/moon-grove-druid/voice-lines/move_variant_2.mp3 +0 -0
- package/assets/characters/moon-grove-druid/voice-lines/move_variant_3.mp3 +0 -0
- package/assets/characters/moon-grove-druid/voice-lines/selected_variant_1.mp3 +0 -0
- package/assets/characters/moon-grove-druid/voice-lines/selected_variant_2.mp3 +0 -0
- package/assets/characters/moon-grove-druid/voice-lines/selected_variant_3.mp3 +0 -0
- package/assets/characters/necromancer-male/animations/walk/east/0.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/east/1.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/east/2.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/east/3.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/east/4.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/east/5.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/east/6.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/east/7.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/north/0.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/north/1.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/north/2.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/north/3.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/north/4.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/north/5.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/north/6.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/north/7.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/south/0.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/south/1.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/south/2.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/south/3.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/south/4.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/south/5.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/south/6.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/south/7.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/west/0.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/west/1.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/west/2.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/west/3.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/west/4.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/west/5.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/west/6.png +0 -0
- package/assets/characters/necromancer-male/animations/walk/west/7.png +0 -0
- package/assets/characters/necromancer-male/animations/working/0.png +0 -0
- package/assets/characters/necromancer-male/animations/working/1.png +0 -0
- package/assets/characters/necromancer-male/animations/working/10.png +0 -0
- package/assets/characters/necromancer-male/animations/working/11.png +0 -0
- package/assets/characters/necromancer-male/animations/working/12.png +0 -0
- package/assets/characters/necromancer-male/animations/working/13.png +0 -0
- package/assets/characters/necromancer-male/animations/working/14.png +0 -0
- package/assets/characters/necromancer-male/animations/working/15.png +0 -0
- package/assets/characters/necromancer-male/animations/working/2.png +0 -0
- package/assets/characters/necromancer-male/animations/working/3.png +0 -0
- package/assets/characters/necromancer-male/animations/working/4.png +0 -0
- package/assets/characters/necromancer-male/animations/working/5.png +0 -0
- package/assets/characters/necromancer-male/animations/working/6.png +0 -0
- package/assets/characters/necromancer-male/animations/working/7.png +0 -0
- package/assets/characters/necromancer-male/animations/working/8.png +0 -0
- package/assets/characters/necromancer-male/animations/working/9.png +0 -0
- package/assets/characters/necromancer-male/rotations/east.png +0 -0
- package/assets/characters/necromancer-male/rotations/north.png +0 -0
- package/assets/characters/necromancer-male/rotations/south.png +0 -0
- package/assets/characters/necromancer-male/rotations/west.png +0 -0
- package/assets/characters/necromancer-male/voice-lines/arrive.mp3 +0 -0
- package/assets/characters/necromancer-male/voice-lines/attention.mp3 +0 -0
- package/assets/characters/necromancer-male/voice-lines/complete.mp3 +0 -0
- package/assets/characters/necromancer-male/voice-lines/death.mp3 +0 -0
- package/assets/characters/necromancer-male/voice-lines/move_variant_1.mp3 +0 -0
- package/assets/characters/necromancer-male/voice-lines/move_variant_2.mp3 +0 -0
- package/assets/characters/necromancer-male/voice-lines/move_variant_3.mp3 +0 -0
- package/assets/characters/necromancer-male/voice-lines/selected_variant_1.mp3 +0 -0
- package/assets/characters/necromancer-male/voice-lines/selected_variant_2.mp3 +0 -0
- package/assets/characters/necromancer-male/voice-lines/selected_variant_3.mp3 +0 -0
- package/assets/characters/oracle-seer/animations/walk/east/0.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/east/1.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/east/2.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/east/3.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/east/4.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/east/5.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/east/6.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/east/7.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/north/0.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/north/1.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/north/2.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/north/3.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/north/4.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/north/5.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/north/6.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/north/7.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/south/0.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/south/1.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/south/2.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/south/3.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/south/4.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/south/5.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/south/6.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/south/7.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/west/0.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/west/1.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/west/2.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/west/3.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/west/4.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/west/5.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/west/6.png +0 -0
- package/assets/characters/oracle-seer/animations/walk/west/7.png +0 -0
- package/assets/characters/oracle-seer/animations/working/0.png +0 -0
- package/assets/characters/oracle-seer/animations/working/1.png +0 -0
- package/assets/characters/oracle-seer/animations/working/10.png +0 -0
- package/assets/characters/oracle-seer/animations/working/11.png +0 -0
- package/assets/characters/oracle-seer/animations/working/12.png +0 -0
- package/assets/characters/oracle-seer/animations/working/13.png +0 -0
- package/assets/characters/oracle-seer/animations/working/14.png +0 -0
- package/assets/characters/oracle-seer/animations/working/15.png +0 -0
- package/assets/characters/oracle-seer/animations/working/2.png +0 -0
- package/assets/characters/oracle-seer/animations/working/3.png +0 -0
- package/assets/characters/oracle-seer/animations/working/4.png +0 -0
- package/assets/characters/oracle-seer/animations/working/5.png +0 -0
- package/assets/characters/oracle-seer/animations/working/6.png +0 -0
- package/assets/characters/oracle-seer/animations/working/7.png +0 -0
- package/assets/characters/oracle-seer/animations/working/8.png +0 -0
- package/assets/characters/oracle-seer/animations/working/9.png +0 -0
- package/assets/characters/oracle-seer/rotations/east.png +0 -0
- package/assets/characters/oracle-seer/rotations/north.png +0 -0
- package/assets/characters/oracle-seer/rotations/south.png +0 -0
- package/assets/characters/oracle-seer/rotations/west.png +0 -0
- package/assets/characters/oracle-seer/voice-lines/arrive.mp3 +0 -0
- package/assets/characters/oracle-seer/voice-lines/attention.mp3 +0 -0
- package/assets/characters/oracle-seer/voice-lines/complete.mp3 +0 -0
- package/assets/characters/oracle-seer/voice-lines/death.mp3 +0 -0
- package/assets/characters/oracle-seer/voice-lines/move_variant_1.mp3 +0 -0
- package/assets/characters/oracle-seer/voice-lines/move_variant_2.mp3 +0 -0
- package/assets/characters/oracle-seer/voice-lines/move_variant_3.mp3 +0 -0
- package/assets/characters/oracle-seer/voice-lines/selected_variant_1.mp3 +0 -0
- package/assets/characters/oracle-seer/voice-lines/selected_variant_2.mp3 +0 -0
- package/assets/characters/oracle-seer/voice-lines/selected_variant_3.mp3 +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/east/0.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/east/1.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/east/2.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/east/3.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/east/4.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/east/5.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/east/6.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/east/7.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/north/0.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/north/1.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/north/2.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/north/3.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/north/4.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/north/5.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/north/6.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/north/7.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/south/0.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/south/1.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/south/2.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/south/3.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/south/4.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/south/5.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/south/6.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/south/7.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/west/0.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/west/1.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/west/2.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/west/3.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/west/4.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/west/5.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/west/6.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/walk/west/7.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/working/0.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/working/1.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/working/10.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/working/11.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/working/12.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/working/13.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/working/14.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/working/15.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/working/2.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/working/3.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/working/4.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/working/5.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/working/6.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/working/7.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/working/8.png +0 -0
- package/assets/characters/pyromancer-wizard/animations/working/9.png +0 -0
- package/assets/characters/pyromancer-wizard/rotations/east.png +0 -0
- package/assets/characters/pyromancer-wizard/rotations/north.png +0 -0
- package/assets/characters/pyromancer-wizard/rotations/south.png +0 -0
- package/assets/characters/pyromancer-wizard/rotations/west.png +0 -0
- package/assets/characters/pyromancer-wizard/voice-lines/arrive.mp3 +0 -0
- package/assets/characters/pyromancer-wizard/voice-lines/attention.mp3 +0 -0
- package/assets/characters/pyromancer-wizard/voice-lines/complete.mp3 +0 -0
- package/assets/characters/pyromancer-wizard/voice-lines/death.mp3 +0 -0
- package/assets/characters/pyromancer-wizard/voice-lines/move_variant_1.mp3 +0 -0
- package/assets/characters/pyromancer-wizard/voice-lines/move_variant_2.mp3 +0 -0
- package/assets/characters/pyromancer-wizard/voice-lines/move_variant_3.mp3 +0 -0
- package/assets/characters/pyromancer-wizard/voice-lines/selected_variant_1.mp3 +0 -0
- package/assets/characters/pyromancer-wizard/voice-lines/selected_variant_2.mp3 +0 -0
- package/assets/characters/pyromancer-wizard/voice-lines/selected_variant_3.mp3 +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/east/0.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/east/1.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/east/2.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/east/3.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/east/4.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/east/5.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/east/6.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/east/7.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/north/0.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/north/1.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/north/2.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/north/3.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/north/4.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/north/5.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/north/6.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/north/7.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/south/0.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/south/1.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/south/2.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/south/3.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/south/4.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/south/5.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/south/6.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/south/7.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/west/0.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/west/1.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/west/2.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/west/3.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/west/4.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/west/5.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/west/6.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/walk/west/7.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/working/0.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/working/1.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/working/10.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/working/11.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/working/12.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/working/13.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/working/14.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/working/15.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/working/2.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/working/3.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/working/4.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/working/5.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/working/6.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/working/7.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/working/8.png +0 -0
- package/assets/characters/sun-priestess-healer/animations/working/9.png +0 -0
- package/assets/characters/sun-priestess-healer/rotations/east.png +0 -0
- package/assets/characters/sun-priestess-healer/rotations/north.png +0 -0
- package/assets/characters/sun-priestess-healer/rotations/south.png +0 -0
- package/assets/characters/sun-priestess-healer/rotations/west.png +0 -0
- package/assets/characters/sun-priestess-healer/voice-lines/arrive.mp3 +0 -0
- package/assets/characters/sun-priestess-healer/voice-lines/attention.mp3 +0 -0
- package/assets/characters/sun-priestess-healer/voice-lines/complete.mp3 +0 -0
- package/assets/characters/sun-priestess-healer/voice-lines/death.mp3 +0 -0
- package/assets/characters/sun-priestess-healer/voice-lines/move_variant_1.mp3 +0 -0
- package/assets/characters/sun-priestess-healer/voice-lines/move_variant_2.mp3 +0 -0
- package/assets/characters/sun-priestess-healer/voice-lines/move_variant_3.mp3 +0 -0
- package/assets/characters/sun-priestess-healer/voice-lines/selected_variant_1.mp3 +0 -0
- package/assets/characters/sun-priestess-healer/voice-lines/selected_variant_2.mp3 +0 -0
- package/assets/characters/sun-priestess-healer/voice-lines/selected_variant_3.mp3 +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/east/0.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/east/1.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/east/2.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/east/3.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/east/4.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/east/5.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/east/6.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/east/7.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/north/0.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/north/1.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/north/2.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/north/3.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/north/4.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/north/5.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/north/6.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/north/7.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/south/0.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/south/1.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/south/2.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/south/3.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/south/4.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/south/5.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/south/6.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/south/7.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/west/0.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/west/1.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/west/2.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/west/3.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/west/4.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/west/5.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/west/6.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/walk/west/7.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/working/0.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/working/1.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/working/10.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/working/11.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/working/12.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/working/13.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/working/14.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/working/15.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/working/2.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/working/3.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/working/4.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/working/5.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/working/6.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/working/7.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/working/8.png +0 -0
- package/assets/characters/valkyrie-spearmaid/animations/working/9.png +0 -0
- package/assets/characters/valkyrie-spearmaid/rotations/east.png +0 -0
- package/assets/characters/valkyrie-spearmaid/rotations/north.png +0 -0
- package/assets/characters/valkyrie-spearmaid/rotations/south.png +0 -0
- package/assets/characters/valkyrie-spearmaid/rotations/west.png +0 -0
- package/assets/characters/valkyrie-spearmaid/voice-lines/arrive.mp3 +0 -0
- package/assets/characters/valkyrie-spearmaid/voice-lines/attention.mp3 +0 -0
- package/assets/characters/valkyrie-spearmaid/voice-lines/complete.mp3 +0 -0
- package/assets/characters/valkyrie-spearmaid/voice-lines/death.mp3 +0 -0
- package/assets/characters/valkyrie-spearmaid/voice-lines/move_variant_1.mp3 +0 -0
- package/assets/characters/valkyrie-spearmaid/voice-lines/move_variant_2.mp3 +0 -0
- package/assets/characters/valkyrie-spearmaid/voice-lines/move_variant_3.mp3 +0 -0
- package/assets/characters/valkyrie-spearmaid/voice-lines/selected_variant_1.mp3 +0 -0
- package/assets/characters/valkyrie-spearmaid/voice-lines/selected_variant_2.mp3 +0 -0
- package/assets/characters/valkyrie-spearmaid/voice-lines/selected_variant_3.mp3 +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/east/0.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/east/1.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/east/2.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/east/3.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/east/4.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/east/5.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/east/6.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/east/7.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/north/0.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/north/1.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/north/2.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/north/3.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/north/4.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/north/5.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/north/6.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/north/7.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/south/0.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/south/1.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/south/2.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/south/3.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/south/4.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/south/5.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/south/6.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/south/7.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/west/0.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/west/1.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/west/2.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/west/3.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/west/4.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/west/5.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/west/6.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/walk/west/7.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/working/0.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/working/1.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/working/10.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/working/11.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/working/12.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/working/13.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/working/14.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/working/15.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/working/2.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/working/3.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/working/4.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/working/5.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/working/6.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/working/7.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/working/8.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/animations/working/9.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/rotations/east.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/rotations/north.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/rotations/south.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/rotations/west.png +0 -0
- package/assets/characters/witch-hunter-gunslinger/voice-lines/arrive.mp3 +0 -0
- package/assets/characters/witch-hunter-gunslinger/voice-lines/attention.mp3 +0 -0
- package/assets/characters/witch-hunter-gunslinger/voice-lines/complete.mp3 +0 -0
- package/assets/characters/witch-hunter-gunslinger/voice-lines/death.mp3 +0 -0
- package/assets/characters/witch-hunter-gunslinger/voice-lines/move_variant_1.mp3 +0 -0
- package/assets/characters/witch-hunter-gunslinger/voice-lines/move_variant_2.mp3 +0 -0
- package/assets/characters/witch-hunter-gunslinger/voice-lines/move_variant_3.mp3 +0 -0
- package/assets/characters/witch-hunter-gunslinger/voice-lines/selected_variant_1.mp3 +0 -0
- package/assets/characters/witch-hunter-gunslinger/voice-lines/selected_variant_2.mp3 +0 -0
- package/assets/characters/witch-hunter-gunslinger/voice-lines/selected_variant_3.mp3 +0 -0
- package/assets/maps/backgrounds/outpost-v1-2x.png +0 -0
- package/assets/maps/backgrounds/outpost-v1-original.png +0 -0
- package/assets/maps/backgrounds/outpost-v1-upscaled-2x-photo.png +0 -0
- package/assets/maps/backgrounds/outpost-v1.png +0 -0
- package/assets/maps/outpost.json +130 -0
- package/assets/maps/outpost.logic.json +26197 -0
- package/config.example.yaml +91 -0
- package/dist/client/assets/index-B0hs4377.js +80 -0
- package/dist/client/assets/index-TxsheMVB.css +32 -0
- package/dist/client/index.html +13 -0
- package/dist/client/map-mask-editor.html +1853 -0
- package/dist/server/server/assets/avatarCatalog.js +37 -0
- package/dist/server/server/assets/voiceLineCatalog.js +42 -0
- package/dist/server/server/bootstrap/httpApp.js +39 -0
- package/dist/server/server/bootstrap/serverContext.js +60 -0
- package/dist/server/server/bootstrap/shutdown.js +152 -0
- package/dist/server/server/bootstrap/shutdown.test.js +142 -0
- package/dist/server/server/bootstrap/websocketUpgrade.js +111 -0
- package/dist/server/server/bootstrap/websocketUpgrade.test.js +83 -0
- package/dist/server/server/bootstrapApp.js +89 -0
- package/dist/server/server/cli.js +452 -0
- package/dist/server/server/config/discovery.js +159 -0
- package/dist/server/server/config/loadConfig.js +121 -0
- package/dist/server/server/config/schema.js +121 -0
- package/dist/server/server/http/appError.js +30 -0
- package/dist/server/server/http/errorResponse.js +31 -0
- package/dist/server/server/http/errorResponse.test.js +46 -0
- package/dist/server/server/http/requestParsers.js +133 -0
- package/dist/server/server/http/requestParsers.test.js +57 -0
- package/dist/server/server/http/routes/registerApiRoutes.js +146 -0
- package/dist/server/server/index.js +9 -0
- package/dist/server/server/orchestrator/orchestratorService.js +378 -0
- package/dist/server/server/orchestrator/orchestratorService.test.js +111 -0
- package/dist/server/server/orchestrator/reconcile/isSameWorkerRecord.js +17 -0
- package/dist/server/server/orchestrator/spawn/avatarAllocator.js +20 -0
- package/dist/server/server/orchestrator/spawn/command.js +37 -0
- package/dist/server/server/orchestrator/spawn/command.test.js +39 -0
- package/dist/server/server/orchestrator/spawn/resolveSpawnPlan.js +44 -0
- package/dist/server/server/orchestrator/spawn/resolveSpawnPlan.test.js +79 -0
- package/dist/server/server/orchestrator/spawn/spawnPosition.js +147 -0
- package/dist/server/server/orchestrator/spawn/types.js +2 -0
- package/dist/server/server/orchestrator/spawn/windowName.js +12 -0
- package/dist/server/server/persistence/workerRepository.js +211 -0
- package/dist/server/server/status/activityParser.js +172 -0
- package/dist/server/server/status/claudeTranscript/accumulator.js +372 -0
- package/dist/server/server/status/claudeTranscript/constants.js +18 -0
- package/dist/server/server/status/claudeTranscript/io.js +160 -0
- package/dist/server/server/status/claudeTranscript/parser.js +50 -0
- package/dist/server/server/status/claudeTranscript/snapshot.js +82 -0
- package/dist/server/server/status/claudeTranscript/types.js +2 -0
- package/dist/server/server/status/claudeTranscriptTracker.js +59 -0
- package/dist/server/server/status/engine/signalContext.js +41 -0
- package/dist/server/server/status/engine/stateMachine/activity.js +18 -0
- package/dist/server/server/status/engine/stateMachine/constants.js +45 -0
- package/dist/server/server/status/engine/stateMachine/decision.js +213 -0
- package/dist/server/server/status/engine/stateMachine/decision.test.js +139 -0
- package/dist/server/server/status/engine/stateMachine/helpers.js +103 -0
- package/dist/server/server/status/engine/stateMachine/helpers.test.js +113 -0
- package/dist/server/server/status/engine/stateMachine/idleBlockers.js +55 -0
- package/dist/server/server/status/engine/stateMachine/parserErrorRules.js +42 -0
- package/dist/server/server/status/engine/stateMachine/types.js +2 -0
- package/dist/server/server/status/engine/stateMachine/workingEvidence.js +97 -0
- package/dist/server/server/status/engine/stateMachine.js +5 -0
- package/dist/server/server/status/engine/types.js +4 -0
- package/dist/server/server/status/paneObservation.js +35 -0
- package/dist/server/server/status/runtime/activityTextExtractors.js +189 -0
- package/dist/server/server/status/runtime/claudeSignals.js +56 -0
- package/dist/server/server/status/runtime/openCodeSignals.js +63 -0
- package/dist/server/server/status/runtime/sessionDetection.js +37 -0
- package/dist/server/server/status/runtime/textSignals.js +21 -0
- package/dist/server/server/status/runtimeSignals.js +21 -0
- package/dist/server/server/status/statusEvaluator.js +16 -0
- package/dist/server/server/status/statusHeuristics.js +146 -0
- package/dist/server/server/status/statusMonitor.js +390 -0
- package/dist/server/server/status/statusMonitor.test.js +191 -0
- package/dist/server/server/status/statusPipeline.js +45 -0
- package/dist/server/server/tmux/tmuxAdapter.js +338 -0
- package/dist/server/server/utils/appRoot.js +40 -0
- package/dist/server/server/utils/path.js +20 -0
- package/dist/server/server/ws/realtimeHub.js +44 -0
- package/dist/server/server/ws/realtimeHub.test.js +43 -0
- package/dist/server/server/ws/terminalBridge.js +153 -0
- package/dist/server/shared/types.js +2 -0
- package/package.json +68 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.listAvailableAvatarTypes = listAvailableAvatarTypes;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const appRoot_1 = require("../utils/appRoot");
|
|
10
|
+
const requiredAvatarFiles = [
|
|
11
|
+
"rotations/south.png",
|
|
12
|
+
"rotations/east.png",
|
|
13
|
+
"rotations/north.png",
|
|
14
|
+
"rotations/west.png",
|
|
15
|
+
"animations/walk/south/0.png",
|
|
16
|
+
"animations/working/0.png"
|
|
17
|
+
];
|
|
18
|
+
function listAvailableAvatarTypes(assetsRoot = (0, appRoot_1.resolveAppPath)("assets", "characters")) {
|
|
19
|
+
let entries;
|
|
20
|
+
try {
|
|
21
|
+
entries = node_fs_1.default.readdirSync(assetsRoot, { withFileTypes: true });
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
return entries
|
|
27
|
+
.filter((entry) => entry.isDirectory())
|
|
28
|
+
.map((entry) => entry.name.trim())
|
|
29
|
+
.filter((avatarType) => avatarType.length > 0)
|
|
30
|
+
.filter((avatarType) => hasRequiredAvatarFiles(assetsRoot, avatarType))
|
|
31
|
+
.sort((a, b) => a.localeCompare(b));
|
|
32
|
+
}
|
|
33
|
+
function hasRequiredAvatarFiles(assetsRoot, avatarType) {
|
|
34
|
+
return requiredAvatarFiles.every((relativeFilePath) => {
|
|
35
|
+
return node_fs_1.default.existsSync(node_path_1.default.join(assetsRoot, avatarType, relativeFilePath));
|
|
36
|
+
});
|
|
37
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.listAvatarVoiceLineFiles = listAvatarVoiceLineFiles;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const appRoot_1 = require("../utils/appRoot");
|
|
10
|
+
const voiceLineExtension = ".mp3";
|
|
11
|
+
function listAvatarVoiceLineFiles(avatarType, assetsRoot = (0, appRoot_1.resolveAppPath)("assets", "characters")) {
|
|
12
|
+
const voiceLinesDir = resolveVoiceLinesDir(assetsRoot, avatarType);
|
|
13
|
+
if (!voiceLinesDir) {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
let entries;
|
|
17
|
+
try {
|
|
18
|
+
entries = node_fs_1.default.readdirSync(voiceLinesDir, { withFileTypes: true });
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
return entries
|
|
24
|
+
.filter((entry) => entry.isFile())
|
|
25
|
+
.map((entry) => entry.name.trim())
|
|
26
|
+
.filter((name) => name.length > 0)
|
|
27
|
+
.filter((name) => name.toLowerCase().endsWith(voiceLineExtension))
|
|
28
|
+
.sort((a, b) => a.localeCompare(b));
|
|
29
|
+
}
|
|
30
|
+
function resolveVoiceLinesDir(assetsRoot, avatarType) {
|
|
31
|
+
const trimmedAvatarType = avatarType.trim();
|
|
32
|
+
if (trimmedAvatarType.length === 0) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const absoluteAssetsRoot = node_path_1.default.resolve(assetsRoot);
|
|
36
|
+
const absoluteVoiceLinesDir = node_path_1.default.resolve(absoluteAssetsRoot, trimmedAvatarType, "voice-lines");
|
|
37
|
+
const expectedPrefix = `${absoluteAssetsRoot}${node_path_1.default.sep}`;
|
|
38
|
+
if (!absoluteVoiceLinesDir.startsWith(expectedPrefix)) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
return absoluteVoiceLinesDir;
|
|
42
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createHttpApp = createHttpApp;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const express_1 = __importDefault(require("express"));
|
|
10
|
+
const errorResponse_1 = require("../http/errorResponse");
|
|
11
|
+
const registerApiRoutes_1 = require("../http/routes/registerApiRoutes");
|
|
12
|
+
const appRoot_1 = require("../utils/appRoot");
|
|
13
|
+
function createHttpApp(context) {
|
|
14
|
+
const app = (0, express_1.default)();
|
|
15
|
+
app.use(express_1.default.json());
|
|
16
|
+
const assetsDir = (0, appRoot_1.resolveAppPath)("assets");
|
|
17
|
+
if (node_fs_1.default.existsSync(assetsDir)) {
|
|
18
|
+
app.use("/api/assets", express_1.default.static(assetsDir));
|
|
19
|
+
}
|
|
20
|
+
(0, registerApiRoutes_1.registerApiRoutes)(app, {
|
|
21
|
+
orchestrator: context.orchestrator,
|
|
22
|
+
hub: context.hub,
|
|
23
|
+
statusMonitor: context.statusMonitor
|
|
24
|
+
});
|
|
25
|
+
const clientDistPath = (0, appRoot_1.resolveAppPath)("dist", "client");
|
|
26
|
+
if (process.env.NODE_ENV === "production" && node_fs_1.default.existsSync(clientDistPath)) {
|
|
27
|
+
app.use(express_1.default.static(clientDistPath));
|
|
28
|
+
app.get("*", (_req, res) => {
|
|
29
|
+
res.sendFile(node_path_1.default.join(clientDistPath, "index.html"));
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
app.use((error, _req, res, _next) => {
|
|
33
|
+
if (res.headersSent) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
(0, errorResponse_1.handleRequestError)(res, error);
|
|
37
|
+
});
|
|
38
|
+
return app;
|
|
39
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createServerContext = createServerContext;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const discovery_1 = require("../config/discovery");
|
|
9
|
+
const loadConfig_1 = require("../config/loadConfig");
|
|
10
|
+
const orchestratorService_1 = require("../orchestrator/orchestratorService");
|
|
11
|
+
const workerRepository_1 = require("../persistence/workerRepository");
|
|
12
|
+
const statusMonitor_1 = require("../status/statusMonitor");
|
|
13
|
+
const tmuxAdapter_1 = require("../tmux/tmuxAdapter");
|
|
14
|
+
const realtimeHub_1 = require("../ws/realtimeHub");
|
|
15
|
+
const terminalBridge_1 = require("../ws/terminalBridge");
|
|
16
|
+
async function createServerContext() {
|
|
17
|
+
const paths = (0, loadConfig_1.getArcaneAgentsPaths)();
|
|
18
|
+
node_fs_1.default.mkdirSync(paths.configDir, { recursive: true });
|
|
19
|
+
node_fs_1.default.mkdirSync(paths.stateDir, { recursive: true });
|
|
20
|
+
node_fs_1.default.mkdirSync(paths.cacheDir, { recursive: true });
|
|
21
|
+
const baseConfig = (0, loadConfig_1.loadResolvedConfig)(paths);
|
|
22
|
+
const discoveryService = new discovery_1.DiscoveryService();
|
|
23
|
+
const initialDiscovery = await discoveryService.discover(baseConfig);
|
|
24
|
+
for (const warning of initialDiscovery.warnings) {
|
|
25
|
+
console.warn(`[arcane-agents] ${warning}`);
|
|
26
|
+
}
|
|
27
|
+
const workers = new workerRepository_1.WorkerRepository(paths.dbPath);
|
|
28
|
+
const tmux = new tmuxAdapter_1.TmuxAdapter(baseConfig.backend.tmux.sessionName);
|
|
29
|
+
await tmux.ensureSessionClipboardDefaults();
|
|
30
|
+
const orchestrator = new orchestratorService_1.OrchestratorService(baseConfig, workers, tmux);
|
|
31
|
+
orchestrator.setDiscoveredProjects(initialDiscovery.projects);
|
|
32
|
+
const hub = new realtimeHub_1.RealtimeHub();
|
|
33
|
+
await orchestrator.reconcileWithTmux();
|
|
34
|
+
const statusMonitor = new statusMonitor_1.StatusMonitor(workers, tmux, baseConfig.backend.tmux.pollIntervalMs, (worker) => {
|
|
35
|
+
hub.broadcast({
|
|
36
|
+
type: "worker-updated",
|
|
37
|
+
worker
|
|
38
|
+
});
|
|
39
|
+
}, (workerId) => {
|
|
40
|
+
hub.broadcast({
|
|
41
|
+
type: "worker-removed",
|
|
42
|
+
workerId
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
const terminalBridge = new terminalBridge_1.TerminalBridge(workers, {
|
|
46
|
+
onSubmittedInput: () => {
|
|
47
|
+
statusMonitor.requestPollSoon();
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return {
|
|
51
|
+
paths,
|
|
52
|
+
config: baseConfig,
|
|
53
|
+
workers,
|
|
54
|
+
tmux,
|
|
55
|
+
orchestrator,
|
|
56
|
+
hub,
|
|
57
|
+
terminalBridge,
|
|
58
|
+
statusMonitor
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerShutdownHandlers = registerShutdownHandlers;
|
|
4
|
+
exports.createShutdownHandler = createShutdownHandler;
|
|
5
|
+
function registerShutdownHandlers({ statusMonitor, server, workers, wsServers, timeoutMs, exit }) {
|
|
6
|
+
const shutdown = createShutdownHandler({
|
|
7
|
+
statusMonitor,
|
|
8
|
+
server,
|
|
9
|
+
workers,
|
|
10
|
+
wsServers,
|
|
11
|
+
timeoutMs,
|
|
12
|
+
exit
|
|
13
|
+
});
|
|
14
|
+
const forceExit = exit ?? process.exit;
|
|
15
|
+
let isShuttingDown = false;
|
|
16
|
+
const handleSignal = (signal) => {
|
|
17
|
+
const forceCode = signal === "SIGINT" ? 130 : 143;
|
|
18
|
+
if (!isShuttingDown) {
|
|
19
|
+
isShuttingDown = true;
|
|
20
|
+
console.log(`[arcane-agents] received ${signal}; shutting down... (press Ctrl-C again to force exit)`);
|
|
21
|
+
void shutdown();
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
console.warn(`[arcane-agents] received ${signal} again; forcing exit.`);
|
|
25
|
+
forceExit(forceCode);
|
|
26
|
+
};
|
|
27
|
+
process.on("SIGINT", () => {
|
|
28
|
+
handleSignal("SIGINT");
|
|
29
|
+
});
|
|
30
|
+
process.on("SIGTERM", () => {
|
|
31
|
+
handleSignal("SIGTERM");
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function createShutdownHandler({ statusMonitor, server, workers, wsServers, timeoutMs = 2_000, exit = process.exit }) {
|
|
35
|
+
let shutdownPromise;
|
|
36
|
+
return async () => {
|
|
37
|
+
if (shutdownPromise) {
|
|
38
|
+
await shutdownPromise;
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
shutdownPromise = runGracefulShutdown({
|
|
42
|
+
statusMonitor,
|
|
43
|
+
server,
|
|
44
|
+
workers,
|
|
45
|
+
wsServers,
|
|
46
|
+
timeoutMs,
|
|
47
|
+
exit
|
|
48
|
+
});
|
|
49
|
+
await shutdownPromise;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
async function runGracefulShutdown({ statusMonitor, server, workers, wsServers, timeoutMs, exit }) {
|
|
53
|
+
let exited = false;
|
|
54
|
+
let timeoutId;
|
|
55
|
+
const complete = (code) => {
|
|
56
|
+
if (exited) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
exited = true;
|
|
60
|
+
clearTimeout(timeoutId);
|
|
61
|
+
exit(code);
|
|
62
|
+
};
|
|
63
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
64
|
+
timeoutId = setTimeout(() => {
|
|
65
|
+
resolve(1);
|
|
66
|
+
}, timeoutMs);
|
|
67
|
+
if (typeof timeoutId.unref === "function") {
|
|
68
|
+
timeoutId.unref();
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
statusMonitor.stop();
|
|
72
|
+
const cleanupPromise = (async () => {
|
|
73
|
+
let hadError = false;
|
|
74
|
+
if (wsServers) {
|
|
75
|
+
terminateWsClients(wsServers.realtimeWss);
|
|
76
|
+
terminateWsClients(wsServers.terminalWss);
|
|
77
|
+
const wsCloseResults = await Promise.allSettled([
|
|
78
|
+
closeWsServer(wsServers.realtimeWss),
|
|
79
|
+
closeWsServer(wsServers.terminalWss)
|
|
80
|
+
]);
|
|
81
|
+
if (wsCloseResults.some((result) => result.status === "rejected")) {
|
|
82
|
+
hadError = true;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
await closeHttpServer(server);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
hadError = true;
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
workers.close();
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
hadError = true;
|
|
96
|
+
}
|
|
97
|
+
return hadError ? 1 : 0;
|
|
98
|
+
})();
|
|
99
|
+
const exitCode = await Promise.race([cleanupPromise, timeoutPromise]);
|
|
100
|
+
complete(exitCode);
|
|
101
|
+
}
|
|
102
|
+
function closeHttpServer(server) {
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
try {
|
|
105
|
+
server.close((error) => {
|
|
106
|
+
if (!error || isServerNotRunningError(error)) {
|
|
107
|
+
resolve();
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
reject(error);
|
|
111
|
+
});
|
|
112
|
+
if (typeof server.closeIdleConnections === "function") {
|
|
113
|
+
server.closeIdleConnections();
|
|
114
|
+
}
|
|
115
|
+
if (typeof server.closeAllConnections === "function") {
|
|
116
|
+
server.closeAllConnections();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
reject(error);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
function closeWsServer(wsServer) {
|
|
125
|
+
return new Promise((resolve, reject) => {
|
|
126
|
+
try {
|
|
127
|
+
wsServer.close((error) => {
|
|
128
|
+
if (!error) {
|
|
129
|
+
resolve();
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
reject(error);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
reject(error);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
function terminateWsClients(wsServer) {
|
|
141
|
+
for (const client of wsServer.clients) {
|
|
142
|
+
try {
|
|
143
|
+
client.terminate();
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// no-op
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function isServerNotRunningError(error) {
|
|
151
|
+
return error.code === "ERR_SERVER_NOT_RUNNING";
|
|
152
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const shutdown_1 = require("./shutdown");
|
|
5
|
+
(0, vitest_1.describe)("createShutdownHandler", () => {
|
|
6
|
+
(0, vitest_1.it)("stops monitor, closes server, closes workers, then exits", async () => {
|
|
7
|
+
const statusMonitor = {
|
|
8
|
+
stop: vitest_1.vi.fn()
|
|
9
|
+
};
|
|
10
|
+
const server = {
|
|
11
|
+
close: vitest_1.vi.fn((callback) => {
|
|
12
|
+
callback();
|
|
13
|
+
})
|
|
14
|
+
};
|
|
15
|
+
const workers = {
|
|
16
|
+
close: vitest_1.vi.fn()
|
|
17
|
+
};
|
|
18
|
+
const exit = vitest_1.vi.fn();
|
|
19
|
+
const shutdown = (0, shutdown_1.createShutdownHandler)({
|
|
20
|
+
statusMonitor,
|
|
21
|
+
server,
|
|
22
|
+
workers,
|
|
23
|
+
timeoutMs: 250,
|
|
24
|
+
exit
|
|
25
|
+
});
|
|
26
|
+
await shutdown();
|
|
27
|
+
(0, vitest_1.expect)(statusMonitor.stop).toHaveBeenCalledTimes(1);
|
|
28
|
+
(0, vitest_1.expect)(server.close).toHaveBeenCalledTimes(1);
|
|
29
|
+
(0, vitest_1.expect)(workers.close).toHaveBeenCalledTimes(1);
|
|
30
|
+
(0, vitest_1.expect)(exit).toHaveBeenCalledWith(0);
|
|
31
|
+
const stopOrder = statusMonitor.stop.mock.invocationCallOrder[0] ?? 0;
|
|
32
|
+
const closeOrder = server.close.mock.invocationCallOrder[0] ?? 0;
|
|
33
|
+
const workersOrder = workers.close.mock.invocationCallOrder[0] ?? 0;
|
|
34
|
+
const exitOrder = exit.mock.invocationCallOrder[0] ?? 0;
|
|
35
|
+
(0, vitest_1.expect)(stopOrder).toBeLessThan(closeOrder);
|
|
36
|
+
(0, vitest_1.expect)(closeOrder).toBeLessThan(workersOrder);
|
|
37
|
+
(0, vitest_1.expect)(workersOrder).toBeLessThan(exitOrder);
|
|
38
|
+
});
|
|
39
|
+
(0, vitest_1.it)("runs shutdown cleanup only once for duplicate invocations", async () => {
|
|
40
|
+
const statusMonitor = {
|
|
41
|
+
stop: vitest_1.vi.fn()
|
|
42
|
+
};
|
|
43
|
+
const server = {
|
|
44
|
+
close: vitest_1.vi.fn((callback) => {
|
|
45
|
+
callback();
|
|
46
|
+
})
|
|
47
|
+
};
|
|
48
|
+
const workers = {
|
|
49
|
+
close: vitest_1.vi.fn()
|
|
50
|
+
};
|
|
51
|
+
const exit = vitest_1.vi.fn();
|
|
52
|
+
const shutdown = (0, shutdown_1.createShutdownHandler)({
|
|
53
|
+
statusMonitor,
|
|
54
|
+
server,
|
|
55
|
+
workers,
|
|
56
|
+
timeoutMs: 250,
|
|
57
|
+
exit
|
|
58
|
+
});
|
|
59
|
+
await Promise.all([shutdown(), shutdown()]);
|
|
60
|
+
(0, vitest_1.expect)(statusMonitor.stop).toHaveBeenCalledTimes(1);
|
|
61
|
+
(0, vitest_1.expect)(server.close).toHaveBeenCalledTimes(1);
|
|
62
|
+
(0, vitest_1.expect)(workers.close).toHaveBeenCalledTimes(1);
|
|
63
|
+
(0, vitest_1.expect)(exit).toHaveBeenCalledTimes(1);
|
|
64
|
+
});
|
|
65
|
+
(0, vitest_1.it)("terminates websocket clients and closes websocket servers", async () => {
|
|
66
|
+
const statusMonitor = {
|
|
67
|
+
stop: vitest_1.vi.fn()
|
|
68
|
+
};
|
|
69
|
+
const server = {
|
|
70
|
+
close: vitest_1.vi.fn((callback) => {
|
|
71
|
+
callback();
|
|
72
|
+
})
|
|
73
|
+
};
|
|
74
|
+
const workers = {
|
|
75
|
+
close: vitest_1.vi.fn()
|
|
76
|
+
};
|
|
77
|
+
const exit = vitest_1.vi.fn();
|
|
78
|
+
const terminateRealtimeClient = vitest_1.vi.fn();
|
|
79
|
+
const terminateTerminalClient = vitest_1.vi.fn();
|
|
80
|
+
const realtimeWss = {
|
|
81
|
+
clients: new Set([{ terminate: terminateRealtimeClient }]),
|
|
82
|
+
close: vitest_1.vi.fn((callback) => {
|
|
83
|
+
callback();
|
|
84
|
+
})
|
|
85
|
+
};
|
|
86
|
+
const terminalWss = {
|
|
87
|
+
clients: new Set([{ terminate: terminateTerminalClient }]),
|
|
88
|
+
close: vitest_1.vi.fn((callback) => {
|
|
89
|
+
callback();
|
|
90
|
+
})
|
|
91
|
+
};
|
|
92
|
+
const shutdown = (0, shutdown_1.createShutdownHandler)({
|
|
93
|
+
statusMonitor,
|
|
94
|
+
server,
|
|
95
|
+
workers,
|
|
96
|
+
wsServers: {
|
|
97
|
+
realtimeWss,
|
|
98
|
+
terminalWss
|
|
99
|
+
},
|
|
100
|
+
timeoutMs: 250,
|
|
101
|
+
exit
|
|
102
|
+
});
|
|
103
|
+
await shutdown();
|
|
104
|
+
(0, vitest_1.expect)(terminateRealtimeClient).toHaveBeenCalledTimes(1);
|
|
105
|
+
(0, vitest_1.expect)(terminateTerminalClient).toHaveBeenCalledTimes(1);
|
|
106
|
+
(0, vitest_1.expect)(realtimeWss.close).toHaveBeenCalledTimes(1);
|
|
107
|
+
(0, vitest_1.expect)(terminalWss.close).toHaveBeenCalledTimes(1);
|
|
108
|
+
const realtimeTerminateOrder = terminateRealtimeClient.mock.invocationCallOrder[0] ?? 0;
|
|
109
|
+
const realtimeCloseOrder = realtimeWss.close.mock.invocationCallOrder[0] ?? 0;
|
|
110
|
+
const serverCloseOrder = server.close.mock.invocationCallOrder[0] ?? 0;
|
|
111
|
+
(0, vitest_1.expect)(realtimeTerminateOrder).toBeLessThan(realtimeCloseOrder);
|
|
112
|
+
(0, vitest_1.expect)(realtimeCloseOrder).toBeLessThan(serverCloseOrder);
|
|
113
|
+
});
|
|
114
|
+
(0, vitest_1.it)("exits with timeout fallback when server close never resolves", async () => {
|
|
115
|
+
vitest_1.vi.useFakeTimers();
|
|
116
|
+
const statusMonitor = {
|
|
117
|
+
stop: vitest_1.vi.fn()
|
|
118
|
+
};
|
|
119
|
+
const server = {
|
|
120
|
+
close: vitest_1.vi.fn((_callback) => {
|
|
121
|
+
// Never calls back.
|
|
122
|
+
})
|
|
123
|
+
};
|
|
124
|
+
const workers = {
|
|
125
|
+
close: vitest_1.vi.fn()
|
|
126
|
+
};
|
|
127
|
+
const exit = vitest_1.vi.fn();
|
|
128
|
+
const shutdown = (0, shutdown_1.createShutdownHandler)({
|
|
129
|
+
statusMonitor,
|
|
130
|
+
server,
|
|
131
|
+
workers,
|
|
132
|
+
timeoutMs: 50,
|
|
133
|
+
exit
|
|
134
|
+
});
|
|
135
|
+
const pending = shutdown();
|
|
136
|
+
await vitest_1.vi.advanceTimersByTimeAsync(50);
|
|
137
|
+
await pending;
|
|
138
|
+
(0, vitest_1.expect)(exit).toHaveBeenCalledWith(1);
|
|
139
|
+
(0, vitest_1.expect)(workers.close).not.toHaveBeenCalled();
|
|
140
|
+
vitest_1.vi.useRealTimers();
|
|
141
|
+
});
|
|
142
|
+
});
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createWsServers = createWsServers;
|
|
4
|
+
exports.attachUpgradeHandler = attachUpgradeHandler;
|
|
5
|
+
exports.decodeTerminalWorkerId = decodeTerminalWorkerId;
|
|
6
|
+
const ws_1 = require("ws");
|
|
7
|
+
const terminalPathPrefix = "/api/terminal/";
|
|
8
|
+
const validWorkerIdPattern = /^[A-Za-z0-9_-]{1,128}$/;
|
|
9
|
+
function createWsServers(context) {
|
|
10
|
+
const realtimeWss = new ws_1.WebSocketServer({ noServer: true });
|
|
11
|
+
realtimeWss.on("connection", (socket) => {
|
|
12
|
+
context.hub.addClient(socket);
|
|
13
|
+
const initialEvent = {
|
|
14
|
+
type: "init",
|
|
15
|
+
workers: context.orchestrator.listWorkers(),
|
|
16
|
+
config: context.orchestrator.getConfig()
|
|
17
|
+
};
|
|
18
|
+
context.hub.sendTo(socket, initialEvent);
|
|
19
|
+
});
|
|
20
|
+
const terminalWss = new ws_1.WebSocketServer({ noServer: true });
|
|
21
|
+
terminalWss.on("connection", (socket) => {
|
|
22
|
+
const workerId = socket.workerId;
|
|
23
|
+
if (!workerId) {
|
|
24
|
+
socket.close(1008, "Invalid agent id");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
context.terminalBridge.connect(workerId, socket);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
32
|
+
console.error(`[arcane-agents] terminal connection error for ${workerId}: ${detail}`);
|
|
33
|
+
if (socket.readyState === socket.OPEN) {
|
|
34
|
+
socket.close(1011, "Terminal connection failed");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
return {
|
|
39
|
+
realtimeWss,
|
|
40
|
+
terminalWss
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function attachUpgradeHandler(server, { realtimeWss, terminalWss }) {
|
|
44
|
+
server.on("upgrade", (request, socket, head) => {
|
|
45
|
+
const requestUrl = parseRequestUrl(request);
|
|
46
|
+
if (!requestUrl) {
|
|
47
|
+
rejectUpgrade(socket, 400, "Bad Request");
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const pathname = requestUrl.pathname;
|
|
51
|
+
if (pathname === "/api/ws") {
|
|
52
|
+
try {
|
|
53
|
+
realtimeWss.handleUpgrade(request, socket, head, (websocket) => {
|
|
54
|
+
realtimeWss.emit("connection", websocket, request);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
rejectUpgrade(socket, 500, "Internal Server Error");
|
|
59
|
+
}
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (pathname.startsWith(terminalPathPrefix)) {
|
|
63
|
+
const workerId = decodeTerminalWorkerId(pathname.slice(terminalPathPrefix.length));
|
|
64
|
+
if (!workerId) {
|
|
65
|
+
rejectUpgrade(socket, 400, "Bad Request");
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
terminalWss.handleUpgrade(request, socket, head, (websocket) => {
|
|
70
|
+
websocket.workerId = workerId;
|
|
71
|
+
terminalWss.emit("connection", websocket, request);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
rejectUpgrade(socket, 500, "Internal Server Error");
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
rejectUpgrade(socket, 404, "Not Found");
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function decodeTerminalWorkerId(rawPathToken) {
|
|
83
|
+
if (!rawPathToken) {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
let decoded;
|
|
87
|
+
try {
|
|
88
|
+
decoded = decodeURIComponent(rawPathToken);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
if (!validWorkerIdPattern.test(decoded)) {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
return decoded;
|
|
97
|
+
}
|
|
98
|
+
function parseRequestUrl(request) {
|
|
99
|
+
try {
|
|
100
|
+
return new URL(request.url ?? "/", `http://${request.headers.host ?? "localhost"}`);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function rejectUpgrade(socket, statusCode, statusText) {
|
|
107
|
+
if (socket.writable) {
|
|
108
|
+
socket.write(`HTTP/1.1 ${statusCode} ${statusText}\r\nConnection: close\r\nContent-Length: 0\r\n\r\n`);
|
|
109
|
+
}
|
|
110
|
+
socket.destroy();
|
|
111
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const node_events_1 = require("node:events");
|
|
4
|
+
const vitest_1 = require("vitest");
|
|
5
|
+
const websocketUpgrade_1 = require("./websocketUpgrade");
|
|
6
|
+
class FakeSocket {
|
|
7
|
+
writable = true;
|
|
8
|
+
write = vitest_1.vi.fn();
|
|
9
|
+
destroy = vitest_1.vi.fn();
|
|
10
|
+
}
|
|
11
|
+
function createRequest(url) {
|
|
12
|
+
return {
|
|
13
|
+
url,
|
|
14
|
+
headers: {
|
|
15
|
+
host: "localhost:7601"
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function createWsServers() {
|
|
20
|
+
const realtimeHandleUpgrade = vitest_1.vi.fn((_request, _socket, _head, callback) => {
|
|
21
|
+
callback({});
|
|
22
|
+
});
|
|
23
|
+
const terminalEmit = vitest_1.vi.fn();
|
|
24
|
+
const terminalHandleUpgrade = vitest_1.vi.fn((_request, _socket, _head, callback) => {
|
|
25
|
+
callback({});
|
|
26
|
+
});
|
|
27
|
+
return {
|
|
28
|
+
servers: {
|
|
29
|
+
realtimeWss: {
|
|
30
|
+
handleUpgrade: realtimeHandleUpgrade,
|
|
31
|
+
emit: vitest_1.vi.fn()
|
|
32
|
+
},
|
|
33
|
+
terminalWss: {
|
|
34
|
+
handleUpgrade: terminalHandleUpgrade,
|
|
35
|
+
emit: terminalEmit
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
realtimeHandleUpgrade,
|
|
39
|
+
terminalHandleUpgrade,
|
|
40
|
+
terminalEmit
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
(0, vitest_1.describe)("decodeTerminalWorkerId", () => {
|
|
44
|
+
(0, vitest_1.it)("accepts valid worker IDs and rejects malformed tokens", () => {
|
|
45
|
+
(0, vitest_1.expect)((0, websocketUpgrade_1.decodeTerminalWorkerId)("worker-1")).toBe("worker-1");
|
|
46
|
+
(0, vitest_1.expect)((0, websocketUpgrade_1.decodeTerminalWorkerId)("worker_1")).toBe("worker_1");
|
|
47
|
+
(0, vitest_1.expect)((0, websocketUpgrade_1.decodeTerminalWorkerId)("worker%2F1")).toBeUndefined();
|
|
48
|
+
(0, vitest_1.expect)((0, websocketUpgrade_1.decodeTerminalWorkerId)("%E0%A4%A")).toBeUndefined();
|
|
49
|
+
(0, vitest_1.expect)((0, websocketUpgrade_1.decodeTerminalWorkerId)("")).toBeUndefined();
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
(0, vitest_1.describe)("attachUpgradeHandler", () => {
|
|
53
|
+
(0, vitest_1.it)("rejects malformed terminal worker IDs with a clean 400 response", () => {
|
|
54
|
+
const server = new node_events_1.EventEmitter();
|
|
55
|
+
const { servers, terminalHandleUpgrade } = createWsServers();
|
|
56
|
+
(0, websocketUpgrade_1.attachUpgradeHandler)(server, servers);
|
|
57
|
+
const socket = new FakeSocket();
|
|
58
|
+
server.emit("upgrade", createRequest("/api/terminal/%E0%A4%A"), socket, Buffer.alloc(0));
|
|
59
|
+
(0, vitest_1.expect)(terminalHandleUpgrade).not.toHaveBeenCalled();
|
|
60
|
+
(0, vitest_1.expect)(socket.write).toHaveBeenCalledWith(vitest_1.expect.stringContaining("400 Bad Request"));
|
|
61
|
+
(0, vitest_1.expect)(socket.destroy).toHaveBeenCalledTimes(1);
|
|
62
|
+
});
|
|
63
|
+
(0, vitest_1.it)("rejects unknown websocket paths with a clean 404 response", () => {
|
|
64
|
+
const server = new node_events_1.EventEmitter();
|
|
65
|
+
const { servers } = createWsServers();
|
|
66
|
+
(0, websocketUpgrade_1.attachUpgradeHandler)(server, servers);
|
|
67
|
+
const socket = new FakeSocket();
|
|
68
|
+
server.emit("upgrade", createRequest("/api/unknown"), socket, Buffer.alloc(0));
|
|
69
|
+
(0, vitest_1.expect)(socket.write).toHaveBeenCalledWith(vitest_1.expect.stringContaining("404 Not Found"));
|
|
70
|
+
(0, vitest_1.expect)(socket.destroy).toHaveBeenCalledTimes(1);
|
|
71
|
+
});
|
|
72
|
+
(0, vitest_1.it)("upgrades valid terminal websocket requests", () => {
|
|
73
|
+
const server = new node_events_1.EventEmitter();
|
|
74
|
+
const { servers, terminalHandleUpgrade, terminalEmit } = createWsServers();
|
|
75
|
+
(0, websocketUpgrade_1.attachUpgradeHandler)(server, servers);
|
|
76
|
+
const socket = new FakeSocket();
|
|
77
|
+
server.emit("upgrade", createRequest("/api/terminal/worker-22"), socket, Buffer.alloc(0));
|
|
78
|
+
(0, vitest_1.expect)(terminalHandleUpgrade).toHaveBeenCalledTimes(1);
|
|
79
|
+
(0, vitest_1.expect)(terminalEmit).toHaveBeenCalledTimes(1);
|
|
80
|
+
const [, websocket] = terminalEmit.mock.calls[0] ?? [];
|
|
81
|
+
(0, vitest_1.expect)(websocket.workerId).toBe("worker-22");
|
|
82
|
+
});
|
|
83
|
+
});
|