@overcrow/mcp 0.0.0 → 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.
Files changed (461) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +91 -1
  3. package/dist/audit/index.js +103 -0
  4. package/dist/audit/lexer.js +417 -0
  5. package/dist/audit/project.js +200 -0
  6. package/dist/audit/rules.js +661 -0
  7. package/dist/bootstrap/download.js +229 -0
  8. package/dist/bootstrap/install.js +280 -0
  9. package/dist/bootstrap/pin.js +85 -0
  10. package/dist/bootstrap/pin.json +119 -0
  11. package/dist/bootstrap/zip.js +258 -0
  12. package/dist/cli.js +200 -0
  13. package/dist/confine.js +244 -0
  14. package/dist/content/docs/en/cli.md +353 -0
  15. package/dist/content/docs/en/dev-channel.md +130 -0
  16. package/dist/content/docs/en/elements.md +469 -0
  17. package/dist/content/docs/en/forms.md +328 -0
  18. package/dist/content/docs/en/guide.md +253 -0
  19. package/dist/content/docs/en/index.md +85 -0
  20. package/dist/content/docs/en/limits.md +241 -0
  21. package/dist/content/docs/en/logic.md +446 -0
  22. package/dist/content/docs/en/manifest.md +381 -0
  23. package/dist/content/docs/en/mcp.md +165 -0
  24. package/dist/content/docs/en/package.md +131 -0
  25. package/dist/content/docs/en/publishing.md +162 -0
  26. package/dist/content/docs/en/reference.md +55 -0
  27. package/dist/content/docs/en/result-shapes.md +332 -0
  28. package/dist/content/docs/en/sdk.md +295 -0
  29. package/dist/content/docs/en/security.md +115 -0
  30. package/dist/content/docs/en/service-reference.md +344 -0
  31. package/dist/content/docs/en/services.md +517 -0
  32. package/dist/content/docs/en/style-properties.md +270 -0
  33. package/dist/content/docs/en/style.md +266 -0
  34. package/dist/content/docs/en/testing.md +400 -0
  35. package/dist/content/docs/en/view.md +338 -0
  36. package/dist/content/docs/en/widgets.md +76 -0
  37. package/dist/content/docs/fr/cli.md +367 -0
  38. package/dist/content/docs/fr/dev-channel.md +140 -0
  39. package/dist/content/docs/fr/elements.md +475 -0
  40. package/dist/content/docs/fr/forms.md +341 -0
  41. package/dist/content/docs/fr/guide.md +264 -0
  42. package/dist/content/docs/fr/index.md +90 -0
  43. package/dist/content/docs/fr/limits.md +244 -0
  44. package/dist/content/docs/fr/logic.md +461 -0
  45. package/dist/content/docs/fr/manifest.md +392 -0
  46. package/dist/content/docs/fr/mcp.md +173 -0
  47. package/dist/content/docs/fr/package.md +139 -0
  48. package/dist/content/docs/fr/publishing.md +172 -0
  49. package/dist/content/docs/fr/reference.md +59 -0
  50. package/dist/content/docs/fr/result-shapes.md +333 -0
  51. package/dist/content/docs/fr/sdk.md +301 -0
  52. package/dist/content/docs/fr/security.md +129 -0
  53. package/dist/content/docs/fr/service-reference.md +346 -0
  54. package/dist/content/docs/fr/services.md +540 -0
  55. package/dist/content/docs/fr/style-properties.md +272 -0
  56. package/dist/content/docs/fr/style.md +281 -0
  57. package/dist/content/docs/fr/testing.md +417 -0
  58. package/dist/content/docs/fr/view.md +352 -0
  59. package/dist/content/docs/fr/widgets.md +81 -0
  60. package/dist/content/examples/clock/LICENSE +21 -0
  61. package/dist/content/examples/clock/README.md +75 -0
  62. package/dist/content/examples/clock/listing.json +19 -0
  63. package/dist/content/examples/clock/locales/en.json +4 -0
  64. package/dist/content/examples/clock/locales/fr.json +4 -0
  65. package/dist/content/examples/clock/logic.ts +85 -0
  66. package/dist/content/examples/clock/manifest.json +44 -0
  67. package/dist/content/examples/clock/package.json +16 -0
  68. package/dist/content/examples/clock/style.ocss +26 -0
  69. package/dist/content/examples/clock/tests/hidden.scenario.json +68 -0
  70. package/dist/content/examples/clock/tests/load-logic.mjs +22 -0
  71. package/dist/content/examples/clock/tests/logic.test.mjs +89 -0
  72. package/dist/content/examples/clock/tests/options.scenario.json +108 -0
  73. package/dist/content/examples/clock/tests/preview.scenario.json +25 -0
  74. package/dist/content/examples/clock/tests/render.scenario.json +94 -0
  75. package/dist/content/examples/clock/tests/summer-time.scenario.json +74 -0
  76. package/dist/content/examples/clock/tests/ticks.scenario.json +120 -0
  77. package/dist/content/examples/clock/tsconfig.json +16 -0
  78. package/dist/content/examples/clock/view.ocml +8 -0
  79. package/dist/content/examples/countdown/LICENSE +20 -0
  80. package/dist/content/examples/countdown/listing.json +10 -0
  81. package/dist/content/examples/countdown/locales/en.json +15 -0
  82. package/dist/content/examples/countdown/locales/fr.json +15 -0
  83. package/dist/content/examples/countdown/logic.ts +179 -0
  84. package/dist/content/examples/countdown/manifest.json +34 -0
  85. package/dist/content/examples/countdown/package.json +15 -0
  86. package/dist/content/examples/countdown/style.ocss +94 -0
  87. package/dist/content/examples/countdown/tsconfig.json +16 -0
  88. package/dist/content/examples/countdown/view.ocml +42 -0
  89. package/dist/content/examples/fps/LICENSE +21 -0
  90. package/dist/content/examples/fps/README.md +64 -0
  91. package/dist/content/examples/fps/listing.json +19 -0
  92. package/dist/content/examples/fps/locales/en.json +11 -0
  93. package/dist/content/examples/fps/locales/fr.json +11 -0
  94. package/dist/content/examples/fps/logic.ts +64 -0
  95. package/dist/content/examples/fps/manifest.json +30 -0
  96. package/dist/content/examples/fps/package.json +16 -0
  97. package/dist/content/examples/fps/style.ocss +31 -0
  98. package/dist/content/examples/fps/tests/label.scenario.json +63 -0
  99. package/dist/content/examples/fps/tests/load-logic.mjs +22 -0
  100. package/dist/content/examples/fps/tests/logic.test.mjs +60 -0
  101. package/dist/content/examples/fps/tests/preview.scenario.json +29 -0
  102. package/dist/content/examples/fps/tests/refused.scenario.json +20 -0
  103. package/dist/content/examples/fps/tests/render.scenario.json +96 -0
  104. package/dist/content/examples/fps/tests/stale.scenario.json +91 -0
  105. package/dist/content/examples/fps/tests/unavailable.scenario.json +111 -0
  106. package/dist/content/examples/fps/tsconfig.json +16 -0
  107. package/dist/content/examples/fps/view.ocml +11 -0
  108. package/dist/content/examples/media/LICENSE +21 -0
  109. package/dist/content/examples/media/README.md +147 -0
  110. package/dist/content/examples/media/listing.json +19 -0
  111. package/dist/content/examples/media/locales/en.json +11 -0
  112. package/dist/content/examples/media/locales/fr.json +11 -0
  113. package/dist/content/examples/media/logic.ts +191 -0
  114. package/dist/content/examples/media/manifest.json +35 -0
  115. package/dist/content/examples/media/package.json +16 -0
  116. package/dist/content/examples/media/style.ocss +148 -0
  117. package/dist/content/examples/media/tests/covers.scenario.json +144 -0
  118. package/dist/content/examples/media/tests/gesture.scenario.json +173 -0
  119. package/dist/content/examples/media/tests/load-logic.mjs +22 -0
  120. package/dist/content/examples/media/tests/logic.test.mjs +176 -0
  121. package/dist/content/examples/media/tests/marquee.scenario.json +127 -0
  122. package/dist/content/examples/media/tests/preview.scenario.json +52 -0
  123. package/dist/content/examples/media/tests/read-only.scenario.json +53 -0
  124. package/dist/content/examples/media/tests/refused.scenario.json +22 -0
  125. package/dist/content/examples/media/tests/refused.test.mjs +31 -0
  126. package/dist/content/examples/media/tests/render.scenario.json +136 -0
  127. package/dist/content/examples/media/tests/states.scenario.json +257 -0
  128. package/dist/content/examples/media/tests/unavailable.scenario.json +120 -0
  129. package/dist/content/examples/media/tsconfig.json +16 -0
  130. package/dist/content/examples/media/view.ocml +41 -0
  131. package/dist/content/examples/notes/LICENSE +21 -0
  132. package/dist/content/examples/notes/README.md +219 -0
  133. package/dist/content/examples/notes/listing.json +19 -0
  134. package/dist/content/examples/notes/locales/en.json +25 -0
  135. package/dist/content/examples/notes/locales/fr.json +25 -0
  136. package/dist/content/examples/notes/logic.ts +799 -0
  137. package/dist/content/examples/notes/manifest.json +40 -0
  138. package/dist/content/examples/notes/package.json +16 -0
  139. package/dist/content/examples/notes/style.ocss +469 -0
  140. package/dist/content/examples/notes/tests/checks.scenario.json +237 -0
  141. package/dist/content/examples/notes/tests/create.scenario.json +260 -0
  142. package/dist/content/examples/notes/tests/delete.scenario.json +342 -0
  143. package/dist/content/examples/notes/tests/drafts.scenario.json +714 -0
  144. package/dist/content/examples/notes/tests/editor.scenario.json +232 -0
  145. package/dist/content/examples/notes/tests/frame.scenario.json +93 -0
  146. package/dist/content/examples/notes/tests/interactive.scenario.json +344 -0
  147. package/dist/content/examples/notes/tests/limits.scenario.json +1351 -0
  148. package/dist/content/examples/notes/tests/load-logic.mjs +22 -0
  149. package/dist/content/examples/notes/tests/logic.test.mjs +514 -0
  150. package/dist/content/examples/notes/tests/preview.scenario.json +99 -0
  151. package/dist/content/examples/notes/tests/read-only.scenario.json +105 -0
  152. package/dist/content/examples/notes/tests/refused.scenario.json +33 -0
  153. package/dist/content/examples/notes/tests/save.scenario.json +378 -0
  154. package/dist/content/examples/notes/tests/states.scenario.json +640 -0
  155. package/dist/content/examples/notes/tests/typing.scenario.json +562 -0
  156. package/dist/content/examples/notes/tests/unavailable.scenario.json +246 -0
  157. package/dist/content/examples/notes/tsconfig.json +16 -0
  158. package/dist/content/examples/notes/view.ocml +154 -0
  159. package/dist/content/examples/performance/LICENSE +21 -0
  160. package/dist/content/examples/performance/README.md +134 -0
  161. package/dist/content/examples/performance/listing.json +19 -0
  162. package/dist/content/examples/performance/locales/en.json +20 -0
  163. package/dist/content/examples/performance/locales/fr.json +20 -0
  164. package/dist/content/examples/performance/logic.ts +210 -0
  165. package/dist/content/examples/performance/manifest.json +83 -0
  166. package/dist/content/examples/performance/package.json +16 -0
  167. package/dist/content/examples/performance/style.ocss +75 -0
  168. package/dist/content/examples/performance/tests/fahrenheit.scenario.json +110 -0
  169. package/dist/content/examples/performance/tests/horizontal.scenario.json +96 -0
  170. package/dist/content/examples/performance/tests/load-logic.mjs +22 -0
  171. package/dist/content/examples/performance/tests/logic.test.mjs +226 -0
  172. package/dist/content/examples/performance/tests/menu.scenario.json +170 -0
  173. package/dist/content/examples/performance/tests/no-fps-source.scenario.json +47 -0
  174. package/dist/content/examples/performance/tests/preview.scenario.json +45 -0
  175. package/dist/content/examples/performance/tests/refused.scenario.json +20 -0
  176. package/dist/content/examples/performance/tests/refused.test.mjs +19 -0
  177. package/dist/content/examples/performance/tests/region.scenario.json +89 -0
  178. package/dist/content/examples/performance/tests/render.scenario.json +112 -0
  179. package/dist/content/examples/performance/tests/sources.scenario.json +151 -0
  180. package/dist/content/examples/performance/tests/stale.scenario.json +111 -0
  181. package/dist/content/examples/performance/tests/telemetry-only.scenario.json +44 -0
  182. package/dist/content/examples/performance/tests/thresholds.scenario.json +147 -0
  183. package/dist/content/examples/performance/tests/waiting.scenario.json +105 -0
  184. package/dist/content/examples/performance/tsconfig.json +16 -0
  185. package/dist/content/examples/performance/view.ocml +18 -0
  186. package/dist/content/examples/playervox-journal/LICENSE +21 -0
  187. package/dist/content/examples/playervox-journal/README.md +150 -0
  188. package/dist/content/examples/playervox-journal/listing.json +19 -0
  189. package/dist/content/examples/playervox-journal/locales/en.json +25 -0
  190. package/dist/content/examples/playervox-journal/locales/fr.json +25 -0
  191. package/dist/content/examples/playervox-journal/logic.ts +556 -0
  192. package/dist/content/examples/playervox-journal/manifest.json +19 -0
  193. package/dist/content/examples/playervox-journal/package.json +16 -0
  194. package/dist/content/examples/playervox-journal/style.ocss +142 -0
  195. package/dist/content/examples/playervox-journal/tests/changes.scenario.json +482 -0
  196. package/dist/content/examples/playervox-journal/tests/delete.scenario.json +432 -0
  197. package/dist/content/examples/playervox-journal/tests/frame.scenario.json +169 -0
  198. package/dist/content/examples/playervox-journal/tests/load-logic.mjs +22 -0
  199. package/dist/content/examples/playervox-journal/tests/logic.test.mjs +349 -0
  200. package/dist/content/examples/playervox-journal/tests/paging.scenario.json +428 -0
  201. package/dist/content/examples/playervox-journal/tests/preview.scenario.json +184 -0
  202. package/dist/content/examples/playervox-journal/tests/read-only.scenario.json +157 -0
  203. package/dist/content/examples/playervox-journal/tests/refused.scenario.json +39 -0
  204. package/dist/content/examples/playervox-journal/tests/scale.scenario.json +286 -0
  205. package/dist/content/examples/playervox-journal/tests/signed-out.scenario.json +134 -0
  206. package/dist/content/examples/playervox-journal/tests/states.scenario.json +741 -0
  207. package/dist/content/examples/playervox-journal/tests/unavailable.scenario.json +183 -0
  208. package/dist/content/examples/playervox-journal/tsconfig.json +16 -0
  209. package/dist/content/examples/playervox-journal/view.ocml +52 -0
  210. package/dist/content/examples/playervox-rating/LICENSE +21 -0
  211. package/dist/content/examples/playervox-rating/README.md +166 -0
  212. package/dist/content/examples/playervox-rating/listing.json +19 -0
  213. package/dist/content/examples/playervox-rating/locales/en.json +35 -0
  214. package/dist/content/examples/playervox-rating/locales/fr.json +35 -0
  215. package/dist/content/examples/playervox-rating/logic.ts +581 -0
  216. package/dist/content/examples/playervox-rating/manifest.json +19 -0
  217. package/dist/content/examples/playervox-rating/package.json +16 -0
  218. package/dist/content/examples/playervox-rating/style.ocss +333 -0
  219. package/dist/content/examples/playervox-rating/tests/account.scenario.json +125 -0
  220. package/dist/content/examples/playervox-rating/tests/bounds.scenario.json +73 -0
  221. package/dist/content/examples/playervox-rating/tests/draft.scenario.json +199 -0
  222. package/dist/content/examples/playervox-rating/tests/form.scenario.json +142 -0
  223. package/dist/content/examples/playervox-rating/tests/load-logic.mjs +22 -0
  224. package/dist/content/examples/playervox-rating/tests/logic.test.mjs +346 -0
  225. package/dist/content/examples/playervox-rating/tests/offline.scenario.json +142 -0
  226. package/dist/content/examples/playervox-rating/tests/preview.scenario.json +44 -0
  227. package/dist/content/examples/playervox-rating/tests/publish-keyboard.scenario.json +221 -0
  228. package/dist/content/examples/playervox-rating/tests/publish-pointer.scenario.json +314 -0
  229. package/dist/content/examples/playervox-rating/tests/read-only.scenario.json +70 -0
  230. package/dist/content/examples/playervox-rating/tests/refused.scenario.json +45 -0
  231. package/dist/content/examples/playervox-rating/tests/states.scenario.json +362 -0
  232. package/dist/content/examples/playervox-rating/tsconfig.json +16 -0
  233. package/dist/content/examples/playervox-rating/view.ocml +62 -0
  234. package/dist/content/examples/playervox-reviews/LICENSE +21 -0
  235. package/dist/content/examples/playervox-reviews/README.md +194 -0
  236. package/dist/content/examples/playervox-reviews/listing.json +19 -0
  237. package/dist/content/examples/playervox-reviews/locales/en.json +32 -0
  238. package/dist/content/examples/playervox-reviews/locales/fr.json +32 -0
  239. package/dist/content/examples/playervox-reviews/logic.ts +822 -0
  240. package/dist/content/examples/playervox-reviews/manifest.json +30 -0
  241. package/dist/content/examples/playervox-reviews/package.json +16 -0
  242. package/dist/content/examples/playervox-reviews/style.ocss +260 -0
  243. package/dist/content/examples/playervox-reviews/tests/account.scenario.json +249 -0
  244. package/dist/content/examples/playervox-reviews/tests/bounds.scenario.json +336 -0
  245. package/dist/content/examples/playervox-reviews/tests/changes.scenario.json +515 -0
  246. package/dist/content/examples/playervox-reviews/tests/filter.scenario.json +400 -0
  247. package/dist/content/examples/playervox-reviews/tests/frame.scenario.json +185 -0
  248. package/dist/content/examples/playervox-reviews/tests/keyboard.scenario.json +188 -0
  249. package/dist/content/examples/playervox-reviews/tests/load-logic.mjs +22 -0
  250. package/dist/content/examples/playervox-reviews/tests/logic.test.mjs +559 -0
  251. package/dist/content/examples/playervox-reviews/tests/offline-start.scenario.json +152 -0
  252. package/dist/content/examples/playervox-reviews/tests/offline.scenario.json +311 -0
  253. package/dist/content/examples/playervox-reviews/tests/paging.scenario.json +497 -0
  254. package/dist/content/examples/playervox-reviews/tests/preview.scenario.json +286 -0
  255. package/dist/content/examples/playervox-reviews/tests/reading.scenario.json +591 -0
  256. package/dist/content/examples/playervox-reviews/tests/refused.scenario.json +54 -0
  257. package/dist/content/examples/playervox-reviews/tests/scale.scenario.json +303 -0
  258. package/dist/content/examples/playervox-reviews/tests/states.scenario.json +700 -0
  259. package/dist/content/examples/playervox-reviews/tests/unavailable.scenario.json +192 -0
  260. package/dist/content/examples/playervox-reviews/tsconfig.json +16 -0
  261. package/dist/content/examples/playervox-reviews/view.ocml +110 -0
  262. package/dist/content/examples/playervox-score/LICENSE +21 -0
  263. package/dist/content/examples/playervox-score/README.md +131 -0
  264. package/dist/content/examples/playervox-score/listing.json +19 -0
  265. package/dist/content/examples/playervox-score/locales/en.json +23 -0
  266. package/dist/content/examples/playervox-score/locales/fr.json +23 -0
  267. package/dist/content/examples/playervox-score/logic.ts +430 -0
  268. package/dist/content/examples/playervox-score/manifest.json +47 -0
  269. package/dist/content/examples/playervox-score/package.json +16 -0
  270. package/dist/content/examples/playervox-score/style.ocss +247 -0
  271. package/dist/content/examples/playervox-score/tests/grades.scenario.json +279 -0
  272. package/dist/content/examples/playervox-score/tests/load-logic.mjs +22 -0
  273. package/dist/content/examples/playervox-score/tests/logic.test.mjs +229 -0
  274. package/dist/content/examples/playervox-score/tests/options.scenario.json +302 -0
  275. package/dist/content/examples/playervox-score/tests/preview.scenario.json +68 -0
  276. package/dist/content/examples/playervox-score/tests/pulse.scenario.json +157 -0
  277. package/dist/content/examples/playervox-score/tests/refused.scenario.json +21 -0
  278. package/dist/content/examples/playervox-score/tests/signed-out.scenario.json +46 -0
  279. package/dist/content/examples/playervox-score/tests/states.scenario.json +450 -0
  280. package/dist/content/examples/playervox-score/tests/unavailable.scenario.json +84 -0
  281. package/dist/content/examples/playervox-score/tsconfig.json +16 -0
  282. package/dist/content/examples/playervox-score/view.ocml +51 -0
  283. package/dist/content/examples/session/LICENSE +21 -0
  284. package/dist/content/examples/session/README.md +57 -0
  285. package/dist/content/examples/session/listing.json +19 -0
  286. package/dist/content/examples/session/locales/en.json +3 -0
  287. package/dist/content/examples/session/locales/fr.json +3 -0
  288. package/dist/content/examples/session/logic.ts +26 -0
  289. package/dist/content/examples/session/manifest.json +19 -0
  290. package/dist/content/examples/session/package.json +16 -0
  291. package/dist/content/examples/session/style.ocss +16 -0
  292. package/dist/content/examples/session/tests/hidden.scenario.json +45 -0
  293. package/dist/content/examples/session/tests/load-logic.mjs +22 -0
  294. package/dist/content/examples/session/tests/logic.test.mjs +37 -0
  295. package/dist/content/examples/session/tests/preview.scenario.json +28 -0
  296. package/dist/content/examples/session/tests/refused.scenario.json +20 -0
  297. package/dist/content/examples/session/tests/refused.test.mjs +16 -0
  298. package/dist/content/examples/session/tests/render.scenario.json +95 -0
  299. package/dist/content/examples/session/tests/ticks.scenario.json +139 -0
  300. package/dist/content/examples/session/tests/unknown.scenario.json +37 -0
  301. package/dist/content/examples/session/tsconfig.json +16 -0
  302. package/dist/content/examples/session/view.ocml +11 -0
  303. package/dist/content/examples/stopwatch/LICENSE +21 -0
  304. package/dist/content/examples/stopwatch/README.md +99 -0
  305. package/dist/content/examples/stopwatch/listing.json +19 -0
  306. package/dist/content/examples/stopwatch/locales/en.json +8 -0
  307. package/dist/content/examples/stopwatch/locales/fr.json +8 -0
  308. package/dist/content/examples/stopwatch/logic.ts +93 -0
  309. package/dist/content/examples/stopwatch/manifest.json +19 -0
  310. package/dist/content/examples/stopwatch/package.json +16 -0
  311. package/dist/content/examples/stopwatch/style.ocss +54 -0
  312. package/dist/content/examples/stopwatch/tests/errors.scenario.json +121 -0
  313. package/dist/content/examples/stopwatch/tests/gesture.scenario.json +154 -0
  314. package/dist/content/examples/stopwatch/tests/hidden.scenario.json +57 -0
  315. package/dist/content/examples/stopwatch/tests/hundredths.scenario.json +173 -0
  316. package/dist/content/examples/stopwatch/tests/load-logic.mjs +22 -0
  317. package/dist/content/examples/stopwatch/tests/logic.test.mjs +99 -0
  318. package/dist/content/examples/stopwatch/tests/preview.scenario.json +36 -0
  319. package/dist/content/examples/stopwatch/tests/read-only.scenario.json +42 -0
  320. package/dist/content/examples/stopwatch/tests/read-only.test.mjs +18 -0
  321. package/dist/content/examples/stopwatch/tests/refused.scenario.json +22 -0
  322. package/dist/content/examples/stopwatch/tests/refused.test.mjs +18 -0
  323. package/dist/content/examples/stopwatch/tests/render.scenario.json +105 -0
  324. package/dist/content/examples/stopwatch/tests/states.scenario.json +246 -0
  325. package/dist/content/examples/stopwatch/tests/unknown.scenario.json +40 -0
  326. package/dist/content/examples/stopwatch/tsconfig.json +16 -0
  327. package/dist/content/examples/stopwatch/view.ocml +29 -0
  328. package/dist/content/examples/twitch-chat/LICENSE +21 -0
  329. package/dist/content/examples/twitch-chat/README.md +283 -0
  330. package/dist/content/examples/twitch-chat/listing.json +19 -0
  331. package/dist/content/examples/twitch-chat/locales/en.json +52 -0
  332. package/dist/content/examples/twitch-chat/locales/fr.json +52 -0
  333. package/dist/content/examples/twitch-chat/logic.ts +887 -0
  334. package/dist/content/examples/twitch-chat/manifest.json +33 -0
  335. package/dist/content/examples/twitch-chat/package.json +16 -0
  336. package/dist/content/examples/twitch-chat/style.ocss +544 -0
  337. package/dist/content/examples/twitch-chat/tests/account.scenario.json +325 -0
  338. package/dist/content/examples/twitch-chat/tests/burst.scenario.json +1866 -0
  339. package/dist/content/examples/twitch-chat/tests/channel-refused.scenario.json +372 -0
  340. package/dist/content/examples/twitch-chat/tests/channel.scenario.json +480 -0
  341. package/dist/content/examples/twitch-chat/tests/draft.scenario.json +279 -0
  342. package/dist/content/examples/twitch-chat/tests/fade.scenario.json +269 -0
  343. package/dist/content/examples/twitch-chat/tests/failures.scenario.json +420 -0
  344. package/dist/content/examples/twitch-chat/tests/favorites.scenario.json +376 -0
  345. package/dist/content/examples/twitch-chat/tests/frame.scenario.json +152 -0
  346. package/dist/content/examples/twitch-chat/tests/lifetime.scenario.json +186 -0
  347. package/dist/content/examples/twitch-chat/tests/load-logic.mjs +22 -0
  348. package/dist/content/examples/twitch-chat/tests/logic.test.mjs +1053 -0
  349. package/dist/content/examples/twitch-chat/tests/passive.scenario.json +536 -0
  350. package/dist/content/examples/twitch-chat/tests/preview.scenario.json +147 -0
  351. package/dist/content/examples/twitch-chat/tests/read-only.scenario.json +202 -0
  352. package/dist/content/examples/twitch-chat/tests/read-only.test.mjs +63 -0
  353. package/dist/content/examples/twitch-chat/tests/refused.scenario.json +65 -0
  354. package/dist/content/examples/twitch-chat/tests/refused.test.mjs +43 -0
  355. package/dist/content/examples/twitch-chat/tests/render.scenario.json +347 -0
  356. package/dist/content/examples/twitch-chat/tests/reply.scenario.json +384 -0
  357. package/dist/content/examples/twitch-chat/tests/send-refused.scenario.json +383 -0
  358. package/dist/content/examples/twitch-chat/tests/send.scenario.json +300 -0
  359. package/dist/content/examples/twitch-chat/tests/states.scenario.json +455 -0
  360. package/dist/content/examples/twitch-chat/tests/unavailable.scenario.json +256 -0
  361. package/dist/content/examples/twitch-chat/tests/unread.scenario.json +997 -0
  362. package/dist/content/examples/twitch-chat/tsconfig.json +16 -0
  363. package/dist/content/examples/twitch-chat/view.ocml +141 -0
  364. package/dist/content/examples/warframe-market/LICENSE +21 -0
  365. package/dist/content/examples/warframe-market/README.md +176 -0
  366. package/dist/content/examples/warframe-market/listing.json +19 -0
  367. package/dist/content/examples/warframe-market/locales/en.json +44 -0
  368. package/dist/content/examples/warframe-market/locales/fr.json +44 -0
  369. package/dist/content/examples/warframe-market/logic.ts +1265 -0
  370. package/dist/content/examples/warframe-market/manifest.json +92 -0
  371. package/dist/content/examples/warframe-market/package.json +16 -0
  372. package/dist/content/examples/warframe-market/style.ocss +422 -0
  373. package/dist/content/examples/warframe-market/tests/bounds.scenario.json +60 -0
  374. package/dist/content/examples/warframe-market/tests/cached.scenario.json +70 -0
  375. package/dist/content/examples/warframe-market/tests/detail.scenario.json +251 -0
  376. package/dist/content/examples/warframe-market/tests/errors.scenario.json +105 -0
  377. package/dist/content/examples/warframe-market/tests/fixtures.json +295 -0
  378. package/dist/content/examples/warframe-market/tests/load-logic.mjs +22 -0
  379. package/dist/content/examples/warframe-market/tests/logic.test.mjs +505 -0
  380. package/dist/content/examples/warframe-market/tests/no-clipboard.scenario.json +104 -0
  381. package/dist/content/examples/warframe-market/tests/passive.scenario.json +87 -0
  382. package/dist/content/examples/warframe-market/tests/preview.scenario.json +146 -0
  383. package/dist/content/examples/warframe-market/tests/refresh.scenario.json +56 -0
  384. package/dist/content/examples/warframe-market/tests/refused.scenario.json +74 -0
  385. package/dist/content/examples/warframe-market/tests/render.scenario.json +210 -0
  386. package/dist/content/examples/warframe-market/tests/search.scenario.json +189 -0
  387. package/dist/content/examples/warframe-market/tests/unavailable.scenario.json +54 -0
  388. package/dist/content/examples/warframe-market/tsconfig.json +16 -0
  389. package/dist/content/examples/warframe-market/view.ocml +116 -0
  390. package/dist/content/examples/weather/LICENSE +20 -0
  391. package/dist/content/examples/weather/listing.json +10 -0
  392. package/dist/content/examples/weather/locales/en.json +9 -0
  393. package/dist/content/examples/weather/locales/fr.json +9 -0
  394. package/dist/content/examples/weather/logic.ts +62 -0
  395. package/dist/content/examples/weather/manifest.json +51 -0
  396. package/dist/content/examples/weather/package.json +15 -0
  397. package/dist/content/examples/weather/style.ocss +29 -0
  398. package/dist/content/examples/weather/tsconfig.json +16 -0
  399. package/dist/content/examples/weather/view.ocml +12 -0
  400. package/dist/content/index.json +3601 -0
  401. package/dist/content/reference/errors.json +1712 -0
  402. package/dist/content/reference/limits.json +1154 -0
  403. package/dist/content/reference/manifest.md +223 -0
  404. package/dist/content/reference/permissions.json +413 -0
  405. package/dist/content/templates/blank/locales/en.json +3 -0
  406. package/dist/content/templates/blank/locales/fr.json +3 -0
  407. package/dist/content/templates/blank/logic.ts +7 -0
  408. package/dist/content/templates/blank/manifest.json +16 -0
  409. package/dist/content/templates/blank/style.ocss +10 -0
  410. package/dist/content/templates/blank/tests/example.scenario.json +10 -0
  411. package/dist/content/templates/blank/view.ocml +6 -0
  412. package/dist/content/templates/chart/locales/en.json +3 -0
  413. package/dist/content/templates/chart/locales/fr.json +3 -0
  414. package/dist/content/templates/chart/logic.ts +27 -0
  415. package/dist/content/templates/chart/manifest.json +16 -0
  416. package/dist/content/templates/chart/style.ocss +27 -0
  417. package/dist/content/templates/chart/tests/example.scenario.json +10 -0
  418. package/dist/content/templates/chart/view.ocml +10 -0
  419. package/dist/content/templates/counter/locales/en.json +4 -0
  420. package/dist/content/templates/counter/locales/fr.json +4 -0
  421. package/dist/content/templates/counter/logic.ts +20 -0
  422. package/dist/content/templates/counter/manifest.json +16 -0
  423. package/dist/content/templates/counter/style.ocss +26 -0
  424. package/dist/content/templates/counter/tests/example.scenario.json +11 -0
  425. package/dist/content/templates/counter/view.ocml +13 -0
  426. package/dist/content/templates/list/locales/en.json +8 -0
  427. package/dist/content/templates/list/locales/fr.json +8 -0
  428. package/dist/content/templates/list/logic.ts +35 -0
  429. package/dist/content/templates/list/manifest.json +16 -0
  430. package/dist/content/templates/list/style.ocss +42 -0
  431. package/dist/content/templates/list/tests/example.scenario.json +10 -0
  432. package/dist/content/templates/list/view.ocml +17 -0
  433. package/dist/content/templates/shared/LICENSE +20 -0
  434. package/dist/content/templates/shared/package.json +14 -0
  435. package/dist/content/templates/shared/tsconfig.json +16 -0
  436. package/dist/content.js +68 -0
  437. package/dist/env.js +156 -0
  438. package/dist/fingerprint.js +32 -0
  439. package/dist/ids.js +27 -0
  440. package/dist/index.js +82 -0
  441. package/dist/knowledge.js +222 -0
  442. package/dist/npm.js +149 -0
  443. package/dist/prompts.js +47 -0
  444. package/dist/resources.js +82 -0
  445. package/dist/run.js +120 -0
  446. package/dist/server.js +43 -0
  447. package/dist/session.js +205 -0
  448. package/dist/sources.js +218 -0
  449. package/dist/text.js +80 -0
  450. package/dist/texts.js +44 -0
  451. package/dist/tools/audit.js +105 -0
  452. package/dist/tools/build.js +453 -0
  453. package/dist/tools/common.js +122 -0
  454. package/dist/tools/docs.js +196 -0
  455. package/dist/tools/preview.js +87 -0
  456. package/dist/tools/project.js +178 -0
  457. package/dist/tools/setup.js +146 -0
  458. package/dist/tools/submission.js +369 -0
  459. package/dist/version.js +3 -0
  460. package/npm-shrinkwrap.json +402 -0
  461. package/package.json +50 -4
@@ -0,0 +1,84 @@
1
+ {
2
+ "scenarioVersion": 1,
3
+ "name": "unavailable",
4
+ "description": "The host's score source fails: the subscription ends with unavailable, the widget shows it, subscribes again 5 s later and shows the score the restarted source reports.",
5
+ "fixtures": {
6
+ "subscriptions": {
7
+ "playervox.score.subscribe": {
8
+ "state": "ready",
9
+ "name": "Portal 2",
10
+ "score": 94.2,
11
+ "grade": "S+",
12
+ "ratingsCount": 1284,
13
+ "criteria": {
14
+ "gameplay": 97.4,
15
+ "art": 90.1,
16
+ "tech": 94.6
17
+ }
18
+ }
19
+ }
20
+ },
21
+ "steps": [
22
+ {
23
+ "expect": {
24
+ "text": [
25
+ "Portal 2"
26
+ ],
27
+ "state": "running",
28
+ "calls": [
29
+ {
30
+ "service": "playervox.score.subscribe",
31
+ "outcome": "ok"
32
+ }
33
+ ]
34
+ }
35
+ },
36
+ {
37
+ "publish": {
38
+ "service": "playervox.score.subscribe",
39
+ "error": "unavailable"
40
+ }
41
+ },
42
+ {
43
+ "expect": {
44
+ "text": [
45
+ "Score unavailable",
46
+ "Retrying automatically"
47
+ ],
48
+ "noText": [
49
+ "Portal 2"
50
+ ],
51
+ "image": "unavailable"
52
+ }
53
+ },
54
+ {
55
+ "advance": {
56
+ "ms": 4999
57
+ }
58
+ },
59
+ {
60
+ "expect": {
61
+ "calls": []
62
+ }
63
+ },
64
+ {
65
+ "advance": {
66
+ "ms": 1
67
+ }
68
+ },
69
+ {
70
+ "expect": {
71
+ "text": [
72
+ "Portal 2"
73
+ ],
74
+ "calls": [
75
+ {
76
+ "service": "playervox.score.subscribe",
77
+ "outcome": "ok"
78
+ }
79
+ ],
80
+ "image": "recovered"
81
+ }
82
+ }
83
+ ]
84
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2023",
4
+ "lib": ["ES2023"],
5
+ "types": [],
6
+ "module": "ES2022",
7
+ "moduleResolution": "bundler",
8
+ "strict": true,
9
+ "noEmit": true,
10
+ "isolatedModules": true,
11
+ "verbatimModuleSyntax": true,
12
+ "noUncheckedIndexedAccess": true,
13
+ "exactOptionalPropertyTypes": true
14
+ },
15
+ "include": ["logic.ts"]
16
+ }
@@ -0,0 +1,51 @@
1
+ <!-- PlayerVox Score: the community grade badge of the active Steam game,
2
+ its rounded score, rating count, game name and three criteria
3
+ (parity sheet: playervox-overcrow docs/builtin-parity/playervox-score.md).
4
+ The badge and the PlayerVox mark are canvases drawn from
5
+ widgets-shared/playervox-badge; the host animates the badge's pulse. -->
6
+ <box class={rootClass(state)} label={t("label")} tooltip={tooltip(state.score)}>
7
+ <if test={!badgeOnly(state)}>
8
+ <box class="header">
9
+ <if test={state.showTitle}>
10
+ <text class="title">{title(state.score)}</text>
11
+ </if>
12
+ <canvas ref="mark" class="mark" label={t("mark")}/>
13
+ </box>
14
+ </if>
15
+ <box class={mainClass(state)}>
16
+ <box class="slot">
17
+ <canvas ref="badge" class={state.badgeClass} label={badgeName(state.score)}/>
18
+ </box>
19
+ <if test={hasSide(state)}>
20
+ <box class="side">
21
+ <if test={rated(state.score)}>
22
+ <if test={state.showScore}>
23
+ <text class="value"><span>{scoreText(state.score)}</span><span class="max">/100</span></text>
24
+ </if>
25
+ <if test={state.showVotes}>
26
+ <text class={votesClass(state.showScore)}>{votes(state.score)}</text>
27
+ </if>
28
+ </if>
29
+ <else>
30
+ <text class="status">{t(status(state.score).label)}</text>
31
+ <if test={state.showVotes && status(state.score).hint != ""}>
32
+ <text class="hint">{t(status(state.score).hint)}</text>
33
+ </if>
34
+ </else>
35
+ </box>
36
+ </if>
37
+ </box>
38
+ <if test={state.showCriteria}>
39
+ <box class="criteria">
40
+ <for each={criteria(state.score)} as="criterion" key={criterion.key}>
41
+ <box class="criterion">
42
+ <box class="criterion-head">
43
+ <text class="criterion-name">{criterion.name}</text>
44
+ <text class="criterion-value">{criterion.text}</text>
45
+ </box>
46
+ <progress class={criterion.bar} value={criterion.value} max="100" label={criterion.label}/>
47
+ </box>
48
+ </for>
49
+ </box>
50
+ </if>
51
+ </box>
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Valhallab SASU
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,57 @@
1
+ # Session
2
+
3
+ `com.playervox.overcrow.session` — how long the current game has been
4
+ running, as `HH:MM:SS`. A built-in of OverCrow, written against the public
5
+ `@overcrow/sdk` and packaged with `overcrow-widget` like any creator's
6
+ widget. MIT.
7
+
8
+ ## What it shows
9
+
10
+ | State | Shows |
11
+ | --- | --- |
12
+ | Running | `01:27:43`; hours never wrap (`25:01:01`, `100:00:00`) |
13
+ | Duration unknown, no grant, or the service failed | `--:--:--` |
14
+
15
+ The duration counts from the start of the game process, on Linux and
16
+ Windows alike, truncated to whole seconds.
17
+
18
+ ## Menu
19
+
20
+ No widget row: only the host's rows.
21
+
22
+ ## Permissions
23
+
24
+ `session.read`: the duration of the active game session, never its
25
+ identity. Not sensitive.
26
+
27
+ ## How it works
28
+
29
+ `session.subscribe` gives an anchor, `{ elapsedMs, at }` on the host's
30
+ monotonic clock; the view's `elapsed` element shows it and the host
31
+ advances it at each whole second. The widget runs no timer and sends
32
+ nothing while the game runs; a clock change never moves the value. Its
33
+ accessible label is "Session time" / "Temps de session".
34
+
35
+ ## Tests
36
+
37
+ - `tests/logic.test.mjs`, `tests/refused.test.mjs`: the logic on
38
+ `@overcrow/sdk/testing`.
39
+ - Scenarios with their reference images: `render` (both themes and
40
+ languages at 100 and 150 %), `unknown`, `ticks` (whole seconds, past 24
41
+ and 99 hours, a new anchor, the end of the game), `hidden`, `refused`.
42
+
43
+ ## Cost
44
+
45
+ Measured on 2026-09-30 with OverCrow's release build, on an AMD Ryzen 7
46
+ 5800X3D Linux workstation and in a Windows 11 virtual machine (2 vCPU):
47
+
48
+ | | Linux | Windows (VM) |
49
+ | --- | --- | --- |
50
+ | Widget start, warm, into the overlay's runtime | 7 ms at most | — |
51
+ | VM memory | 0.56–0.59 MiB anonymous | similar to the Clock's 0.83 MiB private working set |
52
+ | VM CPU while the game runs | none: the host advances the value | — |
53
+ | Overlay frames | one each second while shown | — |
54
+
55
+ With the Clock and FPS widgets beside it, the overlay's process grows by
56
+ about 2 MB per widget and stays at 0.1 % of one core; nothing runs while
57
+ the overlay is hidden.
@@ -0,0 +1,19 @@
1
+ {
2
+ "author": "PlayerVox",
3
+ "spdxLicense": "MIT",
4
+ "sourceUrl": "https://github.com/Valhallab/playervox-overcrow-releases/tree/main/widgets/session",
5
+ "preview": "assets/preview.png",
6
+ "defaultLocale": "en",
7
+ "localizations": [
8
+ {
9
+ "locale": "en",
10
+ "name": "Session",
11
+ "description": "Shows how long the current game session has lasted."
12
+ },
13
+ {
14
+ "locale": "fr",
15
+ "name": "Session",
16
+ "description": "Affiche la durée de la session de jeu en cours."
17
+ }
18
+ ]
19
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "label": "Session time"
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "label": "Temps de session"
3
+ }
@@ -0,0 +1,26 @@
1
+ // Session: how long the game has been running. The host sends an anchor
2
+ // (`elapsedMs` at its monotonic `at`) and advances the `elapsed` element
3
+ // itself, so the widget has no timer and a clock change never moves it.
4
+ import { hasGrant, initState, session, type Session } from "@overcrow/sdk";
5
+
6
+ declare module "@overcrow/sdk" {
7
+ interface WidgetState {
8
+ /** The latest anchor, or `null` while the duration is unknown. */
9
+ session: Session | null;
10
+ }
11
+ }
12
+
13
+ const state = initState({ session: null as Session | null });
14
+
15
+ /** The anchor to show: an update's value, or none after a failure. */
16
+ export function anchor(update: { ok: boolean; value?: Session | null }): Session | null {
17
+ return update.ok ? (update.value ?? null) : null;
18
+ }
19
+
20
+ // Without the grant the host would refuse the subscription: show the
21
+ // unknown duration instead of asking.
22
+ if (hasGrant("session.read")) {
23
+ session.subscribe((update) => {
24
+ state.session = anchor(update);
25
+ });
26
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "apiVersion": 1,
4
+ "id": "com.playervox.overcrow.session",
5
+ "version": "1.0.2",
6
+ "name": {
7
+ "en": "Session",
8
+ "fr": "Session"
9
+ },
10
+ "sizing": {
11
+ "fit": "both",
12
+ "preferred": { "width": 110, "height": 44 },
13
+ "min": { "width": 40, "height": 24 },
14
+ "max": { "width": 480, "height": 240 }
15
+ },
16
+ "permissions": {
17
+ "capabilities": ["session.read"]
18
+ }
19
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "overcrow-widget-session",
3
+ "version": "1.0.2",
4
+ "private": true,
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "scripts": {
8
+ "check": "overcrow-widget check",
9
+ "package": "overcrow-widget package",
10
+ "test": "node --test tests/*.test.mjs"
11
+ },
12
+ "devDependencies": {
13
+ "@overcrow/sdk": "1.0.0",
14
+ "typescript": "6.0.3"
15
+ }
16
+ }
@@ -0,0 +1,16 @@
1
+ /* One value; the wrapper draws the panel and its 8 px margin, the content
2
+ adds 2 px on the sides: the built-in's 10 × 8 px margin. */
3
+ .session {
4
+ flex-direction: column;
5
+ align-items: start;
6
+ padding: 0 2px;
7
+ }
8
+
9
+ /* The UI font with tabular figures: the value never shifts. */
10
+ .value {
11
+ font-family: var(--font-ui);
12
+ font-size: var(--font-size-value);
13
+ font-variant-numeric: tabular-nums;
14
+ color: var(--color-text);
15
+ white-space: nowrap;
16
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "scenarioVersion": 1,
3
+ "name": "hidden",
4
+ "description": "Hidden, nothing is repainted; shown again, the value is current at once.",
5
+ "fixtures": {
6
+ "subscriptions": {
7
+ "session.subscribe": {
8
+ "elapsedMs": 60000,
9
+ "at": 0
10
+ }
11
+ }
12
+ },
13
+ "steps": [
14
+ {
15
+ "expect": {
16
+ "text": [
17
+ "00:01:00"
18
+ ]
19
+ }
20
+ },
21
+ {
22
+ "host": {
23
+ "visible": false
24
+ }
25
+ },
26
+ {
27
+ "advance": {
28
+ "ms": 600000
29
+ }
30
+ },
31
+ {
32
+ "host": {
33
+ "visible": true
34
+ }
35
+ },
36
+ {
37
+ "expect": {
38
+ "text": [
39
+ "00:11:00"
40
+ ],
41
+ "fault": "none"
42
+ }
43
+ }
44
+ ]
45
+ }
@@ -0,0 +1,22 @@
1
+ // Compiles this widget's logic.ts with the project's TypeScript into
2
+ // dist/ and imports it, after the test installed its runtime
3
+ // (`@overcrow/sdk/testing`), as the VM runs logic.js after its prelude.
4
+ import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
5
+ import ts from "typescript";
6
+
7
+ export async function loadLogic() {
8
+ const root = new URL("../", import.meta.url);
9
+ const source = readFileSync(new URL("logic.ts", root), "utf8");
10
+ const { outputText } = ts.transpileModule(source, {
11
+ compilerOptions: {
12
+ module: ts.ModuleKind.ES2022,
13
+ target: ts.ScriptTarget.ES2023,
14
+ verbatimModuleSyntax: true,
15
+ },
16
+ });
17
+ mkdirSync(new URL("dist/", root), { recursive: true });
18
+ // One file per test process: test files run in parallel.
19
+ const output = new URL(`dist/logic-${process.pid}.mjs`, root);
20
+ writeFileSync(output, outputText);
21
+ return import(output.href);
22
+ }
@@ -0,0 +1,37 @@
1
+ // Unit tests of the Session's logic on @overcrow/sdk/testing.
2
+ import assert from "node:assert/strict";
3
+ import { test } from "node:test";
4
+ import { installRuntime } from "@overcrow/sdk/testing";
5
+
6
+ import { loadLogic } from "./load-logic.mjs";
7
+
8
+ const vm = installRuntime({ host: { grants: ["session.read"] } });
9
+ const logic = await loadLogic();
10
+ const { state } = await import("@overcrow/sdk");
11
+
12
+ test("with the grant, it subscribes once and starts unknown", () => {
13
+ assert.deepEqual(
14
+ vm.subscriptions.map(({ service, params }) => ({ service, params })),
15
+ [{ service: "session.subscribe", params: {} }],
16
+ );
17
+ assert.equal(state.session, null);
18
+ assert.equal(vm.timers.length, 0, "the host advances the value: no timer");
19
+ });
20
+
21
+ test("each update re-anchors; null and failures show the unknown duration", () => {
22
+ vm.push("session.subscribe", { elapsedMs: 5_263_000, at: 10 });
23
+ assert.deepEqual(state.session, { elapsedMs: 5_263_000, at: 10 });
24
+ vm.push("session.subscribe", { elapsedMs: 0, at: 20 });
25
+ assert.deepEqual(state.session, { elapsedMs: 0, at: 20 }, "a new process");
26
+ vm.push("session.subscribe", null);
27
+ assert.equal(state.session, null, "no active game");
28
+ vm.push("session.subscribe", { elapsedMs: 1, at: 30 });
29
+ vm.fail("session.subscribe", "unavailable");
30
+ assert.equal(state.session, null);
31
+ });
32
+
33
+ test("anchor", () => {
34
+ assert.equal(logic.anchor({ ok: false }), null);
35
+ assert.equal(logic.anchor({ ok: true, value: null }), null);
36
+ assert.deepEqual(logic.anchor({ ok: true, value: { elapsedMs: 5, at: 1 } }), { elapsedMs: 5, at: 1 });
37
+ });
@@ -0,0 +1,28 @@
1
+ {
2
+ "scenarioVersion": 1,
3
+ "name": "preview",
4
+ "description": "A session of 1 h 27 min 43 s. The marketplace preview: dark theme, English, 150 %, on the stage colour; scripts/compose-previews.mjs frames it into assets/preview.png.",
5
+ "host": {
6
+ "scale": 1500,
7
+ "background": "#1e242e"
8
+ },
9
+ "fixtures": {
10
+ "subscriptions": {
11
+ "session.subscribe": {
12
+ "elapsedMs": 5263000,
13
+ "at": 0
14
+ }
15
+ }
16
+ },
17
+ "steps": [
18
+ {
19
+ "expect": {
20
+ "state": "running",
21
+ "text": [
22
+ "01:27:43"
23
+ ],
24
+ "image": "preview"
25
+ }
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "scenarioVersion": 1,
3
+ "name": "refused",
4
+ "description": "Without the session.read grant the widget asks nothing and shows --:--:--.",
5
+ "host": {
6
+ "grants": []
7
+ },
8
+ "steps": [
9
+ {
10
+ "expect": {
11
+ "state": "running",
12
+ "text": [
13
+ "--:--:--"
14
+ ],
15
+ "calls": [],
16
+ "fault": "none"
17
+ }
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,16 @@
1
+ // Without the session.read grant the logic asks the host nothing.
2
+ import assert from "node:assert/strict";
3
+ import { test } from "node:test";
4
+ import { installRuntime } from "@overcrow/sdk/testing";
5
+
6
+ import { loadLogic } from "./load-logic.mjs";
7
+
8
+ const vm = installRuntime({ host: { grants: [] } });
9
+ await loadLogic();
10
+ const { state } = await import("@overcrow/sdk");
11
+
12
+ test("no grant: no subscription, unknown duration", () => {
13
+ assert.equal(vm.subscriptions.length, 0);
14
+ assert.equal(vm.calls.length, 0);
15
+ assert.equal(state.session, null);
16
+ });
@@ -0,0 +1,95 @@
1
+ {
2
+ "scenarioVersion": 1,
3
+ "name": "render",
4
+ "description": "A session of 1 h 27 min 43 s, in both themes, both languages, at 100 % and 150 %.",
5
+ "fixtures": {
6
+ "subscriptions": {
7
+ "session.subscribe": {
8
+ "elapsedMs": 5263000,
9
+ "at": 0
10
+ }
11
+ }
12
+ },
13
+ "steps": [
14
+ {
15
+ "expect": {
16
+ "state": "running",
17
+ "text": [
18
+ "01:27:43"
19
+ ],
20
+ "image": "running-dark-en-100"
21
+ }
22
+ },
23
+ {
24
+ "host": {
25
+ "theme": "light"
26
+ }
27
+ },
28
+ {
29
+ "expect": {
30
+ "image": "running-light-en-100"
31
+ }
32
+ },
33
+ {
34
+ "host": {
35
+ "locale": "fr"
36
+ }
37
+ },
38
+ {
39
+ "expect": {
40
+ "image": "running-light-fr-100"
41
+ }
42
+ },
43
+ {
44
+ "host": {
45
+ "theme": "dark"
46
+ }
47
+ },
48
+ {
49
+ "expect": {
50
+ "image": "running-dark-fr-100"
51
+ }
52
+ },
53
+ {
54
+ "host": {
55
+ "scale": 1500
56
+ }
57
+ },
58
+ {
59
+ "expect": {
60
+ "image": "running-dark-fr-150"
61
+ }
62
+ },
63
+ {
64
+ "host": {
65
+ "theme": "light"
66
+ }
67
+ },
68
+ {
69
+ "expect": {
70
+ "image": "running-light-fr-150"
71
+ }
72
+ },
73
+ {
74
+ "host": {
75
+ "locale": "en"
76
+ }
77
+ },
78
+ {
79
+ "expect": {
80
+ "image": "running-light-en-150"
81
+ }
82
+ },
83
+ {
84
+ "host": {
85
+ "theme": "dark"
86
+ }
87
+ },
88
+ {
89
+ "expect": {
90
+ "image": "running-dark-en-150",
91
+ "fault": "none"
92
+ }
93
+ }
94
+ ]
95
+ }