@overcrow/mcp 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +91 -1
- package/dist/audit/index.js +103 -0
- package/dist/audit/lexer.js +417 -0
- package/dist/audit/project.js +200 -0
- package/dist/audit/rules.js +661 -0
- package/dist/bootstrap/download.js +229 -0
- package/dist/bootstrap/install.js +280 -0
- package/dist/bootstrap/pin.js +85 -0
- package/dist/bootstrap/pin.json +119 -0
- package/dist/bootstrap/zip.js +258 -0
- package/dist/cli.js +200 -0
- package/dist/confine.js +244 -0
- package/dist/content/docs/en/cli.md +353 -0
- package/dist/content/docs/en/dev-channel.md +130 -0
- package/dist/content/docs/en/elements.md +469 -0
- package/dist/content/docs/en/forms.md +328 -0
- package/dist/content/docs/en/guide.md +253 -0
- package/dist/content/docs/en/index.md +85 -0
- package/dist/content/docs/en/limits.md +241 -0
- package/dist/content/docs/en/logic.md +446 -0
- package/dist/content/docs/en/manifest.md +381 -0
- package/dist/content/docs/en/mcp.md +165 -0
- package/dist/content/docs/en/package.md +131 -0
- package/dist/content/docs/en/publishing.md +162 -0
- package/dist/content/docs/en/reference.md +55 -0
- package/dist/content/docs/en/result-shapes.md +332 -0
- package/dist/content/docs/en/sdk.md +295 -0
- package/dist/content/docs/en/security.md +115 -0
- package/dist/content/docs/en/service-reference.md +344 -0
- package/dist/content/docs/en/services.md +517 -0
- package/dist/content/docs/en/style-properties.md +270 -0
- package/dist/content/docs/en/style.md +266 -0
- package/dist/content/docs/en/testing.md +400 -0
- package/dist/content/docs/en/view.md +338 -0
- package/dist/content/docs/en/widgets.md +76 -0
- package/dist/content/docs/fr/cli.md +367 -0
- package/dist/content/docs/fr/dev-channel.md +140 -0
- package/dist/content/docs/fr/elements.md +475 -0
- package/dist/content/docs/fr/forms.md +341 -0
- package/dist/content/docs/fr/guide.md +264 -0
- package/dist/content/docs/fr/index.md +90 -0
- package/dist/content/docs/fr/limits.md +244 -0
- package/dist/content/docs/fr/logic.md +461 -0
- package/dist/content/docs/fr/manifest.md +392 -0
- package/dist/content/docs/fr/mcp.md +173 -0
- package/dist/content/docs/fr/package.md +139 -0
- package/dist/content/docs/fr/publishing.md +172 -0
- package/dist/content/docs/fr/reference.md +59 -0
- package/dist/content/docs/fr/result-shapes.md +333 -0
- package/dist/content/docs/fr/sdk.md +301 -0
- package/dist/content/docs/fr/security.md +129 -0
- package/dist/content/docs/fr/service-reference.md +346 -0
- package/dist/content/docs/fr/services.md +540 -0
- package/dist/content/docs/fr/style-properties.md +272 -0
- package/dist/content/docs/fr/style.md +281 -0
- package/dist/content/docs/fr/testing.md +417 -0
- package/dist/content/docs/fr/view.md +352 -0
- package/dist/content/docs/fr/widgets.md +81 -0
- package/dist/content/examples/clock/LICENSE +21 -0
- package/dist/content/examples/clock/README.md +75 -0
- package/dist/content/examples/clock/listing.json +19 -0
- package/dist/content/examples/clock/locales/en.json +4 -0
- package/dist/content/examples/clock/locales/fr.json +4 -0
- package/dist/content/examples/clock/logic.ts +85 -0
- package/dist/content/examples/clock/manifest.json +44 -0
- package/dist/content/examples/clock/package.json +16 -0
- package/dist/content/examples/clock/style.ocss +26 -0
- package/dist/content/examples/clock/tests/hidden.scenario.json +68 -0
- package/dist/content/examples/clock/tests/load-logic.mjs +22 -0
- package/dist/content/examples/clock/tests/logic.test.mjs +89 -0
- package/dist/content/examples/clock/tests/options.scenario.json +108 -0
- package/dist/content/examples/clock/tests/preview.scenario.json +25 -0
- package/dist/content/examples/clock/tests/render.scenario.json +94 -0
- package/dist/content/examples/clock/tests/summer-time.scenario.json +74 -0
- package/dist/content/examples/clock/tests/ticks.scenario.json +120 -0
- package/dist/content/examples/clock/tsconfig.json +16 -0
- package/dist/content/examples/clock/view.ocml +8 -0
- package/dist/content/examples/countdown/LICENSE +20 -0
- package/dist/content/examples/countdown/listing.json +10 -0
- package/dist/content/examples/countdown/locales/en.json +15 -0
- package/dist/content/examples/countdown/locales/fr.json +15 -0
- package/dist/content/examples/countdown/logic.ts +179 -0
- package/dist/content/examples/countdown/manifest.json +34 -0
- package/dist/content/examples/countdown/package.json +15 -0
- package/dist/content/examples/countdown/style.ocss +94 -0
- package/dist/content/examples/countdown/tsconfig.json +16 -0
- package/dist/content/examples/countdown/view.ocml +42 -0
- package/dist/content/examples/fps/LICENSE +21 -0
- package/dist/content/examples/fps/README.md +64 -0
- package/dist/content/examples/fps/listing.json +19 -0
- package/dist/content/examples/fps/locales/en.json +11 -0
- package/dist/content/examples/fps/locales/fr.json +11 -0
- package/dist/content/examples/fps/logic.ts +64 -0
- package/dist/content/examples/fps/manifest.json +30 -0
- package/dist/content/examples/fps/package.json +16 -0
- package/dist/content/examples/fps/style.ocss +31 -0
- package/dist/content/examples/fps/tests/label.scenario.json +63 -0
- package/dist/content/examples/fps/tests/load-logic.mjs +22 -0
- package/dist/content/examples/fps/tests/logic.test.mjs +60 -0
- package/dist/content/examples/fps/tests/preview.scenario.json +29 -0
- package/dist/content/examples/fps/tests/refused.scenario.json +20 -0
- package/dist/content/examples/fps/tests/render.scenario.json +96 -0
- package/dist/content/examples/fps/tests/stale.scenario.json +91 -0
- package/dist/content/examples/fps/tests/unavailable.scenario.json +111 -0
- package/dist/content/examples/fps/tsconfig.json +16 -0
- package/dist/content/examples/fps/view.ocml +11 -0
- package/dist/content/examples/media/LICENSE +21 -0
- package/dist/content/examples/media/README.md +147 -0
- package/dist/content/examples/media/listing.json +19 -0
- package/dist/content/examples/media/locales/en.json +11 -0
- package/dist/content/examples/media/locales/fr.json +11 -0
- package/dist/content/examples/media/logic.ts +191 -0
- package/dist/content/examples/media/manifest.json +35 -0
- package/dist/content/examples/media/package.json +16 -0
- package/dist/content/examples/media/style.ocss +148 -0
- package/dist/content/examples/media/tests/covers.scenario.json +144 -0
- package/dist/content/examples/media/tests/gesture.scenario.json +173 -0
- package/dist/content/examples/media/tests/load-logic.mjs +22 -0
- package/dist/content/examples/media/tests/logic.test.mjs +176 -0
- package/dist/content/examples/media/tests/marquee.scenario.json +127 -0
- package/dist/content/examples/media/tests/preview.scenario.json +52 -0
- package/dist/content/examples/media/tests/read-only.scenario.json +53 -0
- package/dist/content/examples/media/tests/refused.scenario.json +22 -0
- package/dist/content/examples/media/tests/refused.test.mjs +31 -0
- package/dist/content/examples/media/tests/render.scenario.json +136 -0
- package/dist/content/examples/media/tests/states.scenario.json +257 -0
- package/dist/content/examples/media/tests/unavailable.scenario.json +120 -0
- package/dist/content/examples/media/tsconfig.json +16 -0
- package/dist/content/examples/media/view.ocml +41 -0
- package/dist/content/examples/notes/LICENSE +21 -0
- package/dist/content/examples/notes/README.md +219 -0
- package/dist/content/examples/notes/listing.json +19 -0
- package/dist/content/examples/notes/locales/en.json +25 -0
- package/dist/content/examples/notes/locales/fr.json +25 -0
- package/dist/content/examples/notes/logic.ts +799 -0
- package/dist/content/examples/notes/manifest.json +40 -0
- package/dist/content/examples/notes/package.json +16 -0
- package/dist/content/examples/notes/style.ocss +469 -0
- package/dist/content/examples/notes/tests/checks.scenario.json +237 -0
- package/dist/content/examples/notes/tests/create.scenario.json +260 -0
- package/dist/content/examples/notes/tests/delete.scenario.json +342 -0
- package/dist/content/examples/notes/tests/drafts.scenario.json +714 -0
- package/dist/content/examples/notes/tests/editor.scenario.json +232 -0
- package/dist/content/examples/notes/tests/frame.scenario.json +93 -0
- package/dist/content/examples/notes/tests/interactive.scenario.json +344 -0
- package/dist/content/examples/notes/tests/limits.scenario.json +1351 -0
- package/dist/content/examples/notes/tests/load-logic.mjs +22 -0
- package/dist/content/examples/notes/tests/logic.test.mjs +514 -0
- package/dist/content/examples/notes/tests/preview.scenario.json +99 -0
- package/dist/content/examples/notes/tests/read-only.scenario.json +105 -0
- package/dist/content/examples/notes/tests/refused.scenario.json +33 -0
- package/dist/content/examples/notes/tests/save.scenario.json +378 -0
- package/dist/content/examples/notes/tests/states.scenario.json +640 -0
- package/dist/content/examples/notes/tests/typing.scenario.json +562 -0
- package/dist/content/examples/notes/tests/unavailable.scenario.json +246 -0
- package/dist/content/examples/notes/tsconfig.json +16 -0
- package/dist/content/examples/notes/view.ocml +154 -0
- package/dist/content/examples/performance/LICENSE +21 -0
- package/dist/content/examples/performance/README.md +134 -0
- package/dist/content/examples/performance/listing.json +19 -0
- package/dist/content/examples/performance/locales/en.json +20 -0
- package/dist/content/examples/performance/locales/fr.json +20 -0
- package/dist/content/examples/performance/logic.ts +210 -0
- package/dist/content/examples/performance/manifest.json +83 -0
- package/dist/content/examples/performance/package.json +16 -0
- package/dist/content/examples/performance/style.ocss +75 -0
- package/dist/content/examples/performance/tests/fahrenheit.scenario.json +110 -0
- package/dist/content/examples/performance/tests/horizontal.scenario.json +96 -0
- package/dist/content/examples/performance/tests/load-logic.mjs +22 -0
- package/dist/content/examples/performance/tests/logic.test.mjs +226 -0
- package/dist/content/examples/performance/tests/menu.scenario.json +170 -0
- package/dist/content/examples/performance/tests/no-fps-source.scenario.json +47 -0
- package/dist/content/examples/performance/tests/preview.scenario.json +45 -0
- package/dist/content/examples/performance/tests/refused.scenario.json +20 -0
- package/dist/content/examples/performance/tests/refused.test.mjs +19 -0
- package/dist/content/examples/performance/tests/region.scenario.json +89 -0
- package/dist/content/examples/performance/tests/render.scenario.json +112 -0
- package/dist/content/examples/performance/tests/sources.scenario.json +151 -0
- package/dist/content/examples/performance/tests/stale.scenario.json +111 -0
- package/dist/content/examples/performance/tests/telemetry-only.scenario.json +44 -0
- package/dist/content/examples/performance/tests/thresholds.scenario.json +147 -0
- package/dist/content/examples/performance/tests/waiting.scenario.json +105 -0
- package/dist/content/examples/performance/tsconfig.json +16 -0
- package/dist/content/examples/performance/view.ocml +18 -0
- package/dist/content/examples/playervox-journal/LICENSE +21 -0
- package/dist/content/examples/playervox-journal/README.md +150 -0
- package/dist/content/examples/playervox-journal/listing.json +19 -0
- package/dist/content/examples/playervox-journal/locales/en.json +25 -0
- package/dist/content/examples/playervox-journal/locales/fr.json +25 -0
- package/dist/content/examples/playervox-journal/logic.ts +556 -0
- package/dist/content/examples/playervox-journal/manifest.json +19 -0
- package/dist/content/examples/playervox-journal/package.json +16 -0
- package/dist/content/examples/playervox-journal/style.ocss +142 -0
- package/dist/content/examples/playervox-journal/tests/changes.scenario.json +482 -0
- package/dist/content/examples/playervox-journal/tests/delete.scenario.json +432 -0
- package/dist/content/examples/playervox-journal/tests/frame.scenario.json +169 -0
- package/dist/content/examples/playervox-journal/tests/load-logic.mjs +22 -0
- package/dist/content/examples/playervox-journal/tests/logic.test.mjs +349 -0
- package/dist/content/examples/playervox-journal/tests/paging.scenario.json +428 -0
- package/dist/content/examples/playervox-journal/tests/preview.scenario.json +184 -0
- package/dist/content/examples/playervox-journal/tests/read-only.scenario.json +157 -0
- package/dist/content/examples/playervox-journal/tests/refused.scenario.json +39 -0
- package/dist/content/examples/playervox-journal/tests/scale.scenario.json +286 -0
- package/dist/content/examples/playervox-journal/tests/signed-out.scenario.json +134 -0
- package/dist/content/examples/playervox-journal/tests/states.scenario.json +741 -0
- package/dist/content/examples/playervox-journal/tests/unavailable.scenario.json +183 -0
- package/dist/content/examples/playervox-journal/tsconfig.json +16 -0
- package/dist/content/examples/playervox-journal/view.ocml +52 -0
- package/dist/content/examples/playervox-rating/LICENSE +21 -0
- package/dist/content/examples/playervox-rating/README.md +166 -0
- package/dist/content/examples/playervox-rating/listing.json +19 -0
- package/dist/content/examples/playervox-rating/locales/en.json +35 -0
- package/dist/content/examples/playervox-rating/locales/fr.json +35 -0
- package/dist/content/examples/playervox-rating/logic.ts +581 -0
- package/dist/content/examples/playervox-rating/manifest.json +19 -0
- package/dist/content/examples/playervox-rating/package.json +16 -0
- package/dist/content/examples/playervox-rating/style.ocss +333 -0
- package/dist/content/examples/playervox-rating/tests/account.scenario.json +125 -0
- package/dist/content/examples/playervox-rating/tests/bounds.scenario.json +73 -0
- package/dist/content/examples/playervox-rating/tests/draft.scenario.json +199 -0
- package/dist/content/examples/playervox-rating/tests/form.scenario.json +142 -0
- package/dist/content/examples/playervox-rating/tests/load-logic.mjs +22 -0
- package/dist/content/examples/playervox-rating/tests/logic.test.mjs +346 -0
- package/dist/content/examples/playervox-rating/tests/offline.scenario.json +142 -0
- package/dist/content/examples/playervox-rating/tests/preview.scenario.json +44 -0
- package/dist/content/examples/playervox-rating/tests/publish-keyboard.scenario.json +221 -0
- package/dist/content/examples/playervox-rating/tests/publish-pointer.scenario.json +314 -0
- package/dist/content/examples/playervox-rating/tests/read-only.scenario.json +70 -0
- package/dist/content/examples/playervox-rating/tests/refused.scenario.json +45 -0
- package/dist/content/examples/playervox-rating/tests/states.scenario.json +362 -0
- package/dist/content/examples/playervox-rating/tsconfig.json +16 -0
- package/dist/content/examples/playervox-rating/view.ocml +62 -0
- package/dist/content/examples/playervox-reviews/LICENSE +21 -0
- package/dist/content/examples/playervox-reviews/README.md +194 -0
- package/dist/content/examples/playervox-reviews/listing.json +19 -0
- package/dist/content/examples/playervox-reviews/locales/en.json +32 -0
- package/dist/content/examples/playervox-reviews/locales/fr.json +32 -0
- package/dist/content/examples/playervox-reviews/logic.ts +822 -0
- package/dist/content/examples/playervox-reviews/manifest.json +30 -0
- package/dist/content/examples/playervox-reviews/package.json +16 -0
- package/dist/content/examples/playervox-reviews/style.ocss +260 -0
- package/dist/content/examples/playervox-reviews/tests/account.scenario.json +249 -0
- package/dist/content/examples/playervox-reviews/tests/bounds.scenario.json +336 -0
- package/dist/content/examples/playervox-reviews/tests/changes.scenario.json +515 -0
- package/dist/content/examples/playervox-reviews/tests/filter.scenario.json +400 -0
- package/dist/content/examples/playervox-reviews/tests/frame.scenario.json +185 -0
- package/dist/content/examples/playervox-reviews/tests/keyboard.scenario.json +188 -0
- package/dist/content/examples/playervox-reviews/tests/load-logic.mjs +22 -0
- package/dist/content/examples/playervox-reviews/tests/logic.test.mjs +559 -0
- package/dist/content/examples/playervox-reviews/tests/offline-start.scenario.json +152 -0
- package/dist/content/examples/playervox-reviews/tests/offline.scenario.json +311 -0
- package/dist/content/examples/playervox-reviews/tests/paging.scenario.json +497 -0
- package/dist/content/examples/playervox-reviews/tests/preview.scenario.json +286 -0
- package/dist/content/examples/playervox-reviews/tests/reading.scenario.json +591 -0
- package/dist/content/examples/playervox-reviews/tests/refused.scenario.json +54 -0
- package/dist/content/examples/playervox-reviews/tests/scale.scenario.json +303 -0
- package/dist/content/examples/playervox-reviews/tests/states.scenario.json +700 -0
- package/dist/content/examples/playervox-reviews/tests/unavailable.scenario.json +192 -0
- package/dist/content/examples/playervox-reviews/tsconfig.json +16 -0
- package/dist/content/examples/playervox-reviews/view.ocml +110 -0
- package/dist/content/examples/playervox-score/LICENSE +21 -0
- package/dist/content/examples/playervox-score/README.md +131 -0
- package/dist/content/examples/playervox-score/listing.json +19 -0
- package/dist/content/examples/playervox-score/locales/en.json +23 -0
- package/dist/content/examples/playervox-score/locales/fr.json +23 -0
- package/dist/content/examples/playervox-score/logic.ts +430 -0
- package/dist/content/examples/playervox-score/manifest.json +47 -0
- package/dist/content/examples/playervox-score/package.json +16 -0
- package/dist/content/examples/playervox-score/style.ocss +247 -0
- package/dist/content/examples/playervox-score/tests/grades.scenario.json +279 -0
- package/dist/content/examples/playervox-score/tests/load-logic.mjs +22 -0
- package/dist/content/examples/playervox-score/tests/logic.test.mjs +229 -0
- package/dist/content/examples/playervox-score/tests/options.scenario.json +302 -0
- package/dist/content/examples/playervox-score/tests/preview.scenario.json +68 -0
- package/dist/content/examples/playervox-score/tests/pulse.scenario.json +157 -0
- package/dist/content/examples/playervox-score/tests/refused.scenario.json +21 -0
- package/dist/content/examples/playervox-score/tests/signed-out.scenario.json +46 -0
- package/dist/content/examples/playervox-score/tests/states.scenario.json +450 -0
- package/dist/content/examples/playervox-score/tests/unavailable.scenario.json +84 -0
- package/dist/content/examples/playervox-score/tsconfig.json +16 -0
- package/dist/content/examples/playervox-score/view.ocml +51 -0
- package/dist/content/examples/session/LICENSE +21 -0
- package/dist/content/examples/session/README.md +57 -0
- package/dist/content/examples/session/listing.json +19 -0
- package/dist/content/examples/session/locales/en.json +3 -0
- package/dist/content/examples/session/locales/fr.json +3 -0
- package/dist/content/examples/session/logic.ts +26 -0
- package/dist/content/examples/session/manifest.json +19 -0
- package/dist/content/examples/session/package.json +16 -0
- package/dist/content/examples/session/style.ocss +16 -0
- package/dist/content/examples/session/tests/hidden.scenario.json +45 -0
- package/dist/content/examples/session/tests/load-logic.mjs +22 -0
- package/dist/content/examples/session/tests/logic.test.mjs +37 -0
- package/dist/content/examples/session/tests/preview.scenario.json +28 -0
- package/dist/content/examples/session/tests/refused.scenario.json +20 -0
- package/dist/content/examples/session/tests/refused.test.mjs +16 -0
- package/dist/content/examples/session/tests/render.scenario.json +95 -0
- package/dist/content/examples/session/tests/ticks.scenario.json +139 -0
- package/dist/content/examples/session/tests/unknown.scenario.json +37 -0
- package/dist/content/examples/session/tsconfig.json +16 -0
- package/dist/content/examples/session/view.ocml +11 -0
- package/dist/content/examples/stopwatch/LICENSE +21 -0
- package/dist/content/examples/stopwatch/README.md +99 -0
- package/dist/content/examples/stopwatch/listing.json +19 -0
- package/dist/content/examples/stopwatch/locales/en.json +8 -0
- package/dist/content/examples/stopwatch/locales/fr.json +8 -0
- package/dist/content/examples/stopwatch/logic.ts +93 -0
- package/dist/content/examples/stopwatch/manifest.json +19 -0
- package/dist/content/examples/stopwatch/package.json +16 -0
- package/dist/content/examples/stopwatch/style.ocss +54 -0
- package/dist/content/examples/stopwatch/tests/errors.scenario.json +121 -0
- package/dist/content/examples/stopwatch/tests/gesture.scenario.json +154 -0
- package/dist/content/examples/stopwatch/tests/hidden.scenario.json +57 -0
- package/dist/content/examples/stopwatch/tests/hundredths.scenario.json +173 -0
- package/dist/content/examples/stopwatch/tests/load-logic.mjs +22 -0
- package/dist/content/examples/stopwatch/tests/logic.test.mjs +99 -0
- package/dist/content/examples/stopwatch/tests/preview.scenario.json +36 -0
- package/dist/content/examples/stopwatch/tests/read-only.scenario.json +42 -0
- package/dist/content/examples/stopwatch/tests/read-only.test.mjs +18 -0
- package/dist/content/examples/stopwatch/tests/refused.scenario.json +22 -0
- package/dist/content/examples/stopwatch/tests/refused.test.mjs +18 -0
- package/dist/content/examples/stopwatch/tests/render.scenario.json +105 -0
- package/dist/content/examples/stopwatch/tests/states.scenario.json +246 -0
- package/dist/content/examples/stopwatch/tests/unknown.scenario.json +40 -0
- package/dist/content/examples/stopwatch/tsconfig.json +16 -0
- package/dist/content/examples/stopwatch/view.ocml +29 -0
- package/dist/content/examples/twitch-chat/LICENSE +21 -0
- package/dist/content/examples/twitch-chat/README.md +283 -0
- package/dist/content/examples/twitch-chat/listing.json +19 -0
- package/dist/content/examples/twitch-chat/locales/en.json +52 -0
- package/dist/content/examples/twitch-chat/locales/fr.json +52 -0
- package/dist/content/examples/twitch-chat/logic.ts +887 -0
- package/dist/content/examples/twitch-chat/manifest.json +33 -0
- package/dist/content/examples/twitch-chat/package.json +16 -0
- package/dist/content/examples/twitch-chat/style.ocss +544 -0
- package/dist/content/examples/twitch-chat/tests/account.scenario.json +325 -0
- package/dist/content/examples/twitch-chat/tests/burst.scenario.json +1866 -0
- package/dist/content/examples/twitch-chat/tests/channel-refused.scenario.json +372 -0
- package/dist/content/examples/twitch-chat/tests/channel.scenario.json +480 -0
- package/dist/content/examples/twitch-chat/tests/draft.scenario.json +279 -0
- package/dist/content/examples/twitch-chat/tests/fade.scenario.json +269 -0
- package/dist/content/examples/twitch-chat/tests/failures.scenario.json +420 -0
- package/dist/content/examples/twitch-chat/tests/favorites.scenario.json +376 -0
- package/dist/content/examples/twitch-chat/tests/frame.scenario.json +152 -0
- package/dist/content/examples/twitch-chat/tests/lifetime.scenario.json +186 -0
- package/dist/content/examples/twitch-chat/tests/load-logic.mjs +22 -0
- package/dist/content/examples/twitch-chat/tests/logic.test.mjs +1053 -0
- package/dist/content/examples/twitch-chat/tests/passive.scenario.json +536 -0
- package/dist/content/examples/twitch-chat/tests/preview.scenario.json +147 -0
- package/dist/content/examples/twitch-chat/tests/read-only.scenario.json +202 -0
- package/dist/content/examples/twitch-chat/tests/read-only.test.mjs +63 -0
- package/dist/content/examples/twitch-chat/tests/refused.scenario.json +65 -0
- package/dist/content/examples/twitch-chat/tests/refused.test.mjs +43 -0
- package/dist/content/examples/twitch-chat/tests/render.scenario.json +347 -0
- package/dist/content/examples/twitch-chat/tests/reply.scenario.json +384 -0
- package/dist/content/examples/twitch-chat/tests/send-refused.scenario.json +383 -0
- package/dist/content/examples/twitch-chat/tests/send.scenario.json +300 -0
- package/dist/content/examples/twitch-chat/tests/states.scenario.json +455 -0
- package/dist/content/examples/twitch-chat/tests/unavailable.scenario.json +256 -0
- package/dist/content/examples/twitch-chat/tests/unread.scenario.json +997 -0
- package/dist/content/examples/twitch-chat/tsconfig.json +16 -0
- package/dist/content/examples/twitch-chat/view.ocml +141 -0
- package/dist/content/examples/warframe-market/LICENSE +21 -0
- package/dist/content/examples/warframe-market/README.md +176 -0
- package/dist/content/examples/warframe-market/listing.json +19 -0
- package/dist/content/examples/warframe-market/locales/en.json +44 -0
- package/dist/content/examples/warframe-market/locales/fr.json +44 -0
- package/dist/content/examples/warframe-market/logic.ts +1265 -0
- package/dist/content/examples/warframe-market/manifest.json +92 -0
- package/dist/content/examples/warframe-market/package.json +16 -0
- package/dist/content/examples/warframe-market/style.ocss +422 -0
- package/dist/content/examples/warframe-market/tests/bounds.scenario.json +60 -0
- package/dist/content/examples/warframe-market/tests/cached.scenario.json +70 -0
- package/dist/content/examples/warframe-market/tests/detail.scenario.json +251 -0
- package/dist/content/examples/warframe-market/tests/errors.scenario.json +105 -0
- package/dist/content/examples/warframe-market/tests/fixtures.json +295 -0
- package/dist/content/examples/warframe-market/tests/load-logic.mjs +22 -0
- package/dist/content/examples/warframe-market/tests/logic.test.mjs +505 -0
- package/dist/content/examples/warframe-market/tests/no-clipboard.scenario.json +104 -0
- package/dist/content/examples/warframe-market/tests/passive.scenario.json +87 -0
- package/dist/content/examples/warframe-market/tests/preview.scenario.json +146 -0
- package/dist/content/examples/warframe-market/tests/refresh.scenario.json +56 -0
- package/dist/content/examples/warframe-market/tests/refused.scenario.json +74 -0
- package/dist/content/examples/warframe-market/tests/render.scenario.json +210 -0
- package/dist/content/examples/warframe-market/tests/search.scenario.json +189 -0
- package/dist/content/examples/warframe-market/tests/unavailable.scenario.json +54 -0
- package/dist/content/examples/warframe-market/tsconfig.json +16 -0
- package/dist/content/examples/warframe-market/view.ocml +116 -0
- package/dist/content/examples/weather/LICENSE +20 -0
- package/dist/content/examples/weather/listing.json +10 -0
- package/dist/content/examples/weather/locales/en.json +9 -0
- package/dist/content/examples/weather/locales/fr.json +9 -0
- package/dist/content/examples/weather/logic.ts +62 -0
- package/dist/content/examples/weather/manifest.json +51 -0
- package/dist/content/examples/weather/package.json +15 -0
- package/dist/content/examples/weather/style.ocss +29 -0
- package/dist/content/examples/weather/tsconfig.json +16 -0
- package/dist/content/examples/weather/view.ocml +12 -0
- package/dist/content/index.json +3601 -0
- package/dist/content/reference/errors.json +1712 -0
- package/dist/content/reference/limits.json +1154 -0
- package/dist/content/reference/manifest.md +223 -0
- package/dist/content/reference/permissions.json +413 -0
- package/dist/content/templates/blank/locales/en.json +3 -0
- package/dist/content/templates/blank/locales/fr.json +3 -0
- package/dist/content/templates/blank/logic.ts +7 -0
- package/dist/content/templates/blank/manifest.json +16 -0
- package/dist/content/templates/blank/style.ocss +10 -0
- package/dist/content/templates/blank/tests/example.scenario.json +10 -0
- package/dist/content/templates/blank/view.ocml +6 -0
- package/dist/content/templates/chart/locales/en.json +3 -0
- package/dist/content/templates/chart/locales/fr.json +3 -0
- package/dist/content/templates/chart/logic.ts +27 -0
- package/dist/content/templates/chart/manifest.json +16 -0
- package/dist/content/templates/chart/style.ocss +27 -0
- package/dist/content/templates/chart/tests/example.scenario.json +10 -0
- package/dist/content/templates/chart/view.ocml +10 -0
- package/dist/content/templates/counter/locales/en.json +4 -0
- package/dist/content/templates/counter/locales/fr.json +4 -0
- package/dist/content/templates/counter/logic.ts +20 -0
- package/dist/content/templates/counter/manifest.json +16 -0
- package/dist/content/templates/counter/style.ocss +26 -0
- package/dist/content/templates/counter/tests/example.scenario.json +11 -0
- package/dist/content/templates/counter/view.ocml +13 -0
- package/dist/content/templates/list/locales/en.json +8 -0
- package/dist/content/templates/list/locales/fr.json +8 -0
- package/dist/content/templates/list/logic.ts +35 -0
- package/dist/content/templates/list/manifest.json +16 -0
- package/dist/content/templates/list/style.ocss +42 -0
- package/dist/content/templates/list/tests/example.scenario.json +10 -0
- package/dist/content/templates/list/view.ocml +17 -0
- package/dist/content/templates/shared/LICENSE +20 -0
- package/dist/content/templates/shared/package.json +14 -0
- package/dist/content/templates/shared/tsconfig.json +16 -0
- package/dist/content.js +68 -0
- package/dist/env.js +156 -0
- package/dist/fingerprint.js +32 -0
- package/dist/ids.js +27 -0
- package/dist/index.js +82 -0
- package/dist/knowledge.js +222 -0
- package/dist/npm.js +149 -0
- package/dist/prompts.js +47 -0
- package/dist/resources.js +82 -0
- package/dist/run.js +120 -0
- package/dist/server.js +43 -0
- package/dist/session.js +205 -0
- package/dist/sources.js +218 -0
- package/dist/text.js +80 -0
- package/dist/texts.js +44 -0
- package/dist/tools/audit.js +105 -0
- package/dist/tools/build.js +453 -0
- package/dist/tools/common.js +122 -0
- package/dist/tools/docs.js +196 -0
- package/dist/tools/preview.js +87 -0
- package/dist/tools/project.js +178 -0
- package/dist/tools/setup.js +146 -0
- package/dist/tools/submission.js +369 -0
- package/dist/version.js +3 -0
- package/npm-shrinkwrap.json +402 -0
- package/package.json +50 -4
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2023",
|
|
4
|
+
"lib": ["ES2023"],
|
|
5
|
+
"types": [],
|
|
6
|
+
"module": "ES2022",
|
|
7
|
+
"moduleResolution": "bundler",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"noEmit": true,
|
|
10
|
+
"isolatedModules": true,
|
|
11
|
+
"verbatimModuleSyntax": true,
|
|
12
|
+
"noUncheckedIndexedAccess": true,
|
|
13
|
+
"exactOptionalPropertyTypes": true
|
|
14
|
+
},
|
|
15
|
+
"include": ["logic.ts"]
|
|
16
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
<!-- Twitch chat: the chat of one public Twitch channel (parity sheet:
|
|
2
|
+
playervox-overcrow docs/builtin-parity/twitch-chat.md).
|
|
3
|
+
OverCrow holds the account, the connection, the channel and the
|
|
4
|
+
favorites. The composer is a form bound to the `twitch.chat.send`
|
|
5
|
+
intent: its message field belongs to OverCrow, which keeps the text,
|
|
6
|
+
sends it and empties it once accepted; it takes no `value` here. The
|
|
7
|
+
form's key is the chat's generation: another channel or account is
|
|
8
|
+
another form, without the previous text. -->
|
|
9
|
+
<box class="chat" label={t("label")}>
|
|
10
|
+
<box class="header">
|
|
11
|
+
<icon class="mark" name="message-square" label={t("twitch")}/>
|
|
12
|
+
<if test={phase(state) == "chat"}>
|
|
13
|
+
<if test={state.interactive}>
|
|
14
|
+
<button class={starClass(state)} label={favoriteLabel(state)} tooltip={t(favoriteTip(state))} disabled={favoriteFull(state)} on:activate={toggleFavorite}>
|
|
15
|
+
<icon name="star"/>
|
|
16
|
+
</button>
|
|
17
|
+
</if>
|
|
18
|
+
<else-if test={isFavorite(state)}>
|
|
19
|
+
<icon class="star-mark" name="star" label={t("favorite-channel")}/>
|
|
20
|
+
</else-if>
|
|
21
|
+
</if>
|
|
22
|
+
<text class="heading">{heading(state)}</text>
|
|
23
|
+
<box class={dotClass(state)} label={t(statusKey(state))} tooltip={t(statusKey(state))}/>
|
|
24
|
+
<if test={state.interactive && phase(state) == "chat"}>
|
|
25
|
+
<button class="icon-button" label={t("change-channel")} tooltip={t("change-channel")} on:activate={toggleSelector}>
|
|
26
|
+
<icon name="chevron-right"/>
|
|
27
|
+
</button>
|
|
28
|
+
<button class="icon-button" label={t("leave-channel")} tooltip={t("leave-channel")} on:activate={leave}>
|
|
29
|
+
<icon name="x"/>
|
|
30
|
+
</button>
|
|
31
|
+
</if>
|
|
32
|
+
</box>
|
|
33
|
+
<if test={failureKey(state) != ""}>
|
|
34
|
+
<text class="error">{t(failureKey(state))}</text>
|
|
35
|
+
</if>
|
|
36
|
+
<if test={state.interactive && state.notice != ""}>
|
|
37
|
+
<text class="error">{t(state.notice)}</text>
|
|
38
|
+
</if>
|
|
39
|
+
<if test={phase(state) == "permission"}>
|
|
40
|
+
<text class="status">{t("no-permission")}</text>
|
|
41
|
+
</if>
|
|
42
|
+
<if test={phase(state) == "unavailable"}>
|
|
43
|
+
<text class="status">{t("unavailable")}</text>
|
|
44
|
+
</if>
|
|
45
|
+
<if test={phase(state) == "signed-out"}>
|
|
46
|
+
<text class="status">{t("signed-out")}</text>
|
|
47
|
+
</if>
|
|
48
|
+
<if test={phase(state) == "pending"}>
|
|
49
|
+
<text class="status">{t("pending")}</text>
|
|
50
|
+
</if>
|
|
51
|
+
<if test={phase(state) == "no-channel" && !state.interactive}>
|
|
52
|
+
<text class="status">{t("no-channel")}</text>
|
|
53
|
+
</if>
|
|
54
|
+
<if test={selecting(state)}>
|
|
55
|
+
<!-- The selector's key changes when it starts over: its field is
|
|
56
|
+
OverCrow's to edit, and a new field is an empty one. -->
|
|
57
|
+
<for each={selectors(state)} as="selector" key={selector}>
|
|
58
|
+
<form class="selector" on:submit={join}>
|
|
59
|
+
<field class="input channel" max-length="26" autofocus placeholder={t("channel-name")} label={t("channel-name")} on:input={channelTyped(event.value)}/>
|
|
60
|
+
<button class="action" submit disabled={!canJoin(state)}>
|
|
61
|
+
<text class="action-label">{t("join")}</text>
|
|
62
|
+
</button>
|
|
63
|
+
</form>
|
|
64
|
+
</for>
|
|
65
|
+
<if test={state.favorites.length > 0}>
|
|
66
|
+
<text class="eyebrow">{t("favorites")}</text>
|
|
67
|
+
<scroll class="chips">
|
|
68
|
+
<for each={state.favorites} as="favorite" key={favorite}>
|
|
69
|
+
<button class="chip" on:activate={joinFavorite(favorite)}>
|
|
70
|
+
<text class="chip-label">#{favorite}</text>
|
|
71
|
+
</button>
|
|
72
|
+
</for>
|
|
73
|
+
</scroll>
|
|
74
|
+
</if>
|
|
75
|
+
</if>
|
|
76
|
+
<if test={phase(state) == "chat"}>
|
|
77
|
+
<if test={state.shown.length == 0}>
|
|
78
|
+
<text class="empty">{t(emptyKey(state))}</text>
|
|
79
|
+
</if>
|
|
80
|
+
<list class="history" stick-to-end={state.following} item-height="20" label={heading(state)} on:stick={stuck(event.stuck)}>
|
|
81
|
+
<for each={state.shown} as="row" key={row.key}>
|
|
82
|
+
<if test={row.gap > 0}>
|
|
83
|
+
<text class="gap">{gapText(row.gap)}</text>
|
|
84
|
+
</if>
|
|
85
|
+
<else>
|
|
86
|
+
<box class={row.cls}>
|
|
87
|
+
<if test={row.context != ""}>
|
|
88
|
+
<text class="context">{row.context}</text>
|
|
89
|
+
</if>
|
|
90
|
+
<text class="message">
|
|
91
|
+
<span class="author" color={row.color}>{row.author}</span>
|
|
92
|
+
<for each={row.parts} as="part" key={part.key}>
|
|
93
|
+
<if test={part.emote != ""}>
|
|
94
|
+
<image class="emote" src={part.emote} label={part.text}/>
|
|
95
|
+
</if>
|
|
96
|
+
<else>
|
|
97
|
+
<span>{part.text}</span>
|
|
98
|
+
</else>
|
|
99
|
+
</for>
|
|
100
|
+
</text>
|
|
101
|
+
<if test={composing(state)}>
|
|
102
|
+
<icon class="reply" name="reply" label={t("reply")} tooltip={row.tip} on:activate={replyTo(row.id)}/>
|
|
103
|
+
</if>
|
|
104
|
+
</box>
|
|
105
|
+
</else>
|
|
106
|
+
</for>
|
|
107
|
+
</list>
|
|
108
|
+
<if test={state.interactive && state.unread > 0}>
|
|
109
|
+
<button class="unread" on:activate={latest}>
|
|
110
|
+
<text class="unread-label">{unreadText(state.unread)}</text>
|
|
111
|
+
</button>
|
|
112
|
+
</if>
|
|
113
|
+
</if>
|
|
114
|
+
<!-- The composer stays in the view whatever shows above it, hidden when
|
|
115
|
+
nothing can be composed: OverCrow keeps the text of its field through
|
|
116
|
+
Passive mode and a failed subscription. -->
|
|
117
|
+
<for each={composers(state)} as="composer" key={composer}>
|
|
118
|
+
<form class={composerClass(state)} intent="twitch.chat.send" target={replyTarget(state)} on:submit={submitted(event.outcome, event.error)}>
|
|
119
|
+
<if test={state.reply}>
|
|
120
|
+
<box class="replying">
|
|
121
|
+
<text class="replying-label">{replyingTo(state)}</text>
|
|
122
|
+
<button class="icon-button small" label={t("cancel-reply")} tooltip={t("cancel-reply")} on:activate={cancelReply}>
|
|
123
|
+
<icon name="x"/>
|
|
124
|
+
</button>
|
|
125
|
+
</box>
|
|
126
|
+
</if>
|
|
127
|
+
<if test={state.sendError != ""}>
|
|
128
|
+
<text class="error">{t(state.sendError)}</text>
|
|
129
|
+
</if>
|
|
130
|
+
<box class="compose">
|
|
131
|
+
<field class="input message-field" name="message" max-length="500" placeholder={t(composerHint(state))} label={t("message-label")} disabled={!state.canSend} on:input={drafted(event.value)} on:keydown={keyed(event.key)}/>
|
|
132
|
+
<if test={sendMark(state) != ""}>
|
|
133
|
+
<text class={sendMarkClass(state)}>{t(sendMark(state))}</text>
|
|
134
|
+
</if>
|
|
135
|
+
<button class="action" submit disabled={!canSubmit(state)} on:activate={sendPressed}>
|
|
136
|
+
<text class="action-label">{t("send")}</text>
|
|
137
|
+
</button>
|
|
138
|
+
</box>
|
|
139
|
+
</form>
|
|
140
|
+
</for>
|
|
141
|
+
</box>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Valhallab SASU
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# Warframe Market
|
|
2
|
+
|
|
3
|
+
`com.playervox.overcrow.warframe.market` — searches the public PC item
|
|
4
|
+
catalog of [warframe.market](https://warframe.market), shows the online
|
|
5
|
+
sellers and buyers of one item in two tabs and copies a trade whisper when
|
|
6
|
+
you click. A
|
|
7
|
+
PlayerVox widget of the catalog, not a built-in: written against the public
|
|
8
|
+
`@overcrow/sdk` and packaged with `overcrow-widget` like any creator's
|
|
9
|
+
widget. MIT. Version 3.0.0 replaced the Web widget (2.0.6) of the retired
|
|
10
|
+
runtime, under the same ID; 3.1.0 shows every online offer instead of the
|
|
11
|
+
five best, in tabs, with a refresh button and an optional auto refresh.
|
|
12
|
+
|
|
13
|
+
Warframe and related names remain trademarks of their respective owners
|
|
14
|
+
([trademarks](../../TRADEMARKS.md)); this widget is not affiliated with
|
|
15
|
+
them or with warframe.market.
|
|
16
|
+
|
|
17
|
+
## What it shows
|
|
18
|
+
|
|
19
|
+
| State | Shows |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| Loading | "Loading catalog…" until the stored or downloaded catalog is ready |
|
|
22
|
+
| Search | Up to 12 items whose English name or slug holds the text, in catalog order |
|
|
23
|
+
| Selected item | Lowest sell and highest buy price per item, then two tabs, Sellers (first) and Buyers, each with its count: every visible PC offer of a player in game or online, sellers by rising and buyers by falling price per item, the best 150 shown and "+N more" below them: price, trader followed by a dot for the player's state (green in game, amber online, named on hover and for screen readers; a long name is cut before the dot), quantity and variant (rank, charges, stars, subtype). A legend of the dots stays at the bottom, out of the scroll |
|
|
24
|
+
| Refresh | The button beside "Back" reloads the item's offers; it is off while they load. The offers shown stay until the new ones arrive ("Refreshing offers…"); a failed refresh keeps them ("Refresh failed · showing the previous offers") |
|
|
25
|
+
| Copy | "Whisper" writes `/w <trader> Hi, WTB <item> (<variant>) for <price>p` (WTS for a buyer; `n x … total` for several items) to the clipboard; the button then says "Copied", or "Retry" when it failed |
|
|
26
|
+
| Passive mode | The last results, with "Switch to interactive mode to search" |
|
|
27
|
+
| Errors | Catalog unavailable (with or without a cached catalog), orders unavailable, storage unavailable |
|
|
28
|
+
|
|
29
|
+
The interface is in English and French; item names stay in English, as the
|
|
30
|
+
provider sends them, and so does the whisper, which goes to the game's
|
|
31
|
+
trade chat. Prices use the user's number format.
|
|
32
|
+
|
|
33
|
+
## Permissions
|
|
34
|
+
|
|
35
|
+
| Permission | Why |
|
|
36
|
+
| --- | --- |
|
|
37
|
+
| `network` | Three `GET` routes of `https://api.warframe.market`, each with its response bound: `/v2/versions` (4 KiB; its answer is about 0.5 KB), `/v2/items` (3 MiB; the catalog is 1.6 MB and the default 1 MiB bound is too small) and `/v2/orders/item/{slug}`, the slug checked as a `slug` parameter of at most 96 bytes (2 MiB; the orders of users seen in the last seven days, 0.4 to 1 MB for popular items on 2026-10-08) |
|
|
38
|
+
| `storage` | The saved search and the compact catalog with its version, in at most four keys and about 70 KB of the 256 KiB quota |
|
|
39
|
+
| `clipboardWrite` | The whisper, on a click in interactive mode only |
|
|
40
|
+
|
|
41
|
+
No capability: the widget reads nothing about the user or the game.
|
|
42
|
+
|
|
43
|
+
## Options menu
|
|
44
|
+
|
|
45
|
+
| Row | Values |
|
|
46
|
+
| --- | --- |
|
|
47
|
+
| Auto refresh | Off (default), every 30 s, every minute: the shown item's offers reload on their own. Only with an item shown, never while a request runs, paused while the widget or the overlay is hidden (a reload that fell due runs when it shows again), and each failure in a row doubles the wait, up to eight times. Off by default: every 30 s, a popular item costs about 1.75 MB of download a minute |
|
|
48
|
+
|
|
49
|
+
## How it works
|
|
50
|
+
|
|
51
|
+
- **Catalog.** At start the widget reads the stored catalog, then asks
|
|
52
|
+
`/v2/versions` for the catalog's version. It downloads `/v2/items` only
|
|
53
|
+
when nothing is stored or the version changed; a failed download keeps
|
|
54
|
+
the stored catalog.
|
|
55
|
+
- **Turns.** The catalog is downloaded as text and read in slices of 250
|
|
56
|
+
items, one host timer (100 ms) apart: each item is parsed alone and
|
|
57
|
+
checked (slug `[a-z0-9_-]`, name without control characters, cut to 96
|
|
58
|
+
characters). The stored copy is written and read back the same way. No
|
|
59
|
+
VM turn handles the whole catalog, so none nears the turn budget, even
|
|
60
|
+
under the VM's CPU ceiling.
|
|
61
|
+
- **Storage.** One line per item: the name, followed by a tab and the slug
|
|
62
|
+
when the slug does not derive from the name (83 of 3,892 items). The
|
|
63
|
+
lines fill chunks of at most 60 KB (two for today's catalog, three at
|
|
64
|
+
most). The index key is removed before the chunks are written and set
|
|
65
|
+
last, so an interrupted write is never read back as a catalog.
|
|
66
|
+
- **Orders.** An item's answer is read as text, 300 orders per VM turn, one
|
|
67
|
+
host timer (100 ms) apart: rows are cut where `},{"id":"` starts the next
|
|
68
|
+
one and each slice is parsed by the engine's `JSON.parse`, so a wrong cut
|
|
69
|
+
fails, never silently, and a slice beyond 512 KB, a malformed envelope or
|
|
70
|
+
more than 20,000 rows refuse the answer ("Orders unavailable"). Parsing a
|
|
71
|
+
1 MB answer in one turn would exceed the turn budget under the VM's CPU
|
|
72
|
+
ceiling. Only visible PC orders of players in game or online are kept.
|
|
73
|
+
- **Requests.** The provider allows three requests per second: a request
|
|
74
|
+
starts at least 400 ms after the previous one. Selecting several items
|
|
75
|
+
quickly sends one request, for the latest; a late answer for an earlier
|
|
76
|
+
selection is dropped. The catalog and the orders run one after the other:
|
|
77
|
+
their bounds (3 and 2 MiB) do not fit the widget's 4 MiB network budget
|
|
78
|
+
together.
|
|
79
|
+
- **Search.** In memory, at each keystroke; the text is saved a second
|
|
80
|
+
after the last one.
|
|
81
|
+
|
|
82
|
+
## Differences from the Web widget
|
|
83
|
+
|
|
84
|
+
- The catalog lived in IndexedDB; it is now in host storage, compacted.
|
|
85
|
+
- Its layout adapted to the panel width with CSS media queries; the style
|
|
86
|
+
subset has none, so the offer rows keep one grid and the panel scrolls.
|
|
87
|
+
- After "Clear", the Web widget put the focus back in the search field.
|
|
88
|
+
The SDK has no focus API; a future SDK version could add one.
|
|
89
|
+
- A "Back to results" button returns from an item to the search results.
|
|
90
|
+
|
|
91
|
+
## Tests
|
|
92
|
+
|
|
93
|
+
- `tests/logic.test.mjs`: the logic on `@overcrow/sdk/testing`: start,
|
|
94
|
+
pacing, storage writes, search, selection, copy and its failure, refresh
|
|
95
|
+
(offers kept while they reload, a failed refresh), auto refresh (off by
|
|
96
|
+
default, every 30 s or minute, slower after errors, never two at once,
|
|
97
|
+
none without an item), tabs, the catalog and the orders one after the
|
|
98
|
+
other, the incremental readers (strings, nesting, slices, malformed or
|
|
99
|
+
oversized answers), the catalog, orders and whisper rules, the 150-offer
|
|
100
|
+
cap, and a catalog of today's size that fits two storage values.
|
|
101
|
+
- Scenarios, played by `overcrow-widget test` in OverCrow's headless
|
|
102
|
+
runtime, with synthetic `http.fetch` fixtures (no request reaches
|
|
103
|
+
warframe.market) and their reference images: `render` (both themes and
|
|
104
|
+
languages at 100 and 150 %), `detail` (both tabs, copies, back, clicks at
|
|
105
|
+
100 and 150 %), `tabs` (161 sellers: the 150 cap and "+11 more", at the
|
|
106
|
+
minimum and default widths, both themes and languages), `auto-refresh`
|
|
107
|
+
(every 30 s, nothing while hidden, the due reload when shown again, the
|
|
108
|
+
refresh button), `search`, `passive`, `cached`, `refresh`, `bounds` (a
|
|
109
|
+
version answer beyond its 4 KiB bound), `errors`, `unavailable`,
|
|
110
|
+
`refused` (without `network`) and `no-clipboard`.
|
|
111
|
+
|
|
112
|
+
```sh
|
|
113
|
+
node ../../scripts/prepare-widgets.mjs
|
|
114
|
+
overcrow-widget check && overcrow-widget package
|
|
115
|
+
node --test tests/*.test.mjs
|
|
116
|
+
overcrow-widget test --runtime <overcrow-widget-headless>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Cost
|
|
120
|
+
|
|
121
|
+
Measured on 2026-09-30 with OverCrow's headless runtime (release build),
|
|
122
|
+
on an AMD Ryzen 7 5800X3D Linux workstation (the VM in its Bubblewrap and
|
|
123
|
+
seccomp sandbox, without the per-widget cgroup) and in a Windows 11 virtual
|
|
124
|
+
machine (2 vCPU, cross-built runtime, full containment: Less Privileged
|
|
125
|
+
AppContainer, Job, mitigations). The catalog is synthetic, 3,892 items
|
|
126
|
+
shaped and sized like the provider's (1.63 MB). Figures of the VM process:
|
|
127
|
+
`RssAnon`, `VmHWM` and `schedstat` on Linux; private commit, private
|
|
128
|
+
working set and peak working set on Windows. Three runs each; Windows
|
|
129
|
+
samples every few milliseconds on 2 vCPU and can miss a short peak.
|
|
130
|
+
|
|
131
|
+
| | Linux | Windows (VM) |
|
|
132
|
+
| --- | --- | --- |
|
|
133
|
+
| VM private memory, catalog downloaded and stored (peak) | 5.0 MiB `RssAnon` | 5.7–5.8 MiB commit, 5.1–5.3 MiB private working set |
|
|
134
|
+
| VM private memory, at rest after searches | 3.7 MiB `RssAnon` | 3.4–5.1 MiB private working set |
|
|
135
|
+
| VM private memory, start from the stored catalog | 3.2 MiB `RssAnon` | 2.6–3.0 MiB commit |
|
|
136
|
+
| VM resident peak, shared pages included | 11.5–11.7 MiB `VmHWM` | 14.9–15.1 MiB peak working set |
|
|
137
|
+
| VM CPU, download, check and store the catalog | 126–137 ms in about 35 turns | 110–160 ms (15.6 ms clock) |
|
|
138
|
+
| VM CPU per keystroke of a search | about 0.3 ms | not resolved by the clock |
|
|
139
|
+
| VM CPU at rest | none: no timer runs once the catalog is loaded | the same |
|
|
140
|
+
| First load, catalog downloaded | searchable after about 16 turns (1.6 s after the answer), stored after about 35 turns at 100 ms (3.5 s) | the same turns |
|
|
141
|
+
| Searchable after a start from the stored catalog | 5 turns, about 0.5 s | the same turns |
|
|
142
|
+
| Network, a refresh | 1.64 MB (catalog) + 0.5 KB (version), plus about 0.6 KB of headers each | — |
|
|
143
|
+
| Network, a start with the current catalog stored | 0.5 KB (version) | — |
|
|
144
|
+
|
|
145
|
+
All within the 8 MB engineering goal per widget. The eleven scenarios of
|
|
146
|
+
3.0.1 pass on Windows too; their 22 images are identical, pixel for pixel,
|
|
147
|
+
to the Linux references.
|
|
148
|
+
|
|
149
|
+
The offers of one item (3.1.0), measured on 2026-10-08 on the same Linux
|
|
150
|
+
workstation with the provider's real answers, the VM in its sandbox with
|
|
151
|
+
the production cgroup leaf (a quarter of one core, 64 MiB):
|
|
152
|
+
|
|
153
|
+
| | 876 KB answer (1,718 orders, about 115 online) | synthetic 2 MB answer (3,895 orders) |
|
|
154
|
+
| --- | --- | --- |
|
|
155
|
+
| VM resident peak (`VmHWM`) | 9.4 MiB | 11.5 MiB |
|
|
156
|
+
| VM CPU per slice of 300 orders | 2 to 3 ms | the same |
|
|
157
|
+
| Last turn (sort, scene) | 3.5 to 6 ms | the same |
|
|
158
|
+
| Offers shown after the answer | 6 slices, about 0.6 s | 13 slices, about 1.3 s |
|
|
159
|
+
| Turns killed by the turn budget, 25 runs | none | none |
|
|
160
|
+
| One turn for the whole answer (rejected design) | killed 5 times in 5 | killed 5 times in 5 |
|
|
161
|
+
|
|
162
|
+
Sixty refreshes in a row leave the heap at 1.0 MiB and the resident memory
|
|
163
|
+
flat. The most offers found on a side among twelve popular items was 112
|
|
164
|
+
(Primed Flow): 933 scene nodes, about 15 ms of host work once when the list
|
|
165
|
+
arrives; 150 offers, the cap, stay near 1,250 nodes, far below the 4,096
|
|
166
|
+
nodes of a scene. Network, a refresh of a popular item: 0.4 to 1 MB, about
|
|
167
|
+
1.75 MB a minute every 30 s (the host's broker takes no compression).
|
|
168
|
+
|
|
169
|
+
At the declared ceiling (a synthetic 3.0 MB catalog of 7,200 items) the
|
|
170
|
+
first load takes about 60 turns, the VM peaks at 8.1 MiB private on Linux
|
|
171
|
+
and the default 16 MiB heap suffices. The catalog then needs four storage
|
|
172
|
+
values, beyond three: it is searchable but kept in memory only, and
|
|
173
|
+
downloaded again at the next start. A catalog beyond 3 MiB fails with
|
|
174
|
+
`response_body_limit`, and the widget shows "Catalog unavailable" (or keeps
|
|
175
|
+
its stored catalog). Not measured: the overlay's share and frame times
|
|
176
|
+
(the headless runtime renders on the CPU).
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"author": "PlayerVox",
|
|
3
|
+
"spdxLicense": "MIT",
|
|
4
|
+
"sourceUrl": "https://github.com/Valhallab/playervox-overcrow-releases/tree/main/widgets/warframe-market",
|
|
5
|
+
"preview": "assets/preview.png",
|
|
6
|
+
"defaultLocale": "en",
|
|
7
|
+
"localizations": [
|
|
8
|
+
{
|
|
9
|
+
"locale": "en",
|
|
10
|
+
"name": "Warframe Market",
|
|
11
|
+
"description": "Searches public PC items from a cached catalog, shows an item’s online sellers and buyers in two tabs, and copies a trade whisper when you click."
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"locale": "fr",
|
|
15
|
+
"name": "Marché Warframe",
|
|
16
|
+
"description": "Recherche les objets PC publics dans un catalogue en cache, affiche les vendeurs et acheteurs en ligne d’un objet dans deux onglets et copie un message d’échange sur un clic."
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"eyebrow": "Market",
|
|
3
|
+
"subtitle": "Trade assistant",
|
|
4
|
+
"platform": "PC market",
|
|
5
|
+
"search-label": "Search items",
|
|
6
|
+
"search-field": "Item name",
|
|
7
|
+
"placeholder": "Arcane Energize, Soma Prime…",
|
|
8
|
+
"clear": "Clear",
|
|
9
|
+
"hint-interactive": "Results update as you type",
|
|
10
|
+
"hint-passive": "Switch to interactive mode to search",
|
|
11
|
+
"status-loading": "Loading catalog…",
|
|
12
|
+
"status-catalog-unavailable": "Catalog unavailable",
|
|
13
|
+
"status-catalog-stale": "Catalog refresh unavailable · using cached items",
|
|
14
|
+
"status-storage_unavailable": "Storage unavailable · changes may not survive restart",
|
|
15
|
+
"status-orders_unavailable": "Orders unavailable · select an item to retry",
|
|
16
|
+
"status-loading-orders": "Loading offers…",
|
|
17
|
+
"status-refreshing": "Refreshing offers…",
|
|
18
|
+
"status-refresh-failed": "Refresh failed · showing the previous offers",
|
|
19
|
+
"status-ready": "{count} items cached · select an item to view offers",
|
|
20
|
+
"status-detail": "{count} items cached",
|
|
21
|
+
"empty-loading": "Loading the item catalog…",
|
|
22
|
+
"empty-unavailable": "The item catalog could not be loaded. Reopen the widget later to try again.",
|
|
23
|
+
"empty-start": "Find an item to compare offers and copy a trade whisper.",
|
|
24
|
+
"empty-no-match": "No matching items. Try a different name.",
|
|
25
|
+
"selected": "Selected item",
|
|
26
|
+
"back": "Back to results",
|
|
27
|
+
"refresh": "Refresh",
|
|
28
|
+
"min-sell": "Min sell / item",
|
|
29
|
+
"max-buy": "Max buy / item",
|
|
30
|
+
"sellers": "Sellers",
|
|
31
|
+
"buyers": "Buyers",
|
|
32
|
+
"no-sell-offers": "No sell offers available.",
|
|
33
|
+
"no-buy-offers": "No buy offers available.",
|
|
34
|
+
"more": "+{count} more",
|
|
35
|
+
"presence-ingame": "In game",
|
|
36
|
+
"presence-online": "Online",
|
|
37
|
+
"one-item": "1 item",
|
|
38
|
+
"per-trade": "{count} items · total price",
|
|
39
|
+
"copy": "Whisper",
|
|
40
|
+
"copy-pending": "Copying…",
|
|
41
|
+
"copy-copied": "Copied",
|
|
42
|
+
"copy-failed": "Retry",
|
|
43
|
+
"copy-to": "Copy whisper to {name}"
|
|
44
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"eyebrow": "Marché",
|
|
3
|
+
"subtitle": "Assistant d’échange",
|
|
4
|
+
"platform": "Marché PC",
|
|
5
|
+
"search-label": "Rechercher un objet",
|
|
6
|
+
"search-field": "Nom de l’objet",
|
|
7
|
+
"placeholder": "Arcane Energize, Soma Prime…",
|
|
8
|
+
"clear": "Effacer",
|
|
9
|
+
"hint-interactive": "Les résultats suivent votre saisie",
|
|
10
|
+
"hint-passive": "Passez en mode interactif pour chercher",
|
|
11
|
+
"status-loading": "Chargement du catalogue…",
|
|
12
|
+
"status-catalog-unavailable": "Catalogue indisponible",
|
|
13
|
+
"status-catalog-stale": "Actualisation impossible · objets en cache utilisés",
|
|
14
|
+
"status-storage_unavailable": "Stockage indisponible · les changements peuvent être perdus au redémarrage",
|
|
15
|
+
"status-orders_unavailable": "Offres indisponibles · sélectionnez un objet pour réessayer",
|
|
16
|
+
"status-loading-orders": "Chargement des offres…",
|
|
17
|
+
"status-refreshing": "Actualisation des offres…",
|
|
18
|
+
"status-refresh-failed": "Actualisation impossible · offres précédentes affichées",
|
|
19
|
+
"status-ready": "{count} objets en cache · sélectionnez un objet pour voir les offres",
|
|
20
|
+
"status-detail": "{count} objets en cache",
|
|
21
|
+
"empty-loading": "Chargement du catalogue d’objets…",
|
|
22
|
+
"empty-unavailable": "Le catalogue d’objets n’a pas pu être chargé. Rouvrez le widget plus tard pour réessayer.",
|
|
23
|
+
"empty-start": "Cherchez un objet pour comparer les offres et copier un message d’échange.",
|
|
24
|
+
"empty-no-match": "Aucun objet ne correspond. Essayez un autre nom.",
|
|
25
|
+
"selected": "Objet sélectionné",
|
|
26
|
+
"back": "Retour aux résultats",
|
|
27
|
+
"refresh": "Actualiser",
|
|
28
|
+
"min-sell": "Vente min. / objet",
|
|
29
|
+
"max-buy": "Achat max. / objet",
|
|
30
|
+
"sellers": "Vendeurs",
|
|
31
|
+
"buyers": "Acheteurs",
|
|
32
|
+
"no-sell-offers": "Aucune offre de vente.",
|
|
33
|
+
"no-buy-offers": "Aucune offre d’achat.",
|
|
34
|
+
"more": "+{count} autres",
|
|
35
|
+
"presence-ingame": "En jeu",
|
|
36
|
+
"presence-online": "En ligne",
|
|
37
|
+
"one-item": "1 objet",
|
|
38
|
+
"per-trade": "{count} objets · prix total",
|
|
39
|
+
"copy": "Chuchoter",
|
|
40
|
+
"copy-pending": "Copie…",
|
|
41
|
+
"copy-copied": "Copié",
|
|
42
|
+
"copy-failed": "Réessayer",
|
|
43
|
+
"copy-to": "Copier le message pour {name}"
|
|
44
|
+
}
|