@overcrow/mcp 0.0.0 → 0.1.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 (489) 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 +768 -0
  15. package/dist/content/docs/en/creator-space.md +78 -0
  16. package/dist/content/docs/en/dev-channel.md +130 -0
  17. package/dist/content/docs/en/elements.md +469 -0
  18. package/dist/content/docs/en/forms.md +328 -0
  19. package/dist/content/docs/en/guide.md +252 -0
  20. package/dist/content/docs/en/index.md +85 -0
  21. package/dist/content/docs/en/limits.md +241 -0
  22. package/dist/content/docs/en/logic.md +446 -0
  23. package/dist/content/docs/en/manifest.md +388 -0
  24. package/dist/content/docs/en/mcp.md +165 -0
  25. package/dist/content/docs/en/package.md +131 -0
  26. package/dist/content/docs/en/publish-a-widget.md +94 -0
  27. package/dist/content/docs/en/publish-keys.md +95 -0
  28. package/dist/content/docs/en/publishing.md +167 -0
  29. package/dist/content/docs/en/reference.md +55 -0
  30. package/dist/content/docs/en/result-shapes.md +332 -0
  31. package/dist/content/docs/en/sdk.md +295 -0
  32. package/dist/content/docs/en/security.md +115 -0
  33. package/dist/content/docs/en/service-reference.md +344 -0
  34. package/dist/content/docs/en/services.md +517 -0
  35. package/dist/content/docs/en/style-properties.md +270 -0
  36. package/dist/content/docs/en/style.md +266 -0
  37. package/dist/content/docs/en/testing.md +400 -0
  38. package/dist/content/docs/en/verified-domain.md +46 -0
  39. package/dist/content/docs/en/view.md +338 -0
  40. package/dist/content/docs/en/widget-listing.md +65 -0
  41. package/dist/content/docs/en/widget-review.md +57 -0
  42. package/dist/content/docs/en/widget-statistics.md +134 -0
  43. package/dist/content/docs/en/widgets.md +76 -0
  44. package/dist/content/docs/fr/cli.md +802 -0
  45. package/dist/content/docs/fr/creator-space.md +83 -0
  46. package/dist/content/docs/fr/dev-channel.md +140 -0
  47. package/dist/content/docs/fr/elements.md +475 -0
  48. package/dist/content/docs/fr/forms.md +341 -0
  49. package/dist/content/docs/fr/guide.md +263 -0
  50. package/dist/content/docs/fr/index.md +90 -0
  51. package/dist/content/docs/fr/limits.md +244 -0
  52. package/dist/content/docs/fr/logic.md +461 -0
  53. package/dist/content/docs/fr/manifest.md +401 -0
  54. package/dist/content/docs/fr/mcp.md +173 -0
  55. package/dist/content/docs/fr/package.md +139 -0
  56. package/dist/content/docs/fr/publish-a-widget.md +101 -0
  57. package/dist/content/docs/fr/publish-keys.md +97 -0
  58. package/dist/content/docs/fr/publishing.md +177 -0
  59. package/dist/content/docs/fr/reference.md +59 -0
  60. package/dist/content/docs/fr/result-shapes.md +333 -0
  61. package/dist/content/docs/fr/sdk.md +301 -0
  62. package/dist/content/docs/fr/security.md +129 -0
  63. package/dist/content/docs/fr/service-reference.md +346 -0
  64. package/dist/content/docs/fr/services.md +540 -0
  65. package/dist/content/docs/fr/style-properties.md +272 -0
  66. package/dist/content/docs/fr/style.md +281 -0
  67. package/dist/content/docs/fr/testing.md +417 -0
  68. package/dist/content/docs/fr/verified-domain.md +49 -0
  69. package/dist/content/docs/fr/view.md +352 -0
  70. package/dist/content/docs/fr/widget-listing.md +69 -0
  71. package/dist/content/docs/fr/widget-review.md +59 -0
  72. package/dist/content/docs/fr/widget-statistics.md +141 -0
  73. package/dist/content/docs/fr/widgets.md +81 -0
  74. package/dist/content/examples/clock/LICENSE +21 -0
  75. package/dist/content/examples/clock/README.md +75 -0
  76. package/dist/content/examples/clock/listing.json +19 -0
  77. package/dist/content/examples/clock/locales/en.json +4 -0
  78. package/dist/content/examples/clock/locales/fr.json +4 -0
  79. package/dist/content/examples/clock/logic.ts +85 -0
  80. package/dist/content/examples/clock/manifest.json +44 -0
  81. package/dist/content/examples/clock/package.json +16 -0
  82. package/dist/content/examples/clock/style.ocss +26 -0
  83. package/dist/content/examples/clock/tests/hidden.scenario.json +68 -0
  84. package/dist/content/examples/clock/tests/load-logic.mjs +22 -0
  85. package/dist/content/examples/clock/tests/logic.test.mjs +89 -0
  86. package/dist/content/examples/clock/tests/options.scenario.json +108 -0
  87. package/dist/content/examples/clock/tests/preview.scenario.json +25 -0
  88. package/dist/content/examples/clock/tests/render.scenario.json +94 -0
  89. package/dist/content/examples/clock/tests/summer-time.scenario.json +74 -0
  90. package/dist/content/examples/clock/tests/ticks.scenario.json +120 -0
  91. package/dist/content/examples/clock/tsconfig.json +16 -0
  92. package/dist/content/examples/clock/view.ocml +8 -0
  93. package/dist/content/examples/countdown/LICENSE +20 -0
  94. package/dist/content/examples/countdown/listing.json +10 -0
  95. package/dist/content/examples/countdown/locales/en.json +15 -0
  96. package/dist/content/examples/countdown/locales/fr.json +15 -0
  97. package/dist/content/examples/countdown/logic.ts +179 -0
  98. package/dist/content/examples/countdown/manifest.json +34 -0
  99. package/dist/content/examples/countdown/package.json +15 -0
  100. package/dist/content/examples/countdown/style.ocss +94 -0
  101. package/dist/content/examples/countdown/tsconfig.json +16 -0
  102. package/dist/content/examples/countdown/view.ocml +42 -0
  103. package/dist/content/examples/fps/LICENSE +21 -0
  104. package/dist/content/examples/fps/README.md +64 -0
  105. package/dist/content/examples/fps/listing.json +19 -0
  106. package/dist/content/examples/fps/locales/en.json +11 -0
  107. package/dist/content/examples/fps/locales/fr.json +11 -0
  108. package/dist/content/examples/fps/logic.ts +64 -0
  109. package/dist/content/examples/fps/manifest.json +30 -0
  110. package/dist/content/examples/fps/package.json +16 -0
  111. package/dist/content/examples/fps/style.ocss +31 -0
  112. package/dist/content/examples/fps/submission.json +8 -0
  113. package/dist/content/examples/fps/tests/label.scenario.json +63 -0
  114. package/dist/content/examples/fps/tests/load-logic.mjs +22 -0
  115. package/dist/content/examples/fps/tests/logic.test.mjs +60 -0
  116. package/dist/content/examples/fps/tests/preview.scenario.json +29 -0
  117. package/dist/content/examples/fps/tests/refused.scenario.json +20 -0
  118. package/dist/content/examples/fps/tests/render.scenario.json +96 -0
  119. package/dist/content/examples/fps/tests/stale.scenario.json +91 -0
  120. package/dist/content/examples/fps/tests/unavailable.scenario.json +111 -0
  121. package/dist/content/examples/fps/tsconfig.json +16 -0
  122. package/dist/content/examples/fps/view.ocml +11 -0
  123. package/dist/content/examples/media/LICENSE +21 -0
  124. package/dist/content/examples/media/README.md +147 -0
  125. package/dist/content/examples/media/listing.json +19 -0
  126. package/dist/content/examples/media/locales/en.json +11 -0
  127. package/dist/content/examples/media/locales/fr.json +11 -0
  128. package/dist/content/examples/media/logic.ts +191 -0
  129. package/dist/content/examples/media/manifest.json +35 -0
  130. package/dist/content/examples/media/package.json +16 -0
  131. package/dist/content/examples/media/style.ocss +148 -0
  132. package/dist/content/examples/media/submission.json +12 -0
  133. package/dist/content/examples/media/tests/covers.scenario.json +144 -0
  134. package/dist/content/examples/media/tests/gesture.scenario.json +173 -0
  135. package/dist/content/examples/media/tests/load-logic.mjs +22 -0
  136. package/dist/content/examples/media/tests/logic.test.mjs +176 -0
  137. package/dist/content/examples/media/tests/marquee.scenario.json +127 -0
  138. package/dist/content/examples/media/tests/preview.scenario.json +52 -0
  139. package/dist/content/examples/media/tests/read-only.scenario.json +53 -0
  140. package/dist/content/examples/media/tests/refused.scenario.json +22 -0
  141. package/dist/content/examples/media/tests/refused.test.mjs +31 -0
  142. package/dist/content/examples/media/tests/render.scenario.json +136 -0
  143. package/dist/content/examples/media/tests/states.scenario.json +257 -0
  144. package/dist/content/examples/media/tests/unavailable.scenario.json +120 -0
  145. package/dist/content/examples/media/tsconfig.json +16 -0
  146. package/dist/content/examples/media/view.ocml +41 -0
  147. package/dist/content/examples/notes/LICENSE +21 -0
  148. package/dist/content/examples/notes/README.md +219 -0
  149. package/dist/content/examples/notes/listing.json +19 -0
  150. package/dist/content/examples/notes/locales/en.json +25 -0
  151. package/dist/content/examples/notes/locales/fr.json +25 -0
  152. package/dist/content/examples/notes/logic.ts +799 -0
  153. package/dist/content/examples/notes/manifest.json +40 -0
  154. package/dist/content/examples/notes/package.json +16 -0
  155. package/dist/content/examples/notes/style.ocss +469 -0
  156. package/dist/content/examples/notes/submission.json +12 -0
  157. package/dist/content/examples/notes/tests/checks.scenario.json +237 -0
  158. package/dist/content/examples/notes/tests/create.scenario.json +260 -0
  159. package/dist/content/examples/notes/tests/delete.scenario.json +342 -0
  160. package/dist/content/examples/notes/tests/drafts.scenario.json +714 -0
  161. package/dist/content/examples/notes/tests/editor.scenario.json +232 -0
  162. package/dist/content/examples/notes/tests/frame.scenario.json +93 -0
  163. package/dist/content/examples/notes/tests/interactive.scenario.json +344 -0
  164. package/dist/content/examples/notes/tests/limits.scenario.json +1351 -0
  165. package/dist/content/examples/notes/tests/load-logic.mjs +22 -0
  166. package/dist/content/examples/notes/tests/logic.test.mjs +514 -0
  167. package/dist/content/examples/notes/tests/preview.scenario.json +99 -0
  168. package/dist/content/examples/notes/tests/read-only.scenario.json +105 -0
  169. package/dist/content/examples/notes/tests/refused.scenario.json +33 -0
  170. package/dist/content/examples/notes/tests/save.scenario.json +378 -0
  171. package/dist/content/examples/notes/tests/states.scenario.json +640 -0
  172. package/dist/content/examples/notes/tests/typing.scenario.json +562 -0
  173. package/dist/content/examples/notes/tests/unavailable.scenario.json +246 -0
  174. package/dist/content/examples/notes/tsconfig.json +16 -0
  175. package/dist/content/examples/notes/view.ocml +154 -0
  176. package/dist/content/examples/performance/LICENSE +21 -0
  177. package/dist/content/examples/performance/README.md +134 -0
  178. package/dist/content/examples/performance/listing.json +19 -0
  179. package/dist/content/examples/performance/locales/en.json +20 -0
  180. package/dist/content/examples/performance/locales/fr.json +20 -0
  181. package/dist/content/examples/performance/logic.ts +210 -0
  182. package/dist/content/examples/performance/manifest.json +83 -0
  183. package/dist/content/examples/performance/package.json +16 -0
  184. package/dist/content/examples/performance/style.ocss +75 -0
  185. package/dist/content/examples/performance/submission.json +12 -0
  186. package/dist/content/examples/performance/tests/fahrenheit.scenario.json +110 -0
  187. package/dist/content/examples/performance/tests/horizontal.scenario.json +96 -0
  188. package/dist/content/examples/performance/tests/load-logic.mjs +22 -0
  189. package/dist/content/examples/performance/tests/logic.test.mjs +226 -0
  190. package/dist/content/examples/performance/tests/menu.scenario.json +170 -0
  191. package/dist/content/examples/performance/tests/no-fps-source.scenario.json +47 -0
  192. package/dist/content/examples/performance/tests/preview.scenario.json +45 -0
  193. package/dist/content/examples/performance/tests/refused.scenario.json +20 -0
  194. package/dist/content/examples/performance/tests/refused.test.mjs +19 -0
  195. package/dist/content/examples/performance/tests/region.scenario.json +89 -0
  196. package/dist/content/examples/performance/tests/render.scenario.json +112 -0
  197. package/dist/content/examples/performance/tests/sources.scenario.json +151 -0
  198. package/dist/content/examples/performance/tests/stale.scenario.json +111 -0
  199. package/dist/content/examples/performance/tests/telemetry-only.scenario.json +44 -0
  200. package/dist/content/examples/performance/tests/thresholds.scenario.json +147 -0
  201. package/dist/content/examples/performance/tests/waiting.scenario.json +105 -0
  202. package/dist/content/examples/performance/tsconfig.json +16 -0
  203. package/dist/content/examples/performance/view.ocml +18 -0
  204. package/dist/content/examples/playervox-journal/LICENSE +21 -0
  205. package/dist/content/examples/playervox-journal/README.md +150 -0
  206. package/dist/content/examples/playervox-journal/listing.json +19 -0
  207. package/dist/content/examples/playervox-journal/locales/en.json +25 -0
  208. package/dist/content/examples/playervox-journal/locales/fr.json +25 -0
  209. package/dist/content/examples/playervox-journal/logic.ts +556 -0
  210. package/dist/content/examples/playervox-journal/manifest.json +19 -0
  211. package/dist/content/examples/playervox-journal/package.json +16 -0
  212. package/dist/content/examples/playervox-journal/style.ocss +142 -0
  213. package/dist/content/examples/playervox-journal/submission.json +12 -0
  214. package/dist/content/examples/playervox-journal/tests/changes.scenario.json +482 -0
  215. package/dist/content/examples/playervox-journal/tests/delete.scenario.json +432 -0
  216. package/dist/content/examples/playervox-journal/tests/frame.scenario.json +169 -0
  217. package/dist/content/examples/playervox-journal/tests/load-logic.mjs +22 -0
  218. package/dist/content/examples/playervox-journal/tests/logic.test.mjs +349 -0
  219. package/dist/content/examples/playervox-journal/tests/paging.scenario.json +428 -0
  220. package/dist/content/examples/playervox-journal/tests/preview.scenario.json +184 -0
  221. package/dist/content/examples/playervox-journal/tests/read-only.scenario.json +157 -0
  222. package/dist/content/examples/playervox-journal/tests/refused.scenario.json +39 -0
  223. package/dist/content/examples/playervox-journal/tests/scale.scenario.json +286 -0
  224. package/dist/content/examples/playervox-journal/tests/signed-out.scenario.json +134 -0
  225. package/dist/content/examples/playervox-journal/tests/states.scenario.json +741 -0
  226. package/dist/content/examples/playervox-journal/tests/unavailable.scenario.json +183 -0
  227. package/dist/content/examples/playervox-journal/tsconfig.json +16 -0
  228. package/dist/content/examples/playervox-journal/view.ocml +52 -0
  229. package/dist/content/examples/playervox-rating/LICENSE +21 -0
  230. package/dist/content/examples/playervox-rating/README.md +166 -0
  231. package/dist/content/examples/playervox-rating/listing.json +19 -0
  232. package/dist/content/examples/playervox-rating/locales/en.json +35 -0
  233. package/dist/content/examples/playervox-rating/locales/fr.json +35 -0
  234. package/dist/content/examples/playervox-rating/logic.ts +581 -0
  235. package/dist/content/examples/playervox-rating/manifest.json +19 -0
  236. package/dist/content/examples/playervox-rating/package.json +16 -0
  237. package/dist/content/examples/playervox-rating/style.ocss +333 -0
  238. package/dist/content/examples/playervox-rating/submission.json +12 -0
  239. package/dist/content/examples/playervox-rating/tests/account.scenario.json +125 -0
  240. package/dist/content/examples/playervox-rating/tests/bounds.scenario.json +73 -0
  241. package/dist/content/examples/playervox-rating/tests/draft.scenario.json +199 -0
  242. package/dist/content/examples/playervox-rating/tests/form.scenario.json +142 -0
  243. package/dist/content/examples/playervox-rating/tests/load-logic.mjs +22 -0
  244. package/dist/content/examples/playervox-rating/tests/logic.test.mjs +346 -0
  245. package/dist/content/examples/playervox-rating/tests/offline.scenario.json +142 -0
  246. package/dist/content/examples/playervox-rating/tests/preview.scenario.json +44 -0
  247. package/dist/content/examples/playervox-rating/tests/publish-keyboard.scenario.json +221 -0
  248. package/dist/content/examples/playervox-rating/tests/publish-pointer.scenario.json +314 -0
  249. package/dist/content/examples/playervox-rating/tests/read-only.scenario.json +70 -0
  250. package/dist/content/examples/playervox-rating/tests/refused.scenario.json +45 -0
  251. package/dist/content/examples/playervox-rating/tests/states.scenario.json +362 -0
  252. package/dist/content/examples/playervox-rating/tsconfig.json +16 -0
  253. package/dist/content/examples/playervox-rating/view.ocml +62 -0
  254. package/dist/content/examples/playervox-reviews/LICENSE +21 -0
  255. package/dist/content/examples/playervox-reviews/README.md +194 -0
  256. package/dist/content/examples/playervox-reviews/listing.json +19 -0
  257. package/dist/content/examples/playervox-reviews/locales/en.json +32 -0
  258. package/dist/content/examples/playervox-reviews/locales/fr.json +32 -0
  259. package/dist/content/examples/playervox-reviews/logic.ts +822 -0
  260. package/dist/content/examples/playervox-reviews/manifest.json +30 -0
  261. package/dist/content/examples/playervox-reviews/package.json +16 -0
  262. package/dist/content/examples/playervox-reviews/style.ocss +260 -0
  263. package/dist/content/examples/playervox-reviews/submission.json +8 -0
  264. package/dist/content/examples/playervox-reviews/tests/account.scenario.json +249 -0
  265. package/dist/content/examples/playervox-reviews/tests/bounds.scenario.json +336 -0
  266. package/dist/content/examples/playervox-reviews/tests/changes.scenario.json +515 -0
  267. package/dist/content/examples/playervox-reviews/tests/filter.scenario.json +400 -0
  268. package/dist/content/examples/playervox-reviews/tests/frame.scenario.json +185 -0
  269. package/dist/content/examples/playervox-reviews/tests/keyboard.scenario.json +188 -0
  270. package/dist/content/examples/playervox-reviews/tests/load-logic.mjs +22 -0
  271. package/dist/content/examples/playervox-reviews/tests/logic.test.mjs +559 -0
  272. package/dist/content/examples/playervox-reviews/tests/offline-start.scenario.json +152 -0
  273. package/dist/content/examples/playervox-reviews/tests/offline.scenario.json +311 -0
  274. package/dist/content/examples/playervox-reviews/tests/paging.scenario.json +497 -0
  275. package/dist/content/examples/playervox-reviews/tests/preview.scenario.json +286 -0
  276. package/dist/content/examples/playervox-reviews/tests/reading.scenario.json +591 -0
  277. package/dist/content/examples/playervox-reviews/tests/refused.scenario.json +54 -0
  278. package/dist/content/examples/playervox-reviews/tests/scale.scenario.json +303 -0
  279. package/dist/content/examples/playervox-reviews/tests/states.scenario.json +700 -0
  280. package/dist/content/examples/playervox-reviews/tests/unavailable.scenario.json +192 -0
  281. package/dist/content/examples/playervox-reviews/tsconfig.json +16 -0
  282. package/dist/content/examples/playervox-reviews/view.ocml +110 -0
  283. package/dist/content/examples/playervox-score/LICENSE +21 -0
  284. package/dist/content/examples/playervox-score/README.md +131 -0
  285. package/dist/content/examples/playervox-score/listing.json +19 -0
  286. package/dist/content/examples/playervox-score/locales/en.json +23 -0
  287. package/dist/content/examples/playervox-score/locales/fr.json +23 -0
  288. package/dist/content/examples/playervox-score/logic.ts +430 -0
  289. package/dist/content/examples/playervox-score/manifest.json +47 -0
  290. package/dist/content/examples/playervox-score/package.json +16 -0
  291. package/dist/content/examples/playervox-score/style.ocss +247 -0
  292. package/dist/content/examples/playervox-score/submission.json +8 -0
  293. package/dist/content/examples/playervox-score/tests/grades.scenario.json +279 -0
  294. package/dist/content/examples/playervox-score/tests/load-logic.mjs +22 -0
  295. package/dist/content/examples/playervox-score/tests/logic.test.mjs +229 -0
  296. package/dist/content/examples/playervox-score/tests/options.scenario.json +302 -0
  297. package/dist/content/examples/playervox-score/tests/preview.scenario.json +68 -0
  298. package/dist/content/examples/playervox-score/tests/pulse.scenario.json +157 -0
  299. package/dist/content/examples/playervox-score/tests/refused.scenario.json +21 -0
  300. package/dist/content/examples/playervox-score/tests/signed-out.scenario.json +46 -0
  301. package/dist/content/examples/playervox-score/tests/states.scenario.json +450 -0
  302. package/dist/content/examples/playervox-score/tests/unavailable.scenario.json +84 -0
  303. package/dist/content/examples/playervox-score/tsconfig.json +16 -0
  304. package/dist/content/examples/playervox-score/view.ocml +51 -0
  305. package/dist/content/examples/session/LICENSE +21 -0
  306. package/dist/content/examples/session/README.md +57 -0
  307. package/dist/content/examples/session/listing.json +19 -0
  308. package/dist/content/examples/session/locales/en.json +3 -0
  309. package/dist/content/examples/session/locales/fr.json +3 -0
  310. package/dist/content/examples/session/logic.ts +26 -0
  311. package/dist/content/examples/session/manifest.json +19 -0
  312. package/dist/content/examples/session/package.json +16 -0
  313. package/dist/content/examples/session/style.ocss +16 -0
  314. package/dist/content/examples/session/submission.json +8 -0
  315. package/dist/content/examples/session/tests/hidden.scenario.json +45 -0
  316. package/dist/content/examples/session/tests/load-logic.mjs +22 -0
  317. package/dist/content/examples/session/tests/logic.test.mjs +37 -0
  318. package/dist/content/examples/session/tests/preview.scenario.json +28 -0
  319. package/dist/content/examples/session/tests/refused.scenario.json +20 -0
  320. package/dist/content/examples/session/tests/refused.test.mjs +16 -0
  321. package/dist/content/examples/session/tests/render.scenario.json +95 -0
  322. package/dist/content/examples/session/tests/ticks.scenario.json +139 -0
  323. package/dist/content/examples/session/tests/unknown.scenario.json +37 -0
  324. package/dist/content/examples/session/tsconfig.json +16 -0
  325. package/dist/content/examples/session/view.ocml +11 -0
  326. package/dist/content/examples/stopwatch/LICENSE +21 -0
  327. package/dist/content/examples/stopwatch/README.md +99 -0
  328. package/dist/content/examples/stopwatch/listing.json +19 -0
  329. package/dist/content/examples/stopwatch/locales/en.json +8 -0
  330. package/dist/content/examples/stopwatch/locales/fr.json +8 -0
  331. package/dist/content/examples/stopwatch/logic.ts +93 -0
  332. package/dist/content/examples/stopwatch/manifest.json +19 -0
  333. package/dist/content/examples/stopwatch/package.json +16 -0
  334. package/dist/content/examples/stopwatch/style.ocss +54 -0
  335. package/dist/content/examples/stopwatch/submission.json +12 -0
  336. package/dist/content/examples/stopwatch/tests/errors.scenario.json +121 -0
  337. package/dist/content/examples/stopwatch/tests/gesture.scenario.json +154 -0
  338. package/dist/content/examples/stopwatch/tests/hidden.scenario.json +57 -0
  339. package/dist/content/examples/stopwatch/tests/hundredths.scenario.json +173 -0
  340. package/dist/content/examples/stopwatch/tests/load-logic.mjs +22 -0
  341. package/dist/content/examples/stopwatch/tests/logic.test.mjs +99 -0
  342. package/dist/content/examples/stopwatch/tests/preview.scenario.json +36 -0
  343. package/dist/content/examples/stopwatch/tests/read-only.scenario.json +42 -0
  344. package/dist/content/examples/stopwatch/tests/read-only.test.mjs +18 -0
  345. package/dist/content/examples/stopwatch/tests/refused.scenario.json +22 -0
  346. package/dist/content/examples/stopwatch/tests/refused.test.mjs +18 -0
  347. package/dist/content/examples/stopwatch/tests/render.scenario.json +105 -0
  348. package/dist/content/examples/stopwatch/tests/states.scenario.json +246 -0
  349. package/dist/content/examples/stopwatch/tests/unknown.scenario.json +40 -0
  350. package/dist/content/examples/stopwatch/tsconfig.json +16 -0
  351. package/dist/content/examples/stopwatch/view.ocml +29 -0
  352. package/dist/content/examples/twitch-chat/LICENSE +21 -0
  353. package/dist/content/examples/twitch-chat/README.md +283 -0
  354. package/dist/content/examples/twitch-chat/listing.json +19 -0
  355. package/dist/content/examples/twitch-chat/locales/en.json +52 -0
  356. package/dist/content/examples/twitch-chat/locales/fr.json +52 -0
  357. package/dist/content/examples/twitch-chat/logic.ts +887 -0
  358. package/dist/content/examples/twitch-chat/manifest.json +33 -0
  359. package/dist/content/examples/twitch-chat/package.json +16 -0
  360. package/dist/content/examples/twitch-chat/style.ocss +544 -0
  361. package/dist/content/examples/twitch-chat/submission.json +12 -0
  362. package/dist/content/examples/twitch-chat/tests/account.scenario.json +325 -0
  363. package/dist/content/examples/twitch-chat/tests/burst.scenario.json +1866 -0
  364. package/dist/content/examples/twitch-chat/tests/channel-refused.scenario.json +372 -0
  365. package/dist/content/examples/twitch-chat/tests/channel.scenario.json +480 -0
  366. package/dist/content/examples/twitch-chat/tests/draft.scenario.json +279 -0
  367. package/dist/content/examples/twitch-chat/tests/fade.scenario.json +269 -0
  368. package/dist/content/examples/twitch-chat/tests/failures.scenario.json +420 -0
  369. package/dist/content/examples/twitch-chat/tests/favorites.scenario.json +376 -0
  370. package/dist/content/examples/twitch-chat/tests/frame.scenario.json +152 -0
  371. package/dist/content/examples/twitch-chat/tests/lifetime.scenario.json +186 -0
  372. package/dist/content/examples/twitch-chat/tests/load-logic.mjs +22 -0
  373. package/dist/content/examples/twitch-chat/tests/logic.test.mjs +1053 -0
  374. package/dist/content/examples/twitch-chat/tests/passive.scenario.json +536 -0
  375. package/dist/content/examples/twitch-chat/tests/preview.scenario.json +147 -0
  376. package/dist/content/examples/twitch-chat/tests/read-only.scenario.json +202 -0
  377. package/dist/content/examples/twitch-chat/tests/read-only.test.mjs +63 -0
  378. package/dist/content/examples/twitch-chat/tests/refused.scenario.json +65 -0
  379. package/dist/content/examples/twitch-chat/tests/refused.test.mjs +43 -0
  380. package/dist/content/examples/twitch-chat/tests/render.scenario.json +347 -0
  381. package/dist/content/examples/twitch-chat/tests/reply.scenario.json +384 -0
  382. package/dist/content/examples/twitch-chat/tests/send-refused.scenario.json +383 -0
  383. package/dist/content/examples/twitch-chat/tests/send.scenario.json +300 -0
  384. package/dist/content/examples/twitch-chat/tests/states.scenario.json +455 -0
  385. package/dist/content/examples/twitch-chat/tests/unavailable.scenario.json +256 -0
  386. package/dist/content/examples/twitch-chat/tests/unread.scenario.json +997 -0
  387. package/dist/content/examples/twitch-chat/tsconfig.json +16 -0
  388. package/dist/content/examples/twitch-chat/view.ocml +141 -0
  389. package/dist/content/examples/warframe-market/LICENSE +21 -0
  390. package/dist/content/examples/warframe-market/README.md +176 -0
  391. package/dist/content/examples/warframe-market/listing.json +19 -0
  392. package/dist/content/examples/warframe-market/locales/en.json +44 -0
  393. package/dist/content/examples/warframe-market/locales/fr.json +44 -0
  394. package/dist/content/examples/warframe-market/logic.ts +1265 -0
  395. package/dist/content/examples/warframe-market/manifest.json +92 -0
  396. package/dist/content/examples/warframe-market/package.json +16 -0
  397. package/dist/content/examples/warframe-market/style.ocss +422 -0
  398. package/dist/content/examples/warframe-market/submission.json +24 -0
  399. package/dist/content/examples/warframe-market/tests/bounds.scenario.json +60 -0
  400. package/dist/content/examples/warframe-market/tests/cached.scenario.json +70 -0
  401. package/dist/content/examples/warframe-market/tests/detail.scenario.json +251 -0
  402. package/dist/content/examples/warframe-market/tests/errors.scenario.json +105 -0
  403. package/dist/content/examples/warframe-market/tests/fixtures.json +295 -0
  404. package/dist/content/examples/warframe-market/tests/load-logic.mjs +22 -0
  405. package/dist/content/examples/warframe-market/tests/logic.test.mjs +505 -0
  406. package/dist/content/examples/warframe-market/tests/no-clipboard.scenario.json +104 -0
  407. package/dist/content/examples/warframe-market/tests/passive.scenario.json +87 -0
  408. package/dist/content/examples/warframe-market/tests/preview.scenario.json +146 -0
  409. package/dist/content/examples/warframe-market/tests/refresh.scenario.json +56 -0
  410. package/dist/content/examples/warframe-market/tests/refused.scenario.json +74 -0
  411. package/dist/content/examples/warframe-market/tests/render.scenario.json +210 -0
  412. package/dist/content/examples/warframe-market/tests/search.scenario.json +189 -0
  413. package/dist/content/examples/warframe-market/tests/unavailable.scenario.json +54 -0
  414. package/dist/content/examples/warframe-market/tsconfig.json +16 -0
  415. package/dist/content/examples/warframe-market/view.ocml +116 -0
  416. package/dist/content/examples/weather/LICENSE +20 -0
  417. package/dist/content/examples/weather/listing.json +10 -0
  418. package/dist/content/examples/weather/locales/en.json +9 -0
  419. package/dist/content/examples/weather/locales/fr.json +9 -0
  420. package/dist/content/examples/weather/logic.ts +62 -0
  421. package/dist/content/examples/weather/manifest.json +51 -0
  422. package/dist/content/examples/weather/package.json +15 -0
  423. package/dist/content/examples/weather/style.ocss +29 -0
  424. package/dist/content/examples/weather/submission.json +17 -0
  425. package/dist/content/examples/weather/tsconfig.json +16 -0
  426. package/dist/content/examples/weather/view.ocml +12 -0
  427. package/dist/content/index.json +3705 -0
  428. package/dist/content/reference/errors.json +1924 -0
  429. package/dist/content/reference/limits.json +1154 -0
  430. package/dist/content/reference/manifest.md +223 -0
  431. package/dist/content/reference/permissions.json +413 -0
  432. package/dist/content/templates/blank/locales/en.json +3 -0
  433. package/dist/content/templates/blank/locales/fr.json +3 -0
  434. package/dist/content/templates/blank/logic.ts +7 -0
  435. package/dist/content/templates/blank/manifest.json +16 -0
  436. package/dist/content/templates/blank/style.ocss +10 -0
  437. package/dist/content/templates/blank/tests/example.scenario.json +10 -0
  438. package/dist/content/templates/blank/view.ocml +6 -0
  439. package/dist/content/templates/chart/locales/en.json +3 -0
  440. package/dist/content/templates/chart/locales/fr.json +3 -0
  441. package/dist/content/templates/chart/logic.ts +27 -0
  442. package/dist/content/templates/chart/manifest.json +16 -0
  443. package/dist/content/templates/chart/style.ocss +27 -0
  444. package/dist/content/templates/chart/tests/example.scenario.json +10 -0
  445. package/dist/content/templates/chart/view.ocml +10 -0
  446. package/dist/content/templates/counter/locales/en.json +4 -0
  447. package/dist/content/templates/counter/locales/fr.json +4 -0
  448. package/dist/content/templates/counter/logic.ts +20 -0
  449. package/dist/content/templates/counter/manifest.json +16 -0
  450. package/dist/content/templates/counter/style.ocss +26 -0
  451. package/dist/content/templates/counter/tests/example.scenario.json +11 -0
  452. package/dist/content/templates/counter/view.ocml +13 -0
  453. package/dist/content/templates/list/locales/en.json +8 -0
  454. package/dist/content/templates/list/locales/fr.json +8 -0
  455. package/dist/content/templates/list/logic.ts +35 -0
  456. package/dist/content/templates/list/manifest.json +16 -0
  457. package/dist/content/templates/list/style.ocss +42 -0
  458. package/dist/content/templates/list/tests/example.scenario.json +10 -0
  459. package/dist/content/templates/list/view.ocml +17 -0
  460. package/dist/content/templates/shared/LICENSE +20 -0
  461. package/dist/content/templates/shared/package.json +14 -0
  462. package/dist/content/templates/shared/tsconfig.json +16 -0
  463. package/dist/content.js +68 -0
  464. package/dist/env.js +156 -0
  465. package/dist/fingerprint.js +32 -0
  466. package/dist/hidden.js +47 -0
  467. package/dist/ids.js +27 -0
  468. package/dist/index.js +82 -0
  469. package/dist/knowledge.js +222 -0
  470. package/dist/npm.js +149 -0
  471. package/dist/prompts.js +47 -0
  472. package/dist/resources.js +82 -0
  473. package/dist/run.js +120 -0
  474. package/dist/server.js +43 -0
  475. package/dist/session.js +205 -0
  476. package/dist/sources.js +218 -0
  477. package/dist/text.js +80 -0
  478. package/dist/texts.js +44 -0
  479. package/dist/tools/audit.js +105 -0
  480. package/dist/tools/build.js +453 -0
  481. package/dist/tools/common.js +122 -0
  482. package/dist/tools/docs.js +196 -0
  483. package/dist/tools/preview.js +87 -0
  484. package/dist/tools/project.js +183 -0
  485. package/dist/tools/setup.js +146 -0
  486. package/dist/tools/submission.js +369 -0
  487. package/dist/version.js +3 -0
  488. package/npm-shrinkwrap.json +402 -0
  489. package/package.json +50 -4
@@ -0,0 +1,115 @@
1
+ # Security
2
+
3
+ PlayerVox OverCrow treats every widget as untrusted code, built-ins
4
+ included: the same package checks, the same sandbox, the same permissions
5
+ and the same consent apply to a PlayerVox widget and to yours. This page
6
+ describes what that means for a widget author.
7
+
8
+ ## The sandbox
9
+
10
+ Each widget runs behind two barriers.
11
+
12
+ 1. **The VM.** Your `logic.js` runs in its own QuickJS virtual machine with
13
+ a heap ceiling, a time budget per turn, a bounded stack and bounded
14
+ queues. There is no `eval`, no `Function` constructor, no module loader,
15
+ no `WebAssembly` and no shared memory; the only global besides
16
+ ECMAScript is the frozen SDK. Local time is UTC: the SDK applies the
17
+ user's offset for you.
18
+ 2. **The process.** Each VM runs in its own operating-system process that
19
+ needs no display, GPU, network or files, so its sandbox takes all of them
20
+ away. On Linux, Bubblewrap namespaces, a seccomp allowlist that kills the
21
+ process on any attempt to open a file, a socket or another process, and
22
+ a cgroup per widget. On Windows, a Less Privileged AppContainer without
23
+ capabilities, a Job Object per widget, and process mitigations that
24
+ forbid dynamic code and the window system.
25
+
26
+ OverCrow draws everything itself: the VM sends a description of the view,
27
+ never pixels, and never runs code in OverCrow's process. Hover, focus,
28
+ pressed states and transitions are resolved by OverCrow, so a widget does
29
+ not observe pointer motion it has not asked for through an event.
30
+
31
+ Going over a budget ends only that widget. OverCrow shows a fixed error in
32
+ its frame and restarts it after 1, 5 and 15 seconds, at most three times;
33
+ a package or protocol error waits for the user to enable it again. The
34
+ numbers are in [limits](limits.md#logic).
35
+
36
+ ## Permissions and consent
37
+
38
+ A widget gets nothing it has not declared in `manifest.json`, and a
39
+ declaration grants nothing by itself. When the widget is installed, the
40
+ Control Center proposes each permission checked, and the user may uncheck
41
+ any. Later, the user allows or takes back each permission in the Control
42
+ Center; taking one back restarts the widget without it.
43
+ OverCrow checks the permission again at every call of a service.
44
+
45
+ Four permissions open general services: `network` (exact HTTPS routes,
46
+ through OverCrow's broker), `storage` (a key-value store for this widget
47
+ only), `clipboardWrite` (writing text, during a user action) and
48
+ `gameEvents` (named game events).
49
+
50
+ Capabilities give access to data and actions of OverCrow and of the user's
51
+ accounts. A **sensitive** capability reveals personal data or the game
52
+ being played: a widget that declares one cannot also declare `network` or
53
+ `clipboardWrite`, and its storage lasts only as long as its process, so the
54
+ data cannot leave the machine through the widget.
55
+
56
+ Account connections (PlayerVox, Twitch) belong to OverCrow: sign-in, codes
57
+ and tokens are drawn and kept by OverCrow, and a widget receives only the
58
+ data its capability describes.
59
+
60
+ Each permission, each capability and the services it opens are described
61
+ in [services and permissions](services.md). Declare the least you need:
62
+ reviewers read every permission and route, and users see them before they
63
+ consent. Widgets tagged `built-in` in the signed catalog (PlayerVox widgets
64
+ only) start with their declared permissions granted; an update that asks
65
+ for more needs the user's consent, built-ins included.
66
+
67
+ ## User actions
68
+
69
+ Services that change something for the user can be called only while the
70
+ logic handles a real action of the user in the widget: a click, a key, an
71
+ edit, a submitted form. A call from a timer, from a service answer or from
72
+ a row of the options menu is refused with `gesture_required`. Widgets
73
+ receive input only in OverCrow's Interactive mode; in Passive mode they are
74
+ click-through. Deleting a note or a journal session also asks the user to
75
+ confirm in a dialog drawn by OverCrow. See
76
+ [calls that need a user action](services.md#calls-that-need-a-user-action).
77
+
78
+ What the user writes to notes, ratings and chat never passes through your
79
+ logic: a `form` with an `intent` sends the values of its own text fields and
80
+ sliders, which OverCrow fills, edits and submits itself. Your logic can read
81
+ them, not set them. See
82
+ [forms that write user data](forms.md#forms-that-write-user-data).
83
+
84
+ ## What a widget cannot do
85
+
86
+ - Read or write files, open sockets, reach the local network or any address
87
+ its manifest does not declare.
88
+ - Start processes, load native code, compile code at runtime or fetch code:
89
+ the only code is the reviewed `logic.js` of the package.
90
+ - See other widgets, their state, storage or permissions, or the game's
91
+ memory, window or input. OverCrow never injects into the game.
92
+ - Draw outside its frame, cover or imitate OverCrow's frame, menus or
93
+ confirmations.
94
+ - Read account tokens, cookies or credentials.
95
+ - Read the clipboard.
96
+ - Write to logs in production: `log.*` output appears only in a local
97
+ development session.
98
+ - Grant itself a permission, or use a menu row as a user action.
99
+
100
+ ## What OverCrow verifies
101
+
102
+ Every package is checked when it is admitted to the catalog and again each
103
+ time OverCrow starts it: the signed catalog, the ledger of its files and
104
+ the compiled view must match, or the widget does not start. See
105
+ [the package](package.md#how-overcrow-checks-a-package) and
106
+ [publishing and review](publishing.md).
107
+
108
+ A version of the catalog can be suspended or revoked after its
109
+ publication: OverCrow then stops the installed copy. See
110
+ [version statuses](publishing.md#version-statuses).
111
+
112
+ ## Reporting a vulnerability
113
+
114
+ Report vulnerabilities privately, as described in the repository's
115
+ [security policy](../../../SECURITY.md).
@@ -0,0 +1,344 @@
1
+ # Service reference
2
+
3
+ Every service that the logic of a PlayerVox OverCrow widget can call, with
4
+ what it requires, when it can be called, its parameters and its result.
5
+ [Services and permissions](services.md) explains how calls, subscriptions,
6
+ errors and user actions work; this page is the list.
7
+
8
+ <!-- source: widgets/stopwatch/logic.ts -->
9
+ ```ts
10
+ if (canRead) {
11
+ state.stopwatch = next;
12
+ }
13
+ },
14
+ () => {},
15
+ );
16
+ }
17
+ ```
18
+
19
+ In the SDK, a service `stopwatch.subscribe` is the function
20
+ `stopwatch.subscribe` of the `stopwatch` namespace. A call returns a
21
+ promise of its result; a subscription takes a listener that receives each
22
+ update.
23
+
24
+ ## How to read a service
25
+
26
+ - **Kind**: a *call* is answered once; a *subscription* delivers a value at
27
+ once, then each new value.
28
+ - **Requires**: the permission or the capability to declare in
29
+ [the manifest](manifest.md#permissions), which the user must grant.
30
+ - **When it can be called**: at any time, or only during a
31
+ [user action](services.md#calls-that-need-a-user-action).
32
+ - **Parameters**: the members of the object to pass; a `?` marks an
33
+ optional one. A type such as "text ≤ 128 bytes" gives a
34
+ [limit](limits.md).
35
+ - **Result**, or **Each update** for a subscription: what the service
36
+ answers, and the error codes that are specific to it. Every service can
37
+ also fail with the general [error codes](services.md#errors).
38
+ - **Shape**: the type of the result, described in
39
+ [result shapes](result-shapes.md).
40
+
41
+ ## Services
42
+
43
+ <!-- generated:services -->
44
+ ### `storage.get`
45
+
46
+ - **Kind**: call, answered once
47
+ - **Requires**: permission `storage`
48
+ - **When it can be called**: At any time
49
+ - **Parameters**: `key`: text ≤ 128 bytes
50
+ - **Result**: stored JSON value or `null`
51
+ - **Shape**: JSON
52
+
53
+ ### `storage.set`
54
+
55
+ - **Kind**: call, answered once
56
+ - **Requires**: permission `storage`
57
+ - **When it can be called**: At any time
58
+ - **Parameters**: `key`: text ≤ 128 bytes; `value`: JSON
59
+ - **Result**: `null`; `quota_exceeded` beyond 256 KiB
60
+ - **Shape**: `null`
61
+
62
+ ### `storage.remove`
63
+
64
+ - **Kind**: call, answered once
65
+ - **Requires**: permission `storage`
66
+ - **When it can be called**: At any time
67
+ - **Parameters**: `key`: text ≤ 128 bytes
68
+ - **Result**: `null`
69
+
70
+ ### `storage.keys`
71
+
72
+ - **Kind**: call, answered once
73
+ - **Requires**: permission `storage`
74
+ - **When it can be called**: At any time
75
+ - **Parameters**: none
76
+ - **Result**: list of keys
77
+ - **Shape**: list of text
78
+
79
+ ### `http.fetch`
80
+
81
+ - **Kind**: call, answered once
82
+ - **Requires**: permission `network`
83
+ - **When it can be called**: At any time
84
+ - **Parameters**: `url`: text ≤ 2 KiB; `method`: `GET` \| `POST` \| `PUT` \| `PATCH` \| `DELETE`; `contentType?`: `application/json` \| `text/plain`; `as`: `json` \| `text` \| `bytes` \| `image`
85
+ - **Result**: `{ status, contentType }` with the body, ≤ the rule's `maxResponseBytes` (1 MiB when absent), or `{ status, asset }` from a body ≤ 1 MiB
86
+ - **Shape**: [`HttpResponse`](result-shapes.md#httpresponse)
87
+
88
+ ### `clipboard.writeText`
89
+
90
+ - **Kind**: call, answered once
91
+ - **Requires**: permission `clipboardWrite`
92
+ - **When it can be called**: Only during a user action
93
+ - **Parameters**: `text`: text ≤ 16 KiB
94
+ - **Result**: `null`
95
+
96
+ ### `gameEvents.subscribe`
97
+
98
+ - **Kind**: subscription
99
+ - **Requires**: permission `gameEvents`
100
+ - **When it can be called**: At any time
101
+ - **Parameters**: none
102
+ - **Each update**: `{ event, at }` for each declared event
103
+ - **Shape**: [`GameEvent`](result-shapes.md#gameevent)
104
+
105
+ ### `session.subscribe`
106
+
107
+ - **Kind**: subscription
108
+ - **Requires**: capability `session.read`
109
+ - **When it can be called**: At any time
110
+ - **Parameters**: none
111
+ - **Each update**: `{ elapsedMs, at }` counted from the start of the game process, or `null` without an active game
112
+ - **Shape**: [`Session`](result-shapes.md#session) or `null`
113
+
114
+ ### `telemetry.subscribe`
115
+
116
+ - **Kind**: subscription
117
+ - **Requires**: capability `telemetry.read`
118
+ - **When it can be called**: At any time
119
+ - **Parameters**: none
120
+ - **Each update**: `{ cpu, ram, cpuTemperature, gpuTemperature, sources }`, or `null` without an active game: `cpu` is the game's share of the whole machine in % (0–100), `ram` its resident bytes, temperatures are °C or `null`, `sources` `{ cpuTemperature, gpuTemperature }` says whether the host has each sensor
121
+ - **Shape**: [`Telemetry`](result-shapes.md#telemetry) or `null`
122
+
123
+ ### `fps.subscribe`
124
+
125
+ - **Kind**: subscription
126
+ - **Requires**: capability `fps.read`
127
+ - **When it can be called**: At any time
128
+ - **Parameters**: none
129
+ - **Each update**: `{ fps, stale, status }`: `fps` a number or `null`; the host sets `stale` 3 s after the last sample; `status` is `ready`, `waiting`, `unsupported`, `permission_denied`, `ambiguous`, `events_lost` or `unavailable`
130
+ - **Shape**: [`Fps`](result-shapes.md#fps)
131
+
132
+ ### `media.subscribe`
133
+
134
+ - **Kind**: subscription
135
+ - **Requires**: capability `media.read`
136
+ - **When it can be called**: At any time
137
+ - **Parameters**: `cover?`: boolean
138
+ - **Each update**: `null` without a player, or `{ player, title, artists, playing, canPrevious, canPlayPause, canNext, cover }`: `player` an opaque ID, `artists` a list, `cover` an `asset:` handle of at most 512 px or `null`
139
+ - **Shape**: [`Media`](result-shapes.md#media) or `null`
140
+
141
+ ### `media.previous`
142
+
143
+ - **Kind**: call, answered once
144
+ - **Requires**: capability `media.control`
145
+ - **When it can be called**: Only during a user action
146
+ - **Parameters**: `player?`: text ≤ 128 bytes
147
+ - **Result**: `null`; `stale_context` when `player` is no longer current
148
+ - **Shape**: `null`
149
+
150
+ ### `media.playPause`
151
+
152
+ - **Kind**: call, answered once
153
+ - **Requires**: capability `media.control`
154
+ - **When it can be called**: Only during a user action
155
+ - **Parameters**: `player?`: text ≤ 128 bytes
156
+ - **Result**: `null`; `stale_context` when `player` is no longer current
157
+ - **Shape**: `null`
158
+
159
+ ### `media.next`
160
+
161
+ - **Kind**: call, answered once
162
+ - **Requires**: capability `media.control`
163
+ - **When it can be called**: Only during a user action
164
+ - **Parameters**: `player?`: text ≤ 128 bytes
165
+ - **Result**: `null`; `stale_context` when `player` is no longer current
166
+ - **Shape**: `null`
167
+
168
+ ### `stopwatch.subscribe`
169
+
170
+ - **Kind**: subscription
171
+ - **Requires**: capability `stopwatch.read`
172
+ - **When it can be called**: At any time
173
+ - **Parameters**: none
174
+ - **Each update**: `{ running, elapsedMs, at, shortcuts }`, or `null` without an active game; `shortcuts` `{ toggle, reset, bound }` holds host-formatted key chords
175
+ - **Shape**: [`Stopwatch`](result-shapes.md#stopwatch) or `null`
176
+
177
+ ### `stopwatch.toggle`
178
+
179
+ - **Kind**: call, answered once
180
+ - **Requires**: capability `stopwatch.control`
181
+ - **When it can be called**: Only during a user action
182
+ - **Parameters**: none
183
+ - **Result**: the new state, as in `stopwatch.subscribe`; `unavailable` when the host cannot act
184
+ - **Shape**: [`Stopwatch`](result-shapes.md#stopwatch) or `null`
185
+
186
+ ### `stopwatch.reset`
187
+
188
+ - **Kind**: call, answered once
189
+ - **Requires**: capability `stopwatch.control`
190
+ - **When it can be called**: Only during a user action
191
+ - **Parameters**: none
192
+ - **Result**: the new state, as in `stopwatch.subscribe`; `unavailable` when the host cannot act
193
+ - **Shape**: [`Stopwatch`](result-shapes.md#stopwatch) or `null`
194
+
195
+ ### `notes.subscribe`
196
+
197
+ - **Kind**: subscription
198
+ - **Requires**: capability `notes.read`
199
+ - **When it can be called**: At any time
200
+ - **Parameters**: none
201
+ - **Each update**: `{ active, notes }` of the user's single notes document; each note `{ id, title, body, items }`, each item `{ id, text, checked }`
202
+ - **Shape**: [`Notes`](result-shapes.md#notes)
203
+
204
+ ### `notes.create`
205
+
206
+ - **Kind**: call, answered once
207
+ - **Requires**: capability `notes.write`
208
+ - **When it can be called**: Only during a user action
209
+ - **Parameters**: none
210
+ - **Result**: `{ note }`, a new empty active note titled `Note {n}` in the user's language; `quota_exceeded` beyond 8
211
+ - **Shape**: [`CreatedNote`](result-shapes.md#creatednote)
212
+
213
+ ### `notes.select`
214
+
215
+ - **Kind**: call, answered once
216
+ - **Requires**: capability `notes.write`
217
+ - **When it can be called**: Only during a user action
218
+ - **Parameters**: `note`: text ≤ 128 bytes
219
+ - **Result**: `null`; the host stores the active note
220
+ - **Shape**: `null`
221
+
222
+ ### `notes.setItem`
223
+
224
+ - **Kind**: call, answered once
225
+ - **Requires**: capability `notes.write`
226
+ - **When it can be called**: Only during a user action
227
+ - **Parameters**: `note`: text ≤ 128 bytes; `item`: text ≤ 128 bytes; `checked`: boolean
228
+ - **Result**: `null`
229
+
230
+ ### `notes.delete`
231
+
232
+ - **Kind**: call, answered once; the user confirms it first, in a dialog drawn by OverCrow
233
+ - **Requires**: capability `notes.write`
234
+ - **When it can be called**: Only during a user action
235
+ - **Parameters**: `note`: text ≤ 128 bytes
236
+ - **Result**: `null`, or `cancelled` when the user declines
237
+ - **Shape**: `null`
238
+
239
+ ### `playervox.score.subscribe`
240
+
241
+ - **Kind**: subscription
242
+ - **Requires**: capability `playervox.score.read`
243
+ - **When it can be called**: At any time
244
+ - **Parameters**: none
245
+ - **Each update**: `{ state, name, score, grade, ratingsCount, criteria }`: `state` is `idle`, `unsupported`, `loading`, `ready`, `no_ratings`, `not_found` or `unavailable`; `criteria` `{ gameplay, art, tech }`, each from 0 to 100 or `null`
246
+ - **Shape**: [`Score`](result-shapes.md#score)
247
+
248
+ ### `playervox.rating.subscribe`
249
+
250
+ - **Kind**: subscription
251
+ - **Requires**: capability `playervox.rating.read`
252
+ - **When it can be called**: At any time
253
+ - **Parameters**: none
254
+ - **Each update**: `{ state, name, offline, rating }`: `state` is `idle`, `unsupported`, `loading`, `ready` or `unavailable`; `rating` is `null` before the user's first rating, or `{ gameplay, art, tech, review, publishedAt, offsetMinutes }`. Nothing is sent while the PlayerVox account is signed out, pending or expired. A published rating is sent again by the subscription. The host fills the `playervox.rating.publish` controls from it
255
+ - **Shape**: [`RatingState`](result-shapes.md#ratingstate)
256
+
257
+ ### `playervox.reviews.subscribe`
258
+
259
+ - **Kind**: subscription
260
+ - **Requires**: capability `playervox.reviews.read`
261
+ - **When it can be called**: At any time
262
+ - **Parameters**: none
263
+ - **Each update**: `{ state, revision, offline }`: `state` is `idle`, `unsupported` or `ready`; `revision` changes whenever the reviews to read change (another game, another PlayerVox account, reviews changed on PlayerVox), so the widget reads its page again; `offline` while PlayerVox is unreachable. Nothing is sent while the PlayerVox account is signed out, pending or expired. Holding this subscription is what keeps the host's reviews source running
264
+ - **Shape**: [`ReviewsState`](result-shapes.md#reviewsstate)
265
+
266
+ ### `playervox.reviews.page`
267
+
268
+ - **Kind**: call, answered once
269
+ - **Requires**: capability `playervox.reviews.read`
270
+ - **When it can be called**: At any time
271
+ - **Parameters**: `page?`: integer 1 to 100000; `followedOnly?`: boolean
272
+ - **Result**: `{ gameName, items, page, totalPages, count }`: three reviews of the active game per page, in the language of the host's interface; a page past the end answers the last page; each item `{ id, author, grade, score, text, original, hidden, publishedAt, offsetMinutes }`, `text` translated when a translation exists, `original` the untranslated text of a translated review or `null`, both cut by the host to 16 KiB. Each call reads its own page: the host keeps no page position or filter shared between widgets
273
+ - **Shape**: [`ReviewsPage`](result-shapes.md#reviewspage)
274
+
275
+ ### `journal.subscribe`
276
+
277
+ - **Kind**: subscription
278
+ - **Requires**: capability `journal.read`
279
+ - **When it can be called**: At any time
280
+ - **Parameters**: none
281
+ - **Each update**: `null` without an active game, or `{ revision, notice }`: `revision` changes whenever the merged journal of the active game changes (a session recorded or deleted, cloud sessions merged, the PlayerVox account or sync changed), so the widget reads its page again; `notice` is `null`, `offline`, `storage_unavailable`, `full`, `expired`, `busy` or `unavailable`. Holding this subscription is what keeps the host's journal source running
282
+ - **Shape**: [`JournalState`](result-shapes.md#journalstate) or `null`
283
+
284
+ ### `journal.page`
285
+
286
+ - **Kind**: call, answered once
287
+ - **Requires**: capability `journal.read`
288
+ - **When it can be called**: At any time
289
+ - **Parameters**: `cursor?`: text ≤ 128 bytes
290
+ - **Result**: `{ gameName, items, page, next, previous }`: five local and cloud sessions of the active game, merged and deduplicated, newest first; without `cursor`, the first page; each item `{ id, startedAt, offsetMinutes, durationMs, source }`; cursors are host handles that stay valid for the widget whatever other widgets read, and a cursor past the end answers the last page
291
+ - **Shape**: [`JournalPage`](result-shapes.md#journalpage)
292
+
293
+ ### `journal.delete`
294
+
295
+ - **Kind**: call, answered once; the user confirms it first, in a dialog drawn by OverCrow
296
+ - **Requires**: capability `journal.delete`
297
+ - **When it can be called**: Only during a user action
298
+ - **Parameters**: `session`: text ≤ 128 bytes
299
+ - **Result**: `null`, or `cancelled` when the user declines; `not_connected` for a cloud session while PlayerVox is disconnected
300
+ - **Shape**: `null`
301
+
302
+ ### `twitch.chat.subscribe`
303
+
304
+ - **Kind**: subscription
305
+ - **Requires**: capability `twitch.chat.read`
306
+ - **When it can be called**: At any time
307
+ - **Parameters**: none
308
+ - **Each update**: `{ account, channel, joinState, failure, favorites, canSend, generation, reset, messages, removed, skipped }`: `account` is `signed_out`, `pending`, `connected` or `expired` (sign-in is drawn by the host); `failure` is the fixed category of a `failed` join; messages arrive as deltas, at most one update per 100 ms, with `reset` after subscribing, a generation change or a show, and nothing while the widget is hidden; a faster chat is sampled, `skipped` counting the new messages left out; each message `{ id, author, color, badges, fragments, reply, deleted, receivedAt }` with at most 16 fragments, emotes and badges as `asset:` handles for the current theme and scale
309
+ - **Shape**: [`TwitchChat`](result-shapes.md#twitchchat)
310
+
311
+ ### `twitch.chat.join`
312
+
313
+ - **Kind**: call, answered once
314
+ - **Requires**: capability `twitch.chat.read`
315
+ - **When it can be called**: Only during a user action
316
+ - **Parameters**: `channel`: text ≤ 25 bytes
317
+ - **Result**: `null`; the host remembers the channel and rejoins it when the widget starts
318
+ - **Shape**: `null`
319
+
320
+ ### `twitch.chat.leave`
321
+
322
+ - **Kind**: call, answered once
323
+ - **Requires**: capability `twitch.chat.read`
324
+ - **When it can be called**: Only during a user action
325
+ - **Parameters**: none
326
+ - **Result**: `null`; the host forgets the channel
327
+ - **Shape**: `null`
328
+
329
+ ### `twitch.chat.favorite`
330
+
331
+ - **Kind**: call, answered once
332
+ - **Requires**: capability `twitch.chat.read`
333
+ - **When it can be called**: Only during a user action
334
+ - **Parameters**: `channel`: text ≤ 25 bytes; `favorite`: boolean
335
+ - **Result**: `null`; `quota_exceeded` beyond 20
336
+ - **Shape**: `null`
337
+ <!-- /generated:services -->
338
+
339
+ ## Writes that go through a form
340
+
341
+ Saving a note, publishing a rating and sending a chat message are not in
342
+ this list: they are write intents, sent by a `form` from the values that
343
+ the user typed. See
344
+ [forms that write user data](forms.md#forms-that-write-user-data).