psinetron-opencode-visualizer 1.0.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.
Files changed (393) hide show
  1. package/README.md +113 -0
  2. package/index.ts +307 -0
  3. package/package.json +13 -0
  4. package/visualizer/index.html +869 -0
  5. package/visualizer/person1/person1/animations/coffee/south/frame_000.png +0 -0
  6. package/visualizer/person1/person1/animations/coffee/south/frame_001.png +0 -0
  7. package/visualizer/person1/person1/animations/coffee/south/frame_002.png +0 -0
  8. package/visualizer/person1/person1/animations/coffee/south/frame_003.png +0 -0
  9. package/visualizer/person1/person1/animations/coffee/south/frame_004.png +0 -0
  10. package/visualizer/person1/person1/animations/coffee/south/frame_005.png +0 -0
  11. package/visualizer/person1/person1/animations/error/south/frame_000.png +0 -0
  12. package/visualizer/person1/person1/animations/error/south/frame_001.png +0 -0
  13. package/visualizer/person1/person1/animations/error/south/frame_002.png +0 -0
  14. package/visualizer/person1/person1/animations/error/south/frame_003.png +0 -0
  15. package/visualizer/person1/person1/animations/error/south/frame_004.png +0 -0
  16. package/visualizer/person1/person1/animations/error/south/frame_005.png +0 -0
  17. package/visualizer/person1/person1/animations/idle/south/frame_000.png +0 -0
  18. package/visualizer/person1/person1/animations/idle/south/frame_001.png +0 -0
  19. package/visualizer/person1/person1/animations/idle/south/frame_002.png +0 -0
  20. package/visualizer/person1/person1/animations/idle/south/frame_003.png +0 -0
  21. package/visualizer/person1/person1/animations/scratch/south/frame_000.png +0 -0
  22. package/visualizer/person1/person1/animations/scratch/south/frame_001.png +0 -0
  23. package/visualizer/person1/person1/animations/scratch/south/frame_002.png +0 -0
  24. package/visualizer/person1/person1/animations/scratch/south/frame_003.png +0 -0
  25. package/visualizer/person1/person1/animations/scratch/south/frame_004.png +0 -0
  26. package/visualizer/person1/person1/animations/scratch/south/frame_005.png +0 -0
  27. package/visualizer/person1/person1/animations/sit/south/frame_000.png +0 -0
  28. package/visualizer/person1/person1/animations/sit/south/frame_001.png +0 -0
  29. package/visualizer/person1/person1/animations/sit/south/frame_002.png +0 -0
  30. package/visualizer/person1/person1/animations/sit/south/frame_003.png +0 -0
  31. package/visualizer/person1/person1/animations/sit/south/frame_004.png +0 -0
  32. package/visualizer/person1/person1/animations/sit/south/frame_005.png +0 -0
  33. package/visualizer/person1/person1/animations/sit/south/frame_006.png +0 -0
  34. package/visualizer/person1/person1/animations/walk/east/frame_000.png +0 -0
  35. package/visualizer/person1/person1/animations/walk/east/frame_001.png +0 -0
  36. package/visualizer/person1/person1/animations/walk/east/frame_002.png +0 -0
  37. package/visualizer/person1/person1/animations/walk/east/frame_003.png +0 -0
  38. package/visualizer/person1/person1/animations/walk/east/frame_004.png +0 -0
  39. package/visualizer/person1/person1/animations/walk/east/frame_005.png +0 -0
  40. package/visualizer/person1/person1/animations/walk/north/frame_000.png +0 -0
  41. package/visualizer/person1/person1/animations/walk/north/frame_001.png +0 -0
  42. package/visualizer/person1/person1/animations/walk/north/frame_002.png +0 -0
  43. package/visualizer/person1/person1/animations/walk/north/frame_003.png +0 -0
  44. package/visualizer/person1/person1/animations/walk/north/frame_004.png +0 -0
  45. package/visualizer/person1/person1/animations/walk/north/frame_005.png +0 -0
  46. package/visualizer/person1/person1/animations/walk/south/frame_000.png +0 -0
  47. package/visualizer/person1/person1/animations/walk/south/frame_001.png +0 -0
  48. package/visualizer/person1/person1/animations/walk/south/frame_002.png +0 -0
  49. package/visualizer/person1/person1/animations/walk/south/frame_003.png +0 -0
  50. package/visualizer/person1/person1/animations/walk/south/frame_004.png +0 -0
  51. package/visualizer/person1/person1/animations/walk/south/frame_005.png +0 -0
  52. package/visualizer/person1/person1/animations/walk/west/frame_000.png +0 -0
  53. package/visualizer/person1/person1/animations/walk/west/frame_001.png +0 -0
  54. package/visualizer/person1/person1/animations/walk/west/frame_002.png +0 -0
  55. package/visualizer/person1/person1/animations/walk/west/frame_003.png +0 -0
  56. package/visualizer/person1/person1/animations/walk/west/frame_004.png +0 -0
  57. package/visualizer/person1/person1/animations/walk/west/frame_005.png +0 -0
  58. package/visualizer/person1/person1/animations/work/south/frame_000.png +0 -0
  59. package/visualizer/person1/person1/animations/work/south/frame_001.png +0 -0
  60. package/visualizer/person1/person1/animations/work/south/frame_002.png +0 -0
  61. package/visualizer/person1/person1/animations/work/south/frame_003.png +0 -0
  62. package/visualizer/person1/person1/animations/work/south/frame_004.png +0 -0
  63. package/visualizer/person1/person1/animations/work/south/frame_005.png +0 -0
  64. package/visualizer/person1/person1/animations/yawn/south/frame_000.png +0 -0
  65. package/visualizer/person1/person1/animations/yawn/south/frame_001.png +0 -0
  66. package/visualizer/person1/person1/animations/yawn/south/frame_002.png +0 -0
  67. package/visualizer/person1/person1/animations/yawn/south/frame_003.png +0 -0
  68. package/visualizer/person1/person1/animations/yawn/south/frame_004.png +0 -0
  69. package/visualizer/person1/person1/animations/yawn/south/frame_005.png +0 -0
  70. package/visualizer/person1/person1/animations/yawn/south/frame_006.png +0 -0
  71. package/visualizer/person1/person1/rotations/east.png +0 -0
  72. package/visualizer/person1/person1/rotations/north-east.png +0 -0
  73. package/visualizer/person1/person1/rotations/north-west.png +0 -0
  74. package/visualizer/person1/person1/rotations/north.png +0 -0
  75. package/visualizer/person1/person1/rotations/south-east.png +0 -0
  76. package/visualizer/person1/person1/rotations/south-west.png +0 -0
  77. package/visualizer/person1/person1/rotations/south.png +0 -0
  78. package/visualizer/person1/person1/rotations/west.png +0 -0
  79. package/visualizer/person2/person2/animations/coffee/south/frame_000.png +0 -0
  80. package/visualizer/person2/person2/animations/coffee/south/frame_001.png +0 -0
  81. package/visualizer/person2/person2/animations/coffee/south/frame_002.png +0 -0
  82. package/visualizer/person2/person2/animations/coffee/south/frame_003.png +0 -0
  83. package/visualizer/person2/person2/animations/coffee/south/frame_004.png +0 -0
  84. package/visualizer/person2/person2/animations/coffee/south/frame_005.png +0 -0
  85. package/visualizer/person2/person2/animations/coffee/south/frame_006.png +0 -0
  86. package/visualizer/person2/person2/animations/idle/south/frame_000.png +0 -0
  87. package/visualizer/person2/person2/animations/idle/south/frame_001.png +0 -0
  88. package/visualizer/person2/person2/animations/idle/south/frame_002.png +0 -0
  89. package/visualizer/person2/person2/animations/idle/south/frame_003.png +0 -0
  90. package/visualizer/person2/person2/animations/scratch/south/frame_000.png +0 -0
  91. package/visualizer/person2/person2/animations/scratch/south/frame_001.png +0 -0
  92. package/visualizer/person2/person2/animations/scratch/south/frame_002.png +0 -0
  93. package/visualizer/person2/person2/animations/scratch/south/frame_003.png +0 -0
  94. package/visualizer/person2/person2/animations/scratch/south/frame_004.png +0 -0
  95. package/visualizer/person2/person2/animations/scratch/south/frame_005.png +0 -0
  96. package/visualizer/person2/person2/animations/sit/south/frame_000.png +0 -0
  97. package/visualizer/person2/person2/animations/sit/south/frame_001.png +0 -0
  98. package/visualizer/person2/person2/animations/sit/south/frame_002.png +0 -0
  99. package/visualizer/person2/person2/animations/sit/south/frame_003.png +0 -0
  100. package/visualizer/person2/person2/animations/sit/south/frame_004.png +0 -0
  101. package/visualizer/person2/person2/animations/sit/south/frame_005.png +0 -0
  102. package/visualizer/person2/person2/animations/sit/south/frame_006.png +0 -0
  103. package/visualizer/person2/person2/animations/walk/east/frame_000.png +0 -0
  104. package/visualizer/person2/person2/animations/walk/east/frame_001.png +0 -0
  105. package/visualizer/person2/person2/animations/walk/east/frame_002.png +0 -0
  106. package/visualizer/person2/person2/animations/walk/east/frame_003.png +0 -0
  107. package/visualizer/person2/person2/animations/walk/east/frame_004.png +0 -0
  108. package/visualizer/person2/person2/animations/walk/east/frame_005.png +0 -0
  109. package/visualizer/person2/person2/animations/walk/north/frame_000.png +0 -0
  110. package/visualizer/person2/person2/animations/walk/north/frame_001.png +0 -0
  111. package/visualizer/person2/person2/animations/walk/north/frame_002.png +0 -0
  112. package/visualizer/person2/person2/animations/walk/north/frame_003.png +0 -0
  113. package/visualizer/person2/person2/animations/walk/north/frame_004.png +0 -0
  114. package/visualizer/person2/person2/animations/walk/north/frame_005.png +0 -0
  115. package/visualizer/person2/person2/animations/walk/south/frame_000.png +0 -0
  116. package/visualizer/person2/person2/animations/walk/south/frame_001.png +0 -0
  117. package/visualizer/person2/person2/animations/walk/south/frame_002.png +0 -0
  118. package/visualizer/person2/person2/animations/walk/south/frame_003.png +0 -0
  119. package/visualizer/person2/person2/animations/walk/south/frame_004.png +0 -0
  120. package/visualizer/person2/person2/animations/walk/south/frame_005.png +0 -0
  121. package/visualizer/person2/person2/animations/walk/west/frame_000.png +0 -0
  122. package/visualizer/person2/person2/animations/walk/west/frame_001.png +0 -0
  123. package/visualizer/person2/person2/animations/walk/west/frame_002.png +0 -0
  124. package/visualizer/person2/person2/animations/walk/west/frame_003.png +0 -0
  125. package/visualizer/person2/person2/animations/walk/west/frame_004.png +0 -0
  126. package/visualizer/person2/person2/animations/walk/west/frame_005.png +0 -0
  127. package/visualizer/person2/person2/animations/work/south/frame_000.png +0 -0
  128. package/visualizer/person2/person2/animations/work/south/frame_001.png +0 -0
  129. package/visualizer/person2/person2/animations/work/south/frame_002.png +0 -0
  130. package/visualizer/person2/person2/animations/work/south/frame_003.png +0 -0
  131. package/visualizer/person2/person2/animations/work/south/frame_004.png +0 -0
  132. package/visualizer/person2/person2/animations/work/south/frame_005.png +0 -0
  133. package/visualizer/person2/person2/animations/work/south/frame_006.png +0 -0
  134. package/visualizer/person2/person2/animations/work/south/frame_007.png +0 -0
  135. package/visualizer/person2/person2/animations/yawn/south/frame_000.png +0 -0
  136. package/visualizer/person2/person2/animations/yawn/south/frame_001.png +0 -0
  137. package/visualizer/person2/person2/animations/yawn/south/frame_002.png +0 -0
  138. package/visualizer/person2/person2/animations/yawn/south/frame_003.png +0 -0
  139. package/visualizer/person2/person2/animations/yawn/south/frame_004.png +0 -0
  140. package/visualizer/person2/person2/animations/yawn/south/frame_005.png +0 -0
  141. package/visualizer/person2/person2/animations/yawn/south/frame_006.png +0 -0
  142. package/visualizer/person2/person2/animations/yawn/south/frame_007.png +0 -0
  143. package/visualizer/person2/person2/animations/yawn/south/frame_008.png +0 -0
  144. package/visualizer/person2/person2/animations/yawn/south/frame_009.png +0 -0
  145. package/visualizer/person2/person2/animations/yawn/south/frame_010.png +0 -0
  146. package/visualizer/person2/person2/animations/yawn/south/frame_011.png +0 -0
  147. package/visualizer/person2/person2/animations/yawn/south/frame_012.png +0 -0
  148. package/visualizer/person2/person2/rotations/east.png +0 -0
  149. package/visualizer/person2/person2/rotations/north-east.png +0 -0
  150. package/visualizer/person2/person2/rotations/north-west.png +0 -0
  151. package/visualizer/person2/person2/rotations/north.png +0 -0
  152. package/visualizer/person2/person2/rotations/south-east.png +0 -0
  153. package/visualizer/person2/person2/rotations/south-west.png +0 -0
  154. package/visualizer/person2/person2/rotations/south.png +0 -0
  155. package/visualizer/person2/person2/rotations/west.png +0 -0
  156. package/visualizer/person3/person3/animations/coffee/south/frame_000.png +0 -0
  157. package/visualizer/person3/person3/animations/coffee/south/frame_001.png +0 -0
  158. package/visualizer/person3/person3/animations/coffee/south/frame_002.png +0 -0
  159. package/visualizer/person3/person3/animations/coffee/south/frame_003.png +0 -0
  160. package/visualizer/person3/person3/animations/coffee/south/frame_004.png +0 -0
  161. package/visualizer/person3/person3/animations/coffee/south/frame_005.png +0 -0
  162. package/visualizer/person3/person3/animations/coffee/south/frame_006.png +0 -0
  163. package/visualizer/person3/person3/animations/coffee/south/frame_007.png +0 -0
  164. package/visualizer/person3/person3/animations/coffee/south/frame_008.png +0 -0
  165. package/visualizer/person3/person3/animations/coffee/south/frame_009.png +0 -0
  166. package/visualizer/person3/person3/animations/coffee/south/frame_010.png +0 -0
  167. package/visualizer/person3/person3/animations/coffee/south/frame_011.png +0 -0
  168. package/visualizer/person3/person3/animations/coffee/south/frame_012.png +0 -0
  169. package/visualizer/person3/person3/animations/idle/south/frame_000.png +0 -0
  170. package/visualizer/person3/person3/animations/idle/south/frame_001.png +0 -0
  171. package/visualizer/person3/person3/animations/idle/south/frame_002.png +0 -0
  172. package/visualizer/person3/person3/animations/idle/south/frame_003.png +0 -0
  173. package/visualizer/person3/person3/animations/scratch/south/frame_000.png +0 -0
  174. package/visualizer/person3/person3/animations/scratch/south/frame_001.png +0 -0
  175. package/visualizer/person3/person3/animations/scratch/south/frame_002.png +0 -0
  176. package/visualizer/person3/person3/animations/scratch/south/frame_003.png +0 -0
  177. package/visualizer/person3/person3/animations/scratch/south/frame_004.png +0 -0
  178. package/visualizer/person3/person3/animations/scratch/south/frame_005.png +0 -0
  179. package/visualizer/person3/person3/animations/sit/south/frame_000.png +0 -0
  180. package/visualizer/person3/person3/animations/sit/south/frame_001.png +0 -0
  181. package/visualizer/person3/person3/animations/sit/south/frame_002.png +0 -0
  182. package/visualizer/person3/person3/animations/sit/south/frame_003.png +0 -0
  183. package/visualizer/person3/person3/animations/sit/south/frame_004.png +0 -0
  184. package/visualizer/person3/person3/animations/sit/south/frame_005.png +0 -0
  185. package/visualizer/person3/person3/animations/sit/south/frame_006.png +0 -0
  186. package/visualizer/person3/person3/animations/walk/east/frame_000.png +0 -0
  187. package/visualizer/person3/person3/animations/walk/east/frame_001.png +0 -0
  188. package/visualizer/person3/person3/animations/walk/east/frame_002.png +0 -0
  189. package/visualizer/person3/person3/animations/walk/east/frame_003.png +0 -0
  190. package/visualizer/person3/person3/animations/walk/east/frame_004.png +0 -0
  191. package/visualizer/person3/person3/animations/walk/east/frame_005.png +0 -0
  192. package/visualizer/person3/person3/animations/walk/north/frame_000.png +0 -0
  193. package/visualizer/person3/person3/animations/walk/north/frame_001.png +0 -0
  194. package/visualizer/person3/person3/animations/walk/north/frame_002.png +0 -0
  195. package/visualizer/person3/person3/animations/walk/north/frame_003.png +0 -0
  196. package/visualizer/person3/person3/animations/walk/north/frame_004.png +0 -0
  197. package/visualizer/person3/person3/animations/walk/north/frame_005.png +0 -0
  198. package/visualizer/person3/person3/animations/walk/south/frame_000.png +0 -0
  199. package/visualizer/person3/person3/animations/walk/south/frame_001.png +0 -0
  200. package/visualizer/person3/person3/animations/walk/south/frame_002.png +0 -0
  201. package/visualizer/person3/person3/animations/walk/south/frame_003.png +0 -0
  202. package/visualizer/person3/person3/animations/walk/south/frame_004.png +0 -0
  203. package/visualizer/person3/person3/animations/walk/south/frame_005.png +0 -0
  204. package/visualizer/person3/person3/animations/walk/west/frame_000.png +0 -0
  205. package/visualizer/person3/person3/animations/walk/west/frame_001.png +0 -0
  206. package/visualizer/person3/person3/animations/walk/west/frame_002.png +0 -0
  207. package/visualizer/person3/person3/animations/walk/west/frame_003.png +0 -0
  208. package/visualizer/person3/person3/animations/walk/west/frame_004.png +0 -0
  209. package/visualizer/person3/person3/animations/walk/west/frame_005.png +0 -0
  210. package/visualizer/person3/person3/animations/work/south/frame_000.png +0 -0
  211. package/visualizer/person3/person3/animations/work/south/frame_001.png +0 -0
  212. package/visualizer/person3/person3/animations/work/south/frame_002.png +0 -0
  213. package/visualizer/person3/person3/animations/work/south/frame_003.png +0 -0
  214. package/visualizer/person3/person3/animations/work/south/frame_004.png +0 -0
  215. package/visualizer/person3/person3/animations/work/south/frame_005.png +0 -0
  216. package/visualizer/person3/person3/animations/yawn/south/frame_000.png +0 -0
  217. package/visualizer/person3/person3/animations/yawn/south/frame_001.png +0 -0
  218. package/visualizer/person3/person3/animations/yawn/south/frame_002.png +0 -0
  219. package/visualizer/person3/person3/animations/yawn/south/frame_003.png +0 -0
  220. package/visualizer/person3/person3/animations/yawn/south/frame_004.png +0 -0
  221. package/visualizer/person3/person3/animations/yawn/south/frame_005.png +0 -0
  222. package/visualizer/person3/person3/animations/yawn/south/frame_006.png +0 -0
  223. package/visualizer/person3/person3/animations/yawn/south/frame_007.png +0 -0
  224. package/visualizer/person3/person3/animations/yawn/south/frame_008.png +0 -0
  225. package/visualizer/person3/person3/animations/yawn/south/frame_009.png +0 -0
  226. package/visualizer/person3/person3/animations/yawn/south/frame_010.png +0 -0
  227. package/visualizer/person3/person3/animations/yawn/south/frame_011.png +0 -0
  228. package/visualizer/person3/person3/rotations/east.png +0 -0
  229. package/visualizer/person3/person3/rotations/north-east.png +0 -0
  230. package/visualizer/person3/person3/rotations/north-west.png +0 -0
  231. package/visualizer/person3/person3/rotations/north.png +0 -0
  232. package/visualizer/person3/person3/rotations/south-east.png +0 -0
  233. package/visualizer/person3/person3/rotations/south-west.png +0 -0
  234. package/visualizer/person3/person3/rotations/south.png +0 -0
  235. package/visualizer/person3/person3/rotations/west.png +0 -0
  236. package/visualizer/person4/person4/animations/coffee/south/frame_000.png +0 -0
  237. package/visualizer/person4/person4/animations/coffee/south/frame_001.png +0 -0
  238. package/visualizer/person4/person4/animations/coffee/south/frame_002.png +0 -0
  239. package/visualizer/person4/person4/animations/coffee/south/frame_003.png +0 -0
  240. package/visualizer/person4/person4/animations/coffee/south/frame_004.png +0 -0
  241. package/visualizer/person4/person4/animations/coffee/south/frame_005.png +0 -0
  242. package/visualizer/person4/person4/animations/coffee/south/frame_006.png +0 -0
  243. package/visualizer/person4/person4/animations/coffee/south/frame_007.png +0 -0
  244. package/visualizer/person4/person4/animations/coffee/south/frame_008.png +0 -0
  245. package/visualizer/person4/person4/animations/idle/south/frame_000.png +0 -0
  246. package/visualizer/person4/person4/animations/idle/south/frame_001.png +0 -0
  247. package/visualizer/person4/person4/animations/idle/south/frame_002.png +0 -0
  248. package/visualizer/person4/person4/animations/idle/south/frame_003.png +0 -0
  249. package/visualizer/person4/person4/animations/scratch/south/frame_000.png +0 -0
  250. package/visualizer/person4/person4/animations/scratch/south/frame_001.png +0 -0
  251. package/visualizer/person4/person4/animations/scratch/south/frame_002.png +0 -0
  252. package/visualizer/person4/person4/animations/scratch/south/frame_003.png +0 -0
  253. package/visualizer/person4/person4/animations/scratch/south/frame_004.png +0 -0
  254. package/visualizer/person4/person4/animations/scratch/south/frame_005.png +0 -0
  255. package/visualizer/person4/person4/animations/scratch/south/frame_006.png +0 -0
  256. package/visualizer/person4/person4/animations/sit/south/frame_000.png +0 -0
  257. package/visualizer/person4/person4/animations/sit/south/frame_001.png +0 -0
  258. package/visualizer/person4/person4/animations/sit/south/frame_002.png +0 -0
  259. package/visualizer/person4/person4/animations/sit/south/frame_003.png +0 -0
  260. package/visualizer/person4/person4/animations/sit/south/frame_004.png +0 -0
  261. package/visualizer/person4/person4/animations/sit/south/frame_005.png +0 -0
  262. package/visualizer/person4/person4/animations/sit/south/frame_006.png +0 -0
  263. package/visualizer/person4/person4/animations/walk/east/frame_000.png +0 -0
  264. package/visualizer/person4/person4/animations/walk/east/frame_001.png +0 -0
  265. package/visualizer/person4/person4/animations/walk/east/frame_002.png +0 -0
  266. package/visualizer/person4/person4/animations/walk/east/frame_003.png +0 -0
  267. package/visualizer/person4/person4/animations/walk/east/frame_004.png +0 -0
  268. package/visualizer/person4/person4/animations/walk/east/frame_005.png +0 -0
  269. package/visualizer/person4/person4/animations/walk/north/frame_000.png +0 -0
  270. package/visualizer/person4/person4/animations/walk/north/frame_001.png +0 -0
  271. package/visualizer/person4/person4/animations/walk/north/frame_002.png +0 -0
  272. package/visualizer/person4/person4/animations/walk/north/frame_003.png +0 -0
  273. package/visualizer/person4/person4/animations/walk/north/frame_004.png +0 -0
  274. package/visualizer/person4/person4/animations/walk/north/frame_005.png +0 -0
  275. package/visualizer/person4/person4/animations/walk/south/frame_000.png +0 -0
  276. package/visualizer/person4/person4/animations/walk/south/frame_001.png +0 -0
  277. package/visualizer/person4/person4/animations/walk/south/frame_002.png +0 -0
  278. package/visualizer/person4/person4/animations/walk/south/frame_003.png +0 -0
  279. package/visualizer/person4/person4/animations/walk/south/frame_004.png +0 -0
  280. package/visualizer/person4/person4/animations/walk/south/frame_005.png +0 -0
  281. package/visualizer/person4/person4/animations/walk/west/frame_000.png +0 -0
  282. package/visualizer/person4/person4/animations/walk/west/frame_001.png +0 -0
  283. package/visualizer/person4/person4/animations/walk/west/frame_002.png +0 -0
  284. package/visualizer/person4/person4/animations/walk/west/frame_003.png +0 -0
  285. package/visualizer/person4/person4/animations/walk/west/frame_004.png +0 -0
  286. package/visualizer/person4/person4/animations/walk/west/frame_005.png +0 -0
  287. package/visualizer/person4/person4/animations/work/south/frame_000.png +0 -0
  288. package/visualizer/person4/person4/animations/work/south/frame_001.png +0 -0
  289. package/visualizer/person4/person4/animations/work/south/frame_002.png +0 -0
  290. package/visualizer/person4/person4/animations/work/south/frame_003.png +0 -0
  291. package/visualizer/person4/person4/animations/work/south/frame_004.png +0 -0
  292. package/visualizer/person4/person4/animations/work/south/frame_005.png +0 -0
  293. package/visualizer/person4/person4/animations/yawn/south/frame_000.png +0 -0
  294. package/visualizer/person4/person4/animations/yawn/south/frame_001.png +0 -0
  295. package/visualizer/person4/person4/animations/yawn/south/frame_002.png +0 -0
  296. package/visualizer/person4/person4/animations/yawn/south/frame_003.png +0 -0
  297. package/visualizer/person4/person4/animations/yawn/south/frame_004.png +0 -0
  298. package/visualizer/person4/person4/animations/yawn/south/frame_005.png +0 -0
  299. package/visualizer/person4/person4/animations/yawn/south/frame_006.png +0 -0
  300. package/visualizer/person4/person4/animations/yawn/south/frame_007.png +0 -0
  301. package/visualizer/person4/person4/rotations/east.png +0 -0
  302. package/visualizer/person4/person4/rotations/north-east.png +0 -0
  303. package/visualizer/person4/person4/rotations/north-west.png +0 -0
  304. package/visualizer/person4/person4/rotations/north.png +0 -0
  305. package/visualizer/person4/person4/rotations/south-east.png +0 -0
  306. package/visualizer/person4/person4/rotations/south-west.png +0 -0
  307. package/visualizer/person4/person4/rotations/south.png +0 -0
  308. package/visualizer/person4/person4/rotations/west.png +0 -0
  309. package/visualizer/person5/person5/animations/coffee/south/frame_000.png +0 -0
  310. package/visualizer/person5/person5/animations/coffee/south/frame_001.png +0 -0
  311. package/visualizer/person5/person5/animations/coffee/south/frame_002.png +0 -0
  312. package/visualizer/person5/person5/animations/coffee/south/frame_003.png +0 -0
  313. package/visualizer/person5/person5/animations/coffee/south/frame_004.png +0 -0
  314. package/visualizer/person5/person5/animations/coffee/south/frame_005.png +0 -0
  315. package/visualizer/person5/person5/animations/coffee/south/frame_006.png +0 -0
  316. package/visualizer/person5/person5/animations/coffee/south/frame_007.png +0 -0
  317. package/visualizer/person5/person5/animations/coffee/south/frame_008.png +0 -0
  318. package/visualizer/person5/person5/animations/coffee/south/frame_009.png +0 -0
  319. package/visualizer/person5/person5/animations/coffee/south/frame_010.png +0 -0
  320. package/visualizer/person5/person5/animations/idle/south/frame_000.png +0 -0
  321. package/visualizer/person5/person5/animations/idle/south/frame_001.png +0 -0
  322. package/visualizer/person5/person5/animations/idle/south/frame_002.png +0 -0
  323. package/visualizer/person5/person5/animations/idle/south/frame_003.png +0 -0
  324. package/visualizer/person5/person5/animations/scratch/south/frame_000.png +0 -0
  325. package/visualizer/person5/person5/animations/scratch/south/frame_001.png +0 -0
  326. package/visualizer/person5/person5/animations/scratch/south/frame_002.png +0 -0
  327. package/visualizer/person5/person5/animations/scratch/south/frame_003.png +0 -0
  328. package/visualizer/person5/person5/animations/scratch/south/frame_004.png +0 -0
  329. package/visualizer/person5/person5/animations/scratch/south/frame_005.png +0 -0
  330. package/visualizer/person5/person5/animations/scratch/south/frame_006.png +0 -0
  331. package/visualizer/person5/person5/animations/scratch/south/frame_007.png +0 -0
  332. package/visualizer/person5/person5/animations/scratch/south/frame_008.png +0 -0
  333. package/visualizer/person5/person5/animations/scratch/south/frame_009.png +0 -0
  334. package/visualizer/person5/person5/animations/scratch/south/frame_010.png +0 -0
  335. package/visualizer/person5/person5/animations/scratch/south/frame_011.png +0 -0
  336. package/visualizer/person5/person5/animations/sit/south/frame_000.png +0 -0
  337. package/visualizer/person5/person5/animations/sit/south/frame_001.png +0 -0
  338. package/visualizer/person5/person5/animations/sit/south/frame_002.png +0 -0
  339. package/visualizer/person5/person5/animations/sit/south/frame_003.png +0 -0
  340. package/visualizer/person5/person5/animations/sit/south/frame_004.png +0 -0
  341. package/visualizer/person5/person5/animations/sit/south/frame_005.png +0 -0
  342. package/visualizer/person5/person5/animations/sit/south/frame_006.png +0 -0
  343. package/visualizer/person5/person5/animations/walk/east/frame_000.png +0 -0
  344. package/visualizer/person5/person5/animations/walk/east/frame_001.png +0 -0
  345. package/visualizer/person5/person5/animations/walk/east/frame_002.png +0 -0
  346. package/visualizer/person5/person5/animations/walk/east/frame_003.png +0 -0
  347. package/visualizer/person5/person5/animations/walk/east/frame_004.png +0 -0
  348. package/visualizer/person5/person5/animations/walk/east/frame_005.png +0 -0
  349. package/visualizer/person5/person5/animations/walk/north/frame_000.png +0 -0
  350. package/visualizer/person5/person5/animations/walk/north/frame_001.png +0 -0
  351. package/visualizer/person5/person5/animations/walk/north/frame_002.png +0 -0
  352. package/visualizer/person5/person5/animations/walk/north/frame_003.png +0 -0
  353. package/visualizer/person5/person5/animations/walk/north/frame_004.png +0 -0
  354. package/visualizer/person5/person5/animations/walk/north/frame_005.png +0 -0
  355. package/visualizer/person5/person5/animations/walk/south/frame_000.png +0 -0
  356. package/visualizer/person5/person5/animations/walk/south/frame_001.png +0 -0
  357. package/visualizer/person5/person5/animations/walk/south/frame_002.png +0 -0
  358. package/visualizer/person5/person5/animations/walk/south/frame_003.png +0 -0
  359. package/visualizer/person5/person5/animations/walk/south/frame_004.png +0 -0
  360. package/visualizer/person5/person5/animations/walk/south/frame_005.png +0 -0
  361. package/visualizer/person5/person5/animations/walk/west/frame_000.png +0 -0
  362. package/visualizer/person5/person5/animations/walk/west/frame_001.png +0 -0
  363. package/visualizer/person5/person5/animations/walk/west/frame_002.png +0 -0
  364. package/visualizer/person5/person5/animations/walk/west/frame_003.png +0 -0
  365. package/visualizer/person5/person5/animations/walk/west/frame_004.png +0 -0
  366. package/visualizer/person5/person5/animations/walk/west/frame_005.png +0 -0
  367. package/visualizer/person5/person5/animations/work/south/frame_000.png +0 -0
  368. package/visualizer/person5/person5/animations/work/south/frame_001.png +0 -0
  369. package/visualizer/person5/person5/animations/work/south/frame_002.png +0 -0
  370. package/visualizer/person5/person5/animations/work/south/frame_003.png +0 -0
  371. package/visualizer/person5/person5/animations/work/south/frame_004.png +0 -0
  372. package/visualizer/person5/person5/animations/work/south/frame_005.png +0 -0
  373. package/visualizer/person5/person5/animations/work/south/frame_006.png +0 -0
  374. package/visualizer/person5/person5/animations/yawn/south/frame_000.png +0 -0
  375. package/visualizer/person5/person5/animations/yawn/south/frame_001.png +0 -0
  376. package/visualizer/person5/person5/animations/yawn/south/frame_002.png +0 -0
  377. package/visualizer/person5/person5/animations/yawn/south/frame_003.png +0 -0
  378. package/visualizer/person5/person5/animations/yawn/south/frame_004.png +0 -0
  379. package/visualizer/person5/person5/animations/yawn/south/frame_005.png +0 -0
  380. package/visualizer/person5/person5/animations/yawn/south/frame_006.png +0 -0
  381. package/visualizer/person5/person5/animations/yawn/south/frame_007.png +0 -0
  382. package/visualizer/person5/person5/animations/yawn/south/frame_008.png +0 -0
  383. package/visualizer/person5/person5/rotations/east.png +0 -0
  384. package/visualizer/person5/person5/rotations/north-east.png +0 -0
  385. package/visualizer/person5/person5/rotations/north-west.png +0 -0
  386. package/visualizer/person5/person5/rotations/north.png +0 -0
  387. package/visualizer/person5/person5/rotations/south-east.png +0 -0
  388. package/visualizer/person5/person5/rotations/south-west.png +0 -0
  389. package/visualizer/person5/person5/rotations/south.png +0 -0
  390. package/visualizer/person5/person5/rotations/west.png +0 -0
  391. package/visualizer/textures/background.png +0 -0
  392. package/visualizer/textures/coffeetable.png +0 -0
  393. package/visualizer/textures/desktop.png +0 -0
package/README.md ADDED
@@ -0,0 +1,113 @@
1
+ # OpenCode Visualizer
2
+
3
+ Real-time pixel-art office scene that visualizes OpenCode AI agent sessions. Watch your agents walk, sit at desks, type on laptops, drink coffee, and react to events — all rendered in a charming retro pixel-art style.
4
+
5
+ ![OpenCode Visualizer](visualizer/textures/background.png)
6
+
7
+ ## Features
8
+
9
+ - **5 unique pixel-art characters** — each with distinct idle, working, and reaction animations
10
+ - **12 animation states** — idle, walking, sitting, typing, drinking coffee, scratching head, yawning, error reactions, and more
11
+ - **Persistent office layout** — 5 desks, a coffee zone, and a rest area with Y-sorted rendering
12
+ - **Real-time WebSocket sync** — events stream from OpenCode sessions to the visualizer instantly
13
+ - **Cross-platform standalone window** — automatically opens in Chrome app mode on macOS, Windows, and Linux; falls back to default browser
14
+
15
+ ## Requirements
16
+
17
+ - [OpenCode](https://opencode.ai)
18
+ - [Bun](https://bun.sh) (runtime)
19
+ - Chrome, Chromium, or Edge (for app-mode window; optional — any browser works)
20
+
21
+ ## Installation
22
+
23
+ ### Via OpenCode UI (recommended)
24
+
25
+ 1. Press `Cmd+P` (`Ctrl+P` on Windows/Linux) to open the command palette
26
+ 2. Select **Install plugin**
27
+ 3. Enter the package name: `slybeaver-opencode-visualizer`
28
+
29
+ OpenCode will install the plugin and automatically add it to your project's `opencode.json`.
30
+
31
+ ### Manual configuration
32
+
33
+ Add the plugin to your OpenCode config (`opencode.json` or `opencode.jsonc`):
34
+
35
+ ```json
36
+ {
37
+ "plugin": ["slybeaver-opencode-visualizer"]
38
+ }
39
+ ```
40
+
41
+ Or install from a local path:
42
+
43
+ ```json
44
+ {
45
+ "plugin": ["./path/to/OpenCodeVisualizer"]
46
+ }
47
+ ```
48
+
49
+ ## How It Works
50
+
51
+ ```
52
+ OpenCode session
53
+ │ event hook
54
+
55
+ Plugin (index.ts) ─── WebSocket ───► Bun Server (port 5173)
56
+ │ broadcast
57
+
58
+ Frontend (Canvas, 1024×768)
59
+ Pixel-art office with animated agents
60
+ ```
61
+
62
+ 1. The plugin starts a Bun HTTP + WebSocket server on `localhost:5173`
63
+ 2. It opens the visualizer in a Chrome app window (or your default browser)
64
+ 3. OpenCode session events stream through WebSocket to the visualizer
65
+ 4. The canvas renders agents navigating the office, sitting at desks, and animating in real time
66
+
67
+ ## Project Structure
68
+
69
+ ```
70
+ ├── index.ts # Plugin entry point (server + WebSocket + Chrome launcher)
71
+ ├── opencode.json # OpenCode plugin manifest
72
+ ├── package.json # npm metadata
73
+ ├── visualizer/
74
+ │ ├── index.html # SPA canvas app (all rendering logic in <script>)
75
+ │ ├── textures/ # Background, desk, and coffee table sprites
76
+ │ └── person1-5/ # Character sprites (8 rotation + 6-8 animation types each)
77
+ │ └── personN/
78
+ │ ├── rotations/ # Direction sprites (N, S, E, W, NE, NW, SE, SW)
79
+ │ └── animations/ # Frame-by-frame animation sprites (idle, walk, sit, work, coffee, scratch, yawn)
80
+ ```
81
+
82
+ ## Agent States
83
+
84
+ | State | Description |
85
+ |-------|-------------|
86
+ | `idle` | Standing still, breathing animation |
87
+ | `walking` | Walking to a destination |
88
+ | `walking_to_desk` | Heading to an assigned desk |
89
+ | `sitting` | Sitting down transition |
90
+ | `working` | Typing on a laptop |
91
+ | `drinking` | At the coffee zone |
92
+ | `scratching` | Idle desk animation — scratching head |
93
+ | `yawning` | Idle desk animation — yawning |
94
+ | `error` | Reacting to an error |
95
+ | `flash` | White flash on session diff |
96
+ | `idle_rest` | Standing in the rest area |
97
+ | `leaving` | Walking to the exit door |
98
+
99
+ ## Development
100
+
101
+ ```bash
102
+ # Run the plugin (requires OpenCode)
103
+ opencode
104
+
105
+ # The visualizer runs at http://localhost:5173
106
+ # Open it manually in any browser
107
+ ```
108
+
109
+ No build step required — Bun runs TypeScript directly.
110
+
111
+ ## License
112
+
113
+ MIT
package/index.ts ADDED
@@ -0,0 +1,307 @@
1
+ import type { Plugin } from "@opencode-ai/plugin"
2
+ import { join } from "path"
3
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs"
4
+ import { platform } from "os"
5
+
6
+ const SERVER_PORT = 5173
7
+
8
+ // ─── WebSocket server ───────────────────────────────────────────────
9
+
10
+ interface PluginClient {
11
+ instanceId: string
12
+ ws: WebSocket
13
+ cwd: string
14
+ skin: string
15
+ connectedAt: number
16
+ }
17
+
18
+ interface FrontendClient {
19
+ ws: WebSocket
20
+ }
21
+
22
+ const pluginClients = new Map<string, PluginClient>()
23
+ const frontendClients = new Set<FrontendClient>()
24
+ let windowOpened = false
25
+ function broadcast(data: Record<string, unknown>) {
26
+ const msg = JSON.stringify(data)
27
+ for (const client of frontendClients) {
28
+ if (client.ws.readyState === WebSocket.OPEN) {
29
+ try { client.ws.send(msg) } catch {}
30
+ }
31
+ }
32
+ }
33
+
34
+ function openBrowserWindow() {
35
+ if (windowOpened) return
36
+ windowOpened = true
37
+ const url = `http://localhost:${SERVER_PORT}`
38
+
39
+ setTimeout(() => {
40
+ if (frontendClients.size > 0) return
41
+
42
+ const os = platform()
43
+
44
+ try {
45
+ if (os === "darwin") {
46
+ Bun.spawn(["open", "-n", "-a", "Google Chrome", "--args", `--app=${url}`, "--window-size=1024,768"], {
47
+ stdio: ["ignore", "ignore", "ignore"],
48
+ })
49
+ } else if (os === "win32") {
50
+ Bun.spawn(["cmd.exe", "/c", "start", "chrome", `--app=${url}`, "--window-size=1024,768"], {
51
+ stdio: ["ignore", "ignore", "ignore"],
52
+ })
53
+ } else {
54
+ Bun.spawn(["google-chrome", `--app=${url}`, "--window-size=1024,768"], {
55
+ stdio: ["ignore", "ignore", "ignore"],
56
+ })
57
+ }
58
+ } catch {
59
+ console.warn(`[visualizer] Failed to open Chrome app window, open manually: ${url}`)
60
+ }
61
+ }, 3000)
62
+ }
63
+
64
+ let shutdownTimer: ReturnType<typeof setTimeout> | null = null
65
+ let server: ReturnType<typeof Bun.serve> | null = null
66
+
67
+ function resetShutdownTimer() {
68
+ if (shutdownTimer) clearTimeout(shutdownTimer)
69
+ shutdownTimer = setTimeout(() => {
70
+ if (pluginClients.size === 0) {
71
+ server?.stop()
72
+ process.exit(0)
73
+ }
74
+ }, 10_000)
75
+ }
76
+
77
+ try {
78
+ const VISUALIZER_DIR = join(import.meta.dir, "visualizer")
79
+
80
+ server = Bun.serve({
81
+ port: SERVER_PORT,
82
+ hostname: "127.0.0.1",
83
+ async fetch(req) {
84
+ if (server.upgrade(req)) {
85
+ return
86
+ }
87
+ try {
88
+ const url = new URL(req.url)
89
+ const pathname = url.pathname === "/" ? "/index.html" : url.pathname
90
+ const filePath = join(VISUALIZER_DIR, pathname)
91
+ if (existsSync(filePath)) {
92
+ return new Response(Bun.file(filePath), {
93
+ headers: { "Cache-Control": "no-store, no-cache, must-revalidate" },
94
+ })
95
+ }
96
+ return new Response("Not found", { status: 404 })
97
+ } catch {
98
+ return new Response("<h1>Visualization server — error</h1>", {
99
+ headers: { "Content-Type": "text/html" },
100
+ status: 500,
101
+ })
102
+ }
103
+ },
104
+ websocket: {
105
+ open(_ws) {},
106
+ message(ws, message) {
107
+ let data: Record<string, unknown>
108
+ try {
109
+ data = JSON.parse(message as string)
110
+ } catch {
111
+ return
112
+ }
113
+
114
+ switch (data.type) {
115
+ case "register": {
116
+ const id = data.instanceId as string
117
+ pluginClients.set(id, {
118
+ instanceId: id,
119
+ ws,
120
+ cwd: (data.cwd as string) || "",
121
+ skin: (data.skin as string) || "",
122
+ connectedAt: Date.now(),
123
+ })
124
+
125
+ broadcast({
126
+ type: "instance.added",
127
+ instanceId: id,
128
+ cwd: data.cwd,
129
+ skin: data.skin,
130
+ })
131
+
132
+ openBrowserWindow()
133
+ resetShutdownTimer()
134
+ break
135
+ }
136
+
137
+ case "frontend.register": {
138
+ frontendClients.add({ ws })
139
+ const instances = [...pluginClients.values()].map((c) => ({
140
+ instanceId: c.instanceId,
141
+ cwd: c.cwd,
142
+ skin: c.skin,
143
+ }))
144
+ ws.send(JSON.stringify({ type: "state.sync", instances }))
145
+ break
146
+ }
147
+
148
+ case "event": {
149
+ broadcast({
150
+ type: "instance.event",
151
+ instanceId: data.instanceId,
152
+ event: data.event,
153
+ })
154
+ break
155
+ }
156
+ }
157
+ },
158
+ close(ws) {
159
+ for (const [id, client] of pluginClients) {
160
+ if (client.ws === ws) {
161
+ pluginClients.delete(id)
162
+ broadcast({ type: "instance.removed", instanceId: id })
163
+ break
164
+ }
165
+ }
166
+
167
+ for (const client of frontendClients) {
168
+ if (client.ws === ws) {
169
+ frontendClients.delete(client)
170
+ break
171
+ }
172
+ }
173
+
174
+ resetShutdownTimer()
175
+ },
176
+ },
177
+ })
178
+ } catch (err) {
179
+ console.error("[visualizer] Failed to start server:", err)
180
+ }
181
+
182
+ // ─── Plugin client ──────────────────────────────────────────────────
183
+
184
+ const AVAILABLE_SKINS = ["person1", "person2", "person3", "person4", "person5"]
185
+
186
+ function resolveSkin(cwd: string): string {
187
+ const configDir = join(cwd, ".opencode")
188
+ const configPath = join(configDir, "viz-skin.json")
189
+ try {
190
+ const data = JSON.parse(readFileSync(configPath, "utf-8"))
191
+ if (data.skin && AVAILABLE_SKINS.includes(data.skin)) return data.skin
192
+ } catch {}
193
+ const skin = AVAILABLE_SKINS[Math.floor(Math.random() * AVAILABLE_SKINS.length)]
194
+ try {
195
+ mkdirSync(configDir, { recursive: true })
196
+ writeFileSync(configPath, JSON.stringify({ skin }))
197
+ } catch {}
198
+ return skin
199
+ }
200
+
201
+ let ws: WebSocket | null = null
202
+ let reconnectTimer: ReturnType<typeof setTimeout> | null = null
203
+ const instanceId = `oc-${process.pid}-${Math.random().toString(36).slice(2, 8)}`
204
+
205
+ function connectToServer(skin: string): Promise<void> {
206
+ return new Promise((resolve, reject) => {
207
+ const socket = new WebSocket(`ws://localhost:${SERVER_PORT}`)
208
+
209
+ const timeout = setTimeout(() => {
210
+ socket.close()
211
+ reject(new Error("Connection timeout"))
212
+ }, 3000)
213
+
214
+ socket.onopen = () => {
215
+ clearTimeout(timeout)
216
+ if (reconnectTimer) {
217
+ clearTimeout(reconnectTimer)
218
+ reconnectTimer = null
219
+ }
220
+
221
+ ws = socket
222
+ socket.send(
223
+ JSON.stringify({
224
+ type: "register",
225
+ instanceId,
226
+ cwd: process.cwd(),
227
+ skin,
228
+ })
229
+ )
230
+ resolve()
231
+ }
232
+
233
+ socket.onerror = () => {
234
+ clearTimeout(timeout)
235
+ socket.close()
236
+ reject(new Error("Connection failed"))
237
+ }
238
+
239
+ socket.onclose = () => {
240
+ ws = null
241
+ if (!reconnectTimer) {
242
+ reconnectTimer = setTimeout(() => {
243
+ reconnectTimer = null
244
+ connectToServer(skin).catch(() => {})
245
+ }, 2000)
246
+ }
247
+ }
248
+
249
+ socket.onmessage = () => {}
250
+ })
251
+ }
252
+
253
+ function sendEvent(eventType: string, payload: Record<string, unknown> = {}) {
254
+ if (!ws || ws.readyState !== WebSocket.OPEN) return
255
+ ws.send(
256
+ JSON.stringify({
257
+ type: "event",
258
+ instanceId,
259
+ event: { type: eventType, ...payload },
260
+ })
261
+ )
262
+ }
263
+
264
+ // ─── Plugin export ──────────────────────────────────────────────────
265
+
266
+ const VisualizerPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
267
+ const skin = resolveSkin(directory)
268
+ // Wait up to 6 seconds for the server to be ready
269
+ for (let i = 0; i < 20; i++) {
270
+ try {
271
+ await connectToServer(skin)
272
+ break
273
+ } catch {
274
+ await new Promise((r) => setTimeout(r, 300))
275
+ }
276
+ }
277
+
278
+ const interestingEvents = new Set([
279
+ "session.status",
280
+ "session.created",
281
+ "session.deleted",
282
+ "session.idle",
283
+ "session.error",
284
+ "session.diff",
285
+ "message.updated",
286
+ "todo.updated",
287
+ ])
288
+
289
+ return {
290
+ event: async ({ event }) => {
291
+ if (interestingEvents.has(event.type)) {
292
+ sendEvent(event.type, event.properties as Record<string, unknown>)
293
+ }
294
+ },
295
+
296
+ "tool.execute.after": async (input, _output) => {
297
+ sendEvent("tool.execute.after", { tool: input.tool })
298
+ },
299
+
300
+ "tool.execute.before": async (input, _output) => {
301
+ sendEvent("tool.execute.before", { tool: input.tool })
302
+ },
303
+ }
304
+ }
305
+
306
+ export { VisualizerPlugin }
307
+ export default VisualizerPlugin
package/package.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "psinetron-opencode-visualizer",
3
+ "version": "1.0.0",
4
+ "main": "index.ts",
5
+ "description": "OpenCode session visualizer — real-time pixel-art office scene with animated agents",
6
+ "files": [
7
+ "index.ts",
8
+ "visualizer/"
9
+ ],
10
+ "keywords": ["opencode", "opencode-plugin", "visualizer", "monitor"],
11
+ "license": "MIT",
12
+ "type": "module"
13
+ }