@bitefoundry/retrieviewer 0.0.0-stage → 0.0.1

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 (292) hide show
  1. package/ASSET-PROVENANCE.md +43 -0
  2. package/ASSETS-LICENSE.md +58 -0
  3. package/ATTRIBUTION.md +54 -0
  4. package/EMBEDDING.md +96 -0
  5. package/INSTALLING.md +107 -0
  6. package/LICENSE +16 -0
  7. package/LICENSE-CODE +21 -0
  8. package/PLUGIN.md +110 -0
  9. package/PUPPY-MEMORY.md +57 -0
  10. package/PUPPY-Q5-COMPARISON.md +73 -0
  11. package/README.md +61 -2
  12. package/RELEASING.md +61 -0
  13. package/THIRD-PARTY-NOTICES.md +17 -0
  14. package/TRADEMARKS.md +21 -0
  15. package/braille.mjs +45 -0
  16. package/examples/bridge.py +62 -0
  17. package/examples/embed.mjs +15 -0
  18. package/examples/live.mjs +40 -0
  19. package/examples/plugin.mjs +21 -0
  20. package/integrations/opencode/runtime.mjs +195 -0
  21. package/integrations/opencode/tui.tsx +59 -0
  22. package/locomotion-core.mjs +21 -0
  23. package/locomotion-puppy.animal +0 -0
  24. package/package.json +125 -4
  25. package/pet-q5-manifest.json +118 -0
  26. package/puppy-clean.mjs +51 -0
  27. package/puppy-companion-interactions-v3-q5.bin.gz +0 -0
  28. package/puppy-companion-interactions-v3.json +1 -0
  29. package/puppy-companion-life.mjs +182 -0
  30. package/puppy-companion-objects.mjs +30 -0
  31. package/puppy-companion-sprites.mjs +14 -0
  32. package/puppy-continuous.mjs +57 -0
  33. package/puppy-face.mjs +46 -0
  34. package/puppy-frame-predictive.mjs +147 -0
  35. package/puppy-frame-store.mjs +108 -0
  36. package/puppy-mouth-anchor.json +1 -0
  37. package/puppy-mouth-anchor.mjs +33 -0
  38. package/puppy-paper-actions-v9-q5.bin.gz +0 -0
  39. package/puppy-paper-actions-v9.json +1 -0
  40. package/puppy-paper-actions.mjs +48 -0
  41. package/puppy-paper-approach-q5.bin.gz +0 -0
  42. package/puppy-paper-approach.json +1 -0
  43. package/puppy-paper-area.mjs +15 -0
  44. package/puppy-paper-arrival-seat-q5.bin.gz +0 -0
  45. package/puppy-paper-arrival-seat.json +1 -0
  46. package/puppy-paper-behaviors-q5.bin.gz +0 -0
  47. package/puppy-paper-behaviors.json +1 -0
  48. package/puppy-paper-behaviors.mjs +8 -0
  49. package/puppy-paper-contact.mjs +103 -0
  50. package/puppy-paper-director.mjs +21 -0
  51. package/puppy-paper-paw-transport.mjs +76 -0
  52. package/puppy-paper-rear-gallop-q5.bin.gz +0 -0
  53. package/puppy-paper-rear-gallop.json +1 -0
  54. package/puppy-paper-seat-q5.bin.gz +0 -0
  55. package/puppy-paper-seat.json +14 -0
  56. package/puppy-paper-seat.mjs +13 -0
  57. package/puppy-paper-trick-timing.mjs +58 -0
  58. package/puppy-paper-world.mjs +108 -0
  59. package/puppy-paper.mjs +271 -0
  60. package/puppy-stable-meta.json +1606 -0
  61. package/puppy-stable.mjs +72 -0
  62. package/puppy-stride-meta.json +343 -0
  63. package/puppy-stride-tweens-q5.bin.gz +0 -0
  64. package/puppy-zoomies.mjs +27 -0
  65. package/puppy-zoomies30.mjs +12 -0
  66. package/retrieviewer-cli.mjs +81 -0
  67. package/retrieviewer-config.mjs +49 -0
  68. package/retrieviewer-install.mjs +157 -0
  69. package/retrieviewer-plugin.d.mts +44 -0
  70. package/retrieviewer-plugin.mjs +97 -0
  71. package/retrieviewer-stdio.mjs +38 -0
  72. package/retrieviewer.d.mts +85 -0
  73. package/retrieviewer.mjs +142 -0
  74. package/vendor/procedural-animals/LICENSE +21 -0
  75. package/vendor/procedural-animals/package.json +40 -0
  76. package/vendor/procedural-animals/src/animal.js +146 -0
  77. package/vendor/procedural-animals/src/bake.js +51 -0
  78. package/vendor/procedural-animals/src/build.js +81 -0
  79. package/vendor/procedural-animals/src/core/build/coatKit.js +121 -0
  80. package/vendor/procedural-animals/src/core/build/featherCards.js +189 -0
  81. package/vendor/procedural-animals/src/core/build/finEdges.js +85 -0
  82. package/vendor/procedural-animals/src/core/build/furSlope.js +115 -0
  83. package/vendor/procedural-animals/src/core/build/mesh.js +67 -0
  84. package/vendor/procedural-animals/src/core/build/pipeline.js +272 -0
  85. package/vendor/procedural-animals/src/core/build/seams.js +183 -0
  86. package/vendor/procedural-animals/src/core/build/warp.js +112 -0
  87. package/vendor/procedural-animals/src/core/build/weights.js +393 -0
  88. package/vendor/procedural-animals/src/core/math/vec.js +81 -0
  89. package/vendor/procedural-animals/src/core/motion/actions.js +800 -0
  90. package/vendor/procedural-animals/src/core/motion/bird.js +3063 -0
  91. package/vendor/procedural-animals/src/core/motion/birdActions.js +1059 -0
  92. package/vendor/procedural-animals/src/core/motion/common.js +158 -0
  93. package/vendor/procedural-animals/src/core/motion/index.js +22 -0
  94. package/vendor/procedural-animals/src/core/motion/quadruped.js +2875 -0
  95. package/vendor/procedural-animals/src/core/motion/snake.js +1594 -0
  96. package/vendor/procedural-animals/src/core/motion/spider.js +1810 -0
  97. package/vendor/procedural-animals/src/core/motion/swimmer.js +1047 -0
  98. package/vendor/procedural-animals/src/core/motion/swimmerActions.js +613 -0
  99. package/vendor/procedural-animals/src/core/render/animalObject.js +262 -0
  100. package/vendor/procedural-animals/src/core/render/coatMaterial.js +1301 -0
  101. package/vendor/procedural-animals/src/core/render/dqs.js +159 -0
  102. package/vendor/procedural-animals/src/core/render/eyes.js +676 -0
  103. package/vendor/procedural-animals/src/core/render/membranes.js +77 -0
  104. package/vendor/procedural-animals/src/core/render/skeleton.js +41 -0
  105. package/vendor/procedural-animals/src/core/rig/bird.js +327 -0
  106. package/vendor/procedural-animals/src/core/rig/quadruped.js +76 -0
  107. package/vendor/procedural-animals/src/core/rig/rig.js +79 -0
  108. package/vendor/procedural-animals/src/core/rig/snake.js +76 -0
  109. package/vendor/procedural-animals/src/core/rig/spider.js +110 -0
  110. package/vendor/procedural-animals/src/core/rig/swimmer.js +181 -0
  111. package/vendor/procedural-animals/src/core/sdf/eyeSocket.js +53 -0
  112. package/vendor/procedural-animals/src/core/sdf/mesher.js +238 -0
  113. package/vendor/procedural-animals/src/core/sdf/sdf.js +263 -0
  114. package/vendor/procedural-animals/src/index.d.ts +98 -0
  115. package/vendor/procedural-animals/src/index.js +29 -0
  116. package/vendor/procedural-animals/src/registry.js +48 -0
  117. package/vendor/procedural-animals/src/species/bear/behaviour.js +463 -0
  118. package/vendor/procedural-animals/src/species/bear/claws.js +147 -0
  119. package/vendor/procedural-animals/src/species/bear/coat.js +726 -0
  120. package/vendor/procedural-animals/src/species/bear/index.js +139 -0
  121. package/vendor/procedural-animals/src/species/bear/motion.js +112 -0
  122. package/vendor/procedural-animals/src/species/bear/regions.js +78 -0
  123. package/vendor/procedural-animals/src/species/bear/rig.js +112 -0
  124. package/vendor/procedural-animals/src/species/bear/sculpt.js +272 -0
  125. package/vendor/procedural-animals/src/species/boar/behaviour.js +335 -0
  126. package/vendor/procedural-animals/src/species/boar/coat.js +372 -0
  127. package/vendor/procedural-animals/src/species/boar/index.js +110 -0
  128. package/vendor/procedural-animals/src/species/boar/motion.js +85 -0
  129. package/vendor/procedural-animals/src/species/boar/regions.js +88 -0
  130. package/vendor/procedural-animals/src/species/boar/rig.js +111 -0
  131. package/vendor/procedural-animals/src/species/boar/sculpt.js +285 -0
  132. package/vendor/procedural-animals/src/species/cat/behaviour.js +559 -0
  133. package/vendor/procedural-animals/src/species/cat/coat.js +841 -0
  134. package/vendor/procedural-animals/src/species/cat/index.js +211 -0
  135. package/vendor/procedural-animals/src/species/cat/motion.js +101 -0
  136. package/vendor/procedural-animals/src/species/cat/regions.js +82 -0
  137. package/vendor/procedural-animals/src/species/cat/rig.js +100 -0
  138. package/vendor/procedural-animals/src/species/cat/sculpt.js +266 -0
  139. package/vendor/procedural-animals/src/species/cat/whiskers.js +110 -0
  140. package/vendor/procedural-animals/src/species/cheetah/coat.js +427 -0
  141. package/vendor/procedural-animals/src/species/cheetah/index.js +51 -0
  142. package/vendor/procedural-animals/src/species/cheetah/joints.js +3 -0
  143. package/vendor/procedural-animals/src/species/cheetah/motion.js +77 -0
  144. package/vendor/procedural-animals/src/species/cheetah/regions.js +95 -0
  145. package/vendor/procedural-animals/src/species/cheetah/rig.js +66 -0
  146. package/vendor/procedural-animals/src/species/cheetah/sculpt.js +158 -0
  147. package/vendor/procedural-animals/src/species/chicken/coat.js +313 -0
  148. package/vendor/procedural-animals/src/species/chicken/coverts.js +320 -0
  149. package/vendor/procedural-animals/src/species/chicken/index.js +110 -0
  150. package/vendor/procedural-animals/src/species/chicken/motion.js +177 -0
  151. package/vendor/procedural-animals/src/species/chicken/regions.js +66 -0
  152. package/vendor/procedural-animals/src/species/chicken/rig.js +144 -0
  153. package/vendor/procedural-animals/src/species/chicken/sculpt.js +389 -0
  154. package/vendor/procedural-animals/src/species/chicken/wingLook.js +66 -0
  155. package/vendor/procedural-animals/src/species/chicken/wingStack.js +124 -0
  156. package/vendor/procedural-animals/src/species/cow/behaviour.js +521 -0
  157. package/vendor/procedural-animals/src/species/cow/coat.js +465 -0
  158. package/vendor/procedural-animals/src/species/cow/index.js +118 -0
  159. package/vendor/procedural-animals/src/species/cow/motion.js +81 -0
  160. package/vendor/procedural-animals/src/species/cow/regions.js +98 -0
  161. package/vendor/procedural-animals/src/species/cow/rig.js +116 -0
  162. package/vendor/procedural-animals/src/species/cow/sculpt.js +339 -0
  163. package/vendor/procedural-animals/src/species/crow/coat.js +145 -0
  164. package/vendor/procedural-animals/src/species/crow/index.js +70 -0
  165. package/vendor/procedural-animals/src/species/crow/joints.js +3 -0
  166. package/vendor/procedural-animals/src/species/crow/motion.js +101 -0
  167. package/vendor/procedural-animals/src/species/crow/regions.js +50 -0
  168. package/vendor/procedural-animals/src/species/crow/rig.js +83 -0
  169. package/vendor/procedural-animals/src/species/crow/sculpt.js +118 -0
  170. package/vendor/procedural-animals/src/species/deer/behaviour.js +513 -0
  171. package/vendor/procedural-animals/src/species/deer/coat.js +391 -0
  172. package/vendor/procedural-animals/src/species/deer/index.js +106 -0
  173. package/vendor/procedural-animals/src/species/deer/motion.js +97 -0
  174. package/vendor/procedural-animals/src/species/deer/regions.js +60 -0
  175. package/vendor/procedural-animals/src/species/deer/rig.js +124 -0
  176. package/vendor/procedural-animals/src/species/deer/sculpt.js +297 -0
  177. package/vendor/procedural-animals/src/species/dog/behaviour.js +521 -0
  178. package/vendor/procedural-animals/src/species/dog/coat.js +495 -0
  179. package/vendor/procedural-animals/src/species/dog/index.js +144 -0
  180. package/vendor/procedural-animals/src/species/dog/motion.js +118 -0
  181. package/vendor/procedural-animals/src/species/dog/regions.js +61 -0
  182. package/vendor/procedural-animals/src/species/dog/rig.js +129 -0
  183. package/vendor/procedural-animals/src/species/dog/sculpt.js +246 -0
  184. package/vendor/procedural-animals/src/species/eagle/coat.js +250 -0
  185. package/vendor/procedural-animals/src/species/eagle/index.js +76 -0
  186. package/vendor/procedural-animals/src/species/eagle/joints.js +3 -0
  187. package/vendor/procedural-animals/src/species/eagle/motion.js +137 -0
  188. package/vendor/procedural-animals/src/species/eagle/regions.js +57 -0
  189. package/vendor/procedural-animals/src/species/eagle/rig.js +107 -0
  190. package/vendor/procedural-animals/src/species/eagle/sculpt.js +137 -0
  191. package/vendor/procedural-animals/src/species/fish/coat.js +271 -0
  192. package/vendor/procedural-animals/src/species/fish/index.js +88 -0
  193. package/vendor/procedural-animals/src/species/fish/motion.js +92 -0
  194. package/vendor/procedural-animals/src/species/fish/regions.js +27 -0
  195. package/vendor/procedural-animals/src/species/fish/rig.js +143 -0
  196. package/vendor/procedural-animals/src/species/fish/sculpt.js +214 -0
  197. package/vendor/procedural-animals/src/species/fish/variants.js +126 -0
  198. package/vendor/procedural-animals/src/species/fox/behaviour.js +314 -0
  199. package/vendor/procedural-animals/src/species/fox/coat.js +444 -0
  200. package/vendor/procedural-animals/src/species/fox/index.js +120 -0
  201. package/vendor/procedural-animals/src/species/fox/motion.js +81 -0
  202. package/vendor/procedural-animals/src/species/fox/regions.js +59 -0
  203. package/vendor/procedural-animals/src/species/fox/rig.js +91 -0
  204. package/vendor/procedural-animals/src/species/fox/sculpt.js +202 -0
  205. package/vendor/procedural-animals/src/species/frog/behaviour.js +590 -0
  206. package/vendor/procedural-animals/src/species/frog/coat.js +305 -0
  207. package/vendor/procedural-animals/src/species/frog/index.js +97 -0
  208. package/vendor/procedural-animals/src/species/frog/motion.js +69 -0
  209. package/vendor/procedural-animals/src/species/frog/regions.js +46 -0
  210. package/vendor/procedural-animals/src/species/frog/rig.js +156 -0
  211. package/vendor/procedural-animals/src/species/frog/sculpt.js +240 -0
  212. package/vendor/procedural-animals/src/species/goat/behaviour.js +509 -0
  213. package/vendor/procedural-animals/src/species/goat/coat.js +590 -0
  214. package/vendor/procedural-animals/src/species/goat/index.js +149 -0
  215. package/vendor/procedural-animals/src/species/goat/motion.js +95 -0
  216. package/vendor/procedural-animals/src/species/goat/regions.js +98 -0
  217. package/vendor/procedural-animals/src/species/goat/rig.js +181 -0
  218. package/vendor/procedural-animals/src/species/goat/sculpt.js +547 -0
  219. package/vendor/procedural-animals/src/species/horse/coat.js +361 -0
  220. package/vendor/procedural-animals/src/species/horse/coatSeam.js +122 -0
  221. package/vendor/procedural-animals/src/species/horse/index.js +80 -0
  222. package/vendor/procedural-animals/src/species/horse/motion.js +245 -0
  223. package/vendor/procedural-animals/src/species/horse/regions.js +60 -0
  224. package/vendor/procedural-animals/src/species/horse/rig.js +117 -0
  225. package/vendor/procedural-animals/src/species/horse/sculpt.js +316 -0
  226. package/vendor/procedural-animals/src/species/horse/seamWeights.js +272 -0
  227. package/vendor/procedural-animals/src/species/lion/behaviour.js +509 -0
  228. package/vendor/procedural-animals/src/species/lion/coat.js +1016 -0
  229. package/vendor/procedural-animals/src/species/lion/index.js +111 -0
  230. package/vendor/procedural-animals/src/species/lion/motion.js +87 -0
  231. package/vendor/procedural-animals/src/species/lion/regions.js +106 -0
  232. package/vendor/procedural-animals/src/species/lion/rig.js +110 -0
  233. package/vendor/procedural-animals/src/species/lion/sculpt.js +384 -0
  234. package/vendor/procedural-animals/src/species/lion/whiskers.js +132 -0
  235. package/vendor/procedural-animals/src/species/pig/behaviour.js +575 -0
  236. package/vendor/procedural-animals/src/species/pig/coat.js +730 -0
  237. package/vendor/procedural-animals/src/species/pig/ears.js +242 -0
  238. package/vendor/procedural-animals/src/species/pig/index.js +161 -0
  239. package/vendor/procedural-animals/src/species/pig/motion.js +105 -0
  240. package/vendor/procedural-animals/src/species/pig/regions.js +100 -0
  241. package/vendor/procedural-animals/src/species/pig/rig.js +152 -0
  242. package/vendor/procedural-animals/src/species/pig/sculpt.js +382 -0
  243. package/vendor/procedural-animals/src/species/rabbit/behaviour.js +605 -0
  244. package/vendor/procedural-animals/src/species/rabbit/coat.js +285 -0
  245. package/vendor/procedural-animals/src/species/rabbit/index.js +85 -0
  246. package/vendor/procedural-animals/src/species/rabbit/motion.js +85 -0
  247. package/vendor/procedural-animals/src/species/rabbit/regions.js +48 -0
  248. package/vendor/procedural-animals/src/species/rabbit/rig.js +99 -0
  249. package/vendor/procedural-animals/src/species/rabbit/sculpt.js +148 -0
  250. package/vendor/procedural-animals/src/species/rat/behaviour.js +539 -0
  251. package/vendor/procedural-animals/src/species/rat/coat.js +341 -0
  252. package/vendor/procedural-animals/src/species/rat/index.js +111 -0
  253. package/vendor/procedural-animals/src/species/rat/motion.js +90 -0
  254. package/vendor/procedural-animals/src/species/rat/regions.js +92 -0
  255. package/vendor/procedural-animals/src/species/rat/rig.js +112 -0
  256. package/vendor/procedural-animals/src/species/rat/sculpt.js +163 -0
  257. package/vendor/procedural-animals/src/species/rat/whiskers.js +119 -0
  258. package/vendor/procedural-animals/src/species/shark/coat.js +383 -0
  259. package/vendor/procedural-animals/src/species/shark/index.js +104 -0
  260. package/vendor/procedural-animals/src/species/shark/motion.js +69 -0
  261. package/vendor/procedural-animals/src/species/shark/regions.js +34 -0
  262. package/vendor/procedural-animals/src/species/shark/rig.js +194 -0
  263. package/vendor/procedural-animals/src/species/shark/sculpt.js +343 -0
  264. package/vendor/procedural-animals/src/species/shark/variants.js +105 -0
  265. package/vendor/procedural-animals/src/species/sheep/behaviour.js +522 -0
  266. package/vendor/procedural-animals/src/species/sheep/coat.js +529 -0
  267. package/vendor/procedural-animals/src/species/sheep/index.js +152 -0
  268. package/vendor/procedural-animals/src/species/sheep/motion.js +86 -0
  269. package/vendor/procedural-animals/src/species/sheep/neck.js +41 -0
  270. package/vendor/procedural-animals/src/species/sheep/regions.js +62 -0
  271. package/vendor/procedural-animals/src/species/sheep/rig.js +163 -0
  272. package/vendor/procedural-animals/src/species/sheep/sculpt.js +542 -0
  273. package/vendor/procedural-animals/src/species/snake/coat.js +315 -0
  274. package/vendor/procedural-animals/src/species/snake/index.js +73 -0
  275. package/vendor/procedural-animals/src/species/snake/motion.js +51 -0
  276. package/vendor/procedural-animals/src/species/snake/regions.js +51 -0
  277. package/vendor/procedural-animals/src/species/snake/rig.js +108 -0
  278. package/vendor/procedural-animals/src/species/snake/sculpt.js +122 -0
  279. package/vendor/procedural-animals/src/species/spider/coat.js +279 -0
  280. package/vendor/procedural-animals/src/species/spider/index.js +78 -0
  281. package/vendor/procedural-animals/src/species/spider/motion.js +72 -0
  282. package/vendor/procedural-animals/src/species/spider/regions.js +87 -0
  283. package/vendor/procedural-animals/src/species/spider/rig.js +118 -0
  284. package/vendor/procedural-animals/src/species/spider/sculpt.js +182 -0
  285. package/vendor/procedural-animals/src/species/wolf/behaviour.js +160 -0
  286. package/vendor/procedural-animals/src/species/wolf/coat.js +749 -0
  287. package/vendor/procedural-animals/src/species/wolf/index.js +107 -0
  288. package/vendor/procedural-animals/src/species/wolf/motion.js +80 -0
  289. package/vendor/procedural-animals/src/species/wolf/regions.js +57 -0
  290. package/vendor/procedural-animals/src/species/wolf/rig.js +87 -0
  291. package/vendor/procedural-animals/src/species/wolf/sculpt.js +339 -0
  292. package/vendor/procedural-animals/src/worker.js +29 -0
@@ -0,0 +1,72 @@
1
+ import {createZoomies} from './puppy-zoomies.mjs';
2
+ import {createSpriteTween} from './puppy-continuous.mjs';
3
+ export const STABLE_SPEC={width:320,height:320,count:42,tempo:.6,cycle:21};
4
+ const ease=p=>{p=Math.max(0,Math.min(1,p));return p*p*p*(p*(p*6-15)+10);};
5
+ const mix=(a,b,p)=>a+(b-a)*p;
6
+ // Integral of a smooth velocity ramp: quick acceleration, cruise, soft stop.
7
+ export function launchProgress(p){
8
+ p=Math.max(0,Math.min(1,p));const a=.10,b=.22,v=1/(1-(a+b)/2),integral=u=>u*u*u-.5*u*u*u*u;
9
+ if(p<a)return v*a*integral(p/a);
10
+ if(p>1-b)return 1-v*b*integral((1-p)/b);
11
+ return v*(p-a/2);
12
+ }
13
+ // The estimated thick-body root is ALWAYS (160,180). Stage depth/scale never comes from
14
+ // sprite silhouette dimensions. Gait-local vertical contact correction is separate.
15
+ export function stableAt(seconds,{mode='auto',easedTurns=false,rampRest=false,tempo=.6,quickLaunch=false,movingTurns=false}={}){
16
+ if(!Number.isFinite(seconds)||seconds<0||!Number.isFinite(tempo)||tempo<=0||tempo>4||!['auto','run','pant'].includes(mode))throw Error('Invalid stable animation time/mode');
17
+ const time=seconds*tempo,cycle=quickLaunch?20.18:21,local=time%cycle;
18
+ const t=quickLaunch?(local<.18?local/.18:local+.82):local;
19
+ const state=(kind,pair,blend,x=.58,flip=false)=>({state:kind,pair,blend,x,flip,floor:.94,scale:.72,pose:pair<=40?pair:[0,41,0,30,20,0][pair-41],z:1});
20
+ const pant=phase=>{const p=phase*15,i=Math.floor(p);return state('pant',20+i%10,p-i);};
21
+ const run=(p,from,to,start,end,flip)=>{const u=(p-start)/(end-start),progress=from===to?u:quickLaunch&&start===1?launchProgress(u):ease(u),cycles=Math.max(1,Math.round((end-start)*.9)),gait=progress*cycles*20,i=Math.floor(gait);return state('run',i%20,gait-i,mix(from,to,progress),flip);};
22
+ const turn=(p,x,reverse)=>{
23
+ const q=ease(p/1.5),direction=reverse?-1:1;
24
+ const position=s=>{
25
+ if(movingTurns){
26
+ // Fixed observer: the ACTOR follows a small U-shaped ground path.
27
+ // Same depth and scale throughout; no camera orbit or silhouette resizing.
28
+ s.x=x+direction*(-.04+.04*Math.cos(Math.PI*q)+.065*Math.sin(Math.PI*q));
29
+ s.floor+=.035*Math.sin(Math.PI*q);
30
+ }
31
+ return s;
32
+ };
33
+ if(p<.2)return position(state('turn',reverse?43:41,ease(p/.2),x));
34
+ if(p<1.3){const progress=(p-.2)/1.1,q=(easedTurns?ease(progress):progress)*11,index=Math.min(10,Math.floor(q)),a=q-index;return position(state('turn',reverse?40-index:30+index,reverse?1-a:a,x));}
35
+ return position(state('turn',reverse?44:42,ease((p-1.3)/.2),x));
36
+ };
37
+ if(mode==='pant')return pant(time);
38
+ if(mode==='run')return run(time,.58,.58,0,1,false);
39
+ if(t<1)return state('launch',45,ease(t));
40
+ if(t<3)return run(t,.58,.78,1,3,false);
41
+ if(t<4.5)return turn(t-3,.78,false);
42
+ if(t<47/6)return run(t,movingTurns?.70:.78,.22,4.5,47/6,true);
43
+ if(t<28/3)return turn(t-47/6,.22,true);
44
+ if(t<34/3)return run(t,movingTurns?.30:.22,.58,28/3,34/3,false);
45
+ if(t<37/3)return state('settle',46,ease(t-34/3));
46
+ const rest=t-37/3;
47
+ if(rampRest){
48
+ const duration=26/3,ramp=.5,rate=120/(duration-ramp),integral=u=>u**6-3*u**5+2.5*u**4;
49
+ const phase=rest<ramp?rate*ramp*integral(rest/ramp):rest>duration-ramp?120-rate*ramp*integral((duration-rest)/ramp):rate*(rest-ramp/2);
50
+ return pant(phase/15);
51
+ }
52
+ return pant(rest);
53
+ }
54
+ export function groundOffset(state,meta){
55
+ const [a,b]=meta.pairs[state.pair],p=state.blend;
56
+ const v=meta.ground_offsets;
57
+ if(state.pair<30){
58
+ const start=state.pair<20?0:20,n=start?10:20,index=a-start;
59
+ const before=v[start+(index+n-1)%n],after=v[start+(index+2)%n];
60
+ // Periodic Catmull-Rom: root velocity is continuous across pose boundaries.
61
+ return .5*((2*v[a])+(-before+v[b])*p+(2*before-5*v[a]+4*v[b]-after)*p*p+(-before+3*v[a]-3*v[b]+after)*p*p*p);
62
+ }
63
+ return mix(v[a],v[b],p);
64
+ }
65
+ export function createStableZoomies(atlas,fields,meta,width,height,{sampleState=stableAt,frameProvider,groundAt=groundOffset}={}){
66
+ if(meta.count!==42||meta.pairs.length!==47||meta.ground_offsets.length!==42)throw Error('Invalid stable metadata');
67
+ const tween=frameProvider??createSpriteTween(atlas,fields,{count:42,pairs:meta.pairs});
68
+ const stateAt=(seconds,options)=>{
69
+ const s=sampleState(seconds,options);s.floor+=groundAt(s,meta)*s.scale/320;return s;
70
+ };
71
+ return createZoomies(atlas,width,height,{spec:STABLE_SPEC,stateAt,frameProvider:tween});
72
+ }
@@ -0,0 +1,343 @@
1
+ {
2
+ "pairs": 47,
3
+ "samples": 17,
4
+ "width": 320,
5
+ "height": 320,
6
+ "channels": 1,
7
+ "bytes": 81817600,
8
+ "gzip_bytes": 27353427,
9
+ "sha256": "15e8ef49947cec4a1dcb3393d43a2ad48125d1bcd30f01275087c3df61627392",
10
+ "source_sha256": "773530ca2986c127013c5f37630701c6660c943a79f16ba1560ae2ddbda204fc",
11
+ "method": "RIFE v4.6, nihui/rife-ncnn-vulkan pinned release 20221029; exact original endpoints; curated single-flight gait, three new skip bridges",
12
+ "tool_provenance": "tools/rife-20221029/provenance.json",
13
+ "run_motion_costs": [
14
+ 29.32706069946289,
15
+ 38.92640686035156,
16
+ 35.9362678527832,
17
+ 26.38045883178711,
18
+ 23.560644149780273,
19
+ 37.207794189453125,
20
+ 17.431142807006836,
21
+ 31.60407257080078
22
+ ],
23
+ "run_timing": [
24
+ 0.0,
25
+ 2.267557382583618,
26
+ 5.171559810638428,
27
+ 8.922640800476074,
28
+ 10.962368965148926,
29
+ 12.820930480957031,
30
+ 15.697823524475098,
31
+ 17.556385040283203,
32
+ 20.0
33
+ ],
34
+ "run_sequence": [
35
+ 0,
36
+ 1,
37
+ 6,
38
+ 9,
39
+ 10,
40
+ 11,
41
+ 12,
42
+ 13
43
+ ],
44
+ "pair_map": [
45
+ [
46
+ 0,
47
+ 1,
48
+ false,
49
+ false
50
+ ],
51
+ [
52
+ 1,
53
+ 6,
54
+ false,
55
+ false
56
+ ],
57
+ [
58
+ 6,
59
+ 9,
60
+ false,
61
+ false
62
+ ],
63
+ [
64
+ 9,
65
+ 10,
66
+ false,
67
+ false
68
+ ],
69
+ [
70
+ 10,
71
+ 11,
72
+ false,
73
+ false
74
+ ],
75
+ [
76
+ 11,
77
+ 12,
78
+ false,
79
+ false
80
+ ],
81
+ [
82
+ 12,
83
+ 13,
84
+ false,
85
+ false
86
+ ],
87
+ [
88
+ 13,
89
+ 0,
90
+ false,
91
+ false
92
+ ],
93
+ [
94
+ 8,
95
+ 9,
96
+ false,
97
+ false
98
+ ],
99
+ [
100
+ 9,
101
+ 10,
102
+ false,
103
+ false
104
+ ],
105
+ [
106
+ 10,
107
+ 11,
108
+ false,
109
+ false
110
+ ],
111
+ [
112
+ 11,
113
+ 12,
114
+ false,
115
+ false
116
+ ],
117
+ [
118
+ 12,
119
+ 13,
120
+ false,
121
+ false
122
+ ],
123
+ [
124
+ 13,
125
+ 14,
126
+ false,
127
+ false
128
+ ],
129
+ [
130
+ 14,
131
+ 15,
132
+ false,
133
+ false
134
+ ],
135
+ [
136
+ 15,
137
+ 16,
138
+ false,
139
+ false
140
+ ],
141
+ [
142
+ 16,
143
+ 17,
144
+ false,
145
+ false
146
+ ],
147
+ [
148
+ 17,
149
+ 18,
150
+ false,
151
+ false
152
+ ],
153
+ [
154
+ 18,
155
+ 19,
156
+ false,
157
+ false
158
+ ],
159
+ [
160
+ 19,
161
+ 0,
162
+ false,
163
+ false
164
+ ],
165
+ [
166
+ 20,
167
+ 21,
168
+ false,
169
+ false
170
+ ],
171
+ [
172
+ 21,
173
+ 22,
174
+ false,
175
+ false
176
+ ],
177
+ [
178
+ 22,
179
+ 23,
180
+ false,
181
+ false
182
+ ],
183
+ [
184
+ 23,
185
+ 24,
186
+ false,
187
+ false
188
+ ],
189
+ [
190
+ 24,
191
+ 25,
192
+ false,
193
+ false
194
+ ],
195
+ [
196
+ 25,
197
+ 26,
198
+ false,
199
+ false
200
+ ],
201
+ [
202
+ 26,
203
+ 27,
204
+ false,
205
+ false
206
+ ],
207
+ [
208
+ 27,
209
+ 28,
210
+ false,
211
+ false
212
+ ],
213
+ [
214
+ 28,
215
+ 29,
216
+ false,
217
+ false
218
+ ],
219
+ [
220
+ 29,
221
+ 20,
222
+ false,
223
+ false
224
+ ],
225
+ [
226
+ 30,
227
+ 31,
228
+ false,
229
+ false
230
+ ],
231
+ [
232
+ 31,
233
+ 32,
234
+ false,
235
+ false
236
+ ],
237
+ [
238
+ 32,
239
+ 33,
240
+ false,
241
+ false
242
+ ],
243
+ [
244
+ 33,
245
+ 34,
246
+ false,
247
+ false
248
+ ],
249
+ [
250
+ 34,
251
+ 35,
252
+ false,
253
+ false
254
+ ],
255
+ [
256
+ 35,
257
+ 36,
258
+ false,
259
+ false
260
+ ],
261
+ [
262
+ 36,
263
+ 37,
264
+ false,
265
+ false
266
+ ],
267
+ [
268
+ 37,
269
+ 38,
270
+ false,
271
+ false
272
+ ],
273
+ [
274
+ 38,
275
+ 39,
276
+ false,
277
+ false
278
+ ],
279
+ [
280
+ 39,
281
+ 40,
282
+ false,
283
+ false
284
+ ],
285
+ [
286
+ 40,
287
+ 41,
288
+ false,
289
+ false
290
+ ],
291
+ [
292
+ 0,
293
+ 30,
294
+ false,
295
+ false
296
+ ],
297
+ [
298
+ 41,
299
+ 0,
300
+ false,
301
+ true
302
+ ],
303
+ [
304
+ 0,
305
+ 41,
306
+ true,
307
+ false
308
+ ],
309
+ [
310
+ 30,
311
+ 0,
312
+ false,
313
+ false
314
+ ],
315
+ [
316
+ 20,
317
+ 0,
318
+ false,
319
+ false
320
+ ],
321
+ [
322
+ 0,
323
+ 20,
324
+ false,
325
+ false
326
+ ]
327
+ ],
328
+ "new_edges": [
329
+ [
330
+ 1,
331
+ 6
332
+ ],
333
+ [
334
+ 6,
335
+ 9
336
+ ],
337
+ [
338
+ 13,
339
+ 0
340
+ ]
341
+ ],
342
+ "previous_cache_sha256": "8d91d81cdd41629e23b0d8d6421baa0efa8d74a64a611035f3b97fd6f86fbd7d"
343
+ }
Binary file
@@ -0,0 +1,27 @@
1
+ export const ZOOMIES={width:320,height:320,count:12,columns:4,rows:3};
2
+ const ease=x=>x*x*(3-2*x);
3
+ export function zoomiesAt(seconds,{mode='auto'}={}){
4
+ if(!Number.isFinite(seconds)||seconds<0||!['auto','run','pant'].includes(mode))throw Error('Invalid zoomies state');
5
+ const t=mode==='run'?seconds%6:seconds%16;
6
+ if(mode==='pant'||(mode==='auto'&&t>=8))return {state:'pant',pose:8+Math.floor(seconds*6)%4,x:.58,floor:.96,scale:.90,flip:false};
7
+ if(t>=6){const s=ease(Math.min(1,(t-6)/2));return {state:t<6.5?'brake':'settle',pose:t<6.5?7:8,x:.58,floor:.96,scale:.66+.24*s,flip:false};}
8
+ const leg=Math.floor(t/2),p=ease((t%2)/2),x=leg===0?.22+.56*p:leg===1?.78-.56*p:.22+.36*p;
9
+ return {state:'run',pose:Math.floor(seconds*12)%8,x,floor:.83+.045*Math.sin(t*Math.PI/3),scale:.62+.04*Math.sin(t*Math.PI/3),flip:leg===1};
10
+ }
11
+ export function createZoomies(atlas,width,height,{spec=ZOOMIES,stateAt=zoomiesAt,frameProvider}={}){
12
+ const {width:sw,height:sh,count}=spec,stride=sw*sh*4;
13
+ if(atlas.length!==stride*count||![width,height].every(Number.isInteger)||width<2||height<2||width*height>1_000_000)throw Error('Invalid zoomies atlas or stage');
14
+ const out=new Uint8ClampedArray(width*height*4);
15
+ return function render(seconds,options={}){
16
+ const state=stateAt(seconds,options),side=height*state.scale,span=side*(state.widthScale??1),left=width*state.x-span/2,top=height*state.floor-side,offset=frameProvider?0:state.pose*stride,image=frameProvider?frameProvider(state):atlas;
17
+ out.fill(0);for(let i=3;i<out.length;i+=4)out[i]=255;
18
+ for(let y=Math.max(0,Math.floor(top));y<Math.min(height,Math.ceil(top+side));y++)for(let x=Math.max(0,Math.floor(left));x<Math.min(width,Math.ceil(left+span));x++){
19
+ let u=(x-left)/span;if(state.flip)u=1-u;const v=(y-top)/side;
20
+ if(u<0||u>1||v<0||v>1)continue;
21
+ const sx=u*(sw-1),sy=v*(sh-1),x0=Math.floor(sx),y0=Math.floor(sy),x1=Math.min(sw-1,x0+1),y1=Math.min(sh-1,y0+1),fx=sx-x0,fy=sy-y0;
22
+ const a=offset+(y0*sw+x0)*4,b=offset+(y0*sw+x1)*4,c=offset+(y1*sw+x0)*4,d=offset+(y1*sw+x1)*4,j=(y*width+x)*4;
23
+ for(let k=0;k<3;k++)out[j+k]=(image[a+k]*(1-fx)+image[b+k]*fx)*(1-fy)+(image[c+k]*(1-fx)+image[d+k]*fx)*fy;
24
+ }
25
+ return out;
26
+ };
27
+ }
@@ -0,0 +1,12 @@
1
+ import {createZoomies,zoomiesAt} from './puppy-zoomies.mjs';
2
+ export const ZOOMIES30={width:320,height:320,count:30,runCount:20,pantCount:10,fps:30,tempo:.6};
3
+ export function zoomies30At(seconds,options={}){
4
+ // Slow the shared behavior/pose clock, not the display refresh rate.
5
+ const time=seconds*ZOOMIES30.tempo,state=zoomiesAt(time,options);
6
+ if(state.state==='run')state.pose=Math.floor(time*30)%20;
7
+ else if(state.state==='brake')state.pose=19;
8
+ else if(state.state==='settle')state.pose=20;
9
+ else state.pose=20+Math.floor(time*15)%10;
10
+ return state;
11
+ }
12
+ export function createZoomies30(atlas,width,height){return createZoomies(atlas,width,height,{spec:ZOOMIES30,stateAt:zoomies30At});}
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env node
2
+ // Installer entrypoint. Never imports art for help/status/doctor or config planning.
3
+ import {createInstaller,AGENTS} from './retrieviewer-install.mjs';
4
+ import {createInterface} from 'node:readline/promises';
5
+
6
+ const HELP=`Retrieviewer — autonomous Braille companion
7
+
8
+ Usage:
9
+ retrieviewer enable [--agent ID] [--yes] [--dry-run]
10
+ retrieviewer disable --agent ID
11
+ retrieviewer disconnect --agent ID [--yes] [--dry-run]
12
+ retrieviewer status [--agent ID] [--json]
13
+ retrieviewer doctor [--agent ID] [--json]
14
+ retrieviewer agents [--json]
15
+ retrieviewer preview [--original]
16
+
17
+ Enable opens a first-run selection/confirmation wizard on a real terminal.
18
+ Non-interactive changes require --agent and --yes. Unsupported native renderers
19
+ are refused: MCP connectivity alone is never treated as in-screen rendering.
20
+ No command changes credentials, shell profiles or agent executables.
21
+ `;
22
+ export function parseArguments(args){
23
+ const [command='help',...rest]=args,options={};
24
+ for(let i=0;i<rest.length;i++){
25
+ const token=rest[i];
26
+ if(token==='--agent'){
27
+ if(options.agent||!rest[i+1]||rest[i+1].startsWith('-'))throw Error('--agent requires one ID');
28
+ options.agent=rest[++i];
29
+ }else if(['--yes','--json','--dry-run','--original'].includes(token))options[token.slice(2)]=true;
30
+ else throw Error('Unknown argument: '+token);
31
+ }
32
+ if(options.agent&&!AGENTS.some(a=>a.id===options.agent))throw Error('Unknown agent: '+options.agent);
33
+ if(!['help','--help','-h','enable','disable','disconnect','status','doctor','agents','preview'].includes(command))throw Error('Unknown command: '+command);
34
+ const allowed={enable:['agent','yes','json','dry-run'],disconnect:['agent','yes','json','dry-run'],disable:['agent','json'],status:['agent','json'],doctor:['agent','json'],agents:['json'],preview:['original']};
35
+ for(const key of Object.keys(options))if(!(allowed[command]??[]).includes(key))throw Error(`--${key} is not supported by ${command}`);
36
+ return {command,options};
37
+ }
38
+ export async function runCli(args,{input=process.stdin,output=process.stdout,error=process.stderr,installer=createInstaller()}={}){
39
+ const {command,options}=parseArguments(args),emit=value=>output.write(JSON.stringify(value,null,2)+'\n');
40
+ if(['help','--help','-h'].includes(command)){output.write(HELP);return 0;}
41
+ if(command==='preview'){await import('./examples/live.mjs');return 0;}
42
+ if(['status','doctor','agents'].includes(command)){
43
+ const result=command==='agents'?await installer.list():await installer[command](options.agent);
44
+ if(options.json||command==='doctor')emit(result);
45
+ else for(const row of Array.isArray(result)?result:[result])output.write(`${row.id}: ${row.detected?'detected '+(row.version??'unknown version'):'not installed'} | ${row.enabled?'enabled':'disabled'} | ${row.connected?'registered':'not registered'} | renderer ${row.renderer?.status??'unknown'}${row.renderer?.reason?' — '+row.renderer.reason:''}\n`);
46
+ return 0;
47
+ }
48
+ let agent=options.agent,rl;
49
+ const interactive=!!input.isTTY&&!!output.isTTY;
50
+ try{
51
+ if(!agent){
52
+ if(!interactive)throw Error('Specify --agent ID. Run retrieviewer agents to list targets.');
53
+ if(command!=='enable')throw Error('--agent is required');
54
+ const list=await installer.list();
55
+ output.write('Choose an agent (unavailable renderers cannot be enabled):\n');
56
+ list.forEach((row,i)=>output.write(` ${i+1}. ${row.label} — ${row.detected?'detected':'not installed'} / ${row.renderer.status}\n`));
57
+ rl=createInterface({input,output});const selected=await rl.question('Number or agent ID (Enter cancels): ');
58
+ if(!selected.trim()){output.write('Cancelled; no settings changed.\n');return 0;}
59
+ agent=list[Number(selected)-1]?.id??selected.trim();
60
+ if(!list.some(row=>row.id===agent))throw Error('Unknown selection');
61
+ }
62
+ if(command==='disable'){emit(await installer.disable(agent));return 0;}
63
+ const plan=await installer.plan(agent);
64
+ if(command==='enable'&&!plan.supported){emit(plan);error.write('Native in-screen renderer is not available for this target; nothing changed.\n');return 2;}
65
+ output.write(`${command==='enable'?'Enable':'Disconnect'} Retrieviewer for ${agent}\n`);
66
+ for(const change of plan.changes??[])output.write(` ${change.path}: ${command==='disconnect'?'remove only the Retrieviewer-owned registration; preserve other settings':change.description}\n`);
67
+ if(options['dry-run']){emit({...plan,dryRun:true,operation:command});return 0;}
68
+ let confirmed=options.yes===true;
69
+ if(!confirmed&&interactive){rl??=createInterface({input,output});confirmed=/^y(?:es)?$/i.test((await rl.question('Back up and apply these changes? [y/N] ')).trim());}
70
+ if(!confirmed){if(!interactive)throw Error('No settings changed. Review --dry-run, then use --yes to confirm.');output.write('Cancelled; no settings changed.\n');return 0;}
71
+ emit(await installer[command](agent,{confirm:true}));
72
+ if(command==='enable')output.write('Registration complete; restart the agent. Rendering is checked separately by doctor.\n');
73
+ return 0;
74
+ }finally{rl?.close();}
75
+ }
76
+
77
+ // CLI is deliberately a separate module from the side-effect-free library.
78
+ import {pathToFileURL} from 'node:url';
79
+ if(process.argv[1]&&import.meta.url===pathToFileURL(process.argv[1]).href){
80
+ try{process.exitCode=await runCli(process.argv.slice(2));}catch(e){process.stderr.write('Retrieviewer: '+e.message+'\n');process.exitCode=1;}
81
+ }
@@ -0,0 +1,49 @@
1
+ // Tiny runtime settings API. No art, processes, timers or I/O on import.
2
+ import {homedir} from 'node:os';
3
+ import {join,resolve} from 'node:path';
4
+ import {readFile,mkdir,lstat,open,rename,unlink} from 'node:fs/promises';
5
+ import {randomUUID} from 'node:crypto';
6
+
7
+ export function getConfigPaths({home=homedir(),env=process.env,stateDir}={}){
8
+ const root=resolve(stateDir??env.RETRIEVIEWER_HOME??join(home,'.config','retrieviewer'));
9
+ return {root,settings:join(root,'settings.json'),lock:join(root,'settings.lock')};
10
+ }
11
+ const agentId=id=>{if(typeof id!=='string'||!/^[a-z][a-z0-9-]{0,47}$/.test(id))throw TypeError('Invalid agent ID');return id;};
12
+ async function noLink(path){try{if((await lstat(path)).isSymbolicLink())throw Error('Refusing symlink: '+path);}catch(e){if(e.code!=='ENOENT')throw e;}}
13
+ export async function readSettings(options={}){
14
+ const {root,settings}=getConfigPaths(options);await noLink(root);await noLink(settings);
15
+ let bytes;try{bytes=await readFile(settings,'utf8');}catch(e){if(e.code==='ENOENT')return {version:1,agents:{}};throw e;}
16
+ if(bytes.length>1024*1024)throw Error('Retrieviewer settings exceed 1 MiB');
17
+ const data=JSON.parse(bytes);
18
+ if(!data||data.version!==1||!data.agents||typeof data.agents!=='object'||Array.isArray(data.agents))throw Error('Unsupported Retrieviewer settings format');
19
+ return data;
20
+ }
21
+ export async function readAgentSettings(agent,options={}){
22
+ agentId(agent);const data=await readSettings(options);
23
+ return Object.hasOwn(data.agents,agent)?{...data.agents[agent],enabled:data.agents[agent]?.enabled===true}:{enabled:false};
24
+ }
25
+ export async function writeAtomicJson(path,value){
26
+ await noLink(path);const temp=path+'.'+randomUUID()+'.tmp';let owned=false;
27
+ try{const file=await open(temp,'wx',0o600);owned=true;try{await file.writeFile(JSON.stringify(value,null,2)+'\n');await file.sync();}finally{await file.close();}await rename(temp,path);owned=false;}
28
+ finally{if(owned)await unlink(temp).catch(()=>{});}
29
+ }
30
+ export async function withSettingsLock(fn,options={}){
31
+ const paths=getConfigPaths(options);await noLink(paths.root);await mkdir(paths.root,{recursive:true,mode:0o700});
32
+ await noLink(paths.lock);let handle;
33
+ try{handle=await open(paths.lock,'wx',0o600);}catch(e){if(e.code==='EEXIST')throw Error('Retrieviewer settings are locked by another operation; retry when it finishes.');throw e;}
34
+ try{return await fn(paths);}finally{await handle.close();await unlink(paths.lock);}
35
+ }
36
+ export async function setAgentEnabled(agent,enabled,options={}){
37
+ agentId(agent);if(typeof enabled!=='boolean')throw TypeError('enabled must be boolean');
38
+ await withSettingsLock(async({settings})=>{
39
+ const data=await readSettings(options);
40
+ if(!Object.hasOwn(data.agents,agent))throw Error('Agent is not connected. Run retrieviewer enable --agent '+agent+' first.');
41
+ data.agents[agent]={...data.agents[agent],enabled};await writeAtomicJson(settings,data);
42
+ },options);
43
+ }
44
+ export async function writeRuntimeReceipt(agent,receipt,options={}){
45
+ agentId(agent);const {root}=getConfigPaths(options);await noLink(root);await mkdir(root,{recursive:true,mode:0o700});
46
+ const {hostVersion,phase,firstFrameAt,columns,rows,frames}=receipt;
47
+ if(!['rendering','stopped'].includes(phase))throw TypeError('Invalid renderer receipt phase');
48
+ await writeAtomicJson(join(root,'runtime-'+agent+'.json'),{version:1,agent,hostVersion,phase,firstFrameAt,columns,rows,frames,pid:process.pid,updatedAt:new Date().toISOString()});
49
+ }