@overcrow/mcp 0.0.0-stage → 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 +90 -2
  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 +52 -4
@@ -0,0 +1,461 @@
1
+ # La logique
2
+
3
+ `logic.ts` est le code d’un widget PlayerVox OverCrow : il détient l’état du
4
+ widget, exporte les fonctions que la vue appelle et dialogue avec OverCrow
5
+ par `@overcrow/sdk`. C’est un seul module TypeScript (ou JavaScript),
6
+ assemblé avec le SDK dans l’unique script du paquet, `logic.js`.
7
+
8
+ <!-- source: templates/counter/logic.ts -->
9
+ ```ts
10
+ // A counter. The view reads `state.count` and calls `increment` and
11
+ // `decrement` on activation; after each handler the VM renders the view
12
+ // again and sends only what changed.
13
+ import { initState } from "@overcrow/sdk";
14
+
15
+ declare module "@overcrow/sdk" {
16
+ interface WidgetState {
17
+ count: number;
18
+ }
19
+ }
20
+
21
+ const state = initState({ count: 0 });
22
+
23
+ export function increment(): void {
24
+ state.count += 1;
25
+ }
26
+
27
+ export function decrement(): void {
28
+ state.count -= 1;
29
+ }
30
+ ```
31
+
32
+ Voilà un module de logique complet : un état à un seul membre, et deux
33
+ gestionnaires que la vue appelle avec `on:activate={increment}`.
34
+
35
+ ## Comment la logique s’exécute
36
+
37
+ - Le module s’exécute une fois, au démarrage du widget, dans sa propre VM
38
+ JavaScript, à l’intérieur d’un processus placé dans un sandbox. Ce n’est
39
+ ni un navigateur ni Node.js : il n’y a ni DOM, ni `window`, ni `fetch`, ni
40
+ `setTimeout`, ni `console`, ni `Intl`, ni `require`. Les objets standard
41
+ d’ECMAScript sont là (`Math`, `JSON`, `Date`, `Map`, `Promise`…), et le
42
+ SDK est la seule porte de sortie.
43
+ - Tout le reste se passe par **tours**. OverCrow envoie un événement, un
44
+ déclenchement de minuteur, une réponse de service ou un changement de ses
45
+ propres données ; votre code s’exécute ; puis la VM réévalue la vue et
46
+ n’envoie à OverCrow que ce qui a changé. Vous ne mettez jamais la vue à
47
+ jour à la main.
48
+ - Un tour a un budget de temps, et la VM un plafond de mémoire. OverCrow
49
+ arrête et relance, quelques fois, un widget qui dépasse l’un ou l’autre ;
50
+ voir [ce qui se passe en cas d’échec](#ce-qui-se-passe-en-cas-déchec).
51
+
52
+ Le seul import permis à un module de logique est `@overcrow/sdk`. Tout ce
53
+ dont il a besoin par ailleurs se trouve dans le module lui-même.
54
+
55
+ ## L’état
56
+
57
+ `state` est un objet ordinaire. Déclarez une fois le type de ses membres en
58
+ étendant l’interface `WidgetState` du SDK, donnez-lui sa première valeur
59
+ avec `initState`, puis modifiez-le par simple affectation.
60
+
61
+ <!-- source: templates/list/logic.ts -->
62
+ ```ts
63
+ interface Item {
64
+ id: number;
65
+ text: string;
66
+ done: boolean;
67
+ }
68
+
69
+ declare module "@overcrow/sdk" {
70
+ interface WidgetState {
71
+ items: Item[];
72
+ }
73
+ }
74
+
75
+ const state = initState({
76
+ items: [
77
+ { id: 1, text: t("first"), done: false },
78
+ { id: 2, text: t("second"), done: false },
79
+ { id: 3, text: t("third"), done: true },
80
+ ] as Item[],
81
+ });
82
+ ```
83
+
84
+ Après chaque tour, la VM réévalue toute la vue et envoie les différences. Il
85
+ n’y a ni abonnement à prendre ni setter à appeler : modifier un membre en
86
+ place ou le remplacer, les deux fonctionnent.
87
+
88
+ <!-- source: templates/list/logic.ts -->
89
+ ```ts
90
+ export function setDone(id: number, done: unknown): void {
91
+ state.items = state.items.map((item) => (item.id === id ? { ...item, done: done === true } : item));
92
+ }
93
+ ```
94
+
95
+ Gardez dans l’état ce que la vue affiche, et dans des variables ordinaires
96
+ ce qui ne sert qu’à la logique (un minuteur, un abonnement). Une valeur de
97
+ l’état doit être une donnée simple : nombres, chaînes, booléens, `null`, et
98
+ tableaux ou objets qui en sont composés.
99
+
100
+ ## Des fonctions pour la vue
101
+
102
+ La vue ne peut appeler que ce que le module de logique exporte par son nom :
103
+
104
+ - dans une **expression**, une fonction qui renvoie ce qu’il faut afficher :
105
+ `{remaining(state.items)}` ;
106
+ - comme **gestionnaire**, une fonction qui modifie l’état :
107
+ `on:activate={remove(item.id)}`.
108
+
109
+ <!-- source: templates/list/logic.ts -->
110
+ ```ts
111
+ export function remove(id: number): void {
112
+ state.items = state.items.filter((item) => item.id !== id);
113
+ }
114
+ ```
115
+
116
+ <!-- source: templates/list/logic.ts -->
117
+ ```ts
118
+ export function remaining(items: readonly Item[]): number {
119
+ return items.filter((item) => !item.done).length;
120
+ }
121
+ ```
122
+
123
+ Les fonctions d’expression s’exécutent à chaque évaluation de la vue :
124
+ gardez-les légères et sans effet de bord. Un gestionnaire nommé sans
125
+ arguments (`on:change={setRepeat}`) reçoit le détail de l’événement :
126
+
127
+ <!-- source: docs/content/examples/countdown/logic.ts -->
128
+ ```ts
129
+ export function setRepeat(event: { value: unknown }): void {
130
+ state.repeat = event.value === true;
131
+ }
132
+ ```
133
+
134
+ `export default` est refusé : la vue appelle des exports nommés. `t` n’a pas
135
+ besoin d’être exporté : une vue qui appelle `t(…)` obtient celui du SDK,
136
+ sauf si la logique exporte le sien.
137
+
138
+ ## Les données d’OverCrow : `host`
139
+
140
+ `host` contient ce qu’OverCrow sait de l’utilisateur et du widget. Ses
141
+ membres donnent toujours la dernière valeur.
142
+
143
+ | Membre | Valeur |
144
+ | --- | --- |
145
+ | `host.locale` | Langue de l’interface, `"en"` ou `"fr"`. |
146
+ | `host.theme` | `"dark"` ou `"light"`. |
147
+ | `host.mode` | `"passive"` ou `"interactive"` : le widget ne reçoit d’entrées qu’en mode interactif. |
148
+ | `host.visible` | Indique si le widget est affiché. |
149
+ | `host.scale` | Échelle du contenu en millièmes : `1000` vaut 100 %. |
150
+ | `host.viewport` | `{ width, height }` du contenu du widget, en pixels logiques. |
151
+ | `host.region` | Les formats régionaux et le décalage UTC de l’utilisateur ; les fonctions de formatage les lisent. |
152
+ | `host.options` | Les valeurs du menu d’options ; lisez-les avec `option`. |
153
+ | `host.grants` | Les capabilities accordées par l’utilisateur ; lisez-les avec `hasGrant`. |
154
+ | `host.messages` | Les messages de la langue active ; lisez-les avec `t`. |
155
+
156
+ `onHost(listener)` appelle votre écouteur quand OverCrow envoie de nouvelles
157
+ valeurs, avec les noms des membres qui ont changé, avant la réévaluation de
158
+ la vue. Utilisez-le quand un changement demande plus que l’affichage de la
159
+ nouvelle valeur : réarmer un minuteur, se réabonner, redessiner un canvas.
160
+ Un membre peut être renvoyé avec la même valeur : comparez-la à celle que
161
+ vous avez gardée quand cela compte.
162
+
163
+ <!-- source: widgets/stopwatch/logic.ts -->
164
+ ```ts
165
+ onHost((changed) => {
166
+ if (changed.includes("mode")) {
167
+ state.interactive = host.mode === "interactive";
168
+ }
169
+ });
170
+ ```
171
+
172
+ La plupart des widgets n’affichent que les boutons utilisables : en mode
173
+ passif, un clic traverse le widget jusqu’au jeu. Le chronomètre masque donc
174
+ ses boutons tant que `host.mode` ne vaut pas `"interactive"`.
175
+
176
+ ## Le menu d’options
177
+
178
+ OverCrow dessine et enregistre les lignes déclarées dans `wrapper.menu` du
179
+ [manifeste](manifest.md#le-menu-doptions). La logique les lit :
180
+
181
+ - `option(id, fallback)` renvoie la valeur enregistrée d’une ligne de type
182
+ bascule, curseur ou choix, ou `fallback` quand il n’y en a pas ou qu’elle
183
+ est d’un autre type ;
184
+ - `onHost` signale `"options"` quand l’utilisateur modifie une ligne ;
185
+ - `onMenu(handler)` reçoit l’identifiant d’une ligne `action` quand
186
+ l’utilisateur la choisit.
187
+
188
+ <!-- source: widgets/clock/logic.ts -->
189
+ ```ts
190
+ export function menuValues(): { seconds: boolean; showDate: boolean; order: DateOrder } {
191
+ return {
192
+ seconds: option("show-seconds", false),
193
+ showDate: option("show-date", true),
194
+ order: DATE_ORDERS[option("date-format", "day-month-year")] ?? "dmy",
195
+ };
196
+ }
197
+ ```
198
+
199
+ <!-- source: docs/content/examples/countdown/logic.ts -->
200
+ ```ts
201
+ onMenu((row) => {
202
+ if (row === "reset-rounds") {
203
+ resetRounds();
204
+ }
205
+ });
206
+ ```
207
+
208
+ Choisir une ligne du menu n’est pas une
209
+ [action de l’utilisateur](services.md#les-appels-qui-demandent-une-action-de-lutilisateur)
210
+ pour un service protégé : une ligne `action` peut modifier l’état, pas
211
+ écrire dans le presse-papiers.
212
+
213
+ ## Minuteurs
214
+
215
+ Il n’y a pas de `setTimeout`. Les minuteurs appartiennent à OverCrow et
216
+ passent par `timers` :
217
+
218
+ | Fonction | Se déclenche |
219
+ | --- | --- |
220
+ | `timers.after(ms, callback)` | une fois, après `ms` |
221
+ | `timers.every(ms, callback)` | toutes les `ms` |
222
+ | `timers.atEach(unit, callback)` | à chaque `"second"`, `"minute"`, `"hour"` ou `"day"` de l’heure locale de l’utilisateur |
223
+
224
+ Chacune renvoie un `Timer` doté de `cancel()`.
225
+
226
+ <!-- source: templates/chart/logic.ts -->
227
+ ```ts
228
+ timers.every(1000, () => {
229
+ const previous = state.values.at(-1) ?? 50;
230
+ state.values = [...state.values.slice(1 - POINTS), sample(previous)];
231
+ });
232
+ ```
233
+
234
+ Puisque les minuteurs appartiennent à OverCrow, trois règles s’appliquent :
235
+
236
+ - **Aucun minuteur de moins de 100 ms.** Un intervalle plus court est porté
237
+ à cette valeur. Le mouvement relève du
238
+ [style](style.md#transitions-et-animations), pas des minuteurs.
239
+ - **Rien ne se déclenche dans un widget masqué.** Un minuteur répétitif
240
+ saute les déclenchements tombés pendant que le widget était masqué ; un
241
+ minuteur à usage unique arrivé à échéance pendant ce temps se déclenche
242
+ une fois quand le widget réapparaît. Calculez le temps écoulé à partir de
243
+ `Date.now()`, jamais en comptant les déclenchements :
244
+
245
+ <!-- source: docs/content/examples/countdown/logic.ts -->
246
+ ```ts
247
+ // A timer does not tick while the widget is hidden: the time left comes
248
+ // from the clock, not from the number of ticks.
249
+ function tick(): void {
250
+ state.remainingMs = Math.max(0, endsAt - Date.now());
251
+ if (state.remainingMs > 0) {
252
+ return;
253
+ }
254
+ stop();
255
+ setRounds(state.rounds + 1);
256
+ log.info(`round ${state.rounds} finished`);
257
+ if (state.repeat) {
258
+ start();
259
+ }
260
+ }
261
+ ```
262
+
263
+ - **16 minuteurs au plus** à la fois.
264
+
265
+ Pour une horloge, `timers.atEach` est le bon outil : un seul minuteur
266
+ répétitif, calé sur les changements d’unité de l’heure locale, qui se
267
+ réveille aussi quand le décalage UTC change (heure d’été) et une fois quand
268
+ le widget réapparaît.
269
+
270
+ <!-- source: widgets/clock/logic.ts -->
271
+ ```ts
272
+ /** Ticks at each second or minute of local time, and shows the time now. */
273
+ function start(): void {
274
+ clock?.cancel();
275
+ clock = timers.atEach(state.seconds ? "second" : "minute", tick);
276
+ tick();
277
+ }
278
+ ```
279
+
280
+ Une durée qui doit seulement avancer à l’écran n’a besoin d’aucun minuteur :
281
+ OverCrow fait avancer l’élément `elapsed` à partir d’un point de départ que
282
+ la logique lui donne. Voir l’[élément `elapsed`](elements.md#elapsed).
283
+
284
+ ## Heure, dates et nombres
285
+
286
+ Dans la VM, l’heure locale est UTC : `Date` ne donne jamais l’heure de
287
+ l’utilisateur, et il n’y a pas d’`Intl`. C’est le SDK qui formate, à partir
288
+ de `host.region` :
289
+
290
+ | Fonction | Donne |
291
+ | --- | --- |
292
+ | `formatTime(ms, { seconds })` | `14:08`, ou `14:08:42` : sur 24 heures, dans le fuseau horaire de l’utilisateur |
293
+ | `formatDate(ms, { order })` | `17/07/2026`, `07/17/2026` ou `2026-07-17`, par défaut dans l’ordre de date de l’utilisateur |
294
+ | `formatNumber(value, options)` | `1,234.5`, `1 234,5` ou `1.234,5` : les séparateurs de l’utilisateur, quelle que soit la langue de l’interface |
295
+ | `formatDuration(ms, options)` | `04:05`, `1:02:03`, ou `04:05.67` avec les centièmes |
296
+ | `localTime(ms)` | les champs de l’instant dans le fuseau horaire de l’utilisateur : `year`, `month`, `day`, `weekday`, `hour`… |
297
+
298
+ <!-- source: widgets/clock/logic.ts -->
299
+ ```ts
300
+ export function clockTime(now: number, seconds: boolean): string {
301
+ return formatTime(now, { seconds });
302
+ }
303
+ ```
304
+
305
+ <!-- source: templates/chart/logic.ts -->
306
+ ```ts
307
+ export function latest(values: readonly number[]): string {
308
+ const last = values.at(-1);
309
+ return last === undefined ? "" : formatNumber(last, { maximumFractionDigits: 0 });
310
+ }
311
+ ```
312
+
313
+ Un horodatage qui vient d’un service porte son propre `offsetMinutes` :
314
+ passez-le à la fonction (`formatTime(at, { offsetMinutes })`) pour qu’une
315
+ session enregistrée dans un autre fuseau horaire affiche l’heure qu’il y
316
+ était. Les noms de mois et de jours de la semaine et l’affichage sur
317
+ 12 heures ne sont pas fournis.
318
+
319
+ ## Messages
320
+
321
+ Placez les textes du widget dans `locales/en.json` et `locales/fr.json` :
322
+ deux objets plats de chaînes, aux mêmes clés. Les deux fichiers, ou aucun.
323
+
324
+ <!-- source: templates/list/locales/en.json -->
325
+ ```json
326
+ {
327
+ "first": "Warm up",
328
+ "remaining": "{count} left",
329
+ "remove": "Remove",
330
+ "second": "Play three matches",
331
+ "third": "Update the drivers",
332
+ "title": "Today"
333
+ }
334
+ ```
335
+
336
+ `t(key, params)` renvoie le message dans la langue de l’utilisateur et
337
+ remplace chaque `{name}` par `params.name` ; une clé absente donne la clé
338
+ elle-même. La fonction s’utilise dans la vue comme dans la logique :
339
+
340
+ <!-- source: templates/list/view.ocml -->
341
+ ```xml
342
+ <text class="summary">{t("remaining", { count: remaining(state.items) })}</text>
343
+ ```
344
+
345
+ <!-- source: widgets/stopwatch/logic.ts -->
346
+ ```ts
347
+ export function toggleLabel(running: boolean): string {
348
+ return t(running ? "pause" : "start");
349
+ }
350
+ ```
351
+
352
+ Quand l’utilisateur change la langue d’OverCrow, la vue est réévaluée avec
353
+ les nouveaux messages. En revanche, un texte que la logique a calculé puis
354
+ rangé dans l’état ne change pas : calculez les textes dans des fonctions que
355
+ la vue appelle, ou rafraîchissez-les dans `onHost` quand `"locale"` change.
356
+ Le nom du widget et les libellés de son menu se trouvent dans le manifeste,
357
+ pas dans les fichiers de langue.
358
+
359
+ `overcrow-widget check` avertit quand la vue appelle `t("key")` avec une clé
360
+ sans message, et refuse deux fichiers dont les clés diffèrent.
361
+
362
+ ## Dessin
363
+
364
+ Pour ce que les éléments ne savent pas afficher, l’élément `canvas` offre
365
+ une surface que la logique peint avec une liste de commandes : chemins,
366
+ remplissages, contours, texte et images. `draw(ref, commands)` remplace tout
367
+ le contenu du canvas nommé `ref`.
368
+
369
+ <!-- source: docs/content/examples/countdown/logic.ts -->
370
+ ```ts
371
+ /** One dot per finished round, on the `dots` canvas. */
372
+ function paint(): void {
373
+ const dots: DrawCommand[] = [];
374
+ for (let index = 0; index < Math.min(state.rounds, MAX_DOTS); index += 1) {
375
+ dots.push(["circle", 6 + index * 14, 6, 4], ["fill", "var(--color-accent)"]);
376
+ }
377
+ draw("dots", dots);
378
+ }
379
+ ```
380
+
381
+ Les coordonnées sont en pixels logiques, depuis le coin supérieur gauche du
382
+ canvas ; les couleurs sont des littéraux (`#rrggbb`) ou des tokens de
383
+ couleur. OverCrow vérifie chaque commande et les dessine lui-même : il n’y a
384
+ ni accès aux pixels ni shader. Redessinez quand ce que vous affichez change,
385
+ et quand `host.theme` change si vous utilisez des couleurs littérales.
386
+
387
+ <!-- generated:draw-commands -->
388
+ | Commande | Arguments | Signification |
389
+ | --- | --- | --- |
390
+ | `moveTo` | `x` : nombre de -16384 à 16384 ; `y` : nombre de -16384 à 16384 | Commence un sous-chemin. |
391
+ | `lineTo` | `x` : nombre de -16384 à 16384 ; `y` : nombre de -16384 à 16384 | Segment de droite. |
392
+ | `quadTo` | `cx` : nombre de -16384 à 16384 ; `cy` : nombre de -16384 à 16384 ; `x` : nombre de -16384 à 16384 ; `y` : nombre de -16384 à 16384 | Segment de Bézier quadratique. |
393
+ | `cubicTo` | `c1x` : nombre de -16384 à 16384 ; `c1y` : nombre de -16384 à 16384 ; `c2x` : nombre de -16384 à 16384 ; `c2y` : nombre de -16384 à 16384 ; `x` : nombre de -16384 à 16384 ; `y` : nombre de -16384 à 16384 | Segment de Bézier cubique. |
394
+ | `arc` | `cx` : nombre de -16384 à 16384 ; `cy` : nombre de -16384 à 16384 ; `r` : nombre de -16384 à 16384 ; `start` : nombre de -720 à 720 ; `end` : nombre de -720 à 720 | Arc de cercle, en degrés, dans le sens horaire. |
395
+ | `rect` | `x` : nombre de -16384 à 16384 ; `y` : nombre de -16384 à 16384 ; `w` : nombre de -16384 à 16384 ; `h` : nombre de -16384 à 16384 ; `radius` : nombre de -16384 à 16384 | Sous-chemin fermé : un rectangle aux coins arrondis. |
396
+ | `circle` | `cx` : nombre de -16384 à 16384 ; `cy` : nombre de -16384 à 16384 ; `r` : nombre de -16384 à 16384 | Sous-chemin fermé : un cercle. |
397
+ | `close` | aucune | Ferme le sous-chemin. |
398
+ | `fill` | `color` : `<color>` | Remplit le chemin courant, puis l’efface. |
399
+ | `stroke` | `color` : `<color>` ; `width` : nombre de 0 à 256 | Trace le contour du chemin courant, puis l’efface. |
400
+ | `text` | `x` : nombre de -16384 à 16384 ; `y` : nombre de -16384 à 16384 ; `text` : texte ≤ 1 Kio ; `size` : nombre de 6 à 96 ; `color` : `<color>` ; `align` : `start` \| `center` \| `end` ; `family` : `ui` \| `mono` \| `display` ; `weight` : `400` \| `500` \| `600` \| `700` | Une ligne de texte, posée sur sa ligne de base. |
401
+ | `image` | `src` : source d’image ; `x` : nombre de -16384 à 16384 ; `y` : nombre de -16384 à 16384 ; `w` : nombre de -16384 à 16384 ; `h` : nombre de -16384 à 16384 | Dessine une image mise à l’échelle du rectangle. |
402
+ | `save` | aucune | Empile la transformation, le rognage et l’opacité, ≤ 16. |
403
+ | `restore` | aucune | Dépile l’état ; un `restore` sans `save` est une erreur. |
404
+ | `clip` | `x` : nombre de -16384 à 16384 ; `y` : nombre de -16384 à 16384 ; `w` : nombre de -16384 à 16384 ; `h` : nombre de -16384 à 16384 | Réduit le rectangle de rognage à son intersection avec celui-ci. |
405
+ | `translate` | `x` : nombre de -16384 à 16384 ; `y` : nombre de -16384 à 16384 | Translation. |
406
+ | `rotate` | `degrees` : nombre de -360 à 360 | Rotation. |
407
+ | `scale` | `x` : nombre de 0 à 8 ; `y` : nombre de 0 à 8 | Mise à l’échelle. |
408
+ | `alpha` | `value` : nombre de 0 à 1 | Multiplie l’opacité. |
409
+ <!-- /generated:draw-commands -->
410
+
411
+ Un graphique, une jauge ou une barre de progression n’ont pas besoin de
412
+ canvas : les éléments `chart`, `gauge` et `progress` les dessinent à partir
413
+ de valeurs.
414
+
415
+ ## Journalisation
416
+
417
+ `log.debug`, `log.info`, `log.warn` et `log.error` prennent un texte. Leur
418
+ sortie apparaît dans le terminal de `overcrow-widget dev` et nulle part
419
+ ailleurs : les journaux d’un widget installé sont ignorés. Ne journalisez
420
+ jamais de données de l’utilisateur.
421
+
422
+ <!-- source: docs/content/examples/countdown/logic.ts -->
423
+ ```ts
424
+ log.info(`round ${state.rounds} finished`);
425
+ ```
426
+
427
+ ## Ce que la logique ne peut pas utiliser
428
+
429
+ `overcrow-widget check` confronte la logique à ce que la VM exécute et
430
+ indique par quoi le SDK remplace ce qui manque :
431
+
432
+ | Code | Règle |
433
+ | --- | --- |
434
+ | `logic.syntax` | Le module s’analyse comme de l’ES2023 ; les types TypeScript sont permis. |
435
+ | `logic.import` | Son seul import est `@overcrow/sdk` : aucun autre module, fichier ou paquet, pas de `export *`. |
436
+ | `logic.dynamic_import`, `logic.import_meta` | Ni `import()` ni `import.meta`. |
437
+ | `logic.eval`, `logic.function_constructor` | Ni `eval`, ni `Function(…)`, ni `new Function(…)`. |
438
+ | `logic.unavailable_global` | Chaque globale lue existe dans la VM. `Intl`, `setTimeout`, `console`, `fetch`, `WebAssembly`, `SharedArrayBuffer`, `performance`, `WeakRef`, les globales du navigateur et de Node.js n’y existent pas. |
439
+ | `logic.top_level_await`, `logic.top_level_this` | Ni `await` ni `for await` au niveau supérieur, ni `this` au niveau supérieur. |
440
+ | `logic.syntax_version` | Rien de plus récent qu’ES2023 : décorateurs, `using`, drapeau `v` des expressions régulières, attributs d’import. |
441
+ | `logic.default_export` | La vue appelle des exports nommés ; `export default` est refusé. |
442
+ | `logic.missing_export` | Chaque fonction que la vue appelle est exportée. |
443
+ | `logic.debugger` | `debugger` donne un avertissement. |
444
+
445
+ Ce contrôle vous aide ; ce n’est pas lui qui protège l’utilisateur. C’est le
446
+ rôle du sandbox, des budgets de la VM et de la vérification par OverCrow de
447
+ tout ce que le widget envoie.
448
+
449
+ ## Ce qui se passe en cas d’échec
450
+
451
+ - Une exception dans un gestionnaire met fin à ce tour ; le widget continue
452
+ de tourner, et `overcrow-widget dev` affiche la faute.
453
+ - Un tour plus long que son budget (50 ms), un tas au-dessus de son plafond
454
+ ou trop de messages dans un tour arrêtent le widget. OverCrow affiche une
455
+ erreur fixe dans son cadre et le relance après 1, 5 puis 15 secondes,
456
+ trois fois au plus.
457
+ - La promesse rejetée d’un appel de service est une erreur ordinaire de
458
+ votre code : interceptez-la. Voir les [erreurs](services.md#erreurs).
459
+
460
+ Les valeurs chiffrées figurent dans les [limites](limits.md#logique). Toute
461
+ l’API du SDK est décrite dans la [référence du SDK](sdk.md).