@litfamily/litclaude 1.0.10 → 1.0.13
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/CHANGELOG.md +36 -0
- package/README.md +436 -45
- package/README_ko-KR.md +403 -17
- package/bin/install-ownership.mjs +155 -18
- package/bin/litclaude-ai.js +91 -9
- package/docs/ab/S11-baseline-desktop.webp +0 -0
- package/docs/ab/S11-baseline-phone.webp +0 -0
- package/docs/ab/S11-litclaude-desktop.webp +0 -0
- package/docs/ab/S11-litclaude-phone.webp +0 -0
- package/docs/ab/S3-baseline-desktop.webp +0 -0
- package/docs/ab/S3-baseline-phone.webp +0 -0
- package/docs/ab/S3-litclaude-desktop.webp +0 -0
- package/docs/ab/S3-litclaude-phone.webp +0 -0
- package/docs/ab/S4-baseline-desktop.webp +0 -0
- package/docs/ab/S4-baseline-phone.webp +0 -0
- package/docs/ab/S4-litclaude-desktop.webp +0 -0
- package/docs/ab/S4-litclaude-phone.webp +0 -0
- package/docs/ab/S5-baseline-pages.webp +0 -0
- package/docs/ab/S5-baseline-slides.webp +0 -0
- package/docs/ab/S5-litclaude-pages.webp +0 -0
- package/docs/ab/S5-litclaude-slides.webp +0 -0
- package/docs/ab/S7-litclaude-diagram.webp +0 -0
- package/docs/ab/S8-baseline-slides.webp +0 -0
- package/docs/ab/S8-litclaude-slides.webp +0 -0
- package/docs/ab/S9-litclaude-pages.webp +0 -0
- package/docs/agents.md +10 -7
- package/docs/assets/cover-motion-still.webp +0 -0
- package/docs/assets/cover-motion.webp +0 -0
- package/docs/assets/readme/badge-version.svg +1 -1
- package/docs/assets/skills/autoconference.webp +0 -0
- package/docs/assets/skills/automatic-checks.webp +0 -0
- package/docs/assets/skills/autoresearch.webp +0 -0
- package/docs/assets/skills/browser-drive.webp +0 -0
- package/docs/assets/skills/debugging.webp +0 -0
- package/docs/assets/skills/deep-interview.webp +0 -0
- package/docs/assets/skills/frontend-ui-ux.webp +0 -0
- package/docs/assets/skills/lit-burnoff-file.webp +0 -0
- package/docs/assets/skills/lit-burnoff.webp +0 -0
- package/docs/assets/skills/lit-code.webp +0 -0
- package/docs/assets/skills/lit-commit.webp +0 -0
- package/docs/assets/skills/lit-comprehend.webp +0 -0
- package/docs/assets/skills/lit-crucible.webp +0 -0
- package/docs/assets/skills/lit-diagram-drawer.webp +0 -0
- package/docs/assets/skills/lit-docx.webp +0 -0
- package/docs/assets/skills/lit-handoff.webp +0 -0
- package/docs/assets/skills/lit-humanizer.webp +0 -0
- package/docs/assets/skills/lit-init.webp +0 -0
- package/docs/assets/skills/lit-loop.webp +0 -0
- package/docs/assets/skills/lit-plan.webp +0 -0
- package/docs/assets/skills/lit-pptx.webp +0 -0
- package/docs/assets/skills/lit-recap.webp +0 -0
- package/docs/assets/skills/lit-scientific-visualization.webp +0 -0
- package/docs/assets/skills/lit-team.webp +0 -0
- package/docs/assets/skills/lit-typographic-motion.webp +0 -0
- package/docs/assets/skills/litgoal.webp +0 -0
- package/docs/assets/skills/litresearch.webp +0 -0
- package/docs/assets/skills/litwork.webp +0 -0
- package/docs/assets/skills/lsp-setup.webp +0 -0
- package/docs/assets/skills/readme-studio.webp +0 -0
- package/docs/assets/skills/refactor.webp +0 -0
- package/docs/assets/skills/review-work.webp +0 -0
- package/docs/assets/skills/start-work.webp +0 -0
- package/docs/assets/skills/structural-search.webp +0 -0
- package/docs/assets/skills/visual-qa.webp +0 -0
- package/docs/assets/skills/wikify.webp +0 -0
- package/docs/hooks.md +185 -41
- package/docs/migration.md +6 -3
- package/docs/privacy.md +6 -1
- package/package.json +4 -2
- package/plugins/litclaude/.claude-plugin/plugin.json +1 -1
- package/plugins/litclaude/agents/korean-prose-editor.md +1 -0
- package/plugins/litclaude/agents/korean-style-analyzer.md +1 -0
- package/plugins/litclaude/agents/meaning-preservation-auditor.md +1 -0
- package/plugins/litclaude/agents/native-flow-reviewer.md +1 -0
- package/plugins/litclaude/agents/polish-orchestrator.md +1 -0
- package/plugins/litclaude/bin/litclaude-hook.js +347 -35
- package/plugins/litclaude/bin/litclaude-hud.js +29 -1
- package/plugins/litclaude/bin/litclaude-mcp.js +1 -1
- package/plugins/litclaude/bundled-rules/lit-humanizer.md +14 -0
- package/plugins/litclaude/commands/korean-ai-slop-remover.md +2 -2
- package/plugins/litclaude/commands/lit-comprehend.md +11 -11
- package/plugins/litclaude/commands/lit-humanizer.md +75 -0
- package/plugins/litclaude/commands/lit-korean.md +4 -130
- package/plugins/litclaude/commands/litresearch.md +12 -10
- package/plugins/litclaude/hooks/hooks.json +1 -1
- package/plugins/litclaude/lib/canonical-runtime-commitments.mjs +2 -2
- package/plugins/litclaude/lib/canonical-skill-catalog.mjs +5 -1
- package/plugins/litclaude/lib/canonical-skill-resources.mjs +618 -13
- package/plugins/litclaude/lib/deliverable-hedge-guard.mjs +256 -350
- package/plugins/litclaude/lib/hud-accent-palette.mjs +33 -0
- package/plugins/litclaude/lib/interface-mode.mjs +33 -0
- package/plugins/litclaude/lib/interface-probe-gate.mjs +125 -0
- package/plugins/litclaude/lib/jev-skill-hint.mjs +445 -0
- package/plugins/litclaude/lib/motion-render-gate.mjs +164 -0
- package/plugins/litclaude/lib/mutated-file-paths.mjs +32 -1
- package/plugins/litclaude/lib/office-runtime-lock/package-lock.json +745 -0
- package/plugins/litclaude/lib/office-runtime-lock/package.json +12 -0
- package/plugins/litclaude/lib/office-runtime-lock/requirements.lock +15 -0
- package/plugins/litclaude/lib/office-runtime.mjs +255 -0
- package/plugins/litclaude/lib/office_data.py +493 -0
- package/plugins/litclaude/lib/office_runtime_bootstrap.py +61 -0
- package/plugins/litclaude/lib/ooxml_integrity.py +199 -0
- package/plugins/litclaude/lib/rename-aliases.mjs +3 -1
- package/plugins/litclaude/lib/render_pages.py +105 -0
- package/plugins/litclaude/skills/autoconference/SKILL.md +2 -0
- package/plugins/litclaude/skills/browser-drive/SKILL.md +19 -6
- package/plugins/litclaude/skills/browser-drive/scripts/capability-probe.mjs +44 -8
- package/plugins/litclaude/skills/frontend-ui-ux/ATTRIBUTION.md +26 -0
- package/plugins/litclaude/skills/frontend-ui-ux/SKILL.md +50 -16
- package/plugins/litclaude/skills/frontend-ui-ux/examples/phase-3-readme-ab/README.md +9 -0
- package/plugins/litclaude/skills/frontend-ui-ux/references/complete-contract.md +32 -6
- package/plugins/litclaude/skills/frontend-ui-ux/references/craft-floor.md +257 -0
- package/plugins/litclaude/skills/frontend-ui-ux/references/default-editorial-pixel.json +6 -0
- package/plugins/litclaude/skills/frontend-ui-ux/references/interaction-motion.md +34 -88
- package/plugins/litclaude/skills/frontend-ui-ux/references/motion-guide.md +130 -0
- package/plugins/litclaude/skills/frontend-ui-ux/references/slop-register.md +150 -0
- package/plugins/litclaude/skills/frontend-ui-ux/references/visual-reconstruction.md +39 -85
- package/plugins/litclaude/skills/frontend-ui-ux/scripts/interface-probe-page.mjs +1534 -0
- package/plugins/litclaude/skills/frontend-ui-ux/scripts/interface-probe-rules.mjs +141 -0
- package/plugins/litclaude/skills/frontend-ui-ux/scripts/interface-probe-server.mjs +57 -0
- package/plugins/litclaude/skills/frontend-ui-ux/scripts/interface-probe-static.mjs +129 -0
- package/plugins/litclaude/skills/frontend-ui-ux/scripts/interface-probe.mjs +316 -0
- package/plugins/litclaude/skills/lit-comprehend/SKILL.md +34 -43
- package/plugins/litclaude/skills/lit-comprehend/references/artifact-template.md +5 -44
- package/plugins/litclaude/skills/lit-comprehend/scripts/verify-explainer.mjs +6 -16
- package/plugins/litclaude/skills/lit-diagram-drawer/NOTICE +33 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/SKILL.md +123 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-architecture-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-architecture-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-architecture-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-bar-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-bar-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-bar-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-beeswarm-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-beeswarm-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-beeswarm-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-bubble-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-bubble-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-bubble-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-bump-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-bump-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-bump-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-data-flow-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-data-flow-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-data-flow-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-datalake-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-datalake-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-datalake-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-db-schema-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-db-schema-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-db-schema-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-dependency-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-dependency-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-dependency-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-deployment-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-deployment-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-deployment-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-dp-integration-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-dp-integration-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-dp-integration-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-er-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-er-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-er-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-fishbone-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-fishbone-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-fishbone-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-flowchart-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-flowchart-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-flowchart-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-gantt-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-gantt-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-gantt-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-heatmap-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-heatmap-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-heatmap-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-high-level-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-high-level-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-high-level-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-import-drawio-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-import-drawio-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-import-drawio-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-it-state-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-it-state-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-it-state-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-journey-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-journey-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-journey-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-kanban-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-kanban-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-kanban-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-layers-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-layers-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-layers-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-line-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-line-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-line-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-loop-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-loop-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-loop-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-marimekko-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-marimekko-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-marimekko-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-medallion-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-medallion-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-medallion-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-nested-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-nested-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-nested-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-org-chart-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-org-chart-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-org-chart-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-polar-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-polar-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-polar-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-process-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-process-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-process-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-pyramid-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-pyramid-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-pyramid-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-quadrant-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-quadrant-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-quadrant-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-queue-animated-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-queue-animated-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-queue-animated-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-radar-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-radar-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-radar-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-ridgeline-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-ridgeline-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-ridgeline-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-sankey-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-sankey-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-sankey-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-scatter-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-scatter-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-scatter-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-sequence-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-sequence-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-sequence-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-slopegraph-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-slopegraph-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-slopegraph-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-state-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-state-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-state-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-story-map-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-story-map-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-story-map-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-streamgraph-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-streamgraph-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-streamgraph-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-swimlane-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-swimlane-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-swimlane-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-timeline-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-timeline-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-timeline-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-tree-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-tree-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-tree-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-treemap-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-treemap-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-treemap-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-uml-class-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-uml-class-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-uml-class-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-venn-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-venn-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-venn-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-wardley-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-wardley-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-wardley-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-waterfall-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-waterfall-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-waterfall-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/fonts/OFL.txt +94 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/fonts/PretendardVariable.woff2 +0 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/fonts/provenance.json +22 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/icons.html +231 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/index.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/licenses/devicon-MIT.txt +20 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/licenses/diagram-design-MIT.txt +21 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/licenses/log-z-MIT.txt +21 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/licenses/simple-icons-CC0.md +30 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/licenses/tabler-MIT.txt +21 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/01-service-architecture/after.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/01-service-architecture/brief.md +33 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/02-release-decision/after.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/02-release-decision/brief.md +18 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/03-data-retention/after.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/03-data-retention/brief.md +19 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/04-oauth-sequence/after.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/04-oauth-sequence/brief.md +17 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/05-review-lanes/after.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/05-review-lanes/brief.md +17 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/06-rollout-gates/after.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/06-rollout-gates/brief.md +17 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/07-deployment-boundary/after.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/07-deployment-boundary/brief.md +19 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/08-policy-traces/after.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/08-policy-traces/brief.md +20 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/accessibility.md +37 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/export.md +29 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/import-drawio.md +21 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/import-excalidraw.md +14 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/import-mermaid.md +18 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/import-schema.md +28 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/korean-typography.md +34 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/motion.md +29 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/office-pptx-docx.md +42 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/output-spec.md +48 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/primitive-annotation.md +12 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/primitive-icons.md +21 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/primitive-sketchy.md +11 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/primitive-terminal.md +11 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/profiles.md +24 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/semantic-patterns.md +27 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/style-guide.md +67 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-architecture.md +51 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-bar.md +51 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-beeswarm.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-bubble.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-bump.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-catalog.json +1433 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-data-flow.md +51 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-datalake.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-db-schema.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-dependency.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-deployment.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-dp-integration.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-dp-security-matrix.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-er.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-fishbone.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-flowchart.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-gantt.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-heatmap.md +53 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-high-level-vertical.md +53 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-high-level.md +53 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-import-drawio.md +53 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-import-excalidraw.md +53 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-import-mermaid.md +53 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-it-state.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-journey.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-kanban.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-layers.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-line.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-loop-terminal.md +53 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-loop.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-marimekko.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-medallion.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-nested.md +59 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-org-chart.md +58 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-paved-road-animated.md +72 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-polar.md +67 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-policy-trace-animated.md +69 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-process.md +58 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-pyramid.md +59 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-quadrant-consultant.md +60 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-quadrant.md +57 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-queue-animated.md +63 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-radar.md +57 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-ridgeline.md +63 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-sankey.md +68 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-scatter.md +60 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-sequence-oauth.md +66 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-sequence.md +63 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-slopegraph.md +65 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-state-lifecycle.md +53 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-state.md +59 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-story-map.md +52 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-streamgraph.md +53 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-swimlane.md +52 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-timeline.md +52 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-tree-block-decomposition.md +57 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-tree.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-treemap.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-uml-class.md +52 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-venn.md +51 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-wardley.md +52 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-waterfall.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/verifier-guide.md +66 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/block-registry.mjs +43 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/brief-contract.mjs +94 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/check-visible-text.mjs +15 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/diagram-metrics.mjs +223 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/doctor.mjs +35 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/drawio-extract.mjs +635 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/excalidraw-extract.mjs +319 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/export.mjs +116 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/mermaid-extract.mjs +438 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/office-safety.mjs +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/renderer.mjs +33 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/verify-all.mjs +58 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/verify-brief.mjs +22 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/verify-coverage.mjs +56 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/verify-diagram.mjs +27 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/verify-motion.mjs +12 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/verify-type.mjs +48 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/visual-quality.mjs +376 -0
- package/plugins/litclaude/skills/lit-docx/NOTICE +33 -0
- package/plugins/litclaude/skills/lit-docx/SKILL.md +170 -0
- package/plugins/litclaude/skills/lit-docx/references/frontmatter_schema.md +42 -0
- package/plugins/litclaude/skills/lit-docx/references/journal_style_spec.md +17 -0
- package/plugins/litclaude/skills/lit-docx/references/markdown_quality_checklist.md +37 -0
- package/plugins/litclaude/skills/lit-docx/references/slop_phrase_list.yaml +58 -0
- package/plugins/litclaude/skills/lit-docx/references/slop_rules.md +35 -0
- package/plugins/litclaude/skills/lit-docx/scripts/clean_markdown.py +95 -0
- package/plugins/litclaude/skills/lit-docx/scripts/convert_md_to_docx.py +1194 -0
- package/plugins/litclaude/skills/lit-docx/scripts/convert_md_to_pdf.py +290 -0
- package/plugins/litclaude/skills/lit-docx/scripts/convert_pdf.py +139 -0
- package/plugins/litclaude/skills/lit-docx/scripts/edit_docx.py +306 -0
- package/plugins/litclaude/skills/lit-docx/scripts/embed_images.py +78 -0
- package/plugins/litclaude/skills/lit-docx/scripts/generate_docx_templates.py +500 -0
- package/plugins/litclaude/skills/lit-docx/scripts/qa_docx.py +177 -0
- package/plugins/litclaude/skills/lit-docx/scripts/slop_lint.py +561 -0
- package/plugins/litclaude/skills/lit-docx/scripts/visual_audit.py +48 -0
- package/plugins/litclaude/skills/lit-docx/templates/docx/acs.docx +0 -0
- package/plugins/litclaude/skills/lit-docx/templates/docx/elsevier.docx +0 -0
- package/plugins/litclaude/skills/lit-docx/templates/docx/ieee.docx +0 -0
- package/plugins/litclaude/skills/lit-docx/templates/docx/korean-generic.docx +0 -0
- package/plugins/litclaude/skills/lit-docx/templates/docx/nature.docx +0 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/acs/README.md +5 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/acs/template.tex +37 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/elsevier/README.md +5 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/elsevier/template.tex +38 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/ieee/README.md +5 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/ieee/template.tex +37 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/korean-generic/README.md +5 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/korean-generic/template.tex +37 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/nature/README.md +5 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/nature/template.tex +37 -0
- package/plugins/litclaude/skills/lit-docx/templates/registry.yaml +1366 -0
- package/plugins/litclaude/skills/lit-humanizer/NOTICE +160 -0
- package/plugins/litclaude/skills/lit-humanizer/SKILL.md +164 -0
- package/plugins/litclaude/skills/lit-humanizer/assets/always-on-rule.md +9 -0
- package/plugins/litclaude/skills/lit-humanizer/assets/report-skeleton.md +25 -0
- package/plugins/litclaude/skills/lit-humanizer/assets/slide-text-skeleton.md +28 -0
- package/plugins/litclaude/skills/lit-humanizer/bench/prompts.md +73 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/accessibility-note/after.md +7 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/accessibility-note/before.md +7 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/api-reference/after.md +9 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/api-reference/before.md +15 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/changelog/after.md +5 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/changelog/before.md +12 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/code-comments/after.md +10 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/code-comments/before.md +19 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/commit/after.md +5 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/commit/before.md +7 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/data-release/after.md +7 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/data-release/before.md +9 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/english-essay/after.md +5 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/english-essay/before.md +5 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/incident-update/after.md +7 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/incident-update/before.md +7 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/ko-essay/after.md +7 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/ko-essay/before.md +9 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/ko-report/after.md +9 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/ko-report/before.md +13 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/ko-slide/after.md +19 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/ko-slide/before.md +21 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/meeting-brief/after.md +9 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/meeting-brief/before.md +11 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/policy-faq/after.md +9 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/policy-faq/before.md +9 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/pr/after.md +15 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/pr/before.md +17 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/project-update/after.md +7 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/project-update/before.md +9 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/readme/after.md +12 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/readme/before.md +14 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/report/after.md +13 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/report/before.md +11 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/research-abstract/after.md +5 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/research-abstract/before.md +5 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/slides/after.md +19 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/slides/before.md +19 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/troubleshooting/after.md +11 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/troubleshooting/before.md +11 -0
- package/plugins/litclaude/skills/lit-humanizer/motion-guide.md +123 -0
- package/plugins/litclaude/skills/lit-humanizer/references/code-patterns.md +468 -0
- package/plugins/litclaude/skills/lit-humanizer/references/deliverable-channels.md +111 -0
- package/plugins/litclaude/skills/lit-humanizer/references/en-patterns-checklist.md +43 -0
- package/plugins/litclaude/skills/lit-humanizer/references/en-patterns-content.md +243 -0
- package/plugins/litclaude/skills/lit-humanizer/references/en-patterns-structure.md +375 -0
- package/plugins/litclaude/skills/lit-humanizer/references/en-patterns.md +57 -0
- package/plugins/litclaude/skills/lit-humanizer/references/ko-metrics.md +33 -0
- package/plugins/litclaude/skills/lit-humanizer/references/ko-patterns-a-d.md +659 -0
- package/plugins/litclaude/skills/lit-humanizer/references/ko-patterns-e-j.md +387 -0
- package/plugins/litclaude/skills/lit-humanizer/references/ko-patterns.md +31 -0
- package/plugins/litclaude/skills/lit-humanizer/references/rewrite-playbook.md +54 -0
- package/plugins/litclaude/skills/lit-humanizer/references/taxonomy.md +153 -0
- package/plugins/litclaude/skills/lit-humanizer/rules.json +884 -0
- package/plugins/litclaude/skills/lit-humanizer/scripts/artifact-text.mjs +38 -0
- package/plugins/litclaude/skills/lit-humanizer/scripts/core.mjs +207 -0
- package/plugins/litclaude/skills/lit-humanizer/scripts/detect.mjs +64 -0
- package/plugins/litclaude/skills/lit-humanizer/scripts/extract_office_text.py +112 -0
- package/plugins/litclaude/skills/lit-humanizer/scripts/ko-metrics.mjs +124 -0
- package/plugins/litclaude/skills/lit-humanizer/scripts/scan-input.mjs +29 -0
- package/plugins/litclaude/skills/lit-loop/SKILL.md +30 -1
- package/plugins/litclaude/skills/lit-plan/SKILL.md +4 -1
- package/plugins/litclaude/skills/lit-pptx/NOTICE +38 -0
- package/plugins/litclaude/skills/lit-pptx/SKILL.md +207 -0
- package/plugins/litclaude/skills/lit-pptx/assets/azure/circle-lg.png +0 -0
- package/plugins/litclaude/skills/lit-pptx/assets/azure/circle-md.png +0 -0
- package/plugins/litclaude/skills/lit-pptx/assets/azure/circle-sm.png +0 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/a2z/A2Z-Black.otf +0 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/a2z/A2Z-Bold.otf +0 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/a2z/A2Z-Light.otf +0 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/a2z/A2Z-Medium.otf +0 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/a2z/A2Z-Regular.otf +0 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/a2z/OFL.txt +94 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/a2z/SOURCE.md +29 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/pretendard/OFL.txt +94 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/pretendard/Pretendard-Bold.otf +0 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/pretendard/Pretendard-Regular.otf +0 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/provenance.json +78 -0
- package/plugins/litclaude/skills/lit-pptx/references/agents/analyst.md +49 -0
- package/plugins/litclaude/skills/lit-pptx/references/agents/antithesis.md +59 -0
- package/plugins/litclaude/skills/lit-pptx/references/agents/architect.md +44 -0
- package/plugins/litclaude/skills/lit-pptx/references/agents/critic.md +42 -0
- package/plugins/litclaude/skills/lit-pptx/references/agents/synthesizer.md +47 -0
- package/plugins/litclaude/skills/lit-pptx/references/agents/thesis.md +33 -0
- package/plugins/litclaude/skills/lit-pptx/references/anti-slop-checklist.md +81 -0
- package/plugins/litclaude/skills/lit-pptx/references/authoring-guide.md +173 -0
- package/plugins/litclaude/skills/lit-pptx/references/consensus-protocol.md +125 -0
- package/plugins/litclaude/skills/lit-pptx/references/data-display-cookbook.md +45 -0
- package/plugins/litclaude/skills/lit-pptx/references/design-system-azure.md +58 -0
- package/plugins/litclaude/skills/lit-pptx/references/interview-protocol.md +113 -0
- package/plugins/litclaude/skills/lit-pptx/references/stages/autopilot.md +48 -0
- package/plugins/litclaude/skills/lit-pptx/references/stages/interview.md +52 -0
- package/plugins/litclaude/skills/lit-pptx/references/stages/plan.md +42 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/compile-deck.js +414 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/craft_extras.py +373 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/deck_craft.py +321 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/embed_fonts.py +215 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/forbidden-terms.json +55 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/layout_inventory.py +418 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/learn_template.py +446 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/derive-palette.js +176 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/directive-parser.js +244 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/font-map.js +79 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/gen-bg.js +86 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/gen-gradient-assets.js +37 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/layout-resolver.js +768 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/markdown-loader.js +136 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/render-adapter-html.js +356 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/render-adapter-pptx.js +2094 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/runtime-require.js +28 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/slide-ast.js +561 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/spec-validator.js +94 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/template-registry.js +394 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/package.json +4 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/qa_deck.py +766 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/validate_pptx.py +215 -0
- package/plugins/litclaude/skills/lit-pptx/specs/markdown-slide-spec-v1.md +251 -0
- package/plugins/litclaude/skills/lit-pptx/specs/markdown-slide-spec-v2.md +214 -0
- package/plugins/litclaude/skills/lit-pptx/specs/slide-ast-v1.schema.json +229 -0
- package/plugins/litclaude/skills/lit-pptx/specs/slide-ast-v2.schema.json +144 -0
- package/plugins/litclaude/skills/lit-pptx/specs/template-enrollment-contract.md +382 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/AZURE-A2Z/capabilities.yaml +146 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/AZURE-A2Z/layout-mapping.yaml +454 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/AZURE-A2Z/template.yaml +37 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/AZURE-PRO/capabilities.yaml +154 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/AZURE-PRO/layout-mapping.yaml +475 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/AZURE-PRO/template.yaml +37 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/capabilities.yaml +179 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/layout-mapping.yaml +299 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/template.yaml +45 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/capabilities.yaml +181 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/layout-mapping.yaml +299 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/template.yaml +44 -0
- package/plugins/litclaude/skills/lit-scientific-visualization/SKILL.md +1 -0
- package/plugins/litclaude/skills/lit-typographic-motion/SKILL.md +131 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/NOTICE +23 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/THIRD_PARTY_NOTICES +56 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/audio/beat_grid.py +56 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/audio/requirements.lock +1084 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/constants.mjs +211 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/contrast.mjs +90 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/events.mjs +46 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/flash.mjs +211 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/gate-rules.mjs +550 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/presets.mjs +123 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/text.mjs +100 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/timeline.mjs +142 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/util.mjs +167 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/voices.mjs +19 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/models/word-timing.json +198 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/analysis.mjs +108 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/brief.mjs +158 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/chrome.mjs +330 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/coverage.mjs +83 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/done.mjs +104 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/encode.mjs +104 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/frame-worker.mjs +36 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/look.mjs +128 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/pipeline.mjs +592 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/png.mjs +112 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/report.mjs +66 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/runtime.mjs +330 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/session.mjs +145 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/sound-cli.mjs +60 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/sound.mjs +641 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/stage-capture.mjs +178 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/stage-gate.mjs +122 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/stage-qa.mjs +295 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/stage-serve.mjs +278 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/stage.mjs +503 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/stills.mjs +100 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/treatment.mjs +343 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/ws-server.mjs +132 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/package-lock.json +25 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/package.json +10 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/stage/init.js +288 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/stage/qa.js +157 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/stage/stage-kit.js +701 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/boot.mjs +123 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/engine.mjs +281 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/gl.mjs +319 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/glsl-common.mjs +78 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/index.html +6 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/lines.mjs +112 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/passes/crt.mjs +98 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/passes/dither.mjs +49 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/passes/glitch.mjs +77 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/passes/swiss-grid.mjs +61 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/passes/terminal-ui.mjs +88 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/passes/tidal-gradient.mjs +86 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/post.mjs +165 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/scale.mjs +15 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/scene.mjs +82 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/scenes/end-card.mjs +30 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/scenes/index.mjs +16 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/scenes/karaoke-line.mjs +47 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/scenes/kinetic-list.mjs +45 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/scenes/number-counter.mjs +29 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/scenes/signature.mjs +73 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/scenes/title-slam.mjs +73 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/stroke.mjs +236 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/type.mjs +180 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/Archivo-w100-400.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/Archivo-w100-700.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/Archivo-w100-900.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/Archivo-w125-400.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/Archivo-w125-700.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/Archivo-w125-900.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/Archivo-w75-400.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/Archivo-w75-700.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/Archivo-w75-900.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/OFL.txt +93 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/manifest.json +437 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/silkscreen/OFL.txt +93 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/silkscreen/Silkscreen-Bold.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/silkscreen/Silkscreen-Regular.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/stroke/CREDITS +42 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/stroke/EMSAllure.svg +216 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/stroke/EMSFelix.svg +216 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/stroke/EMSOsmotron.svg +216 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/stroke/EMSReadability.svg +216 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/stroke/EMSTech.svg +217 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/stroke/OFL.txt +91 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/vt323/OFL.txt +93 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/vt323/VT323-Regular.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/brief-schema.md +91 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/craft-loop.md +69 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/engine-contract.md +104 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/look.md +106 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/runtime.md +65 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/sound.md +83 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/stage.md +192 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/style-bibles.md +117 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/treatment.md +114 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/type-craft.md +79 -0
- package/plugins/litclaude/skills/lit-typographic-motion/scripts/motion-doctor.mjs +78 -0
- package/plugins/litclaude/skills/lit-typographic-motion/scripts/motion-runtime.mjs +67 -0
- package/plugins/litclaude/skills/lit-typographic-motion/scripts/motion.mjs +132 -0
- package/plugins/litclaude/skills/litresearch/SKILL.md +54 -18
- package/scripts/doctor.mjs +5 -0
- package/scripts/postinstall.mjs +1 -0
- package/plugins/litclaude/skills/lit-korean/SKILL.md +0 -327
- /package/plugins/litclaude/skills/{lit-korean/references/fidelity-checklist.md → lit-humanizer/references/litclaude-fidelity-checklist.md} +0 -0
- /package/plugins/litclaude/skills/{lit-korean/references/rewrite-rules.md → lit-humanizer/references/litclaude-rewrite-rules.md} +0 -0
- /package/plugins/litclaude/skills/{lit-korean/references/style-patterns.md → lit-humanizer/references/litclaude-style-patterns.md} +0 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// Minimal PNG encode/decode with node:zlib, so stills, masks, sheets and preview frames never need
|
|
2
|
+
// an image dependency. Encodes 8-bit grayscale, RGB and RGBA; decodes non-interlaced 8-bit PNGs.
|
|
3
|
+
import { deflateSync, inflateSync } from "node:zlib";
|
|
4
|
+
|
|
5
|
+
const CRC_TABLE = (() => {
|
|
6
|
+
const table = new Uint32Array(256);
|
|
7
|
+
for (let n = 0; n < 256; n++) {
|
|
8
|
+
let c = n;
|
|
9
|
+
for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
|
10
|
+
table[n] = c >>> 0;
|
|
11
|
+
}
|
|
12
|
+
return table;
|
|
13
|
+
})();
|
|
14
|
+
|
|
15
|
+
function crc32(buffers) {
|
|
16
|
+
let c = 0xffffffff;
|
|
17
|
+
for (const buf of buffers) for (let i = 0; i < buf.length; i++) c = CRC_TABLE[(c ^ buf[i]) & 0xff] ^ (c >>> 8);
|
|
18
|
+
return (c ^ 0xffffffff) >>> 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function chunk(type, data) {
|
|
22
|
+
const len = Buffer.alloc(4);
|
|
23
|
+
len.writeUInt32BE(data.length);
|
|
24
|
+
const name = Buffer.from(type, "ascii");
|
|
25
|
+
const crc = Buffer.alloc(4);
|
|
26
|
+
crc.writeUInt32BE(crc32([name, data]));
|
|
27
|
+
return Buffer.concat([len, name, data, crc]);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const COLOR_TYPE = { 1: 0, 3: 2, 4: 6 };
|
|
31
|
+
|
|
32
|
+
/** Encode `channels` (1 gray, 3 RGB, 4 RGBA) 8-bit pixels, rows top to bottom. */
|
|
33
|
+
export function encodePng(pixels, width, height, channels = 4, { level = 6 } = {}) {
|
|
34
|
+
const stride = width * channels;
|
|
35
|
+
const raw = Buffer.alloc((stride + 1) * height);
|
|
36
|
+
for (let y = 0; y < height; y++) {
|
|
37
|
+
raw[y * (stride + 1)] = 1; // filter: Sub
|
|
38
|
+
const row = y * stride;
|
|
39
|
+
const out = y * (stride + 1) + 1;
|
|
40
|
+
for (let x = 0; x < stride; x++) raw[out + x] = (pixels[row + x] - (x >= channels ? pixels[row + x - channels] : 0)) & 0xff;
|
|
41
|
+
}
|
|
42
|
+
const ihdr = Buffer.alloc(13);
|
|
43
|
+
ihdr.writeUInt32BE(width, 0);
|
|
44
|
+
ihdr.writeUInt32BE(height, 4);
|
|
45
|
+
ihdr[8] = 8;
|
|
46
|
+
ihdr[9] = COLOR_TYPE[channels];
|
|
47
|
+
return Buffer.concat([
|
|
48
|
+
Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),
|
|
49
|
+
chunk("IHDR", ihdr),
|
|
50
|
+
chunk("IDAT", deflateSync(raw, { level })),
|
|
51
|
+
chunk("IEND", Buffer.alloc(0)),
|
|
52
|
+
]);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** RGBA -> RGB (drops alpha). */
|
|
56
|
+
export function rgbaToRgb(rgba, width, height) {
|
|
57
|
+
const out = Buffer.alloc(width * height * 3);
|
|
58
|
+
for (let i = 0, j = 0; i < rgba.length; i += 4, j += 3) {
|
|
59
|
+
out[j] = rgba[i]; out[j + 1] = rgba[i + 1]; out[j + 2] = rgba[i + 2];
|
|
60
|
+
}
|
|
61
|
+
return out;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Decode an 8-bit non-interlaced PNG to { width, height, channels, pixels }. */
|
|
65
|
+
export function decodePng(buf) {
|
|
66
|
+
if (buf.readUInt32BE(0) !== 0x89504e47) throw new Error("not a PNG");
|
|
67
|
+
let off = 8;
|
|
68
|
+
let width = 0;
|
|
69
|
+
let height = 0;
|
|
70
|
+
let channels = 0;
|
|
71
|
+
const idat = [];
|
|
72
|
+
while (off < buf.length) {
|
|
73
|
+
const len = buf.readUInt32BE(off);
|
|
74
|
+
const type = buf.toString("ascii", off + 4, off + 8);
|
|
75
|
+
const data = buf.subarray(off + 8, off + 8 + len);
|
|
76
|
+
if (type === "IHDR") {
|
|
77
|
+
width = data.readUInt32BE(0);
|
|
78
|
+
height = data.readUInt32BE(4);
|
|
79
|
+
if (data[8] !== 8 || data[12] !== 0) throw new Error("only 8-bit non-interlaced PNG is supported");
|
|
80
|
+
channels = { 0: 1, 2: 3, 6: 4 }[data[9]];
|
|
81
|
+
if (!channels) throw new Error(`unsupported PNG colour type ${data[9]}`);
|
|
82
|
+
} else if (type === "IDAT") idat.push(data);
|
|
83
|
+
else if (type === "IEND") break;
|
|
84
|
+
off += 12 + len;
|
|
85
|
+
}
|
|
86
|
+
const raw = inflateSync(Buffer.concat(idat));
|
|
87
|
+
const stride = width * channels;
|
|
88
|
+
const pixels = Buffer.alloc(stride * height);
|
|
89
|
+
for (let y = 0; y < height; y++) {
|
|
90
|
+
const filter = raw[y * (stride + 1)];
|
|
91
|
+
const src = y * (stride + 1) + 1;
|
|
92
|
+
const dst = y * stride;
|
|
93
|
+
for (let x = 0; x < stride; x++) {
|
|
94
|
+
const a = x >= channels ? pixels[dst + x - channels] : 0;
|
|
95
|
+
const b = y > 0 ? pixels[dst - stride + x] : 0;
|
|
96
|
+
const c = x >= channels && y > 0 ? pixels[dst - stride + x - channels] : 0;
|
|
97
|
+
let v = raw[src + x];
|
|
98
|
+
if (filter === 1) v += a;
|
|
99
|
+
else if (filter === 2) v += b;
|
|
100
|
+
else if (filter === 3) v += (a + b) >> 1;
|
|
101
|
+
else if (filter === 4) {
|
|
102
|
+
const p = a + b - c;
|
|
103
|
+
const pa = Math.abs(p - a);
|
|
104
|
+
const pb = Math.abs(p - b);
|
|
105
|
+
const pc = Math.abs(p - c);
|
|
106
|
+
v += pa <= pb && pa <= pc ? a : pb <= pc ? b : c;
|
|
107
|
+
}
|
|
108
|
+
pixels[dst + x] = v & 0xff;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return { width, height, channels, pixels };
|
|
112
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// The MO-C-17 render report, written verbatim in structure to <out>/gate-report.txt, then one line
|
|
2
|
+
// each for MO-C-25, MO-C-26, MO-C-27, MO-C-29, MO-D-02, MO-D-03 and MO-D-04, then one line per other
|
|
3
|
+
// enforced MO-A / MO-SH / MO-FT rule in rule-index order.
|
|
4
|
+
import { PROVISIONAL_RULES } from "../core/constants.mjs";
|
|
5
|
+
|
|
6
|
+
const pad = (label) => ` ${label}`.padEnd(34);
|
|
7
|
+
const verdict = (rule) => (rule ? `${rule.status}${rule.provisional ? " (provisional number)" : ""}` : "N/A");
|
|
8
|
+
|
|
9
|
+
export function formatReport({ manifest, outputs, reason, gate, round, framesViewed, software, withheld }) {
|
|
10
|
+
const byId = new Map(gate.rules.map((x) => [x.id, x]));
|
|
11
|
+
const line = (id, label, text) => `${pad(`${id} ${label}:`)}${text ?? `${verdict(byId.get(id))} — ${byId.get(id)?.detail ?? "not evaluated"}`}`;
|
|
12
|
+
const flash = byId.get("MO-C-03");
|
|
13
|
+
const contrast = byId.get("MO-C-06");
|
|
14
|
+
const reading = byId.get("MO-C-07/08");
|
|
15
|
+
const det = byId.get("MO-C-09");
|
|
16
|
+
const floors = byId.get("MO-C-10/11/12");
|
|
17
|
+
const sizes = byId.get("MO-C-13");
|
|
18
|
+
const still = byId.get("MO-C-14");
|
|
19
|
+
const passes = (manifest.passRanges ?? []).map((p) => `${p.pass}@${p.sceneId}#${p.shotIndex}:${p.frameStart}-${p.frameEnd}`);
|
|
20
|
+
const lines = [
|
|
21
|
+
"lit-typographic-motion — render report",
|
|
22
|
+
`outputs: ${outputs.film} · ${outputs.preview} (encoder: ${manifest.previewEncoder ?? "none"}) · ${outputs.poster} · ${outputs.still}${withheld ? " [WITHHELD: MO-C-03 flash audit failed; exports are diagnostics in withheld/, not deliverables]" : ""}`,
|
|
23
|
+
`preset: ${manifest.presetId} (chosen because: ${reason})`,
|
|
24
|
+
`duration / fps / resolution: ${manifest.durationSec} s @ ${manifest.fps} fps, ${manifest.resolution[0] * manifest.scale}x${manifest.resolution[1] * manifest.scale}`,
|
|
25
|
+
`GLSL passes (manifest): ${passes.join(", ")}`,
|
|
26
|
+
`WebGL2: ${software ? "software" : "hardware"} — ${manifest.renderer} (flags: ${manifest.chromeFlags.join(" ")})${software ? " [software-rendered, --samples lowered to 1, tidal octaves and crt persistence downgraded]" : ""}`,
|
|
27
|
+
"",
|
|
28
|
+
`QA gate: ${gate.pass ? "PASS" : "FAIL"}`,
|
|
29
|
+
line("MO-C-01", "GLSL presence", `${verdict(byId.get("MO-C-01"))}`),
|
|
30
|
+
line("MO-C-02", "WebGL2 tier", `${verdict(byId.get("MO-C-02"))}`),
|
|
31
|
+
line("MO-C-03", "flash audit", `worst window ${flash?.worst ?? "?"} general / ${flash?.worstRed ?? "?"} red (limit 3 / 3) — ${verdict(flash)}; ${flash?.detail ?? ""}`),
|
|
32
|
+
line("MO-C-04", "title-safe", `${verdict(byId.get("MO-C-04"))} (${byId.get("MO-C-04")?.detail ?? ""})`),
|
|
33
|
+
line("MO-C-05", "action-safe", `${verdict(byId.get("MO-C-05"))}`),
|
|
34
|
+
line("MO-C-06", "type contrast", `${contrast?.detail ?? "not measured"} — ${verdict(contrast)}`),
|
|
35
|
+
line("MO-C-07/08", "reading time", `${reading?.detail ?? ""} — ${verdict(reading)}`),
|
|
36
|
+
line("MO-C-09", "determinism", `rgbaSha256 match ${det?.status === "PASS" ? "Y" : det?.status === "WARN" ? "Y (SwiftShader re-check)" : "N"} (${det?.detail ?? ""})`),
|
|
37
|
+
line("MO-C-10/11/12", "duration/fps/res", `${verdict(floors)} (${floors?.detail ?? ""})`),
|
|
38
|
+
line("MO-C-13", "file sizes", `${sizes?.detail ?? ""} — ${verdict(sizes)}`),
|
|
39
|
+
line("MO-C-14", "reduced-motion still", `${still?.detail ?? ""} — ${verdict(still)}`),
|
|
40
|
+
"",
|
|
41
|
+
`craft rounds run: ${round} / 3 max`,
|
|
42
|
+
`frames actually viewed this run: ${framesViewed ?? 0} (confirmed looked, not just rendered)`,
|
|
43
|
+
"",
|
|
44
|
+
"additional rules:",
|
|
45
|
+
];
|
|
46
|
+
const extraOrder = ["MO-C-25", "MO-C-26", "MO-C-27", "MO-C-29", "MO-D-02", "MO-D-03", "MO-D-04"];
|
|
47
|
+
for (const id of extraOrder) lines.push(line(id, "", undefined).replace(/ :\s*/u, ": "));
|
|
48
|
+
const shown = new Set(["MO-C-01", "MO-C-02", "MO-C-03", "MO-C-04", "MO-C-05", "MO-C-06", "MO-C-07/08", "MO-C-09", "MO-C-10/11/12", "MO-C-13", "MO-C-14", ...extraOrder]);
|
|
49
|
+
for (const rule of gate.rules) if (!shown.has(rule.id)) lines.push(`${pad(`${rule.id}:`)}${verdict(rule)} — ${rule.detail}`);
|
|
50
|
+
lines.push("", `provisional numbers (spec [NEW] defaults awaiting sign-off, implemented as written): ${PROVISIONAL_RULES.join(", ")}`);
|
|
51
|
+
if (!gate.pass) lines.push(`failed rules: ${gate.failed.join(", ")}`);
|
|
52
|
+
return `${lines.join("\n")}\n`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function formatPreflightReport({ preflight, reason, presetId }) {
|
|
56
|
+
const lines = [
|
|
57
|
+
"lit-typographic-motion — render report (pre-flight)",
|
|
58
|
+
`preset: ${presetId} (chosen because: ${reason})`,
|
|
59
|
+
"",
|
|
60
|
+
`QA gate: FAIL (pre-flight; no frame was rendered)`,
|
|
61
|
+
...preflight.rules.map((x) => `${pad(`${x.id}:`)}${x.status} — ${x.detail}`),
|
|
62
|
+
"",
|
|
63
|
+
`failed rules: ${preflight.failed.join(", ")}`,
|
|
64
|
+
];
|
|
65
|
+
return `${lines.join("\n")}\n`;
|
|
66
|
+
}
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
// The motion runtime: pinned engine dependencies, fetched fonts and the opt-in audio venv, all in a
|
|
2
|
+
// LitClaude-owned cache (MO-A-42..55). This reuses the office runtime's cache mechanics (a cache
|
|
3
|
+
// directory keyed by the lockfile, an mkdir lock, `npm ci --omit=dev --ignore-scripts`) but never
|
|
4
|
+
// its first-use trigger: only `litclaude-ai motion-runtime install` and the installer's pre-warm
|
|
5
|
+
// write here. A render only reads, and an unwarmed cache is BLOCKED 14, never a mid-session install.
|
|
6
|
+
//
|
|
7
|
+
// $LITCLAUDE_MOTION_RUNTIME when set
|
|
8
|
+
// ${XDG_CACHE_HOME:-~/.cache}/litclaude/motion-runtime otherwise
|
|
9
|
+
import { createHash } from "node:crypto";
|
|
10
|
+
import { spawnSync } from "node:child_process";
|
|
11
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
12
|
+
import { homedir, tmpdir } from "node:os";
|
|
13
|
+
import path from "node:path";
|
|
14
|
+
import { fileURLToPath } from "node:url";
|
|
15
|
+
|
|
16
|
+
export const SKILL_ROOT = fileURLToPath(new URL("../../", import.meta.url));
|
|
17
|
+
export const ENGINE_ROOT = path.join(SKILL_ROOT, "engine");
|
|
18
|
+
export const FONT_ROOT = path.join(SKILL_ROOT, "fonts");
|
|
19
|
+
const READY = ".litclaude-ready";
|
|
20
|
+
const STALE_LOCK_MS = 20 * 60 * 1000;
|
|
21
|
+
export const INSTALL_COMMAND = "litclaude-ai motion-runtime install";
|
|
22
|
+
|
|
23
|
+
const sha256 = (bytes) => createHash("sha256").update(bytes).digest("hex");
|
|
24
|
+
const fileSha = (file) => sha256(readFileSync(file));
|
|
25
|
+
|
|
26
|
+
export function runtimeRoot(env = process.env) {
|
|
27
|
+
if (env.LITCLAUDE_MOTION_RUNTIME) return path.resolve(env.LITCLAUDE_MOTION_RUNTIME);
|
|
28
|
+
const cacheHome = env.XDG_CACHE_HOME || path.join(homedir(), ".cache");
|
|
29
|
+
return path.join(cacheHome, "litclaude", "motion-runtime");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function lockHash() {
|
|
33
|
+
const h = createHash("sha256");
|
|
34
|
+
for (const file of ["package.json", "package-lock.json"]) h.update(readFileSync(path.join(ENGINE_ROOT, file)));
|
|
35
|
+
return h.digest("hex");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const nodeDir = (env) => path.join(runtimeRoot(env), `node-${lockHash().slice(0, 12)}-${process.platform}-${process.arch}`);
|
|
39
|
+
export const fontsDir = (env) => path.join(runtimeRoot(env), "fonts");
|
|
40
|
+
export const opentypeModule = (env) => path.join(nodeDir(env), "node_modules", "opentype.js", "dist", "opentype.mjs");
|
|
41
|
+
|
|
42
|
+
export function loadFontManifest() {
|
|
43
|
+
return JSON.parse(readFileSync(path.join(FONT_ROOT, "manifest.json"), "utf8"));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Where a font's bytes live after install (bundled, reused lit-pptx file, or the cache). */
|
|
47
|
+
export function fontLocation(key, font, env) {
|
|
48
|
+
if (font.source === "bundled") return path.join(FONT_ROOT, font.path);
|
|
49
|
+
if (font.source === "reuse") {
|
|
50
|
+
const reused = path.resolve(FONT_ROOT, font.path);
|
|
51
|
+
if (existsSync(reused)) return reused;
|
|
52
|
+
return path.join(fontsDir(env), font.fallback.file);
|
|
53
|
+
}
|
|
54
|
+
return path.join(fontsDir(env), font.file);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Verify one font and its licence files. Returns { key, ok, problem, path }. */
|
|
58
|
+
export function checkFont(key, font, env) {
|
|
59
|
+
const file = fontLocation(key, font, env);
|
|
60
|
+
const expected = font.source === "reuse" && !existsSync(path.resolve(FONT_ROOT, font.path)) ? font.fallback.sha256 : font.sha256;
|
|
61
|
+
if (!existsSync(file)) return { key, ok: false, problem: "missing", path: file };
|
|
62
|
+
if (fileSha(file) !== expected) return { key, ok: false, problem: "sha256 mismatch", path: file };
|
|
63
|
+
const licences = font.source === "fetch" ? font.licence.map((l) => ({ file: path.join(fontsDir(env), l.file), sha256: l.sha256 }))
|
|
64
|
+
: font.source === "reuse" && !existsSync(path.resolve(FONT_ROOT, font.path)) ? font.fallback.licence.map((l) => ({ file: path.join(fontsDir(env), l.file), sha256: l.sha256 }))
|
|
65
|
+
: font.licence.map((l) => ({ file: path.resolve(FONT_ROOT, l.path), sha256: l.sha256 }));
|
|
66
|
+
for (const l of licences) {
|
|
67
|
+
if (!existsSync(l.file)) return { key, ok: false, problem: `licence file missing: ${path.basename(l.file)}`, path: file };
|
|
68
|
+
if (fileSha(l.file) !== l.sha256) return { key, ok: false, problem: `licence file sha256 mismatch: ${path.basename(l.file)}`, path: file };
|
|
69
|
+
}
|
|
70
|
+
return { key, ok: true, problem: null, path: file };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function nodeStatus(env) {
|
|
74
|
+
const dir = nodeDir(env);
|
|
75
|
+
let marker = null;
|
|
76
|
+
try {
|
|
77
|
+
marker = JSON.parse(readFileSync(path.join(dir, READY), "utf8"));
|
|
78
|
+
} catch {
|
|
79
|
+
marker = null;
|
|
80
|
+
}
|
|
81
|
+
const expected = lockHash();
|
|
82
|
+
const ready = Boolean(marker) && marker.lockHash === expected && existsSync(opentypeModule(env));
|
|
83
|
+
const pinned = JSON.parse(readFileSync(path.join(ENGINE_ROOT, "package.json"), "utf8")).dependencies;
|
|
84
|
+
return { ready, dir, pinned, problem: ready ? null : marker && marker.lockHash !== expected ? "lockfile hash differs from the installed one" : "not installed" };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ---- audio (Tier 2) ----
|
|
88
|
+
const AUDIO_LOCK = path.join(ENGINE_ROOT, "audio", "requirements.lock");
|
|
89
|
+
const venvPython = (dir) => (process.platform === "win32" ? path.join(dir, "Scripts", "python.exe") : path.join(dir, "bin", "python"));
|
|
90
|
+
|
|
91
|
+
export function pythonCommand(env = process.env) {
|
|
92
|
+
return env.LITCLAUDE_MOTION_PYTHON || "python3";
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function probePython(env) {
|
|
96
|
+
const probe = spawnSync(pythonCommand(env), ["-c", "import sys; print('%d.%d' % sys.version_info[:2])"], { encoding: "utf8" });
|
|
97
|
+
return probe.status === 0 ? probe.stdout.trim() : null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function audioDir(env, version = probePython(env)) {
|
|
101
|
+
const key = createHash("sha256").update(readFileSync(AUDIO_LOCK)).update(`${process.platform}-${process.arch}-py${version ?? "none"}`).digest("hex").slice(0, 12);
|
|
102
|
+
return path.join(runtimeRoot(env), `audio-${key}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** 'absent' (never created), 'ready', or 'mismatch' (a venv whose pins no longer match). */
|
|
106
|
+
export function audioStatus(env) {
|
|
107
|
+
const root = runtimeRoot(env);
|
|
108
|
+
const expected = fileSha(AUDIO_LOCK);
|
|
109
|
+
const dir = audioDir(env);
|
|
110
|
+
let marker = null;
|
|
111
|
+
try {
|
|
112
|
+
marker = JSON.parse(readFileSync(path.join(dir, READY), "utf8"));
|
|
113
|
+
} catch {
|
|
114
|
+
marker = null;
|
|
115
|
+
}
|
|
116
|
+
if (marker && marker.lockSha256 === expected && existsSync(venvPython(dir))) return { state: "ready", dir, python: venvPython(dir) };
|
|
117
|
+
if (marker || (existsSync(root) && existsSync(dir))) return { state: "mismatch", dir, python: venvPython(dir) };
|
|
118
|
+
return { state: "absent", dir, python: null };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export const AUDIO_WARNING = `audio analysis not prewarmed: run ${INSTALL_COMMAND} --audio`;
|
|
122
|
+
|
|
123
|
+
// ---- word timing (Tier 3) ----
|
|
124
|
+
export function loadWordTiming() {
|
|
125
|
+
return JSON.parse(readFileSync(path.join(ENGINE_ROOT, "models", "word-timing.json"), "utf8"));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function wordTimingStatus() {
|
|
129
|
+
const doc = loadWordTiming();
|
|
130
|
+
return { state: doc.alignerRuntime.status === "ready" ? "ready" : "absent", reason: "the Tier-3 aligner runtime is not part of this release", totalBytes: doc.totalBytes };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function licenceVerdict(license, doc = loadWordTiming()) {
|
|
134
|
+
const l = String(license ?? "").toLowerCase();
|
|
135
|
+
if (doc.deniedLicensePatterns.some((p) => l.includes(p))) return "denied";
|
|
136
|
+
return doc.allowedLicenses.includes(l) ? "allowed" : "unknown";
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// ---- status ----
|
|
140
|
+
|
|
141
|
+
/** Required font keys for a preset (all presets when omitted). */
|
|
142
|
+
export function requiredFonts(presetVoices) {
|
|
143
|
+
const keys = new Set();
|
|
144
|
+
for (const voices of presetVoices) for (const v of Object.values(voices)) {
|
|
145
|
+
for (const k of [v.latin, v.hangul, ...(v.weightSteps ?? [])]) if (k) keys.add(k);
|
|
146
|
+
if (v.latin?.startsWith("archivo-")) for (const w of v.latinWidths ?? [100]) keys.add(`archivo-${w}-${v.latin.split("-")[2]}`);
|
|
147
|
+
}
|
|
148
|
+
return [...keys];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function runtimeStatus({ env = process.env, fontKeys } = {}) {
|
|
152
|
+
const manifest = loadFontManifest();
|
|
153
|
+
const keys = fontKeys ?? Object.keys(manifest.fonts);
|
|
154
|
+
const fonts = keys.map((key) => checkFont(key, manifest.fonts[key], env));
|
|
155
|
+
const node = nodeStatus(env);
|
|
156
|
+
const missing = [
|
|
157
|
+
...(node.ready ? [] : [`engine deps (${Object.entries(node.pinned).map(([k, v]) => `${k} ${v}`).join(", ")}): ${node.problem}`]),
|
|
158
|
+
...fonts.filter((f) => !f.ok).map((f) => `font ${f.key}: ${f.problem}`),
|
|
159
|
+
];
|
|
160
|
+
return { root: runtimeRoot(env), node, fonts, audio: audioStatus(env), wordTiming: wordTimingStatus(), ready: missing.length === 0, missing, command: INSTALL_COMMAND };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function formatStatus(status) {
|
|
164
|
+
const lines = [`motion runtime root: ${status.root}`];
|
|
165
|
+
lines.push(`engine deps: ${status.node.ready ? `ready (${Object.entries(status.node.pinned).map(([k, v]) => `${k} ${v}`).join(", ")})` : `missing (${status.node.problem})`}`);
|
|
166
|
+
const bad = status.fonts.filter((f) => !f.ok);
|
|
167
|
+
lines.push(`fonts: ${bad.length === 0 ? `ready (${status.fonts.length} verified by sha256)` : `missing or mismatched: ${bad.map((f) => `${f.key} (${f.problem})`).join(", ")}`}`);
|
|
168
|
+
lines.push(`audio tier (optional): ${status.audio.state === "ready" ? "ready" : status.audio.state === "mismatch" ? `venv pins no longer match; Tier 1 is used; run ${INSTALL_COMMAND} --audio` : `not installed; Tier 1 is used; run ${INSTALL_COMMAND} --audio to enable`}`);
|
|
169
|
+
lines.push(`word timing (optional, --word-timing): ${status.wordTiming.state === "ready" ? "ready" : status.wordTiming.reason}`);
|
|
170
|
+
lines.push(status.ready ? "pre-warm: ready" : `pre-warm: NOT READY — run ${INSTALL_COMMAND}`);
|
|
171
|
+
return lines;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ---- install ----
|
|
175
|
+
|
|
176
|
+
function withLock(root, fn) {
|
|
177
|
+
mkdirSync(root, { recursive: true });
|
|
178
|
+
const lock = path.join(root, ".install.lock");
|
|
179
|
+
const deadline = Date.now() + STALE_LOCK_MS;
|
|
180
|
+
for (;;) {
|
|
181
|
+
try {
|
|
182
|
+
mkdirSync(lock);
|
|
183
|
+
break;
|
|
184
|
+
} catch (error) {
|
|
185
|
+
if (error.code !== "EEXIST") throw error;
|
|
186
|
+
let age = 0;
|
|
187
|
+
try { age = Date.now() - statSync(lock).mtimeMs; } catch { continue; }
|
|
188
|
+
if (age > STALE_LOCK_MS) { rmSync(lock, { recursive: true, force: true }); continue; }
|
|
189
|
+
if (Date.now() > deadline) throw new Error(`MOTION_RUNTIME_LOCKED: ${lock} is held by another installer`);
|
|
190
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 500);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return Promise.resolve().then(fn).finally(() => rmSync(lock, { recursive: true, force: true }));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/** Fetch bytes from an http(s) or file URL. A mirror (tests, air-gapped hosts) serves files by sha256. */
|
|
197
|
+
async function fetchBytes(url, { sha256: expected, env }) {
|
|
198
|
+
const mirror = env.LITCLAUDE_MOTION_MIRROR;
|
|
199
|
+
const source = mirror && expected ? `${mirror.replace(/\/$/u, "")}/${expected}` : url;
|
|
200
|
+
let bytes;
|
|
201
|
+
if (source.startsWith("file://")) bytes = readFileSync(fileURLToPath(source));
|
|
202
|
+
else {
|
|
203
|
+
const response = await fetch(source, { signal: AbortSignal.timeout(120000) });
|
|
204
|
+
if (!response.ok) throw new Error(`HTTP ${response.status} for ${source}`);
|
|
205
|
+
bytes = Buffer.from(await response.arrayBuffer());
|
|
206
|
+
}
|
|
207
|
+
if (expected && sha256(bytes) !== expected) throw new Error(`sha256 mismatch for ${url} (expected ${expected}, got ${sha256(bytes)})`);
|
|
208
|
+
return bytes;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function writeAtomic(file, bytes) {
|
|
212
|
+
mkdirSync(path.dirname(file), { recursive: true });
|
|
213
|
+
const tmp = `${file}.part-${process.pid}`;
|
|
214
|
+
writeFileSync(tmp, bytes);
|
|
215
|
+
renameSync(tmp, file);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export async function installFonts({ env = process.env, log = () => {} } = {}) {
|
|
219
|
+
const manifest = loadFontManifest();
|
|
220
|
+
const done = [];
|
|
221
|
+
for (const [key, font] of Object.entries(manifest.fonts)) {
|
|
222
|
+
const needsFetch = font.source === "fetch" || (font.source === "reuse" && !existsSync(path.resolve(FONT_ROOT, font.path)));
|
|
223
|
+
if (!needsFetch) continue;
|
|
224
|
+
const spec = font.source === "fetch" ? font : font.fallback;
|
|
225
|
+
const status = checkFont(key, font, env);
|
|
226
|
+
if (status.ok) {
|
|
227
|
+
done.push(key);
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
log(`fetching ${key} (${spec.bytes ?? "?"} bytes) from ${spec.url}`);
|
|
231
|
+
writeAtomic(path.join(fontsDir(env), spec.file), await fetchBytes(spec.url, { sha256: spec.sha256, env }));
|
|
232
|
+
for (const l of spec.licence) writeAtomic(path.join(fontsDir(env), l.file), await fetchBytes(l.url, { sha256: l.sha256, env }));
|
|
233
|
+
const after = checkFont(key, font, env);
|
|
234
|
+
if (!after.ok) throw new Error(`font ${key} failed verification after fetch: ${after.problem}`);
|
|
235
|
+
done.push(key);
|
|
236
|
+
}
|
|
237
|
+
return done;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function npm(args, options) {
|
|
241
|
+
const bin = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
242
|
+
return spawnSync(bin, args, { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], ...options });
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export async function installNode({ env = process.env, log = () => {} } = {}) {
|
|
246
|
+
const status = nodeStatus(env);
|
|
247
|
+
if (status.ready) return status;
|
|
248
|
+
const dir = status.dir;
|
|
249
|
+
rmSync(dir, { recursive: true, force: true });
|
|
250
|
+
mkdirSync(dir, { recursive: true });
|
|
251
|
+
for (const file of ["package.json", "package-lock.json"]) copyFileSync(path.join(ENGINE_ROOT, file), path.join(dir, file));
|
|
252
|
+
log(`installing pinned engine packages (${Object.entries(status.pinned).map(([k, v]) => `${k} ${v}`).join(", ")}) into ${dir}`);
|
|
253
|
+
const args = ["ci", "--omit=dev", "--ignore-scripts", "--no-audit", "--no-fund", "--loglevel=error"];
|
|
254
|
+
let cache = null;
|
|
255
|
+
if (env.LITCLAUDE_MOTION_MIRROR) {
|
|
256
|
+
cache = path.join(tmpdir(), `lit-motion-npm-${process.pid}-${Date.now()}`);
|
|
257
|
+
const lock = JSON.parse(readFileSync(path.join(ENGINE_ROOT, "package-lock.json"), "utf8"));
|
|
258
|
+
for (const [name, pkg] of Object.entries(lock.packages)) {
|
|
259
|
+
if (!name) continue;
|
|
260
|
+
const integrity = Buffer.from(pkg.integrity.replace(/^sha512-/u, ""), "base64").toString("hex");
|
|
261
|
+
const mirror = env.LITCLAUDE_MOTION_MIRROR.replace(/\/$/u, "");
|
|
262
|
+
const source = `${mirror}/${path.basename(new URL(pkg.resolved).pathname)}`;
|
|
263
|
+
const bytes = source.startsWith("file://") ? readFileSync(fileURLToPath(source)) : Buffer.from(await (await fetch(source)).arrayBuffer());
|
|
264
|
+
if (createHash("sha512").update(bytes).digest("hex") !== integrity) throw new Error(`integrity mismatch for ${name}`);
|
|
265
|
+
const tarball = path.join(cache, path.basename(new URL(pkg.resolved).pathname));
|
|
266
|
+
writeAtomic(tarball, bytes);
|
|
267
|
+
const add = npm(["cache", "add", tarball, "--cache", cache], { env: { ...env } });
|
|
268
|
+
if (add.status !== 0) throw new Error(`npm cache add failed: ${add.stderr.trim().slice(-400)}`);
|
|
269
|
+
}
|
|
270
|
+
args.push("--offline", "--cache", cache);
|
|
271
|
+
}
|
|
272
|
+
const result = npm(args, { cwd: dir, env: { ...env } });
|
|
273
|
+
if (cache) rmSync(cache, { recursive: true, force: true });
|
|
274
|
+
if (result.error || result.status !== 0) {
|
|
275
|
+
rmSync(dir, { recursive: true, force: true });
|
|
276
|
+
throw new Error(`npm ci exited ${result.status}: ${(result.stderr || result.error?.message || "").trim().slice(-600)}`);
|
|
277
|
+
}
|
|
278
|
+
writeFileSync(path.join(dir, READY), `${JSON.stringify({ lockHash: lockHash(), pinned: status.pinned })}\n`);
|
|
279
|
+
return nodeStatus(env);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export async function installAudio({ env = process.env, log = () => {} } = {}) {
|
|
283
|
+
const version = probePython(env);
|
|
284
|
+
if (!version) throw new Error(`${pythonCommand(env)} was not found; install Python 3.10+ or set LITCLAUDE_MOTION_PYTHON`);
|
|
285
|
+
const dir = audioDir(env, version);
|
|
286
|
+
const current = audioStatus(env);
|
|
287
|
+
if (current.state === "ready") return current;
|
|
288
|
+
rmSync(dir, { recursive: true, force: true });
|
|
289
|
+
log(`creating the audio venv (Python ${version}, librosa and its hash-pinned wheels) in ${dir}`);
|
|
290
|
+
const venv = spawnSync(pythonCommand(env), ["-m", "venv", dir], { encoding: "utf8" });
|
|
291
|
+
if (venv.status !== 0) throw new Error(`python -m venv failed: ${(venv.stderr || "").trim().slice(-400)}`);
|
|
292
|
+
const pip = spawnSync(venvPython(dir), ["-m", "pip", "install", "--require-hashes", "--only-binary=:all:", "--no-input", "--disable-pip-version-check", "--quiet", "-r", AUDIO_LOCK], { encoding: "utf8", env: { ...env } });
|
|
293
|
+
if (pip.status !== 0) {
|
|
294
|
+
rmSync(dir, { recursive: true, force: true });
|
|
295
|
+
throw new Error(`pip install --require-hashes failed: ${(pip.stderr || "").trim().slice(-600)}`);
|
|
296
|
+
}
|
|
297
|
+
writeFileSync(path.join(dir, READY), `${JSON.stringify({ lockSha256: fileSha(AUDIO_LOCK), python: version })}\n`);
|
|
298
|
+
return audioStatus(env);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* The word-timing plan: download size, every pin and its licence verdict. Printed before anything
|
|
303
|
+
* else; with no aligner runtime in this release, nothing is downloaded after it.
|
|
304
|
+
*/
|
|
305
|
+
export function wordTimingPlan() {
|
|
306
|
+
const doc = loadWordTiming();
|
|
307
|
+
const lines = [`word timing: ${(doc.totalBytes / 1e9).toFixed(2)} GB to download (${doc.models.length} models):`];
|
|
308
|
+
const verdicts = [];
|
|
309
|
+
for (const m of doc.models) {
|
|
310
|
+
const verdict = licenceVerdict(m.license, doc);
|
|
311
|
+
verdicts.push(verdict);
|
|
312
|
+
lines.push(` ${m.id} @ ${m.revision} — licence ${m.license} (${verdict}) — ${(m.bytes / 1e6).toFixed(0)} MB — ${m.role}`);
|
|
313
|
+
}
|
|
314
|
+
const blocked = verdicts.some((v) => v !== "allowed");
|
|
315
|
+
lines.push(blocked ? "word timing: a model licence is not on the allowed list; failing closed" : "word timing: every pinned licence is permissive");
|
|
316
|
+
lines.push("word timing: the aligner runtime is not part of this release; nothing was downloaded (Tier 3 stays opt-in and unavailable)");
|
|
317
|
+
return { lines, blocked: true, licenceBlocked: blocked };
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/** Pre-warm: engine deps, then fonts, then the optional audio tier. */
|
|
321
|
+
export async function installRuntime({ env = process.env, audio = false, log = () => {} } = {}) {
|
|
322
|
+
const root = runtimeRoot(env);
|
|
323
|
+
return withLock(root, async () => {
|
|
324
|
+
const node = await installNode({ env, log });
|
|
325
|
+
const fonts = await installFonts({ env, log });
|
|
326
|
+
const result = { root, node, fonts, audio: null };
|
|
327
|
+
if (audio) result.audio = await installAudio({ env, log });
|
|
328
|
+
return result;
|
|
329
|
+
});
|
|
330
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// One render session: the page served from the skill directory and the runtime cache, headless
|
|
2
|
+
// Chrome on the first WebGL2 rung, and frame egress. The WebSocket on 127.0.0.1:0 is the primary
|
|
3
|
+
// path; when `listen` is refused (a sandbox), frames are pulled over CDP from the same readback
|
|
4
|
+
// buffer instead (the sanctioned MO-A-02 variant). The screencast path is never used.
|
|
5
|
+
import { existsSync, mkdirSync, rmSync } from "node:fs";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { APP_ORIGIN, launchWithLadder, findChrome } from "./chrome.mjs";
|
|
8
|
+
import { startFrameServer } from "./ws-server.mjs";
|
|
9
|
+
import { ENGINE_ROOT, loadFontManifest, fontLocation, opentypeModule } from "./runtime.mjs";
|
|
10
|
+
|
|
11
|
+
function faultListen(env) {
|
|
12
|
+
if (env.LITCLAUDE_MOTION_FAULT !== "listen-eperm") return null;
|
|
13
|
+
return () => {
|
|
14
|
+
const error = new Error("listen EPERM: operation not permitted 127.0.0.1");
|
|
15
|
+
error.code = "EPERM";
|
|
16
|
+
throw error;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Plan sent to the page: shots, timing, preset, fonts and the egress endpoint. */
|
|
21
|
+
function pagePlan(plan, { fontKeys, ws }) {
|
|
22
|
+
const manifest = loadFontManifest();
|
|
23
|
+
return {
|
|
24
|
+
presetId: plan.presetId, signalHue: plan.signalHue, fps: plan.fps, seed: plan.seed, frameCount: plan.frameCount,
|
|
25
|
+
durationSec: plan.durationSec, label: plan.label, passParams: plan.passParams, post: plan.post,
|
|
26
|
+
shots: plan.shots.map((s) => ({ ...s, reading: undefined })),
|
|
27
|
+
fonts: fontKeys.map((key) => ({ key, format: manifest.fonts[key].format, weight: manifest.fonts[key].weight, scripts: manifest.fonts[key].scripts, file: path.basename(manifest.fonts[key].path ?? manifest.fonts[key].file) })),
|
|
28
|
+
egress: { ws },
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function openSession({ plan, fontKeys, runDir, env = process.env, softwareOnly = false, log = () => {} }) {
|
|
33
|
+
mkdirSync(runDir, { recursive: true });
|
|
34
|
+
const manifest = loadFontManifest();
|
|
35
|
+
let planJson = "{}";
|
|
36
|
+
const routes = (pathname) => {
|
|
37
|
+
if (pathname === "/run/plan.json") return { body: planJson, type: "application/json" };
|
|
38
|
+
if (pathname === "/vendor/opentype.mjs") return opentypeModule(env);
|
|
39
|
+
if (pathname.startsWith("/fonts/")) {
|
|
40
|
+
const key = pathname.slice("/fonts/".length);
|
|
41
|
+
return manifest.fonts[key] ? fontLocation(key, manifest.fonts[key], env) : null;
|
|
42
|
+
}
|
|
43
|
+
if (pathname.startsWith("/web/") || pathname.startsWith("/core/")) {
|
|
44
|
+
const file = path.resolve(ENGINE_ROOT, `.${pathname}`);
|
|
45
|
+
if (!file.startsWith(path.join(ENGINE_ROOT, path.sep)) || !existsSync(file)) return null;
|
|
46
|
+
return file;
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// Egress first: a refused listen selects the CDP pull and says why.
|
|
52
|
+
const queue = [];
|
|
53
|
+
const waiters = [];
|
|
54
|
+
let pendingMeta = null;
|
|
55
|
+
let server = null;
|
|
56
|
+
let listenError = null;
|
|
57
|
+
try {
|
|
58
|
+
server = await startFrameServer({
|
|
59
|
+
onText: (text) => { pendingMeta = JSON.parse(text); },
|
|
60
|
+
onBinary: (bytes) => {
|
|
61
|
+
queue.push({ meta: pendingMeta, bytes });
|
|
62
|
+
pendingMeta = null;
|
|
63
|
+
const w = waiters.shift();
|
|
64
|
+
if (w) w();
|
|
65
|
+
},
|
|
66
|
+
listen: faultListen(env),
|
|
67
|
+
});
|
|
68
|
+
} catch (error) {
|
|
69
|
+
listenError = error;
|
|
70
|
+
log(`egress: listen failed (${error.message}); using CDP pull of the readback buffer`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const chrome = findChrome(env);
|
|
74
|
+
let launched;
|
|
75
|
+
try {
|
|
76
|
+
launched = await launchWithLadder({ chrome, profileRoot: path.join(runDir, "chrome"), routes, softwareOnly, log });
|
|
77
|
+
} catch (error) {
|
|
78
|
+
await server?.close();
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
const { session, flags, renderer } = launched;
|
|
82
|
+
planJson = JSON.stringify(pagePlan(plan, { fontKeys, ws: server?.url ?? null }));
|
|
83
|
+
await session.navigate(`${APP_ORIGIN}/web/index.html`);
|
|
84
|
+
const deadline = Date.now() + 120000;
|
|
85
|
+
let state;
|
|
86
|
+
for (;;) {
|
|
87
|
+
state = await session.evaluate("({ ready: window.__litMotion?.ready ?? false, error: window.__litMotion?.error ?? null })").catch(() => ({ ready: false, error: null }));
|
|
88
|
+
if (state.ready || state.error) break;
|
|
89
|
+
if (Date.now() > deadline) {
|
|
90
|
+
state.error = `page did not become ready: ${session.logs.slice(0, 5).join(" | ")}`;
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
94
|
+
}
|
|
95
|
+
if (state.error) {
|
|
96
|
+
await session.close();
|
|
97
|
+
await server?.close();
|
|
98
|
+
throw new Error(`engine page failed: ${state.error}\n${session.logs.slice(0, 20).join("\n")}`);
|
|
99
|
+
}
|
|
100
|
+
const info = await session.evaluate("window.__litMotion.info()");
|
|
101
|
+
if (server && info.egress !== "websocket") log("egress: page could not open the WebSocket; using CDP pull");
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Render frames [from, to) and hand each (meta, bytes) to `onFrame` in order. In WebSocket mode
|
|
105
|
+
* the ack is sent after onFrame resolves, which bounds how far the page runs ahead.
|
|
106
|
+
*/
|
|
107
|
+
async function render({ from, to, fps, samples, shutter, stillOverrides = null, tag }, onFrame) {
|
|
108
|
+
const opts = JSON.stringify({ from, to, fps, samples, shutter, stillOverrides, tag });
|
|
109
|
+
if (info.egress === "websocket") {
|
|
110
|
+
let failure = null;
|
|
111
|
+
const streaming = session.evaluate(`window.__litMotion.stream(${opts})`).catch((error) => {
|
|
112
|
+
failure = error;
|
|
113
|
+
while (waiters.length) waiters.shift()();
|
|
114
|
+
});
|
|
115
|
+
for (let n = from; n < to; n++) {
|
|
116
|
+
while (queue.length === 0 && !failure) await new Promise((r) => waiters.push(r));
|
|
117
|
+
if (failure) throw failure;
|
|
118
|
+
const frame = queue.shift();
|
|
119
|
+
await onFrame(frame.meta, frame.bytes);
|
|
120
|
+
server.ack("ok");
|
|
121
|
+
}
|
|
122
|
+
await streaming;
|
|
123
|
+
if (failure) throw failure;
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
for (let n = from; n < to; n++) {
|
|
127
|
+
await session.evaluate(`window.__litMotion.frame(${JSON.stringify({ n, fps, samples, shutter, stillOverrides, tag })})`);
|
|
128
|
+
const pulled = await session.evaluate("window.__litMotion.pull()");
|
|
129
|
+
await onFrame(pulled.meta, Buffer.from(pulled.b64, "base64"));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
session, flags, renderer, info,
|
|
135
|
+
egress: info.egress === "websocket" ? "websocket (127.0.0.1:0, pipe-driven Chrome)" : `CDP pull of the readback buffer${listenError ? ` (listen refused: ${listenError.message})` : ""}`,
|
|
136
|
+
listenError,
|
|
137
|
+
render,
|
|
138
|
+
perf: (frames, fps) => session.evaluate(`window.__litMotion.perf(${JSON.stringify({ frames, fps })})`),
|
|
139
|
+
async close() {
|
|
140
|
+
await session.close();
|
|
141
|
+
await server?.close();
|
|
142
|
+
rmSync(path.join(runDir, "chrome"), { recursive: true, force: true });
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|