zilmate 1.9.3 → 1.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/ad-creative/SKILL.md +362 -0
- package/.agents/skills/ad-creative/evals/evals.json +90 -0
- package/.agents/skills/ad-creative/references/generative-tools.md +637 -0
- package/.agents/skills/ad-creative/references/platform-specs.md +213 -0
- package/.agents/skills/ai-seo/SKILL.md +489 -0
- package/.agents/skills/ai-seo/evals/evals.json +90 -0
- package/.agents/skills/ai-seo/references/content-patterns.md +285 -0
- package/.agents/skills/ai-seo/references/content-types.md +71 -0
- package/.agents/skills/ai-seo/references/okf.md +104 -0
- package/.agents/skills/ai-seo/references/platform-ranking-factors.md +154 -0
- package/.agents/skills/clerk-backend-api/SKILL.md +426 -0
- package/.agents/skills/clerk-backend-api/evals/evals.json +87 -0
- package/.agents/skills/clerk-backend-api/scripts/api-specs-context.sh +30 -0
- package/.agents/skills/clerk-backend-api/scripts/execute-request.sh +88 -0
- package/.agents/skills/clerk-backend-api/scripts/extract-endpoint-detail.sh +165 -0
- package/.agents/skills/clerk-backend-api/scripts/extract-tag-endpoints.sh +208 -0
- package/.agents/skills/clerk-backend-api/scripts/extract-tags.js +14 -0
- package/.agents/skills/copy-editing/SKILL.md +457 -0
- package/.agents/skills/copy-editing/evals/evals.json +89 -0
- package/.agents/skills/copy-editing/references/checklist.md +66 -0
- package/.agents/skills/copy-editing/references/content-refresh.md +38 -0
- package/.agents/skills/copy-editing/references/plain-english-alternatives.md +394 -0
- package/.agents/skills/hyperframes/SKILL.md +163 -0
- package/.agents/skills/hyperframes-cli/SKILL.md +109 -0
- package/.agents/skills/hyperframes-cli/references/doctor-browser.md +45 -0
- package/.agents/skills/hyperframes-cli/references/init-and-scaffold.md +51 -0
- package/.agents/skills/hyperframes-cli/references/lambda.md +132 -0
- package/.agents/skills/hyperframes-cli/references/lint-validate-inspect.md +121 -0
- package/.agents/skills/hyperframes-cli/references/preview-render.md +109 -0
- package/.agents/skills/hyperframes-cli/references/upgrade-info-misc.md +75 -0
- package/.agents/skills/hyperframes-media/SKILL.md +97 -0
- package/.agents/skills/hyperframes-media/assets/sfx/CREDITS.md +35 -0
- package/.agents/skills/hyperframes-media/assets/sfx/manifest.json +97 -0
- package/.agents/skills/hyperframes-media/references/bgm.md +72 -0
- package/.agents/skills/hyperframes-media/references/captions/authoring.md +159 -0
- package/.agents/skills/hyperframes-media/references/captions/motion.md +87 -0
- package/.agents/skills/hyperframes-media/references/captions/transcript-handling.md +97 -0
- package/.agents/skills/hyperframes-media/references/remove-background.md +143 -0
- package/.agents/skills/hyperframes-media/references/requirements.md +29 -0
- package/.agents/skills/hyperframes-media/references/sfx.md +42 -0
- package/.agents/skills/hyperframes-media/references/transcribe.md +52 -0
- package/.agents/skills/hyperframes-media/references/tts-to-captions.md +24 -0
- package/.agents/skills/hyperframes-media/references/tts.md +135 -0
- package/.agents/skills/hyperframes-media/scripts/audio.mjs +282 -0
- package/.agents/skills/hyperframes-media/scripts/heygen-tts.mjs +121 -0
- package/.agents/skills/hyperframes-media/scripts/lib/bgm.mjs +235 -0
- package/.agents/skills/hyperframes-media/scripts/lib/heygen.mjs +131 -0
- package/.agents/skills/hyperframes-media/scripts/lib/sfx.mjs +128 -0
- package/.agents/skills/hyperframes-media/scripts/lib/tts.mjs +220 -0
- package/.agents/skills/hyperframes-media/scripts/lyria-recipe.py +128 -0
- package/.agents/skills/hyperframes-media/scripts/wait-bgm.mjs +167 -0
- package/.agents/skills/hyperframes-registry/SKILL.md +101 -0
- package/.agents/skills/hyperframes-registry/examples/add-block.md +51 -0
- package/.agents/skills/hyperframes-registry/examples/add-component.md +73 -0
- package/.agents/skills/hyperframes-registry/references/contributing.md +166 -0
- package/.agents/skills/hyperframes-registry/references/demo-html-pattern.md +54 -0
- package/.agents/skills/hyperframes-registry/references/discovery.md +215 -0
- package/.agents/skills/hyperframes-registry/references/install-locations.md +45 -0
- package/.agents/skills/hyperframes-registry/references/templates.md +417 -0
- package/.agents/skills/hyperframes-registry/references/wiring-blocks.md +61 -0
- package/.agents/skills/hyperframes-registry/references/wiring-components.md +39 -0
- package/.agents/skills/marketing-psychology/SKILL.md +455 -0
- package/.agents/skills/marketing-psychology/evals/evals.json +88 -0
- package/.agents/skills/mintlify/SKILL.md +328 -0
- package/.agents/skills/product-launch-video/SKILL.md +206 -0
- package/.agents/skills/product-launch-video/references/cut-catalog.md +220 -0
- package/.agents/skills/product-launch-video/references/motion-language.md +156 -0
- package/.agents/skills/product-launch-video/references/story-design.md +373 -0
- package/.agents/skills/product-launch-video/references/visual-design.md +126 -0
- package/.agents/skills/product-launch-video/scripts/assemble-index.mjs +570 -0
- package/.agents/skills/product-launch-video/scripts/audio.mjs +253 -0
- package/.agents/skills/product-launch-video/scripts/build-frame.mjs +536 -0
- package/.agents/skills/product-launch-video/scripts/captions.mjs +508 -0
- package/.agents/skills/product-launch-video/scripts/lib/assets.mjs +55 -0
- package/.agents/skills/product-launch-video/scripts/lib/dimensions.mjs +45 -0
- package/.agents/skills/product-launch-video/scripts/lib/storyboard.mjs +249 -0
- package/.agents/skills/product-launch-video/scripts/lib/tokens.mjs +204 -0
- package/.agents/skills/product-launch-video/scripts/lib/transition-registry.mjs +38 -0
- package/.agents/skills/product-launch-video/scripts/lib/transitions.json +71 -0
- package/.agents/skills/product-launch-video/scripts/stage-assets.mjs +39 -0
- package/.agents/skills/product-launch-video/scripts/transitions.mjs +320 -0
- package/.agents/skills/product-launch-video/sub-agents/frame-worker.md +74 -0
- package/.agents/skills/prompt-engineering-patterns/SKILL.md +144 -0
- package/.agents/skills/prompt-engineering-patterns/assets/few-shot-examples.json +106 -0
- package/.agents/skills/prompt-engineering-patterns/assets/prompt-template-library.md +264 -0
- package/.agents/skills/prompt-engineering-patterns/references/chain-of-thought.md +412 -0
- package/.agents/skills/prompt-engineering-patterns/references/details.md +338 -0
- package/.agents/skills/prompt-engineering-patterns/references/few-shot-learning.md +386 -0
- package/.agents/skills/prompt-engineering-patterns/references/prompt-optimization.md +428 -0
- package/.agents/skills/prompt-engineering-patterns/references/prompt-templates.md +484 -0
- package/.agents/skills/prompt-engineering-patterns/references/system-prompts.md +195 -0
- package/.agents/skills/prompt-engineering-patterns/scripts/optimize-prompt.py +279 -0
- package/.agents/skills/remotion-to-hyperframes/SKILL.md +127 -0
- package/.agents/skills/remotion-to-hyperframes/assets/.gitkeep +0 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/run.sh +249 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/README.md +41 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/expected.json +26 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/hf-src/index.html +61 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/package.json +14 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/remotion.config.ts +13 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/src/Root.tsx +13 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/src/TitleCard.tsx +34 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/src/index.ts +4 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/tsconfig.json +15 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/README.md +54 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/expected.json +29 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/hf-src/index.html +118 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/package.json +14 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/remotion.config.ts +13 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/src/MultiScene.tsx +105 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/src/Root.tsx +13 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/src/index.ts +4 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/tsconfig.json +15 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/setup.sh +34 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/README.md +85 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/expected.json +41 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/hf-src/index.html +269 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/package.json +15 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/remotion.config.ts +13 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/Root.tsx +27 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/Stargazed.tsx +37 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/components/AnimatedNumber.tsx +23 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/components/StatCard.tsx +59 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/components/UnderlinedText.tsx +47 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/index.ts +4 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/scenes/OutroScene.tsx +18 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/scenes/StatsScene.tsx +34 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/scenes/TitleScene.tsx +55 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/tsconfig.json +15 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/README.md +51 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/01-use-state.tsx +29 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/02-use-effect-deps.tsx +29 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/03-async-metadata.tsx +39 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/04-third-party-react.tsx +30 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/05-lambda-config.tsx +38 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/06-warnings-only.tsx +36 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/07-custom-hook.tsx +28 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/08-mixed.tsx +41 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/expected.json +85 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/validate.sh +110 -0
- package/.agents/skills/remotion-to-hyperframes/references/api-map.md +142 -0
- package/.agents/skills/remotion-to-hyperframes/references/escape-hatch.md +115 -0
- package/.agents/skills/remotion-to-hyperframes/references/eval.md +140 -0
- package/.agents/skills/remotion-to-hyperframes/references/fonts.md +112 -0
- package/.agents/skills/remotion-to-hyperframes/references/limitations.md +136 -0
- package/.agents/skills/remotion-to-hyperframes/references/lottie.md +121 -0
- package/.agents/skills/remotion-to-hyperframes/references/media.md +149 -0
- package/.agents/skills/remotion-to-hyperframes/references/parameters.md +167 -0
- package/.agents/skills/remotion-to-hyperframes/references/sequencing.md +195 -0
- package/.agents/skills/remotion-to-hyperframes/references/timing.md +165 -0
- package/.agents/skills/remotion-to-hyperframes/references/transitions.md +114 -0
- package/.agents/skills/remotion-to-hyperframes/scripts/.gitkeep +0 -0
- package/.agents/skills/remotion-to-hyperframes/scripts/frame_strip.sh +107 -0
- package/.agents/skills/remotion-to-hyperframes/scripts/lint_source.py +358 -0
- package/.agents/skills/remotion-to-hyperframes/scripts/render_diff.sh +103 -0
- package/.agents/skills/remotion-to-hyperframes/scripts/tests/fixtures/blocker.tsx +50 -0
- package/.agents/skills/remotion-to-hyperframes/scripts/tests/fixtures/clean.tsx +46 -0
- package/.agents/skills/remotion-to-hyperframes/scripts/tests/smoke.sh +90 -0
- package/.agents/skills/seo-audit/SKILL.md +497 -0
- package/.agents/skills/seo-audit/evals/evals.json +136 -0
- package/.agents/skills/seo-audit/references/ai-writing-detection.md +200 -0
- package/.agents/skills/seo-audit/references/international-seo.md +230 -0
- package/README.md +4 -2
- package/SDK.md +64 -1
- package/dist/agents/coding.agent.d.ts +632 -0
- package/dist/agents/coding.agent.d.ts.map +1 -1
- package/dist/agents/coding.agent.js +11 -3
- package/dist/agents/coding.agent.js.map +1 -1
- package/dist/agents/developer-helper.agent.d.ts +704 -0
- package/dist/agents/developer-helper.agent.d.ts.map +1 -1
- package/dist/agents/developer-helper.agent.js +6 -0
- package/dist/agents/developer-helper.agent.js.map +1 -1
- package/dist/agents/manager.d.ts +1009 -4
- package/dist/agents/manager.d.ts.map +1 -1
- package/dist/agents/manager.js +16 -5
- package/dist/agents/manager.js.map +1 -1
- package/dist/agents/security.agent.d.ts +157 -3
- package/dist/agents/security.agent.d.ts.map +1 -1
- package/dist/agents/security.agent.js +3 -0
- package/dist/agents/security.agent.js.map +1 -1
- package/dist/agents/swarm/main.js +1 -1
- package/dist/agents/swarm/main.js.map +1 -1
- package/dist/agents/swarm/registry.d.ts.map +1 -1
- package/dist/agents/swarm/registry.js +232 -26
- package/dist/agents/swarm/registry.js.map +1 -1
- package/dist/cli/chat.d.ts +1 -1
- package/dist/cli/chat.d.ts.map +1 -1
- package/dist/cli/chat.js +32 -10
- package/dist/cli/chat.js.map +1 -1
- package/dist/cli/doctor.d.ts +14 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +91 -0
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/format.d.ts +1 -0
- package/dist/cli/format.d.ts.map +1 -1
- package/dist/cli/format.js +68 -14
- package/dist/cli/format.js.map +1 -1
- package/dist/cli/menu.d.ts.map +1 -1
- package/dist/cli/menu.js +102 -0
- package/dist/cli/menu.js.map +1 -1
- package/dist/cli/setup.d.ts +10 -0
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +187 -3
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/update.d.ts +2 -0
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +89 -1
- package/dist/cli/update.js.map +1 -1
- package/dist/config/env.d.ts +12 -0
- package/dist/config/env.d.ts.map +1 -1
- package/dist/config/env.js +19 -5
- package/dist/config/env.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +61 -5
- package/dist/index.js.map +1 -1
- package/dist/jobs/trigger-orchestrator.d.ts +5 -1
- package/dist/jobs/trigger-orchestrator.d.ts.map +1 -1
- package/dist/jobs/trigger-orchestrator.js +29 -9
- package/dist/jobs/trigger-orchestrator.js.map +1 -1
- package/dist/jobs/trigger-router.d.ts.map +1 -1
- package/dist/jobs/trigger-router.js +3 -2
- package/dist/jobs/trigger-router.js.map +1 -1
- package/dist/memory/corporate-wiki.d.ts +15 -0
- package/dist/memory/corporate-wiki.d.ts.map +1 -0
- package/dist/memory/corporate-wiki.js +152 -0
- package/dist/memory/corporate-wiki.js.map +1 -0
- package/dist/observability/doctor.d.ts.map +1 -1
- package/dist/observability/doctor.js +12 -4
- package/dist/observability/doctor.js.map +1 -1
- package/dist/pre-init.d.ts +2 -0
- package/dist/pre-init.d.ts.map +1 -0
- package/dist/pre-init.js +3 -0
- package/dist/pre-init.js.map +1 -0
- package/dist/runtime/chat-bridge.d.ts.map +1 -1
- package/dist/runtime/chat-bridge.js +33 -2
- package/dist/runtime/chat-bridge.js.map +1 -1
- package/dist/runtime/swarm.d.ts +0 -1
- package/dist/runtime/swarm.d.ts.map +1 -1
- package/dist/runtime/swarm.js +26 -15
- package/dist/runtime/swarm.js.map +1 -1
- package/dist/safety/approvals.d.ts +2 -2
- package/dist/safety/approvals.d.ts.map +1 -1
- package/dist/safety/approvals.js +47 -1
- package/dist/safety/approvals.js.map +1 -1
- package/dist/safety/redaction.d.ts.map +1 -1
- package/dist/safety/redaction.js +10 -0
- package/dist/safety/redaction.js.map +1 -1
- package/dist/server.d.ts +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -0
- package/dist/server.js.map +1 -1
- package/dist/tools/cloud.tool.d.ts +394 -0
- package/dist/tools/cloud.tool.d.ts.map +1 -0
- package/dist/tools/cloud.tool.js +784 -0
- package/dist/tools/cloud.tool.js.map +1 -0
- package/dist/tools/computer-use.tool.d.ts +6 -6
- package/dist/tools/corporate-wiki.tool.d.ts +22 -0
- package/dist/tools/corporate-wiki.tool.d.ts.map +1 -0
- package/dist/tools/corporate-wiki.tool.js +39 -0
- package/dist/tools/corporate-wiki.tool.js.map +1 -0
- package/dist/tools/desktop.tool.d.ts +96 -0
- package/dist/tools/desktop.tool.d.ts.map +1 -1
- package/dist/tools/desktop.tool.js +439 -0
- package/dist/tools/desktop.tool.js.map +1 -1
- package/dist/tools/devops.tool.d.ts +162 -0
- package/dist/tools/devops.tool.d.ts.map +1 -0
- package/dist/tools/devops.tool.js +377 -0
- package/dist/tools/devops.tool.js.map +1 -0
- package/dist/tools/multimedia.tool.d.ts +126 -0
- package/dist/tools/multimedia.tool.d.ts.map +1 -0
- package/dist/tools/multimedia.tool.js +533 -0
- package/dist/tools/multimedia.tool.js.map +1 -0
- package/dist/tools/osint.tool.d.ts +6 -6
- package/dist/tools/sandbox-dev.tool.d.ts +15 -0
- package/dist/tools/sandbox-dev.tool.d.ts.map +1 -0
- package/dist/tools/sandbox-dev.tool.js +139 -0
- package/dist/tools/sandbox-dev.tool.js.map +1 -0
- package/dist/tools/setup-assistant.tool.d.ts +1 -1
- package/dist/tools/shell.tool.d.ts +82 -0
- package/dist/tools/shell.tool.d.ts.map +1 -1
- package/dist/tools/shell.tool.js +192 -1
- package/dist/tools/shell.tool.js.map +1 -1
- package/dist/tools/swarm-ops.tool.d.ts +14 -0
- package/dist/tools/swarm-ops.tool.d.ts.map +1 -1
- package/dist/tools/swarm-ops.tool.js +44 -0
- package/dist/tools/swarm-ops.tool.js.map +1 -1
- package/dist/tools/sysops.tool.d.ts +157 -0
- package/dist/tools/sysops.tool.d.ts.map +1 -0
- package/dist/tools/sysops.tool.js +643 -0
- package/dist/tools/sysops.tool.js.map +1 -0
- package/dist/voice/cascade.d.ts +1 -0
- package/dist/voice/cascade.d.ts.map +1 -1
- package/dist/voice/cascade.js +16 -1
- package/dist/voice/cascade.js.map +1 -1
- package/dist/voice/deepgram.d.ts.map +1 -1
- package/dist/voice/deepgram.js +34 -2
- package/dist/voice/deepgram.js.map +1 -1
- package/dist/voice/terminal.d.ts +1 -0
- package/dist/voice/terminal.d.ts.map +1 -1
- package/dist/voice/terminal.js +28 -0
- package/dist/voice/terminal.js.map +1 -1
- package/dist/voice/types.d.ts +2 -0
- package/dist/voice/types.d.ts.map +1 -1
- package/package.json +9 -1
- package/scripts/release-github.mjs +23 -18
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { AbsoluteFill } from "remotion";
|
|
2
|
+
import { StatCard } from "../components/StatCard";
|
|
3
|
+
|
|
4
|
+
interface Stat {
|
|
5
|
+
label: string;
|
|
6
|
+
value: number;
|
|
7
|
+
color: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
stats: Stat[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const StatsScene: React.FC<Props> = ({ stats }) => (
|
|
15
|
+
<AbsoluteFill
|
|
16
|
+
style={{
|
|
17
|
+
justifyContent: "center",
|
|
18
|
+
alignItems: "center",
|
|
19
|
+
gap: 48,
|
|
20
|
+
flexDirection: "row",
|
|
21
|
+
fontFamily: "Helvetica, Arial, sans-serif",
|
|
22
|
+
}}
|
|
23
|
+
>
|
|
24
|
+
{stats.map((stat, i) => (
|
|
25
|
+
<StatCard
|
|
26
|
+
key={stat.label}
|
|
27
|
+
label={stat.label}
|
|
28
|
+
value={stat.value}
|
|
29
|
+
color={stat.color}
|
|
30
|
+
delayInFrames={i * 12}
|
|
31
|
+
/>
|
|
32
|
+
))}
|
|
33
|
+
</AbsoluteFill>
|
|
34
|
+
);
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { AbsoluteFill, interpolate, spring, useCurrentFrame, useVideoConfig } from "remotion";
|
|
2
|
+
|
|
3
|
+
interface Props {
|
|
4
|
+
title: string;
|
|
5
|
+
subtitle: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const TitleScene: React.FC<Props> = ({ title, subtitle }) => {
|
|
9
|
+
const frame = useCurrentFrame();
|
|
10
|
+
const { fps } = useVideoConfig();
|
|
11
|
+
|
|
12
|
+
const titleScale = spring({
|
|
13
|
+
frame,
|
|
14
|
+
fps,
|
|
15
|
+
config: { damping: 12, stiffness: 100, mass: 1 },
|
|
16
|
+
});
|
|
17
|
+
const subtitleOpacity = interpolate(frame, [20, 40], [0, 1], {
|
|
18
|
+
extrapolateLeft: "clamp",
|
|
19
|
+
extrapolateRight: "clamp",
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<AbsoluteFill
|
|
24
|
+
style={{
|
|
25
|
+
justifyContent: "center",
|
|
26
|
+
alignItems: "center",
|
|
27
|
+
flexDirection: "column",
|
|
28
|
+
fontFamily: "Helvetica, Arial, sans-serif",
|
|
29
|
+
}}
|
|
30
|
+
>
|
|
31
|
+
<div
|
|
32
|
+
style={{
|
|
33
|
+
fontSize: 160,
|
|
34
|
+
fontWeight: 900,
|
|
35
|
+
color: "#ffffff",
|
|
36
|
+
letterSpacing: "0.05em",
|
|
37
|
+
transform: `scale(${titleScale})`,
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
{title}
|
|
41
|
+
</div>
|
|
42
|
+
<div
|
|
43
|
+
style={{
|
|
44
|
+
fontSize: 36,
|
|
45
|
+
fontWeight: 400,
|
|
46
|
+
color: "#9ca3af",
|
|
47
|
+
marginTop: 24,
|
|
48
|
+
opacity: subtitleOpacity,
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
{subtitle}
|
|
52
|
+
</div>
|
|
53
|
+
</AbsoluteFill>
|
|
54
|
+
);
|
|
55
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2018",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"jsx": "react-jsx",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"moduleResolution": "node",
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"isolatedModules": true
|
|
13
|
+
},
|
|
14
|
+
"include": ["src"]
|
|
15
|
+
}
|
package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/README.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Tier 4 — escape-hatch
|
|
2
|
+
|
|
3
|
+
## What it tests
|
|
4
|
+
|
|
5
|
+
T4 is the **lint-only** tier. There are no renders to diff — the skill is
|
|
6
|
+
graded on whether it correctly _refuses_ to translate each case (and
|
|
7
|
+
recommends the runtime interop pattern from PR #214 instead) or, where
|
|
8
|
+
appropriate, translates after dropping warning-level decorations.
|
|
9
|
+
|
|
10
|
+
Each `cases/*.tsx` file is a minimal Remotion composition that
|
|
11
|
+
demonstrates one specific pattern. The skill should:
|
|
12
|
+
|
|
13
|
+
1. Run `scripts/lint_source.py` over the source.
|
|
14
|
+
2. Compare the JSON output to `expected.json` for that case.
|
|
15
|
+
3. Take the documented `skill_action`:
|
|
16
|
+
- `refuse_translation_recommend_interop` — print the rationale + link to
|
|
17
|
+
the PR #214 interop guide; do not produce HF output.
|
|
18
|
+
- `drop_lambda_code_translate_remainder_if_clean` — drop the
|
|
19
|
+
`@remotion/lambda` code with a note; translate the rest only if no
|
|
20
|
+
other blockers are present.
|
|
21
|
+
- `translate_after_dropping_wrappers` — translate normally; drop
|
|
22
|
+
`useCallback` / `useMemo` / `delayRender` wrappers.
|
|
23
|
+
- `inline_hook_body_if_pure` — inline the custom hook's body if it's a
|
|
24
|
+
pure derivation of `useCurrentFrame`; otherwise bow out.
|
|
25
|
+
|
|
26
|
+
## Cases
|
|
27
|
+
|
|
28
|
+
| # | File | Expected finding | Notes |
|
|
29
|
+
| --- | -------------------------- | ----------------------------------- | ----------------------------------------------- |
|
|
30
|
+
| 01 | `01-use-state.tsx` | blocker `r2hf/use-state` | useState driving animation |
|
|
31
|
+
| 02 | `02-use-effect-deps.tsx` | blocker `r2hf/use-effect-deps` | useEffect/useLayoutEffect with non-empty deps |
|
|
32
|
+
| 03 | `03-async-metadata.tsx` | blocker `r2hf/async-metadata` | calculateMetadata returns a Promise |
|
|
33
|
+
| 04 | `04-third-party-react.tsx` | blocker `r2hf/third-party-react-ui` | imports `@mui/material` |
|
|
34
|
+
| 05 | `05-lambda-config.tsx` | warning `r2hf/lambda-import` | imports `@remotion/lambda` — drops, translates |
|
|
35
|
+
| 06 | `06-warnings-only.tsx` | warnings only | delayRender / useCallback / useMemo |
|
|
36
|
+
| 07 | `07-custom-hook.tsx` | warning `r2hf/custom-hook` | locally-defined `useFadeIn` (export const form) |
|
|
37
|
+
| 08 | `08-mixed.tsx` | 3 blockers + 1 warning | aggregate-findings test |
|
|
38
|
+
|
|
39
|
+
## Validation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
./validate.sh
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The script runs `lint_source.py` against each case and asserts:
|
|
46
|
+
|
|
47
|
+
- Each expected blocker rule fires with severity `blocker`.
|
|
48
|
+
- Each expected warning rule fires with severity `warning` (or stronger).
|
|
49
|
+
- `lint_source.py`'s exit code is 1 when blockers are expected, 0 otherwise.
|
|
50
|
+
|
|
51
|
+
T4 passes when every case matches its expected output. No renders involved.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// T4 case 01 — useState drives animation.
|
|
2
|
+
//
|
|
3
|
+
// Should be detected by lint_source.py as blocker r2hf/use-state.
|
|
4
|
+
// The skill should refuse to translate and recommend the runtime interop
|
|
5
|
+
// pattern from PR #214.
|
|
6
|
+
//
|
|
7
|
+
// Why this is a blocker: useState is React's component-local mutable state.
|
|
8
|
+
// HF's seek-driven model produces deterministic frames from a single time
|
|
9
|
+
// value — there's no per-frame React render cycle to update state on.
|
|
10
|
+
|
|
11
|
+
import React, { useState } from "react";
|
|
12
|
+
import { AbsoluteFill, useCurrentFrame } from "remotion";
|
|
13
|
+
|
|
14
|
+
export const StateDriven: React.FC = () => {
|
|
15
|
+
const frame = useCurrentFrame();
|
|
16
|
+
const [hue, setHue] = useState(0);
|
|
17
|
+
|
|
18
|
+
// Even if this looks innocuous, the setHue call breaks determinism: HF
|
|
19
|
+
// can't reproduce React state mutations across seeks.
|
|
20
|
+
if (frame % 30 === 0 && hue < 360) {
|
|
21
|
+
setHue((h) => h + 30);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<AbsoluteFill style={{ background: `hsl(${hue}, 80%, 50%)` }}>
|
|
26
|
+
<div>frame {frame}</div>
|
|
27
|
+
</AbsoluteFill>
|
|
28
|
+
);
|
|
29
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// T4 case 02 — useEffect with non-empty deps performs side effects per render.
|
|
2
|
+
//
|
|
3
|
+
// Should be detected by lint_source.py as blocker r2hf/use-effect-deps.
|
|
4
|
+
// The skill should refuse to translate.
|
|
5
|
+
//
|
|
6
|
+
// Why this is a blocker: side effects (network, DOM mutation outside the
|
|
7
|
+
// rendered tree, timers) don't translate to a seek-driven model. HF assumes
|
|
8
|
+
// the page is fully rendered and pure between seeks.
|
|
9
|
+
|
|
10
|
+
import React, { useEffect, useRef } from "react";
|
|
11
|
+
import { AbsoluteFill, useCurrentFrame } from "remotion";
|
|
12
|
+
|
|
13
|
+
export const SideEffectDriven: React.FC = () => {
|
|
14
|
+
const frame = useCurrentFrame();
|
|
15
|
+
const canvasRef = useRef<HTMLCanvasElement>(null);
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
const canvas = canvasRef.current;
|
|
19
|
+
if (!canvas) return;
|
|
20
|
+
const ctx = canvas.getContext("2d");
|
|
21
|
+
ctx?.fillRect(frame, frame, 10, 10);
|
|
22
|
+
}, [frame]);
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<AbsoluteFill>
|
|
26
|
+
<canvas ref={canvasRef} width={1280} height={720} />
|
|
27
|
+
</AbsoluteFill>
|
|
28
|
+
);
|
|
29
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// T4 case 03 — calculateMetadata returns a Promise.
|
|
2
|
+
//
|
|
3
|
+
// Should be detected by lint_source.py as blocker r2hf/async-metadata.
|
|
4
|
+
// The skill should refuse to translate.
|
|
5
|
+
//
|
|
6
|
+
// Why this is a blocker: HF needs the composition's duration, dimensions,
|
|
7
|
+
// and props known up-front to produce HTML and seed the timeline. Async
|
|
8
|
+
// metadata fetched from a server at render time has no equivalent in HF —
|
|
9
|
+
// the metadata would need to be resolved at build time before the HTML is
|
|
10
|
+
// authored.
|
|
11
|
+
|
|
12
|
+
import React from "react";
|
|
13
|
+
import { AbsoluteFill, useCurrentFrame } from "remotion";
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
text: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const AsyncMetadataDriven: React.FC<Props> = ({ text }) => {
|
|
20
|
+
const frame = useCurrentFrame();
|
|
21
|
+
return (
|
|
22
|
+
<AbsoluteFill>
|
|
23
|
+
<div>
|
|
24
|
+
{text} · frame {frame}
|
|
25
|
+
</div>
|
|
26
|
+
</AbsoluteFill>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const calculateMetadata = async ({ props }: { props: Props }) => {
|
|
31
|
+
const response = await fetch(
|
|
32
|
+
`https://api.example.com/duration?text=${encodeURIComponent(props.text)}`,
|
|
33
|
+
);
|
|
34
|
+
const { durationInFrames } = await response.json();
|
|
35
|
+
return {
|
|
36
|
+
durationInFrames,
|
|
37
|
+
fps: 30,
|
|
38
|
+
};
|
|
39
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// T4 case 04 — Imports from a third-party React UI library.
|
|
2
|
+
//
|
|
3
|
+
// Should be detected by lint_source.py as blocker r2hf/third-party-react-ui.
|
|
4
|
+
// The skill should refuse to translate.
|
|
5
|
+
//
|
|
6
|
+
// Why this is a blocker: a Material-UI Button (or any React UI library
|
|
7
|
+
// component) is a React-only abstraction with internal hooks, refs, and
|
|
8
|
+
// theme provider context. Translating it to HTML+CSS would require
|
|
9
|
+
// re-implementing the design system, which is out of scope for a video
|
|
10
|
+
// translation skill. Use the runtime interop pattern from PR #214 to keep
|
|
11
|
+
// these components rendering through Remotion's React tree.
|
|
12
|
+
|
|
13
|
+
import React from "react";
|
|
14
|
+
import { Button } from "@mui/material";
|
|
15
|
+
import { AbsoluteFill, useCurrentFrame, interpolate } from "remotion";
|
|
16
|
+
|
|
17
|
+
export const MuiDriven: React.FC = () => {
|
|
18
|
+
const frame = useCurrentFrame();
|
|
19
|
+
const opacity = interpolate(frame, [0, 30], [0, 1], { extrapolateRight: "clamp" });
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<AbsoluteFill style={{ alignItems: "center", justifyContent: "center" }}>
|
|
23
|
+
<div style={{ opacity }}>
|
|
24
|
+
<Button variant="contained" color="primary">
|
|
25
|
+
Click me · frame {frame}
|
|
26
|
+
</Button>
|
|
27
|
+
</div>
|
|
28
|
+
</AbsoluteFill>
|
|
29
|
+
);
|
|
30
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// T4 case 05 — Imports @remotion/lambda for distributed rendering config.
|
|
2
|
+
//
|
|
3
|
+
// Should be detected by lint_source.py as warning r2hf/lambda-import.
|
|
4
|
+
// The skill drops the Lambda code with a note (HF runs single-machine
|
|
5
|
+
// today) and translates the rest of the composition.
|
|
6
|
+
//
|
|
7
|
+
// Why this is a warning, not a blocker: @remotion/lambda config is
|
|
8
|
+
// orthogonal to the rendered composition — it's deployment configuration,
|
|
9
|
+
// not animation logic. Treating it as a hard blocker would refuse
|
|
10
|
+
// translation for compositions that are otherwise clean. The skill drops
|
|
11
|
+
// the Lambda calls in step 3 (Generate) and writes a TRANSLATION_NOTES.md
|
|
12
|
+
// entry so the user knows to set up HF rendering separately.
|
|
13
|
+
|
|
14
|
+
import React from "react";
|
|
15
|
+
import { renderMediaOnLambda } from "@remotion/lambda";
|
|
16
|
+
import { AbsoluteFill, useCurrentFrame, interpolate } from "remotion";
|
|
17
|
+
|
|
18
|
+
export const LambdaConfigured: React.FC = () => {
|
|
19
|
+
const frame = useCurrentFrame();
|
|
20
|
+
const opacity = interpolate(frame, [0, 30], [0, 1]);
|
|
21
|
+
return (
|
|
22
|
+
<AbsoluteFill style={{ opacity }}>
|
|
23
|
+
<div>frame {frame}</div>
|
|
24
|
+
</AbsoluteFill>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Rendered at scale via Lambda — no HF equivalent.
|
|
29
|
+
export async function renderViaLambda() {
|
|
30
|
+
return renderMediaOnLambda({
|
|
31
|
+
region: "us-east-1",
|
|
32
|
+
functionName: "remotion-render",
|
|
33
|
+
composition: "LambdaConfigured",
|
|
34
|
+
serveUrl: "https://example.com/bundle",
|
|
35
|
+
inputProps: {},
|
|
36
|
+
codec: "h264",
|
|
37
|
+
});
|
|
38
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// T4 case 06 — Patterns that warn but don't block.
|
|
2
|
+
//
|
|
3
|
+
// Should be detected by lint_source.py with:
|
|
4
|
+
// - r2hf/delay-render (warning) — drop the call; HF handles asset readiness
|
|
5
|
+
// - r2hf/use-callback (warning) — decorative, drop the wrapper
|
|
6
|
+
// - r2hf/use-memo (warning) — decorative, drop the wrapper
|
|
7
|
+
//
|
|
8
|
+
// 0 blockers expected — the skill should still translate this composition
|
|
9
|
+
// after dropping the wrappers. delayRender is paired with continueRender via
|
|
10
|
+
// an empty-deps useEffect (mount-once side effect), which doesn't trip the
|
|
11
|
+
// use-effect-deps blocker.
|
|
12
|
+
|
|
13
|
+
import React, { useCallback, useMemo } from "react";
|
|
14
|
+
import { AbsoluteFill, delayRender, continueRender, useCurrentFrame, interpolate } from "remotion";
|
|
15
|
+
|
|
16
|
+
const handle = delayRender();
|
|
17
|
+
// Resolve the handle once at module load — no per-frame side effects.
|
|
18
|
+
queueMicrotask(() => continueRender(handle));
|
|
19
|
+
|
|
20
|
+
export const WarningsOnly: React.FC = () => {
|
|
21
|
+
const frame = useCurrentFrame();
|
|
22
|
+
|
|
23
|
+
// useCallback / useMemo — decorative for render-perf in React, no equivalent
|
|
24
|
+
// needed in the seek-driven HF model.
|
|
25
|
+
const opacity = useMemo(
|
|
26
|
+
() => interpolate(frame, [0, 30], [0, 1], { extrapolateRight: "clamp" }),
|
|
27
|
+
[frame],
|
|
28
|
+
);
|
|
29
|
+
const onMount = useCallback(() => {}, []);
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<AbsoluteFill style={{ opacity }} onClick={onMount}>
|
|
33
|
+
<div>frame {frame}</div>
|
|
34
|
+
</AbsoluteFill>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// T4 case 07 — Locally-defined custom hook.
|
|
2
|
+
//
|
|
3
|
+
// Should be detected by lint_source.py as warning r2hf/custom-hook.
|
|
4
|
+
// 0 blockers expected — the skill can attempt translation if the hook body
|
|
5
|
+
// is pure (derives from props/frame alone).
|
|
6
|
+
//
|
|
7
|
+
// Why this is a warning: custom hooks vary widely in what they do. Some are
|
|
8
|
+
// pure derivations of useCurrentFrame (translatable — inline the body); some
|
|
9
|
+
// wrap useState/useEffect (blocker — but those will be caught by the other
|
|
10
|
+
// rules independently). The warning prompts the agent to inspect the body.
|
|
11
|
+
|
|
12
|
+
import React from "react";
|
|
13
|
+
import { AbsoluteFill, useCurrentFrame, interpolate } from "remotion";
|
|
14
|
+
|
|
15
|
+
// Custom hook — pure derivation from frame, no state. Translates fine.
|
|
16
|
+
function useFadeIn(durationInFrames: number) {
|
|
17
|
+
const frame = useCurrentFrame();
|
|
18
|
+
return interpolate(frame, [0, durationInFrames], [0, 1], { extrapolateRight: "clamp" });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const CustomHookDriven: React.FC = () => {
|
|
22
|
+
const opacity = useFadeIn(30);
|
|
23
|
+
return (
|
|
24
|
+
<AbsoluteFill style={{ opacity }}>
|
|
25
|
+
<div>fading in</div>
|
|
26
|
+
</AbsoluteFill>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// T4 case 08 — Multiple blockers + multiple warnings in one file.
|
|
2
|
+
//
|
|
3
|
+
// Should report:
|
|
4
|
+
// blockers: r2hf/use-state, r2hf/use-effect-deps, r2hf/third-party-react-ui
|
|
5
|
+
// warnings: r2hf/use-callback (also r2hf/delay-render via the import chain
|
|
6
|
+
// would only fire if delayRender is actually called)
|
|
7
|
+
//
|
|
8
|
+
// Tests that the linter aggregates findings correctly and does not stop at
|
|
9
|
+
// the first blocker.
|
|
10
|
+
|
|
11
|
+
import React, { useState, useEffect, useCallback } from "react";
|
|
12
|
+
import { AbsoluteFill, useCurrentFrame } from "remotion";
|
|
13
|
+
import { Card } from "@chakra-ui/react";
|
|
14
|
+
|
|
15
|
+
interface Item {
|
|
16
|
+
id: string;
|
|
17
|
+
label: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const MixedBlockers: React.FC = () => {
|
|
21
|
+
const frame = useCurrentFrame();
|
|
22
|
+
const [items, setItems] = useState<Item[]>([]);
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
fetch("/api/items")
|
|
26
|
+
.then((r) => r.json())
|
|
27
|
+
.then(setItems);
|
|
28
|
+
}, [frame]);
|
|
29
|
+
|
|
30
|
+
const onClick = useCallback(() => {
|
|
31
|
+
setItems((prev) => [...prev, { id: String(prev.length), label: "new" }]);
|
|
32
|
+
}, []);
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<AbsoluteFill onClick={onClick}>
|
|
36
|
+
{items.map((item) => (
|
|
37
|
+
<Card key={item.id}>{item.label}</Card>
|
|
38
|
+
))}
|
|
39
|
+
</AbsoluteFill>
|
|
40
|
+
);
|
|
41
|
+
};
|
package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/expected.json
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tier": 4,
|
|
3
|
+
"name": "escape-hatch",
|
|
4
|
+
"description": "Lint-only fixture set. Each case demonstrates a Remotion pattern the skill cannot or should not translate cleanly. The skill is graded on whether lint_source.py emits the right finding for each case — there are no renders to compare. T4 passes when every case triggers its expected rule and no others.",
|
|
5
|
+
"cases": [
|
|
6
|
+
{
|
|
7
|
+
"file": "01-use-state.tsx",
|
|
8
|
+
"expected": {
|
|
9
|
+
"blockers": [{ "rule": "r2hf/use-state", "min_count": 1 }],
|
|
10
|
+
"warnings": [],
|
|
11
|
+
"skill_action": "refuse_translation_recommend_interop"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"file": "02-use-effect-deps.tsx",
|
|
16
|
+
"expected": {
|
|
17
|
+
"blockers": [{ "rule": "r2hf/use-effect-deps", "min_count": 1 }],
|
|
18
|
+
"warnings": [],
|
|
19
|
+
"skill_action": "refuse_translation_recommend_interop"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"file": "03-async-metadata.tsx",
|
|
24
|
+
"expected": {
|
|
25
|
+
"blockers": [{ "rule": "r2hf/async-metadata", "min_count": 1 }],
|
|
26
|
+
"warnings": [],
|
|
27
|
+
"skill_action": "refuse_translation_recommend_interop"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"file": "04-third-party-react.tsx",
|
|
32
|
+
"expected": {
|
|
33
|
+
"blockers": [{ "rule": "r2hf/third-party-react-ui", "min_count": 1 }],
|
|
34
|
+
"warnings": [],
|
|
35
|
+
"skill_action": "refuse_translation_recommend_interop"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"file": "05-lambda-config.tsx",
|
|
40
|
+
"expected": {
|
|
41
|
+
"blockers": [],
|
|
42
|
+
"warnings": [{ "rule": "r2hf/lambda-import", "min_count": 1 }],
|
|
43
|
+
"skill_action": "drop_lambda_code_translate_remainder_if_clean"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"file": "06-warnings-only.tsx",
|
|
48
|
+
"expected": {
|
|
49
|
+
"blockers": [],
|
|
50
|
+
"warnings": [
|
|
51
|
+
{ "rule": "r2hf/delay-render", "min_count": 1 },
|
|
52
|
+
{ "rule": "r2hf/use-callback", "min_count": 1 },
|
|
53
|
+
{ "rule": "r2hf/use-memo", "min_count": 1 }
|
|
54
|
+
],
|
|
55
|
+
"skill_action": "translate_after_dropping_wrappers"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"file": "07-custom-hook.tsx",
|
|
60
|
+
"expected": {
|
|
61
|
+
"blockers": [],
|
|
62
|
+
"warnings": [{ "rule": "r2hf/custom-hook", "min_count": 1 }],
|
|
63
|
+
"skill_action": "inline_hook_body_if_pure"
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"file": "08-mixed.tsx",
|
|
68
|
+
"expected": {
|
|
69
|
+
"blockers": [
|
|
70
|
+
{ "rule": "r2hf/use-state", "min_count": 1 },
|
|
71
|
+
{ "rule": "r2hf/use-effect-deps", "min_count": 1 },
|
|
72
|
+
{ "rule": "r2hf/third-party-react-ui", "min_count": 1 }
|
|
73
|
+
],
|
|
74
|
+
"warnings": [{ "rule": "r2hf/use-callback", "min_count": 1 }],
|
|
75
|
+
"skill_action": "refuse_translation_recommend_interop"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
],
|
|
79
|
+
"totals": {
|
|
80
|
+
"expected_blocker_cases": 5,
|
|
81
|
+
"expected_warning_only_cases": 3,
|
|
82
|
+
"expected_total_blocker_findings_min": 7,
|
|
83
|
+
"expected_total_warning_findings_min": 6
|
|
84
|
+
}
|
|
85
|
+
}
|
package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/validate.sh
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# validate.sh — assert lint_source.py output matches expected.json for every T4 case.
|
|
3
|
+
#
|
|
4
|
+
# T4 has no renders to diff. The skill is graded on whether it correctly
|
|
5
|
+
# refuses to translate each case (or drops only the lambda config in case 5,
|
|
6
|
+
# or warns appropriately in cases 6 and 7).
|
|
7
|
+
#
|
|
8
|
+
# Usage:
|
|
9
|
+
# ./validate.sh
|
|
10
|
+
# Exit 0 on pass.
|
|
11
|
+
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
|
|
14
|
+
THIS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
15
|
+
SCRIPTS_DIR="$(cd "$THIS_DIR/../../../scripts" && pwd)"
|
|
16
|
+
EXPECTED="$THIS_DIR/expected.json"
|
|
17
|
+
|
|
18
|
+
if [[ ! -f "$SCRIPTS_DIR/lint_source.py" ]]; then
|
|
19
|
+
echo "error: lint_source.py not found at $SCRIPTS_DIR/lint_source.py" >&2
|
|
20
|
+
exit 2
|
|
21
|
+
fi
|
|
22
|
+
if [[ ! -f "$EXPECTED" ]]; then
|
|
23
|
+
echo "error: expected.json not found at $EXPECTED" >&2
|
|
24
|
+
exit 2
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# Drive lint_file() in-process so the per-case overhead is one Python startup,
|
|
28
|
+
# not N (8 cases × ~80 ms forking python3 was the dominant cost).
|
|
29
|
+
SCRIPTS_DIR="$SCRIPTS_DIR" \
|
|
30
|
+
THIS_DIR="$THIS_DIR" \
|
|
31
|
+
EXPECTED="$EXPECTED" \
|
|
32
|
+
python3 <<'PY'
|
|
33
|
+
import json
|
|
34
|
+
import os
|
|
35
|
+
import sys
|
|
36
|
+
from collections import Counter
|
|
37
|
+
from pathlib import Path
|
|
38
|
+
|
|
39
|
+
scripts_dir = Path(os.environ["SCRIPTS_DIR"])
|
|
40
|
+
this_dir = Path(os.environ["THIS_DIR"])
|
|
41
|
+
expected_path = Path(os.environ["EXPECTED"])
|
|
42
|
+
cases_dir = this_dir / "cases"
|
|
43
|
+
|
|
44
|
+
sys.path.insert(0, str(scripts_dir))
|
|
45
|
+
from lint_source import BLOCKER, WARNING, lint_file # noqa: E402
|
|
46
|
+
|
|
47
|
+
expected = json.loads(expected_path.read_text())
|
|
48
|
+
|
|
49
|
+
fails: list[str] = []
|
|
50
|
+
passes: list[str] = []
|
|
51
|
+
|
|
52
|
+
for case in expected["cases"]:
|
|
53
|
+
file_name = case["file"]
|
|
54
|
+
fixture = cases_dir / file_name
|
|
55
|
+
if not fixture.exists():
|
|
56
|
+
fails.append(f"{file_name}: fixture missing at {fixture}")
|
|
57
|
+
continue
|
|
58
|
+
|
|
59
|
+
findings = lint_file(fixture)
|
|
60
|
+
rule_counts: Counter[str] = Counter()
|
|
61
|
+
severity_by_rule: dict[str, str] = {}
|
|
62
|
+
for f in findings:
|
|
63
|
+
rule_counts[f.rule] += 1
|
|
64
|
+
severity_by_rule[f.rule] = f.severity
|
|
65
|
+
|
|
66
|
+
case_failed = False
|
|
67
|
+
|
|
68
|
+
def assert_rule(expected_entry, expected_severity_floor, kind):
|
|
69
|
+
global case_failed
|
|
70
|
+
rule = expected_entry["rule"]
|
|
71
|
+
min_count = expected_entry["min_count"]
|
|
72
|
+
actual = rule_counts[rule]
|
|
73
|
+
actual_severity = severity_by_rule.get(rule)
|
|
74
|
+
if actual < min_count:
|
|
75
|
+
fails.append(f"{file_name}: expected >={min_count} {kind} findings of rule {rule}, got {actual}")
|
|
76
|
+
case_failed = True
|
|
77
|
+
elif actual_severity not in expected_severity_floor:
|
|
78
|
+
fails.append(
|
|
79
|
+
f"{file_name}: rule {rule} found but severity={actual_severity!r} (expected {kind})"
|
|
80
|
+
)
|
|
81
|
+
case_failed = True
|
|
82
|
+
|
|
83
|
+
for entry in case["expected"]["blockers"]:
|
|
84
|
+
assert_rule(entry, {BLOCKER}, "blocker")
|
|
85
|
+
for entry in case["expected"]["warnings"]:
|
|
86
|
+
assert_rule(entry, {WARNING, BLOCKER}, "warning")
|
|
87
|
+
|
|
88
|
+
# Implied lint exit code: 1 when blockers are expected, 0 otherwise.
|
|
89
|
+
has_blockers = any(f.severity == BLOCKER for f in findings)
|
|
90
|
+
expected_has_blockers = bool(case["expected"]["blockers"])
|
|
91
|
+
if has_blockers != expected_has_blockers:
|
|
92
|
+
fails.append(
|
|
93
|
+
f"{file_name}: implied lint exit {1 if has_blockers else 0}, "
|
|
94
|
+
f"expected {1 if expected_has_blockers else 0} (blockers expected: {expected_has_blockers})"
|
|
95
|
+
)
|
|
96
|
+
case_failed = True
|
|
97
|
+
|
|
98
|
+
if not case_failed:
|
|
99
|
+
passes.append(file_name)
|
|
100
|
+
|
|
101
|
+
print(f"Passed: {len(passes)}")
|
|
102
|
+
for name in passes:
|
|
103
|
+
print(f" ✓ {name}")
|
|
104
|
+
if fails:
|
|
105
|
+
print(f"Failed: {len(fails)}")
|
|
106
|
+
for msg in fails:
|
|
107
|
+
print(f" ✗ {msg}")
|
|
108
|
+
sys.exit(1)
|
|
109
|
+
sys.exit(0)
|
|
110
|
+
PY
|