@prismer/runtime 2.0.8 → 2.2.63
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 +4004 -0
- package/README.md +34 -12
- package/apc/skills/FIELD-DICTIONARY.md +111 -0
- package/apc/skills/bug-reproduce/SKILL.md +150 -0
- package/apc/skills/bug-reproduce/skill.json +96 -0
- package/apc/skills/code-review/SKILL.md +198 -0
- package/apc/skills/code-review/skill.json +124 -0
- package/apc/skills/design-review/SKILL.md +122 -0
- package/apc/skills/design-review/skill.json +88 -0
- package/apc/skills/doc-sync/SKILL.md +168 -0
- package/apc/skills/doc-sync/skill.json +81 -0
- package/apc/skills/env-doctor/SKILL.md +194 -0
- package/apc/skills/env-doctor/skill.json +209 -0
- package/apc/skills/git-ops/SKILL.md +189 -0
- package/apc/skills/git-ops/skill.json +94 -0
- package/apc/skills/impact-trace/SKILL.md +168 -0
- package/apc/skills/impact-trace/skill.json +104 -0
- package/apc/skills/observability/SKILL.md +195 -0
- package/apc/skills/observability/skill.json +116 -0
- package/apc/skills/release-db-config-sync/SKILL.md +186 -0
- package/apc/skills/release-db-config-sync/skill.json +109 -0
- package/apc/skills/release-ota-promote/SKILL.md +195 -0
- package/apc/skills/release-ota-promote/skill.json +176 -0
- package/apc/skills/release-preflight/SKILL.md +174 -0
- package/apc/skills/release-preflight/skill.json +175 -0
- package/apc/skills/release-rollback/SKILL.md +214 -0
- package/apc/skills/release-rollback/skill.json +230 -0
- package/apc/skills/release-tag/SKILL.md +194 -0
- package/apc/skills/release-tag/skill.json +94 -0
- package/apc/skills/releasing-prod/SKILL.md +49 -0
- package/apc/skills/releasing-test/SKILL.md +144 -0
- package/apc/skills/sdk-release/SKILL.md +200 -0
- package/apc/skills/spec-intake/SKILL.md +169 -0
- package/apc/skills/spec-intake/skill.json +93 -0
- package/apc/skills/test-result-feedback/SKILL.md +239 -0
- package/apc/skills/test-result-feedback/skill.json +193 -0
- package/apc/skills/test-runner/SKILL.md +169 -0
- package/apc/skills/test-runner/skill.json +103 -0
- package/apc/skills/ui-align/SKILL.md +209 -0
- package/apc/skills/ui-align/skill.json +114 -0
- package/apc/skills/ui-canvas/SKILL.md +148 -0
- package/apc/skills/ui-canvas/skill.json +127 -0
- package/built-in-skills/agent-coordination/SKILL.md +77 -38
- package/built-in-skills/agent-meta/SKILL.md +12 -0
- package/built-in-skills/assets/SKILL.md +9 -7
- package/built-in-skills/browser-use/SKILL.md +93 -0
- package/built-in-skills/canvas-design/SKILL.md +4 -3
- package/built-in-skills/canvas-design/canvas-fonts/IBMPlexSerif-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/InstrumentSerif-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/LICENSE-SOURCES.md +16 -0
- package/built-in-skills/claim-agent-ownership/SKILL.md +10 -5
- package/built-in-skills/claude-api/SKILL.md +2 -1
- package/built-in-skills/claude-api/python/claude-api/README.md +2 -2
- package/built-in-skills/claude-api/python/claude-api/tool-use.md +9 -5
- package/built-in-skills/claude-api/python/managed-agents/README.md +11 -1
- package/built-in-skills/claude-api/shared/error-codes.md +4 -4
- package/built-in-skills/claude-api/shared/managed-agents-client-patterns.md +4 -2
- package/built-in-skills/claude-api/shared/managed-agents-core.md +1 -2
- package/built-in-skills/claude-api/shared/managed-agents-events.md +41 -22
- package/built-in-skills/claude-api/shared/managed-agents-multiagent.md +5 -3
- package/built-in-skills/claude-api/shared/managed-agents-self-hosted-sandboxes.md +1 -1
- package/built-in-skills/claude-api/shared/managed-agents-tools.md +2 -3
- package/built-in-skills/claude-api/shared/model-migration.md +3 -3
- package/built-in-skills/claude-api/shared/models.md +1 -1
- package/built-in-skills/claude-api/typescript/claude-api/batches.md +1 -1
- package/built-in-skills/claude-api/typescript/claude-api/files-api.md +3 -1
- package/built-in-skills/claude-api/typescript/claude-api/tool-use.md +8 -2
- package/built-in-skills/claude-api/typescript/managed-agents/README.md +8 -2
- package/built-in-skills/codebase-design/DEEPENING.md +37 -0
- package/built-in-skills/codebase-design/DESIGN-IT-TWICE.md +44 -0
- package/built-in-skills/codebase-design/LICENSE +21 -0
- package/built-in-skills/codebase-design/SKILL.md +130 -0
- package/built-in-skills/codebase-design/references/requesting-code-review/GUIDE.md +291 -0
- package/built-in-skills/codebase-design/references/requesting-code-review/LICENSE +21 -0
- package/built-in-skills/codebase-design/references/requesting-code-review/LICENSE.superpowers +21 -0
- package/built-in-skills/codebase-design/references/requesting-code-review/NOTICE.md +37 -0
- package/built-in-skills/codebase-design/references/sdlc-review/GUIDE.md +130 -0
- package/built-in-skills/codebase-design/references/sdlc-review/LICENSE +21 -0
- package/built-in-skills/codebase-design/references/sdlc-review/NOTICE.md +17 -0
- package/built-in-skills/codebase-design/references/simplify-code/GUIDE.md +269 -0
- package/built-in-skills/codebase-design/references/simplify-code/LICENSE +21 -0
- package/built-in-skills/codebase-design/references/simplify-code/NOTICE.md +37 -0
- package/built-in-skills/competitor-intelligence/LICENSE +21 -0
- package/built-in-skills/competitor-intelligence/NOTICE.md +6 -0
- package/built-in-skills/competitor-intelligence/SKILL.md +125 -0
- package/built-in-skills/competitor-intelligence/scripts/watch_state.py +160 -0
- package/built-in-skills/conversation-compaction/SKILL.md +117 -0
- package/built-in-skills/council-creator/SKILL.md +427 -0
- package/built-in-skills/diagnosing-bugs/LICENSE +21 -0
- package/built-in-skills/diagnosing-bugs/SKILL.md +148 -0
- package/built-in-skills/diagnosing-bugs/references/desktop-dom/GUIDE.md +64 -0
- package/built-in-skills/diagnosing-bugs/references/desktop-dom/LICENSE +21 -0
- package/built-in-skills/diagnosing-bugs/references/desktop-dom/NOTICE.md +17 -0
- package/built-in-skills/diagnosing-bugs/references/systematic-debugging/GUIDE.md +410 -0
- package/built-in-skills/diagnosing-bugs/references/systematic-debugging/LICENSE +21 -0
- package/built-in-skills/diagnosing-bugs/references/systematic-debugging/LICENSE.superpowers +21 -0
- package/built-in-skills/diagnosing-bugs/references/systematic-debugging/NOTICE.md +37 -0
- package/built-in-skills/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
- package/built-in-skills/doc-coauthoring/SKILL.md +7 -0
- package/built-in-skills/doc-coauthoring/references/humanizer/GUIDE.md +647 -0
- package/built-in-skills/doc-coauthoring/references/humanizer/LICENSE +21 -0
- package/built-in-skills/doc-coauthoring/references/humanizer/LICENSE.hermes +21 -0
- package/built-in-skills/doc-coauthoring/references/humanizer/PROVENANCE.md +7 -0
- package/built-in-skills/document-actions/LICENSE +21 -0
- package/built-in-skills/document-actions/NOTICE.md +21 -0
- package/built-in-skills/document-actions/SKILL.md +46 -0
- package/built-in-skills/domain-modeling/ADR-FORMAT.md +47 -0
- package/built-in-skills/domain-modeling/CONTEXT-FORMAT.md +60 -0
- package/built-in-skills/domain-modeling/LICENSE +21 -0
- package/built-in-skills/domain-modeling/SKILL.md +76 -0
- package/built-in-skills/evidence-citations/LICENSE +21 -0
- package/built-in-skills/evidence-citations/NOTICE.md +21 -0
- package/built-in-skills/evidence-citations/SKILL.md +46 -0
- package/built-in-skills/evidence-citations/references/citation-formats.md +68 -0
- package/built-in-skills/evidence-citations/references/grounding-rationale.md +64 -0
- package/built-in-skills/evidence-citations/scripts/sources.py +720 -0
- package/built-in-skills/frontend-design/SKILL.md +7 -0
- package/built-in-skills/frontend-design/references/claude-design/GUIDE.md +650 -0
- package/built-in-skills/frontend-design/references/claude-design/LICENSE +21 -0
- package/built-in-skills/frontend-design/references/claude-design/LICENSE.hermes +21 -0
- package/built-in-skills/frontend-design/references/claude-design/PROVENANCE.md +7 -0
- package/built-in-skills/human-approval/SKILL.md +17 -2
- package/built-in-skills/image-generate/SKILL.md +107 -301
- package/built-in-skills/image-generate/scripts/generate-and-deliver.mjs +310 -0
- package/built-in-skills/ingest/SKILL.md +13 -45
- package/built-in-skills/internal-comms/SKILL.md +1 -0
- package/built-in-skills/liteparse/SKILL.md +130 -110
- package/built-in-skills/mcp-builder/SKILL.md +1 -0
- package/built-in-skills/mcp-builder/reference/evaluation.md +11 -2
- package/built-in-skills/mcp-builder/reference/node_mcp_server.md +34 -5
- package/built-in-skills/mcp-builder/reference/python_mcp_server.md +6 -2
- package/built-in-skills/mcp-builder/scripts/connections.py +1 -1
- package/built-in-skills/mcp-builder/scripts/evaluation.py +52 -34
- package/built-in-skills/mcp-builder/scripts/requirements.txt +2 -2
- package/built-in-skills/meeting-actions/LICENSE +21 -0
- package/built-in-skills/meeting-actions/NOTICE.md +21 -0
- package/built-in-skills/meeting-actions/SKILL.md +48 -0
- package/built-in-skills/memory/SKILL.md +444 -55
- package/built-in-skills/memory/references/llm-wiki/GUIDE.md +468 -0
- package/built-in-skills/memory/references/llm-wiki/LICENSE +21 -0
- package/built-in-skills/memory/references/llm-wiki/NOTICE.md +4 -0
- package/built-in-skills/memory/references/llm-wiki/scripts/lint_wiki.py +84 -0
- package/built-in-skills/memory/references/llm-wiki/scripts/requirements.txt +1 -0
- package/built-in-skills/memory/references/llm-wiki/templates/SCHEMA.md +19 -0
- package/built-in-skills/memory/references/llm-wiki/templates/index.md +9 -0
- package/built-in-skills/memory/references/llm-wiki/templates/log.md +4 -0
- package/built-in-skills/memory-dream/SKILL.md +332 -0
- package/built-in-skills/memory-import/SKILL.md +51 -0
- package/built-in-skills/office-artifacts/NOTICE.md +15 -0
- package/built-in-skills/office-artifacts/SKILL.md +37 -4
- package/built-in-skills/office-artifacts/references/RESOURCE-LIMITS.md +44 -0
- package/built-in-skills/office-artifacts/references/document-generation/GUIDE.md +105 -0
- package/built-in-skills/office-artifacts/references/docx/GUIDE.md +196 -0
- package/built-in-skills/office-artifacts/references/docx/LICENSE +21 -0
- package/built-in-skills/office-artifacts/references/docx/NOTICE.md +21 -0
- package/built-in-skills/office-artifacts/references/docx/references/revisions-and-comments.md +88 -0
- package/built-in-skills/office-artifacts/references/docx/scripts/docx_comments.py +292 -0
- package/built-in-skills/office-artifacts/references/docx/scripts/docx_common.py +93 -0
- package/built-in-skills/office-artifacts/references/docx/scripts/docx_create.py +177 -0
- package/built-in-skills/office-artifacts/references/docx/scripts/docx_edit.py +250 -0
- package/built-in-skills/office-artifacts/references/docx/scripts/docx_read.py +169 -0
- package/built-in-skills/office-artifacts/references/docx/scripts/docx_revisions.py +149 -0
- package/built-in-skills/office-artifacts/references/docx/scripts/docx_template.py +70 -0
- package/built-in-skills/office-artifacts/references/docx/scripts/docx_validate.py +155 -0
- package/built-in-skills/office-artifacts/references/docx/tests/test_docx_skill.py +525 -0
- package/built-in-skills/office-artifacts/references/pdf/GUIDE.md +125 -0
- package/built-in-skills/office-artifacts/references/pdf/LICENSE +21 -0
- package/built-in-skills/office-artifacts/references/pdf/NOTICE.md +21 -0
- package/built-in-skills/office-artifacts/references/pdf/references/forms.md +99 -0
- package/built-in-skills/office-artifacts/references/pdf/references/nano-pdf-editing.md +40 -0
- package/built-in-skills/office-artifacts/references/pdf/references/ocr-extraction.md +165 -0
- package/built-in-skills/office-artifacts/references/pdf/scripts/_raster.py +87 -0
- package/built-in-skills/office-artifacts/references/pdf/scripts/extract_marker.py +95 -0
- package/built-in-skills/office-artifacts/references/pdf/scripts/extract_pymupdf.py +107 -0
- package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_create.py +153 -0
- package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_fill_form.py +97 -0
- package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_form_layout.py +168 -0
- package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_make_form.py +145 -0
- package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_merge.py +50 -0
- package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_meta.py +123 -0
- package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_page_image.py +101 -0
- package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_read.py +153 -0
- package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_secure.py +71 -0
- package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_split.py +86 -0
- package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_stamp.py +145 -0
- package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_watermark.py +51 -0
- package/built-in-skills/office-artifacts/references/pdf/tests/test_pdf_skill.py +414 -0
- package/built-in-skills/office-artifacts/references/powerpoint/GUIDE.md +220 -0
- package/built-in-skills/office-artifacts/references/powerpoint/LICENSE +21 -0
- package/built-in-skills/office-artifacts/references/powerpoint/NOTICE.md +21 -0
- package/built-in-skills/office-artifacts/references/powerpoint/scripts/pptx_create.py +214 -0
- package/built-in-skills/office-artifacts/references/powerpoint/scripts/pptx_edit.py +442 -0
- package/built-in-skills/office-artifacts/references/powerpoint/scripts/pptx_from_template.py +88 -0
- package/built-in-skills/office-artifacts/references/powerpoint/scripts/pptx_read.py +131 -0
- package/built-in-skills/office-artifacts/references/powerpoint/scripts/pptx_render.py +104 -0
- package/built-in-skills/office-artifacts/references/powerpoint/tests/test_powerpoint_skill.py +478 -0
- package/built-in-skills/office-artifacts/references/xlsx/GUIDE.md +196 -0
- package/built-in-skills/office-artifacts/references/xlsx/LICENSE +21 -0
- package/built-in-skills/office-artifacts/references/xlsx/NOTICE.md +21 -0
- package/built-in-skills/office-artifacts/references/xlsx/references/restructuring.md +74 -0
- package/built-in-skills/office-artifacts/references/xlsx/scripts/csv_to_xlsx.py +108 -0
- package/built-in-skills/office-artifacts/references/xlsx/scripts/xlsx_create.py +259 -0
- package/built-in-skills/office-artifacts/references/xlsx/scripts/xlsx_edit.py +269 -0
- package/built-in-skills/office-artifacts/references/xlsx/scripts/xlsx_read.py +160 -0
- package/built-in-skills/office-artifacts/references/xlsx/scripts/xlsx_recalc.py +111 -0
- package/built-in-skills/office-artifacts/references/xlsx/scripts/xlsx_restructure.py +418 -0
- package/built-in-skills/office-artifacts/references/xlsx/scripts/xlsx_to_csv.py +69 -0
- package/built-in-skills/office-artifacts/references/xlsx/tests/test_xlsx_skill.py +542 -0
- package/built-in-skills/office-artifacts/tests/test_resource_regressions.py +272 -0
- package/built-in-skills/okr/SKILL.md +154 -0
- package/built-in-skills/persona/SKILL.md +81 -0
- package/built-in-skills/persona-generator/SKILL.md +296 -0
- package/built-in-skills/pkf-svg/SKILL.md +258 -0
- package/built-in-skills/pkf-svg/references/architecture-diagram/GUIDE.md +148 -0
- package/built-in-skills/pkf-svg/references/architecture-diagram/LICENSE +21 -0
- package/built-in-skills/pkf-svg/references/architecture-diagram/LICENSE.hermes +21 -0
- package/built-in-skills/pkf-svg/references/architecture-diagram/PROVENANCE.md +7 -0
- package/built-in-skills/pkf-svg/references/architecture-diagram/templates/template.html +345 -0
- package/built-in-skills/pkf-writing/SKILL.md +258 -0
- package/built-in-skills/prismer-airtable/LICENSE +21 -0
- package/built-in-skills/prismer-airtable/NOTICE.md +11 -0
- package/built-in-skills/prismer-airtable/SKILL.md +248 -0
- package/built-in-skills/prismer-airtable/scripts/airtable_client.py +76 -0
- package/built-in-skills/prismer-apple-notes/LICENSE +21 -0
- package/built-in-skills/prismer-apple-notes/NOTICE.md +17 -0
- package/built-in-skills/prismer-apple-notes/SKILL.md +118 -0
- package/built-in-skills/prismer-apple-notes/scripts/readiness.py +47 -0
- package/built-in-skills/prismer-apple-reminders/LICENSE +21 -0
- package/built-in-skills/prismer-apple-reminders/NOTICE.md +17 -0
- package/built-in-skills/prismer-apple-reminders/SKILL.md +155 -0
- package/built-in-skills/prismer-apple-reminders/scripts/readiness.py +47 -0
- package/built-in-skills/prismer-ascii-video/LICENSE +21 -0
- package/built-in-skills/prismer-ascii-video/LICENSE.hermes +21 -0
- package/built-in-skills/prismer-ascii-video/PROVENANCE.md +7 -0
- package/built-in-skills/prismer-ascii-video/README.md +290 -0
- package/built-in-skills/prismer-ascii-video/SKILL.md +252 -0
- package/built-in-skills/prismer-ascii-video/provenance/category-DESCRIPTION.md +3 -0
- package/built-in-skills/prismer-ascii-video/references/architecture.md +807 -0
- package/built-in-skills/prismer-ascii-video/references/composition.md +900 -0
- package/built-in-skills/prismer-ascii-video/references/effects.md +1877 -0
- package/built-in-skills/prismer-ascii-video/references/inputs.md +693 -0
- package/built-in-skills/prismer-ascii-video/references/optimization.md +688 -0
- package/built-in-skills/prismer-ascii-video/references/scenes.md +1018 -0
- package/built-in-skills/prismer-ascii-video/references/shaders.md +1408 -0
- package/built-in-skills/prismer-ascii-video/references/troubleshooting.md +360 -0
- package/built-in-skills/prismer-baoyu-infographic/LICENSE +21 -0
- package/built-in-skills/prismer-baoyu-infographic/LICENSE.hermes +21 -0
- package/built-in-skills/prismer-baoyu-infographic/LICENSE.origin +21 -0
- package/built-in-skills/prismer-baoyu-infographic/PORT_NOTES.md +37 -0
- package/built-in-skills/prismer-baoyu-infographic/PROVENANCE.md +7 -0
- package/built-in-skills/prismer-baoyu-infographic/SKILL.md +240 -0
- package/built-in-skills/prismer-baoyu-infographic/references/analysis-framework.md +182 -0
- package/built-in-skills/prismer-baoyu-infographic/references/base-prompt.md +43 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/bento-grid.md +41 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/binary-comparison.md +48 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/bridge.md +41 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/circular-flow.md +41 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/comic-strip.md +41 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/comparison-matrix.md +41 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/dashboard.md +41 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/dense-modules.md +72 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/funnel.md +41 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/hierarchical-layers.md +48 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/hub-spoke.md +41 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/iceberg.md +41 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/isometric-map.md +41 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/jigsaw.md +41 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/linear-progression.md +48 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/periodic-table.md +41 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/story-mountain.md +41 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/structural-breakdown.md +48 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/tree-branching.md +41 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/venn-diagram.md +41 -0
- package/built-in-skills/prismer-baoyu-infographic/references/layouts/winding-roadmap.md +41 -0
- package/built-in-skills/prismer-baoyu-infographic/references/structured-content-template.md +244 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/aged-academia.md +36 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/bold-graphic.md +36 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/chalkboard.md +61 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/claymation.md +29 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/corporate-memphis.md +29 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/craft-handmade.md +44 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/cyberpunk-neon.md +29 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/hand-drawn-edu.md +63 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/ikea-manual.md +29 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/kawaii.md +29 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/knolling.md +29 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/lego-brick.md +29 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/morandi-journal.md +60 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/origami.md +29 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/pixel-art.md +29 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/pop-laboratory.md +48 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/retro-pop-grid.md +47 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/storybook-watercolor.md +29 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/subway-map.md +29 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/technical-schematic.md +36 -0
- package/built-in-skills/prismer-baoyu-infographic/references/styles/ui-wireframe.md +29 -0
- package/built-in-skills/prismer-blocked-page-recovery/LICENSE +21 -0
- package/built-in-skills/prismer-blocked-page-recovery/NOTICE.md +17 -0
- package/built-in-skills/prismer-blocked-page-recovery/SKILL.md +158 -0
- package/built-in-skills/prismer-blocked-page-recovery/scripts/recover_page.py +311 -0
- package/built-in-skills/prismer-box/LICENSE +21 -0
- package/built-in-skills/prismer-box/NOTICE.md +11 -0
- package/built-in-skills/prismer-box/SKILL.md +147 -0
- package/built-in-skills/prismer-box/references/bulk-operations.md +43 -0
- package/built-in-skills/prismer-box/references/cli-guide.md +133 -0
- package/built-in-skills/prismer-box/references/content-workflows.md +86 -0
- package/built-in-skills/prismer-box/references/hubs.md +77 -0
- package/built-in-skills/prismer-box/references/oauth-setup.md +92 -0
- package/built-in-skills/prismer-box/references/rest-api.md +37 -0
- package/built-in-skills/prismer-box/references/sdk-development.md +85 -0
- package/built-in-skills/prismer-box/references/search-and-ai.md +147 -0
- package/built-in-skills/prismer-box/references/troubleshooting.md +33 -0
- package/built-in-skills/prismer-box/references/webhooks-and-events.md +43 -0
- package/built-in-skills/prismer-codebase-inspection/LICENSE +21 -0
- package/built-in-skills/prismer-codebase-inspection/NOTICE.md +17 -0
- package/built-in-skills/prismer-codebase-inspection/SKILL.md +141 -0
- package/built-in-skills/prismer-computer-use/LICENSE +21 -0
- package/built-in-skills/prismer-computer-use/NOTICE.md +17 -0
- package/built-in-skills/prismer-computer-use/SKILL.md +372 -0
- package/built-in-skills/prismer-design-md/LICENSE +21 -0
- package/built-in-skills/prismer-design-md/LICENSE.hermes +21 -0
- package/built-in-skills/prismer-design-md/PROVENANCE.md +7 -0
- package/built-in-skills/prismer-design-md/SKILL.md +227 -0
- package/built-in-skills/prismer-design-md/templates/starter.md +99 -0
- package/built-in-skills/prismer-email-inbox-triage/LICENSE +21 -0
- package/built-in-skills/prismer-email-inbox-triage/NOTICE.md +11 -0
- package/built-in-skills/prismer-email-inbox-triage/SKILL.md +116 -0
- package/built-in-skills/prismer-findmy/LICENSE +21 -0
- package/built-in-skills/prismer-findmy/NOTICE.md +17 -0
- package/built-in-skills/prismer-findmy/SKILL.md +150 -0
- package/built-in-skills/prismer-findmy/scripts/readiness.py +47 -0
- package/built-in-skills/prismer-gif-search/LICENSE +21 -0
- package/built-in-skills/prismer-gif-search/LICENSE.hermes +21 -0
- package/built-in-skills/prismer-gif-search/PROVENANCE.md +7 -0
- package/built-in-skills/prismer-gif-search/SKILL.md +97 -0
- package/built-in-skills/prismer-gif-search/scripts/tenor.py +81 -0
- package/built-in-skills/prismer-github/LICENSE +21 -0
- package/built-in-skills/prismer-github/NOTICE.md +17 -0
- package/built-in-skills/prismer-github/SKILL.md +74 -0
- package/built-in-skills/prismer-github/references/auth.md +91 -0
- package/built-in-skills/prismer-github/references/ci-troubleshooting.md +193 -0
- package/built-in-skills/prismer-github/references/code-review.md +465 -0
- package/built-in-skills/prismer-github/references/conventional-commits.md +81 -0
- package/built-in-skills/prismer-github/references/github-api-cheatsheet.md +177 -0
- package/built-in-skills/prismer-github/references/issue-to-pr.md +74 -0
- package/built-in-skills/prismer-github/references/issues.md +336 -0
- package/built-in-skills/prismer-github/references/pr-workflow.md +346 -0
- package/built-in-skills/prismer-github/references/repo-management.md +484 -0
- package/built-in-skills/prismer-github/references/review-output-template.md +84 -0
- package/built-in-skills/prismer-github/scripts/ensure-gh.py +132 -0
- package/built-in-skills/prismer-github/scripts/gh-env.sh +25 -0
- package/built-in-skills/prismer-github/scripts/git-credential-token.py +68 -0
- package/built-in-skills/prismer-github/scripts/github-api.py +71 -0
- package/built-in-skills/prismer-github/scripts/github-context.py +28 -0
- package/built-in-skills/prismer-github/templates/bug-report.md +35 -0
- package/built-in-skills/prismer-github/templates/feature-request.md +31 -0
- package/built-in-skills/prismer-github/templates/pr-body-bugfix.md +35 -0
- package/built-in-skills/prismer-github/templates/pr-body-feature.md +33 -0
- package/built-in-skills/prismer-google-workspace/LICENSE +21 -0
- package/built-in-skills/prismer-google-workspace/NOTICE.md +11 -0
- package/built-in-skills/prismer-google-workspace/SKILL.md +369 -0
- package/built-in-skills/prismer-google-workspace/references/daily-brief.md +65 -0
- package/built-in-skills/prismer-google-workspace/references/gmail-search-syntax.md +63 -0
- package/built-in-skills/prismer-google-workspace/scripts/_hermes_home.py +17 -0
- package/built-in-skills/prismer-google-workspace/scripts/_private_state.py +39 -0
- package/built-in-skills/prismer-google-workspace/scripts/google_api.py +1339 -0
- package/built-in-skills/prismer-google-workspace/scripts/gws_bridge.py +121 -0
- package/built-in-skills/prismer-google-workspace/scripts/setup.py +563 -0
- package/built-in-skills/prismer-google-workspace/tests/test_productivity_regressions.py +214 -0
- package/built-in-skills/prismer-hermes-agent/LICENSE +21 -0
- package/built-in-skills/prismer-hermes-agent/NOTICE.md +17 -0
- package/built-in-skills/prismer-hermes-agent/SKILL.md +247 -0
- package/built-in-skills/prismer-hermes-agent/references/background-systems.md +108 -0
- package/built-in-skills/prismer-hermes-agent/references/cli-reference.md +158 -0
- package/built-in-skills/prismer-hermes-agent/references/configuration.md +96 -0
- package/built-in-skills/prismer-hermes-agent/references/contributor-guide.md +151 -0
- package/built-in-skills/prismer-hermes-agent/references/delegate-task-concurrency-diagnosis.md +47 -0
- package/built-in-skills/prismer-hermes-agent/references/desktop-plugins.md +215 -0
- package/built-in-skills/prismer-hermes-agent/references/native-mcp.md +351 -0
- package/built-in-skills/prismer-hermes-agent/references/petdex.md +82 -0
- package/built-in-skills/prismer-hermes-agent/references/portal-auth-for-third-party-apps.md +135 -0
- package/built-in-skills/prismer-hermes-agent/references/project-context-files.md +55 -0
- package/built-in-skills/prismer-hermes-agent/references/providers-and-models.md +81 -0
- package/built-in-skills/prismer-hermes-agent/references/security-privacy.md +73 -0
- package/built-in-skills/prismer-hermes-agent/references/slash-commands.md +119 -0
- package/built-in-skills/prismer-hermes-agent/references/themes.md +134 -0
- package/built-in-skills/prismer-hermes-agent/references/troubleshooting.md +87 -0
- package/built-in-skills/prismer-hermes-agent/references/tui-widgets.md +144 -0
- package/built-in-skills/prismer-hermes-agent/references/webhooks.md +219 -0
- package/built-in-skills/prismer-hermes-agent/references/windows-quirks.md +64 -0
- package/built-in-skills/prismer-hermes-agent/templates/clock.mjs +51 -0
- package/built-in-skills/prismer-hermes-agent/templates/plugin.js +97 -0
- package/built-in-skills/prismer-hermes-agent/templates/skin.yaml +49 -0
- package/built-in-skills/prismer-himalaya/LICENSE +21 -0
- package/built-in-skills/prismer-himalaya/NOTICE.md +11 -0
- package/built-in-skills/prismer-himalaya/SKILL.md +340 -0
- package/built-in-skills/prismer-himalaya/references/configuration.md +227 -0
- package/built-in-skills/prismer-himalaya/references/message-composition.md +206 -0
- package/built-in-skills/prismer-himalaya/scripts/compose_draft.py +48 -0
- package/built-in-skills/prismer-im-collab/SKILL.md +27 -7
- package/built-in-skills/prismer-imessage/LICENSE +21 -0
- package/built-in-skills/prismer-imessage/NOTICE.md +17 -0
- package/built-in-skills/prismer-imessage/SKILL.md +128 -0
- package/built-in-skills/prismer-imessage/scripts/readiness.py +47 -0
- package/built-in-skills/prismer-manim-video/LICENSE +21 -0
- package/built-in-skills/prismer-manim-video/LICENSE.hermes +21 -0
- package/built-in-skills/prismer-manim-video/PROVENANCE.md +7 -0
- package/built-in-skills/prismer-manim-video/README.md +23 -0
- package/built-in-skills/prismer-manim-video/SKILL.md +279 -0
- package/built-in-skills/prismer-manim-video/references/animation-design-thinking.md +161 -0
- package/built-in-skills/prismer-manim-video/references/animations.md +282 -0
- package/built-in-skills/prismer-manim-video/references/camera-and-3d.md +135 -0
- package/built-in-skills/prismer-manim-video/references/decorations.md +202 -0
- package/built-in-skills/prismer-manim-video/references/equations.md +216 -0
- package/built-in-skills/prismer-manim-video/references/graphs-and-data.md +163 -0
- package/built-in-skills/prismer-manim-video/references/mobjects.md +333 -0
- package/built-in-skills/prismer-manim-video/references/paper-explainer.md +255 -0
- package/built-in-skills/prismer-manim-video/references/production-quality.md +190 -0
- package/built-in-skills/prismer-manim-video/references/rendering.md +187 -0
- package/built-in-skills/prismer-manim-video/references/scene-planning.md +118 -0
- package/built-in-skills/prismer-manim-video/references/troubleshooting.md +135 -0
- package/built-in-skills/prismer-manim-video/references/updaters-and-trackers.md +260 -0
- package/built-in-skills/prismer-manim-video/references/visual-design.md +124 -0
- package/built-in-skills/prismer-manim-video/scripts/setup.sh +15 -0
- package/built-in-skills/prismer-maps/LICENSE +21 -0
- package/built-in-skills/prismer-maps/NOTICE.md +11 -0
- package/built-in-skills/prismer-maps/SKILL.md +240 -0
- package/built-in-skills/prismer-maps/scripts/maps_client.py +1324 -0
- package/built-in-skills/prismer-node-inspect-debugger/LICENSE +21 -0
- package/built-in-skills/prismer-node-inspect-debugger/NOTICE.md +17 -0
- package/built-in-skills/prismer-node-inspect-debugger/SKILL.md +347 -0
- package/built-in-skills/prismer-notion/LICENSE +21 -0
- package/built-in-skills/prismer-notion/NOTICE.md +11 -0
- package/built-in-skills/prismer-notion/SKILL.md +495 -0
- package/built-in-skills/prismer-notion/references/block-types.md +112 -0
- package/built-in-skills/prismer-obsidian/LICENSE +21 -0
- package/built-in-skills/prismer-obsidian/LICENSE.hermes +21 -0
- package/built-in-skills/prismer-obsidian/PROVENANCE.md +7 -0
- package/built-in-skills/prismer-obsidian/SKILL.md +80 -0
- package/built-in-skills/prismer-obsidian/provenance/category-DESCRIPTION.md +3 -0
- package/built-in-skills/prismer-obsidian/scripts/write_note.py +84 -0
- package/built-in-skills/prismer-p5js/LICENSE +21 -0
- package/built-in-skills/prismer-p5js/LICENSE.hermes +21 -0
- package/built-in-skills/prismer-p5js/PROVENANCE.md +7 -0
- package/built-in-skills/prismer-p5js/README.md +64 -0
- package/built-in-skills/prismer-p5js/SKILL.md +574 -0
- package/built-in-skills/prismer-p5js/references/animation.md +439 -0
- package/built-in-skills/prismer-p5js/references/color-systems.md +355 -0
- package/built-in-skills/prismer-p5js/references/core-api.md +410 -0
- package/built-in-skills/prismer-p5js/references/export-pipeline.md +534 -0
- package/built-in-skills/prismer-p5js/references/interaction.md +398 -0
- package/built-in-skills/prismer-p5js/references/shapes-and-geometry.md +300 -0
- package/built-in-skills/prismer-p5js/references/troubleshooting.md +532 -0
- package/built-in-skills/prismer-p5js/references/typography.md +302 -0
- package/built-in-skills/prismer-p5js/references/visual-effects.md +905 -0
- package/built-in-skills/prismer-p5js/references/webgl-and-3d.md +423 -0
- package/built-in-skills/prismer-p5js/scripts/export-frames.js +91 -0
- package/built-in-skills/prismer-p5js/scripts/render.sh +113 -0
- package/built-in-skills/prismer-p5js/scripts/serve.sh +25 -0
- package/built-in-skills/prismer-p5js/scripts/setup.sh +87 -0
- package/built-in-skills/prismer-p5js/templates/viewer.html +401 -0
- package/built-in-skills/prismer-popular-web-designs/LICENSE +21 -0
- package/built-in-skills/prismer-popular-web-designs/LICENSE.hermes +21 -0
- package/built-in-skills/prismer-popular-web-designs/LICENSE.origin +21 -0
- package/built-in-skills/prismer-popular-web-designs/PROVENANCE.md +7 -0
- package/built-in-skills/prismer-popular-web-designs/SKILL.md +218 -0
- package/built-in-skills/prismer-popular-web-designs/templates/airbnb.md +259 -0
- package/built-in-skills/prismer-popular-web-designs/templates/airtable.md +102 -0
- package/built-in-skills/prismer-popular-web-designs/templates/apple.md +326 -0
- package/built-in-skills/prismer-popular-web-designs/templates/bmw.md +193 -0
- package/built-in-skills/prismer-popular-web-designs/templates/cal.md +272 -0
- package/built-in-skills/prismer-popular-web-designs/templates/claude.md +325 -0
- package/built-in-skills/prismer-popular-web-designs/templates/clay.md +317 -0
- package/built-in-skills/prismer-popular-web-designs/templates/clickhouse.md +294 -0
- package/built-in-skills/prismer-popular-web-designs/templates/cohere.md +279 -0
- package/built-in-skills/prismer-popular-web-designs/templates/coinbase.md +142 -0
- package/built-in-skills/prismer-popular-web-designs/templates/composio.md +320 -0
- package/built-in-skills/prismer-popular-web-designs/templates/cursor.md +322 -0
- package/built-in-skills/prismer-popular-web-designs/templates/elevenlabs.md +278 -0
- package/built-in-skills/prismer-popular-web-designs/templates/expo.md +294 -0
- package/built-in-skills/prismer-popular-web-designs/templates/figma.md +233 -0
- package/built-in-skills/prismer-popular-web-designs/templates/framer.md +259 -0
- package/built-in-skills/prismer-popular-web-designs/templates/hashicorp.md +291 -0
- package/built-in-skills/prismer-popular-web-designs/templates/ibm.md +345 -0
- package/built-in-skills/prismer-popular-web-designs/templates/intercom.md +159 -0
- package/built-in-skills/prismer-popular-web-designs/templates/kraken.md +138 -0
- package/built-in-skills/prismer-popular-web-designs/templates/linear.app.md +380 -0
- package/built-in-skills/prismer-popular-web-designs/templates/lovable.md +311 -0
- package/built-in-skills/prismer-popular-web-designs/templates/minimax.md +270 -0
- package/built-in-skills/prismer-popular-web-designs/templates/mintlify.md +339 -0
- package/built-in-skills/prismer-popular-web-designs/templates/miro.md +121 -0
- package/built-in-skills/prismer-popular-web-designs/templates/mistral.ai.md +274 -0
- package/built-in-skills/prismer-popular-web-designs/templates/mongodb.md +279 -0
- package/built-in-skills/prismer-popular-web-designs/templates/notion.md +322 -0
- package/built-in-skills/prismer-popular-web-designs/templates/nvidia.md +306 -0
- package/built-in-skills/prismer-popular-web-designs/templates/ollama.md +280 -0
- package/built-in-skills/prismer-popular-web-designs/templates/opencode.ai.md +294 -0
- package/built-in-skills/prismer-popular-web-designs/templates/pinterest.md +243 -0
- package/built-in-skills/prismer-popular-web-designs/templates/posthog.md +269 -0
- package/built-in-skills/prismer-popular-web-designs/templates/raycast.md +281 -0
- package/built-in-skills/prismer-popular-web-designs/templates/replicate.md +274 -0
- package/built-in-skills/prismer-popular-web-designs/templates/resend.md +316 -0
- package/built-in-skills/prismer-popular-web-designs/templates/revolut.md +198 -0
- package/built-in-skills/prismer-popular-web-designs/templates/runwayml.md +257 -0
- package/built-in-skills/prismer-popular-web-designs/templates/sanity.md +370 -0
- package/built-in-skills/prismer-popular-web-designs/templates/sentry.md +275 -0
- package/built-in-skills/prismer-popular-web-designs/templates/spacex.md +207 -0
- package/built-in-skills/prismer-popular-web-designs/templates/spotify.md +259 -0
- package/built-in-skills/prismer-popular-web-designs/templates/stripe.md +335 -0
- package/built-in-skills/prismer-popular-web-designs/templates/supabase.md +268 -0
- package/built-in-skills/prismer-popular-web-designs/templates/superhuman.md +265 -0
- package/built-in-skills/prismer-popular-web-designs/templates/together.ai.md +276 -0
- package/built-in-skills/prismer-popular-web-designs/templates/uber.md +308 -0
- package/built-in-skills/prismer-popular-web-designs/templates/vercel.md +323 -0
- package/built-in-skills/prismer-popular-web-designs/templates/voltagent.md +336 -0
- package/built-in-skills/prismer-popular-web-designs/templates/warp.md +266 -0
- package/built-in-skills/prismer-popular-web-designs/templates/webflow.md +105 -0
- package/built-in-skills/prismer-popular-web-designs/templates/wise.md +186 -0
- package/built-in-skills/prismer-popular-web-designs/templates/x.ai.md +270 -0
- package/built-in-skills/prismer-popular-web-designs/templates/zapier.md +341 -0
- package/built-in-skills/prismer-product-price-monitor/LICENSE +21 -0
- package/built-in-skills/prismer-product-price-monitor/NOTICE.md +11 -0
- package/built-in-skills/prismer-product-price-monitor/SKILL.md +97 -0
- package/built-in-skills/prismer-product-price-monitor/scripts/watch_state.py +116 -0
- package/built-in-skills/prismer-python-debugpy/LICENSE +21 -0
- package/built-in-skills/prismer-python-debugpy/NOTICE.md +17 -0
- package/built-in-skills/prismer-python-debugpy/SKILL.md +377 -0
- package/built-in-skills/prismer-python-debugpy/scripts/dap_client.py +68 -0
- package/built-in-skills/prismer-songsee/LICENSE +21 -0
- package/built-in-skills/prismer-songsee/LICENSE.hermes +21 -0
- package/built-in-skills/prismer-songsee/PROVENANCE.md +7 -0
- package/built-in-skills/prismer-songsee/SKILL.md +91 -0
- package/built-in-skills/prismer-songwriting-and-ai-music/LICENSE +21 -0
- package/built-in-skills/prismer-songwriting-and-ai-music/LICENSE.hermes +21 -0
- package/built-in-skills/prismer-songwriting-and-ai-music/PROVENANCE.md +7 -0
- package/built-in-skills/prismer-songwriting-and-ai-music/SKILL.md +317 -0
- package/built-in-skills/prismer-spike/LICENSE +21 -0
- package/built-in-skills/prismer-spike/LICENSE.gsd +21 -0
- package/built-in-skills/prismer-spike/NOTICE.md +17 -0
- package/built-in-skills/prismer-spike/SKILL.md +212 -0
- package/built-in-skills/prismer-teams-meeting-pipeline/LICENSE +21 -0
- package/built-in-skills/prismer-teams-meeting-pipeline/NOTICE.md +11 -0
- package/built-in-skills/prismer-teams-meeting-pipeline/SKILL.md +156 -0
- package/built-in-skills/prismer-xurl/LICENSE +21 -0
- package/built-in-skills/prismer-xurl/LICENSE.hermes +21 -0
- package/built-in-skills/prismer-xurl/PROVENANCE.md +7 -0
- package/built-in-skills/prismer-xurl/SKILL.md +444 -0
- package/built-in-skills/prismer-xurl/provenance/category-DESCRIPTION.md +3 -0
- package/built-in-skills/prismer-youtube-content/LICENSE +21 -0
- package/built-in-skills/prismer-youtube-content/LICENSE.hermes +21 -0
- package/built-in-skills/prismer-youtube-content/PROVENANCE.md +7 -0
- package/built-in-skills/prismer-youtube-content/SKILL.md +86 -0
- package/built-in-skills/prismer-youtube-content/provenance/category-DESCRIPTION.md +3 -0
- package/built-in-skills/prismer-youtube-content/references/output-formats.md +56 -0
- package/built-in-skills/prismer-youtube-content/scripts/fetch_transcript.py +146 -0
- package/built-in-skills/proactivity/SKILL.md +84 -0
- package/built-in-skills/remotion/SKILL.md +431 -0
- package/built-in-skills/research-arxiv/LICENSE +21 -0
- package/built-in-skills/research-arxiv/NOTICE.md +4 -0
- package/built-in-skills/research-arxiv/SKILL.md +263 -0
- package/built-in-skills/research-arxiv/scripts/search_arxiv.py +111 -0
- package/built-in-skills/role-builder/SKILL.md +209 -0
- package/built-in-skills/role-builder/scripts/author-role.mjs +350 -0
- package/built-in-skills/role-builder/scripts/ingest-role.mjs +121 -0
- package/built-in-skills/role-builder/scripts/instantiate-and-run.mjs +304 -0
- package/built-in-skills/role-builder/scripts/operation-harness.mjs +269 -0
- package/built-in-skills/skill-creator/LICENSE.prismer +21 -0
- package/built-in-skills/skill-creator/NOTICE.md +18 -0
- package/built-in-skills/skill-creator/SKILL.md +182 -421
- package/built-in-skills/skill-creator/eval-viewer/generate_review.py +20 -31
- package/built-in-skills/skill-creator/eval-viewer/viewer.html +35 -23
- package/built-in-skills/skill-creator/references/external-library-import.md +110 -0
- package/built-in-skills/skill-creator/references/hermes-agent-skill-authoring/GUIDE.md +220 -0
- package/built-in-skills/skill-creator/references/hermes-agent-skill-authoring/LICENSE +21 -0
- package/built-in-skills/skill-creator/references/skill-authoring/GUIDE.md +134 -0
- package/built-in-skills/{skill-authoring/skill.json → skill-creator/references/skill-authoring/draft-contract.json} +3 -3
- package/built-in-skills/skill-creator/references/skill-builder/GUIDE.md +167 -0
- package/built-in-skills/skill-creator/references/skill-builder/scripts/ingest.mjs +93 -0
- package/built-in-skills/skill-creator/scripts/aggregate_benchmark.py +3 -2
- package/built-in-skills/skill-creator/scripts/import-library.mjs +498 -0
- package/built-in-skills/skill-creator/scripts/improve_description.py +14 -16
- package/built-in-skills/skill-creator/scripts/package_skill.py +16 -9
- package/built-in-skills/skill-creator/scripts/quick_validate.py +22 -5
- package/built-in-skills/skill-creator/scripts/run_eval.py +63 -144
- package/built-in-skills/skill-creator/scripts/run_loop.py +24 -16
- package/built-in-skills/slack-gif-creator/SKILL.md +20 -0
- package/built-in-skills/slack-gif-creator/core/gif_builder.py +13 -2
- package/built-in-skills/slack-gif-creator/core/validators.py +17 -7
- package/built-in-skills/tasks/SKILL.md +39 -24
- package/built-in-skills/tdd/LICENSE +21 -0
- package/built-in-skills/tdd/SKILL.md +117 -0
- package/built-in-skills/tdd/mocking.md +59 -0
- package/built-in-skills/tdd/refactoring.md +10 -0
- package/built-in-skills/tdd/references/test-driven-development/GUIDE.md +356 -0
- package/built-in-skills/tdd/references/test-driven-development/LICENSE +21 -0
- package/built-in-skills/tdd/references/test-driven-development/LICENSE.superpowers +21 -0
- package/built-in-skills/tdd/references/test-driven-development/NOTICE.md +37 -0
- package/built-in-skills/tdd/tests.md +61 -0
- package/built-in-skills/team/SKILL.md +3 -2
- package/built-in-skills/web-artifacts-builder/SKILL.md +4 -3
- package/built-in-skills/web-artifacts-builder/scripts/bundle-artifact.sh +9 -7
- package/built-in-skills/web-artifacts-builder/scripts/init-artifact.sh +28 -55
- package/built-in-skills/webapp-qa/LICENSE +21 -0
- package/built-in-skills/webapp-qa/NOTICE.md +37 -0
- package/built-in-skills/webapp-qa/SKILL.md +41 -0
- package/built-in-skills/webapp-qa/references/dogfood/GUIDE.md +161 -0
- package/built-in-skills/webapp-qa/references/issue-taxonomy.md +109 -0
- package/built-in-skills/webapp-qa/templates/dogfood-report-template.md +86 -0
- package/built-in-skills/webapp-testing/SKILL.md +10 -2
- package/built-in-skills/webapp-testing/examples/console_logging.py +10 -4
- package/built-in-skills/webapp-testing/examples/element_discovery.py +11 -4
- package/built-in-skills/webapp-testing/examples/static_html_automation.py +14 -9
- package/built-in-skills/webapp-testing/scripts/with_server.py +34 -10
- package/built-in-skills/wechat-pay/SKILL.md +59 -0
- package/built-in-skills/weekly-review/LICENSE +21 -0
- package/built-in-skills/weekly-review/NOTICE.md +21 -0
- package/built-in-skills/weekly-review/SKILL.md +49 -0
- package/components/eaas-pi-components.manifest.json +37 -0
- package/dist/cli.cjs +75799 -20210
- package/dist/cli.js +75900 -20248
- package/dist/index.cjs +76159 -20082
- package/dist/index.d.cts +4766 -766
- package/dist/index.d.ts +4766 -766
- package/dist/index.js +76040 -19960
- package/package.json +42 -6
- package/plugins/memory/prismer/__init__.py +1215 -0
- package/plugins/memory/prismer/plugin.yaml +8 -0
- package/plugins/memory/prismer/tool-schemas.generated.json +257 -0
- package/plugins/tools/prismer-recall/__init__.py +282 -0
- package/plugins/tools/prismer-recall/plugin.yaml +15 -0
- package/built-in-skills/memory-curation/SKILL.md +0 -135
- package/built-in-skills/skill-authoring/SKILL.md +0 -124
- package/built-in-skills/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
|
@@ -0,0 +1,807 @@
|
|
|
1
|
+
# Architecture Reference
|
|
2
|
+
|
|
3
|
+
> **See also:** composition.md · effects.md · scenes.md · shaders.md · inputs.md · optimization.md · troubleshooting.md
|
|
4
|
+
|
|
5
|
+
## Grid System
|
|
6
|
+
|
|
7
|
+
### Resolution Presets
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
RESOLUTION_PRESETS = {
|
|
11
|
+
"landscape": (1920, 1080), # 16:9 — YouTube, default
|
|
12
|
+
"portrait": (1080, 1920), # 9:16 — TikTok, Reels, Stories
|
|
13
|
+
"square": (1080, 1080), # 1:1 — Instagram feed
|
|
14
|
+
"ultrawide": (2560, 1080), # 21:9 — cinematic
|
|
15
|
+
"landscape4k":(3840, 2160), # 16:9 — 4K
|
|
16
|
+
"portrait4k": (2160, 3840), # 9:16 — 4K portrait
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
def get_resolution(preset="landscape", custom=None):
|
|
20
|
+
"""Returns (VW, VH) tuple."""
|
|
21
|
+
if custom:
|
|
22
|
+
return custom
|
|
23
|
+
return RESOLUTION_PRESETS.get(preset, RESOLUTION_PRESETS["landscape"])
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Multi-Density Grids
|
|
27
|
+
|
|
28
|
+
Pre-initialize multiple grid sizes. Switch per section for visual variety. Grid dimensions auto-compute from resolution:
|
|
29
|
+
|
|
30
|
+
**Landscape (1920x1080):**
|
|
31
|
+
|
|
32
|
+
| Key | Font Size | Grid (cols x rows) | Use |
|
|
33
|
+
|-----|-----------|-------------------|-----|
|
|
34
|
+
| xs | 8 | 400x108 | Ultra-dense data fields |
|
|
35
|
+
| sm | 10 | 320x83 | Dense detail, rain, starfields |
|
|
36
|
+
| md | 16 | 192x56 | Default balanced, transitions |
|
|
37
|
+
| lg | 20 | 160x45 | Quote/lyric text (readable at 1080p) |
|
|
38
|
+
| xl | 24 | 137x37 | Short quotes, large titles |
|
|
39
|
+
| xxl | 40 | 80x22 | Giant text, minimal |
|
|
40
|
+
|
|
41
|
+
**Portrait (1080x1920):**
|
|
42
|
+
|
|
43
|
+
| Key | Font Size | Grid (cols x rows) | Use |
|
|
44
|
+
|-----|-----------|-------------------|-----|
|
|
45
|
+
| xs | 8 | 225x192 | Ultra-dense, tall data columns |
|
|
46
|
+
| sm | 10 | 180x148 | Dense detail, vertical rain |
|
|
47
|
+
| md | 16 | 112x100 | Default balanced |
|
|
48
|
+
| lg | 20 | 90x80 | Readable text (~30 chars/line centered) |
|
|
49
|
+
| xl | 24 | 75x66 | Short quotes, stacked |
|
|
50
|
+
| xxl | 40 | 45x39 | Giant text, minimal |
|
|
51
|
+
|
|
52
|
+
**Square (1080x1080):**
|
|
53
|
+
|
|
54
|
+
| Key | Font Size | Grid (cols x rows) | Use |
|
|
55
|
+
|-----|-----------|-------------------|-----|
|
|
56
|
+
| sm | 10 | 180x83 | Dense detail |
|
|
57
|
+
| md | 16 | 112x56 | Default balanced |
|
|
58
|
+
| lg | 20 | 90x45 | Readable text |
|
|
59
|
+
|
|
60
|
+
**Key differences in portrait mode:**
|
|
61
|
+
- Fewer columns (90 at `lg` vs 160) — lines must be shorter or wrap
|
|
62
|
+
- Many more rows (80 at `lg` vs 45) — vertical stacking is natural
|
|
63
|
+
- Aspect ratio correction flips: `asp = cw / ch` still works but the visual emphasis is vertical
|
|
64
|
+
- Radial effects appear as tall ellipses unless corrected
|
|
65
|
+
- Vertical effects (rain, embers, fire columns) are naturally enhanced
|
|
66
|
+
- Horizontal effects (spectrum bars, waveforms) need rotation or compression
|
|
67
|
+
|
|
68
|
+
**Grid sizing for text in portrait**: Use `lg` (20px) for 2-3 word lines. Max comfortable line length is ~25-30 chars. For longer quotes, break aggressively into many short lines stacked vertically — portrait has vertical space to spare. `xl` (24px) works for single words or very short phrases.
|
|
69
|
+
|
|
70
|
+
Grid dimensions: `cols = VW // cell_width`, `rows = VH // cell_height`.
|
|
71
|
+
|
|
72
|
+
### Font Selection
|
|
73
|
+
|
|
74
|
+
Don't hardcode a single font. Choose fonts to match the project's mood. Monospace fonts are required for grid alignment but vary widely in personality:
|
|
75
|
+
|
|
76
|
+
| Font | Personality | Platform |
|
|
77
|
+
|------|-------------|----------|
|
|
78
|
+
| Menlo | Clean, neutral, Apple-native | macOS |
|
|
79
|
+
| Monaco | Retro terminal, compact | macOS |
|
|
80
|
+
| Courier New | Classic typewriter, wide | Cross-platform |
|
|
81
|
+
| SF Mono | Modern, tight spacing | macOS |
|
|
82
|
+
| Consolas | Windows native, clean | Windows |
|
|
83
|
+
| JetBrains Mono | Developer, ligature-ready | Install |
|
|
84
|
+
| Fira Code | Geometric, modern | Install |
|
|
85
|
+
| IBM Plex Mono | Corporate, authoritative | Install |
|
|
86
|
+
| Source Code Pro | Adobe, balanced | Install |
|
|
87
|
+
|
|
88
|
+
**Font detection at init**: probe available fonts and fall back gracefully:
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
import platform
|
|
92
|
+
|
|
93
|
+
def find_font(preferences):
|
|
94
|
+
"""Try fonts in order, return first that exists."""
|
|
95
|
+
for name, path in preferences:
|
|
96
|
+
if os.path.exists(path):
|
|
97
|
+
return path
|
|
98
|
+
raise FileNotFoundError(f"No monospace font found. Tried: {[p for _,p in preferences]}")
|
|
99
|
+
|
|
100
|
+
FONT_PREFS_MACOS = [
|
|
101
|
+
("Menlo", "/System/Library/Fonts/Menlo.ttc"),
|
|
102
|
+
("Monaco", "/System/Library/Fonts/Monaco.ttf"),
|
|
103
|
+
("SF Mono", "/System/Library/Fonts/SFNSMono.ttf"),
|
|
104
|
+
("Courier", "/System/Library/Fonts/Courier.ttc"),
|
|
105
|
+
]
|
|
106
|
+
FONT_PREFS_LINUX = [
|
|
107
|
+
("DejaVu Sans Mono", "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf"),
|
|
108
|
+
("Liberation Mono", "/usr/share/fonts/truetype/liberation/LiberationMono-Regular.ttf"),
|
|
109
|
+
("Noto Sans Mono", "/usr/share/fonts/truetype/noto/NotoSansMono-Regular.ttf"),
|
|
110
|
+
("Ubuntu Mono", "/usr/share/fonts/truetype/ubuntu/UbuntuMono-R.ttf"),
|
|
111
|
+
]
|
|
112
|
+
FONT_PREFS_WINDOWS = [
|
|
113
|
+
("Consolas", r"C:\Windows\Fonts\consola.ttf"),
|
|
114
|
+
("Courier New", r"C:\Windows\Fonts\cour.ttf"),
|
|
115
|
+
("Lucida Console", r"C:\Windows\Fonts\lucon.ttf"),
|
|
116
|
+
("Cascadia Code", os.path.expandvars(r"%LOCALAPPDATA%\Microsoft\Windows\Fonts\CascadiaCode.ttf")),
|
|
117
|
+
("Cascadia Mono", os.path.expandvars(r"%LOCALAPPDATA%\Microsoft\Windows\Fonts\CascadiaMono.ttf")),
|
|
118
|
+
]
|
|
119
|
+
|
|
120
|
+
def _get_font_prefs():
|
|
121
|
+
s = platform.system()
|
|
122
|
+
if s == "Darwin":
|
|
123
|
+
return FONT_PREFS_MACOS
|
|
124
|
+
elif s == "Windows":
|
|
125
|
+
return FONT_PREFS_WINDOWS
|
|
126
|
+
return FONT_PREFS_LINUX
|
|
127
|
+
|
|
128
|
+
FONT_PREFS = _get_font_prefs()
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Multi-font rendering**: use different fonts for different layers (e.g., monospace for background, a bolder variant for overlay text). Each GridLayer owns its own font:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
grid_bg = GridLayer(find_font(FONT_PREFS), 16) # background
|
|
135
|
+
grid_text = GridLayer(find_font(BOLD_PREFS), 20) # readable text
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Collecting All Characters
|
|
139
|
+
|
|
140
|
+
Before initializing grids, gather all characters that need bitmap pre-rasterization:
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
all_chars = set()
|
|
144
|
+
for pal in [PAL_DEFAULT, PAL_DENSE, PAL_BLOCKS, PAL_RUNE, PAL_KATA,
|
|
145
|
+
PAL_GREEK, PAL_MATH, PAL_DOTS, PAL_BRAILLE, PAL_STARS,
|
|
146
|
+
PAL_HALFFILL, PAL_HATCH, PAL_BINARY, PAL_MUSIC, PAL_BOX,
|
|
147
|
+
PAL_CIRCUIT, PAL_ARROWS, PAL_HERMES]: # ... all palettes used in project
|
|
148
|
+
all_chars.update(pal)
|
|
149
|
+
# Add any overlay text characters
|
|
150
|
+
all_chars.update("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .,-:;!?/|")
|
|
151
|
+
all_chars.discard(" ") # space is never rendered
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### GridLayer Initialization
|
|
155
|
+
|
|
156
|
+
Each grid pre-computes coordinate arrays for vectorized effect math. The grid automatically adapts to any resolution (landscape, portrait, square):
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
class GridLayer:
|
|
160
|
+
def __init__(self, font_path, font_size, vw=None, vh=None):
|
|
161
|
+
"""Initialize grid for any resolution.
|
|
162
|
+
vw, vh: video width/height in pixels. Defaults to global VW, VH."""
|
|
163
|
+
vw = VW if vw is None else vw; vh = VH if vh is None else vh
|
|
164
|
+
if vw <= 0 or vh <= 0: raise ValueError('Positive dimensions required')
|
|
165
|
+
self.vw = vw; self.vh = vh
|
|
166
|
+
|
|
167
|
+
self.font = ImageFont.truetype(font_path, font_size)
|
|
168
|
+
asc, desc = self.font.getmetrics()
|
|
169
|
+
bbox = self.font.getbbox("M")
|
|
170
|
+
self.cw = bbox[2] - bbox[0] # character cell width
|
|
171
|
+
self.ch = asc + desc # CRITICAL: not textbbox height
|
|
172
|
+
|
|
173
|
+
self.cols = vw // self.cw
|
|
174
|
+
self.rows = vh // self.ch
|
|
175
|
+
if not self.rows or not self.cols: raise ValueError('Canvas is smaller than one cell')
|
|
176
|
+
self.ox = (vw - self.cols * self.cw) // 2 # centering
|
|
177
|
+
self.oy = (vh - self.rows * self.ch) // 2
|
|
178
|
+
|
|
179
|
+
# Aspect ratio metadata
|
|
180
|
+
self.aspect = vw / vh # >1 = landscape, <1 = portrait, 1 = square
|
|
181
|
+
self.is_portrait = vw < vh
|
|
182
|
+
self.is_landscape = vw > vh
|
|
183
|
+
|
|
184
|
+
# Index arrays
|
|
185
|
+
self.rr = np.arange(self.rows, dtype=np.float32)[:, None]
|
|
186
|
+
self.cc = np.arange(self.cols, dtype=np.float32)[None, :]
|
|
187
|
+
|
|
188
|
+
# Polar coordinates (aspect-corrected)
|
|
189
|
+
cx, cy = self.cols / 2.0, self.rows / 2.0
|
|
190
|
+
asp = self.ch / self.cw
|
|
191
|
+
self.dx = self.cc - cx
|
|
192
|
+
self.dy = (self.rr - cy) * asp
|
|
193
|
+
self.dist = np.sqrt(self.dx**2 + self.dy**2)
|
|
194
|
+
self.angle = np.arctan2(self.dy, self.dx)
|
|
195
|
+
|
|
196
|
+
# Normalized (0-1 range) -- for distance falloff
|
|
197
|
+
self.dx_n = (self.cc - cx) / max(self.cols, 1)
|
|
198
|
+
self.dy_n = (self.rr - cy) * self.ch / max(self.cols * self.cw, 1)
|
|
199
|
+
self.dist_n = np.sqrt(self.dx_n**2 + self.dy_n**2)
|
|
200
|
+
|
|
201
|
+
# Pre-rasterize all characters to float32 bitmaps
|
|
202
|
+
self.bm = {}
|
|
203
|
+
for c in all_chars:
|
|
204
|
+
img = Image.new("L", (self.cw, self.ch), 0)
|
|
205
|
+
ImageDraw.Draw(img).text((0, 0), c, fill=255, font=self.font)
|
|
206
|
+
self.bm[c] = np.array(img, dtype=np.float32) / 255.0
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Character Render Loop
|
|
210
|
+
|
|
211
|
+
The bottleneck. Composites pre-rasterized bitmaps onto pixel canvas:
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
def render(self, chars, colors, canvas=None):
|
|
215
|
+
if canvas is None:
|
|
216
|
+
canvas = np.zeros((self.vh, self.vw, 3), dtype=np.uint8)
|
|
217
|
+
for row in range(self.rows):
|
|
218
|
+
y = self.oy + row * self.ch
|
|
219
|
+
if y + self.ch > self.vh: break
|
|
220
|
+
for col in range(self.cols):
|
|
221
|
+
c = chars[row, col]
|
|
222
|
+
if c == " ": continue
|
|
223
|
+
x = self.ox + col * self.cw
|
|
224
|
+
if x + self.cw > self.vw: break
|
|
225
|
+
if c not in self.bm: raise ValueError(f"Unregistered glyph: {c}")
|
|
226
|
+
a = self.bm[c] # float32 bitmap
|
|
227
|
+
canvas[y:y+self.ch, x:x+self.cw] = np.maximum(
|
|
228
|
+
canvas[y:y+self.ch, x:x+self.cw],
|
|
229
|
+
(a[:, :, None] * colors[row, col]).astype(np.uint8))
|
|
230
|
+
return canvas
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Use `np.maximum` for additive blending (brighter chars overwrite dimmer ones, never darken).
|
|
234
|
+
|
|
235
|
+
### Multi-Layer Rendering
|
|
236
|
+
|
|
237
|
+
Render multiple grids onto the same canvas for depth:
|
|
238
|
+
|
|
239
|
+
```python
|
|
240
|
+
canvas = np.zeros((VH, VW, 3), dtype=np.uint8)
|
|
241
|
+
canvas = grid_lg.render(bg_chars, bg_colors, canvas) # background layer
|
|
242
|
+
canvas = grid_md.render(main_chars, main_colors, canvas) # main layer
|
|
243
|
+
canvas = grid_sm.render(detail_chars, detail_colors, canvas) # detail overlay
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## Character Palettes
|
|
249
|
+
|
|
250
|
+
### Design Principles
|
|
251
|
+
|
|
252
|
+
Character palettes are the primary visual texture of ASCII video. They control not just brightness mapping but the entire visual feel. Design palettes intentionally:
|
|
253
|
+
|
|
254
|
+
- **Visual weight**: characters sorted by the amount of ink/pixels they fill. Space is always index 0.
|
|
255
|
+
- **Coherence**: characters within a palette should belong to the same visual family.
|
|
256
|
+
- **Density curve**: the brightness-to-character mapping is nonlinear. Dense palettes (many chars) give smoother gradients; sparse palettes (5-8 chars) give posterized/graphic looks.
|
|
257
|
+
- **Rendering compatibility**: every character in the palette must exist in the font. Test at init and remove missing glyphs.
|
|
258
|
+
|
|
259
|
+
### Palette Library
|
|
260
|
+
|
|
261
|
+
Organized by visual family. Mix and match per project -- don't default to PAL_DEFAULT for everything.
|
|
262
|
+
|
|
263
|
+
#### Density / Brightness Palettes
|
|
264
|
+
```python
|
|
265
|
+
PAL_DEFAULT = " .`'-:;!><=+*^~?/|(){}[]#&$@%" # classic ASCII art
|
|
266
|
+
PAL_DENSE = " .:;+=xX$#@\u2588" # simple 11-level ramp
|
|
267
|
+
PAL_MINIMAL = " .:-=+#@" # 8-level, graphic
|
|
268
|
+
PAL_BINARY = " \u2588" # 2-level, extreme contrast
|
|
269
|
+
PAL_GRADIENT = " \u2591\u2592\u2593\u2588" # 4-level block gradient
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
#### Unicode Block Elements
|
|
273
|
+
```python
|
|
274
|
+
PAL_BLOCKS = " \u2591\u2592\u2593\u2588\u2584\u2580\u2590\u258c" # standard blocks
|
|
275
|
+
PAL_BLOCKS_EXT = " \u2596\u2597\u2598\u2599\u259a\u259b\u259c\u259d\u259e\u259f\u2591\u2592\u2593\u2588" # quadrant blocks (more detail)
|
|
276
|
+
PAL_SHADE = " \u2591\u2592\u2593\u2588\u2587\u2586\u2585\u2584\u2583\u2582\u2581" # vertical fill progression
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
#### Symbolic / Thematic
|
|
280
|
+
```python
|
|
281
|
+
PAL_MATH = " \u00b7\u2218\u2219\u2022\u00b0\u00b1\u2213\u00d7\u00f7\u2248\u2260\u2261\u2264\u2265\u221e\u222b\u2211\u220f\u221a\u2207\u2202\u2206\u03a9" # math symbols
|
|
282
|
+
PAL_BOX = " \u2500\u2502\u250c\u2510\u2514\u2518\u251c\u2524\u252c\u2534\u253c\u2550\u2551\u2554\u2557\u255a\u255d\u2560\u2563\u2566\u2569\u256c" # box drawing
|
|
283
|
+
PAL_CIRCUIT = " .\u00b7\u2500\u2502\u250c\u2510\u2514\u2518\u253c\u25cb\u25cf\u25a1\u25a0\u2206\u2207\u2261" # circuit board
|
|
284
|
+
PAL_RUNE = " .\u16a0\u16a2\u16a6\u16b1\u16b7\u16c1\u16c7\u16d2\u16d6\u16da\u16de\u16df" # elder futhark runes
|
|
285
|
+
PAL_ALCHEMIC = " \u2609\u263d\u2640\u2642\u2643\u2644\u2645\u2646\u2647\u2648\u2649\u264a\u264b" # planetary/alchemical symbols
|
|
286
|
+
PAL_ZODIAC = " \u2648\u2649\u264a\u264b\u264c\u264d\u264e\u264f\u2650\u2651\u2652\u2653" # zodiac
|
|
287
|
+
PAL_ARROWS = " \u2190\u2191\u2192\u2193\u2194\u2195\u2196\u2197\u2198\u2199\u21a9\u21aa\u21bb\u27a1" # directional arrows
|
|
288
|
+
PAL_MUSIC = " \u266a\u266b\u266c\u2669\u266d\u266e\u266f\u25cb\u25cf" # musical notation
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
#### Script / Writing System
|
|
292
|
+
```python
|
|
293
|
+
PAL_KATA = " \u00b7\uff66\uff67\uff68\uff69\uff6a\uff6b\uff6c\uff6d\uff6e\uff6f\uff70\uff71\uff72\uff73\uff74\uff75\uff76\uff77" # katakana halfwidth (matrix rain)
|
|
294
|
+
PAL_GREEK = " \u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03c0\u03c1\u03c3\u03c4\u03c6\u03c8\u03c9" # Greek lowercase
|
|
295
|
+
PAL_CYRILLIC = " \u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448" # Cyrillic lowercase
|
|
296
|
+
PAL_ARABIC = " \u0627\u0628\u062a\u062b\u062c\u062d\u062e\u062f\u0630\u0631\u0632\u0633\u0634\u0635\u0636\u0637" # Arabic letters (isolated forms)
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
#### Dot / Point Progressions
|
|
300
|
+
```python
|
|
301
|
+
PAL_DOTS = " ⋅∘∙●◉◎◆✦★" # dot size progression
|
|
302
|
+
PAL_BRAILLE = " ⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠿" # braille patterns
|
|
303
|
+
PAL_STARS = " ·✧✦✩✨★✶✳✸" # star progression
|
|
304
|
+
PAL_HALFFILL = " ◔◑◕◐◒◓◖◗◙" # directional half-fill progression
|
|
305
|
+
PAL_HATCH = " ▣▤▥▦▧▨▩" # crosshatch density ramp
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
#### Project-Specific (examples -- invent new ones per project)
|
|
309
|
+
```python
|
|
310
|
+
PAL_HERMES = " .\u00b7~=\u2248\u221e\u26a1\u263f\u2726\u2605\u2295\u25ca\u25c6\u25b2\u25bc\u25cf\u25a0" # mythology/tech blend
|
|
311
|
+
PAL_OCEAN = " ~\u2248\u2248\u2248\u223c\u2307\u2248\u224b\u224c\u2248" # water/wave characters
|
|
312
|
+
PAL_ORGANIC = " .\u00b0\u2218\u2022\u25e6\u25c9\u2742\u273f\u2741\u2743" # growing/botanical
|
|
313
|
+
PAL_MACHINE = " _\u2500\u2502\u250c\u2510\u253c\u2261\u25a0\u2588\u2593\u2592\u2591" # mechanical/industrial
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Creating Custom Palettes
|
|
317
|
+
|
|
318
|
+
When designing for a project, build palettes from the content's theme:
|
|
319
|
+
|
|
320
|
+
1. **Choose a visual family** (dots, blocks, symbols, script)
|
|
321
|
+
2. **Sort by visual weight** -- render each char at target font size, count lit pixels, sort ascending
|
|
322
|
+
3. **Test at target grid size** -- some chars collapse to blobs at small sizes
|
|
323
|
+
4. **Validate in font** -- remove chars the font can't render:
|
|
324
|
+
|
|
325
|
+
```python
|
|
326
|
+
def validate_palette(pal, font):
|
|
327
|
+
"""Use the font cmap, not nonzero tofu pixels. Requires fontTools."""
|
|
328
|
+
from fontTools.ttLib import TTFont
|
|
329
|
+
with TTFont(font.path, fontNumber=getattr(font, "index", 0)) as face:
|
|
330
|
+
cmap = face.getBestCmap() or {}
|
|
331
|
+
valid = "".join(c for c in pal if c == " " or ord(c) in cmap)
|
|
332
|
+
if not valid:
|
|
333
|
+
raise ValueError("No supported palette characters")
|
|
334
|
+
return valid
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Mapping Values to Characters
|
|
338
|
+
|
|
339
|
+
```python
|
|
340
|
+
def val2char(v, mask, pal=PAL_DEFAULT):
|
|
341
|
+
"""Map float array (0-1) to character array using palette."""
|
|
342
|
+
n = len(pal)
|
|
343
|
+
idx = np.clip((v * n).astype(int), 0, n - 1)
|
|
344
|
+
out = np.full(v.shape, " ", dtype="U1")
|
|
345
|
+
for i, ch in enumerate(pal):
|
|
346
|
+
out[mask & (idx == i)] = ch
|
|
347
|
+
return out
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
**Nonlinear mapping** for different visual curves:
|
|
351
|
+
|
|
352
|
+
```python
|
|
353
|
+
def val2char_gamma(v, mask, pal, gamma=1.0):
|
|
354
|
+
"""Gamma-corrected palette mapping. gamma<1 = brighter, gamma>1 = darker."""
|
|
355
|
+
v_adj = np.power(np.clip(v, 0, 1), gamma)
|
|
356
|
+
return val2char(v_adj, mask, pal)
|
|
357
|
+
|
|
358
|
+
def val2char_step(v, mask, pal, thresholds):
|
|
359
|
+
"""Custom threshold mapping. thresholds = list of float breakpoints."""
|
|
360
|
+
out = np.full(v.shape, pal[0], dtype="U1")
|
|
361
|
+
for i, thr in enumerate(thresholds):
|
|
362
|
+
out[mask & (v > thr)] = pal[min(i + 1, len(pal) - 1)]
|
|
363
|
+
return out
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## Color System
|
|
369
|
+
|
|
370
|
+
### HSV->RGB (Vectorized)
|
|
371
|
+
|
|
372
|
+
All color computation in HSV for intuitive control, converted at render time:
|
|
373
|
+
|
|
374
|
+
```python
|
|
375
|
+
def hsv2rgb(h, s, v):
|
|
376
|
+
"""Vectorized HSV->RGB. h,s,v are numpy arrays. Returns (R,G,B) uint8 arrays."""
|
|
377
|
+
h = h % 1.0
|
|
378
|
+
c = v * s; x = c * (1 - np.abs((h*6) % 2 - 1)); m = v - c
|
|
379
|
+
sector = np.floor(h * 6).astype(int) % 6
|
|
380
|
+
zero = np.zeros_like(c)
|
|
381
|
+
r = np.select([sector == i for i in range(6)], [c, x, zero, zero, x, c])
|
|
382
|
+
g = np.select([sector == i for i in range(6)], [x, c, c, x, zero, zero])
|
|
383
|
+
b = np.select([sector == i for i in range(6)], [zero, zero, x, c, c, x])
|
|
384
|
+
return (np.clip((r+m)*255, 0, 255).astype(np.uint8),
|
|
385
|
+
np.clip((g+m)*255, 0, 255).astype(np.uint8),
|
|
386
|
+
np.clip((b+m)*255, 0, 255).astype(np.uint8))
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Color Mapping Strategies
|
|
390
|
+
|
|
391
|
+
Don't default to a single strategy. Choose based on the visual intent:
|
|
392
|
+
|
|
393
|
+
| Strategy | Hue source | Effect | Good for |
|
|
394
|
+
|----------|------------|--------|----------|
|
|
395
|
+
| Angle-mapped | `g.angle / (2*pi)` | Rainbow around center | Radial effects, kaleidoscopes |
|
|
396
|
+
| Distance-mapped | `g.dist_n * 0.3` | Gradient from center | Tunnels, depth effects |
|
|
397
|
+
| Frequency-mapped | `f["cent"] * 0.2` | Timbral color shifting | Audio-reactive |
|
|
398
|
+
| Value-mapped | `val * 0.15` | Brightness-dependent hue | Fire, heat maps |
|
|
399
|
+
| Time-cycled | `t * rate` | Slow color rotation | Ambient, chill |
|
|
400
|
+
| Source-sampled | Video frame pixel colors | Preserve original color | Video-to-ASCII |
|
|
401
|
+
| Palette-indexed | Discrete color lookup | Flat graphic style | Retro, pixel art |
|
|
402
|
+
| Temperature | Blend between warm/cool | Emotional tone | Mood-driven scenes |
|
|
403
|
+
| Complementary | `hue` and `hue + 0.5` | High contrast | Bold, dramatic |
|
|
404
|
+
| Triadic | `hue`, `hue + 0.33`, `hue + 0.66` | Vibrant, balanced | Psychedelic |
|
|
405
|
+
| Analogous | `hue +/- 0.08` | Harmonious, subtle | Elegant, cohesive |
|
|
406
|
+
| Monochrome | Fixed hue, vary S and V | Restrained, focused | Noir, minimal |
|
|
407
|
+
|
|
408
|
+
### Color Palettes (Discrete RGB)
|
|
409
|
+
|
|
410
|
+
For non-HSV workflows -- direct RGB color sets for graphic/retro looks:
|
|
411
|
+
|
|
412
|
+
```python
|
|
413
|
+
# Named color palettes -- use for flat/graphic styles or per-character coloring
|
|
414
|
+
COLORS_NEON = [(255,0,102), (0,255,153), (102,0,255), (255,255,0), (0,204,255)]
|
|
415
|
+
COLORS_PASTEL = [(255,179,186), (255,223,186), (255,255,186), (186,255,201), (186,225,255)]
|
|
416
|
+
COLORS_MONO_GREEN = [(0,40,0), (0,80,0), (0,140,0), (0,200,0), (0,255,0)]
|
|
417
|
+
COLORS_MONO_AMBER = [(40,20,0), (80,50,0), (140,90,0), (200,140,0), (255,191,0)]
|
|
418
|
+
COLORS_CYBERPUNK = [(255,0,60), (0,255,200), (180,0,255), (255,200,0)]
|
|
419
|
+
COLORS_VAPORWAVE = [(255,113,206), (1,205,254), (185,103,255), (5,255,161)]
|
|
420
|
+
COLORS_EARTH = [(86,58,26), (139,90,43), (189,154,91), (222,193,136), (245,230,193)]
|
|
421
|
+
COLORS_ICE = [(200,230,255), (150,200,240), (100,170,230), (60,130,210), (30,80,180)]
|
|
422
|
+
COLORS_BLOOD = [(80,0,0), (140,10,10), (200,20,20), (255,50,30), (255,100,80)]
|
|
423
|
+
COLORS_FOREST = [(10,30,10), (20,60,15), (30,100,20), (50,150,30), (80,200,50)]
|
|
424
|
+
|
|
425
|
+
def rgb_palette_map(val, mask, palette):
|
|
426
|
+
"""Map float array (0-1) to RGB colors from a discrete palette."""
|
|
427
|
+
n = len(palette)
|
|
428
|
+
idx = np.clip((val * n).astype(int), 0, n - 1)
|
|
429
|
+
R = np.zeros(val.shape, dtype=np.uint8)
|
|
430
|
+
G = np.zeros(val.shape, dtype=np.uint8)
|
|
431
|
+
B = np.zeros(val.shape, dtype=np.uint8)
|
|
432
|
+
for i, (r, g, b) in enumerate(palette):
|
|
433
|
+
m = mask & (idx == i)
|
|
434
|
+
R[m] = r; G[m] = g; B[m] = b
|
|
435
|
+
return R, G, B
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
### OKLAB Color Space (Perceptually Uniform)
|
|
439
|
+
|
|
440
|
+
HSV hue is perceptually non-uniform: green occupies far more visual range than blue. OKLAB / OKLCH provide perceptually even color steps — hue increments of 0.1 look equally different regardless of starting hue. Use OKLAB for:
|
|
441
|
+
- Gradient interpolation (no unwanted intermediate hues)
|
|
442
|
+
- Color harmony generation (perceptually balanced palettes)
|
|
443
|
+
- Smooth color transitions over time
|
|
444
|
+
|
|
445
|
+
```python
|
|
446
|
+
# --- sRGB <-> Linear sRGB ---
|
|
447
|
+
|
|
448
|
+
def srgb_to_linear(c):
|
|
449
|
+
"""Convert sRGB [0,1] to linear light. c: float32 array."""
|
|
450
|
+
return np.where(c <= 0.04045, c / 12.92, ((c + 0.055) / 1.055) ** 2.4)
|
|
451
|
+
|
|
452
|
+
def linear_to_srgb(c):
|
|
453
|
+
"""Convert linear light to sRGB [0,1]."""
|
|
454
|
+
return np.where(c <= 0.0031308, c * 12.92, 1.055 * np.power(np.maximum(c, 0), 1/2.4) - 0.055)
|
|
455
|
+
|
|
456
|
+
# --- Linear sRGB <-> OKLAB ---
|
|
457
|
+
|
|
458
|
+
def linear_rgb_to_oklab(r, g, b):
|
|
459
|
+
"""Linear sRGB to OKLAB. r,g,b: float32 arrays [0,1].
|
|
460
|
+
Returns (L, a, b) where L=[0,1], a,b=[-0.4, 0.4] approx."""
|
|
461
|
+
l_ = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b
|
|
462
|
+
m_ = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b
|
|
463
|
+
s_ = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b
|
|
464
|
+
l_c = np.cbrt(l_); m_c = np.cbrt(m_); s_c = np.cbrt(s_)
|
|
465
|
+
L = 0.2104542553 * l_c + 0.7936177850 * m_c - 0.0040720468 * s_c
|
|
466
|
+
a = 1.9779984951 * l_c - 2.4285922050 * m_c + 0.4505937099 * s_c
|
|
467
|
+
b_ = 0.0259040371 * l_c + 0.7827717662 * m_c - 0.8086757660 * s_c
|
|
468
|
+
return L, a, b_
|
|
469
|
+
|
|
470
|
+
def oklab_to_linear_rgb(L, a, b):
|
|
471
|
+
"""OKLAB to linear sRGB. Returns (r, g, b) float32 arrays [0,1]."""
|
|
472
|
+
l_ = L + 0.3963377774 * a + 0.2158037573 * b
|
|
473
|
+
m_ = L - 0.1055613458 * a - 0.0638541728 * b
|
|
474
|
+
s_ = L - 0.0894841775 * a - 1.2914855480 * b
|
|
475
|
+
l_c = l_ ** 3; m_c = m_ ** 3; s_c = s_ ** 3
|
|
476
|
+
r = +4.0767416621 * l_c - 3.3077115913 * m_c + 0.2309699292 * s_c
|
|
477
|
+
g = -1.2684380046 * l_c + 2.6097574011 * m_c - 0.3413193965 * s_c
|
|
478
|
+
b_ = -0.0041960863 * l_c - 0.7034186147 * m_c + 1.7076147010 * s_c
|
|
479
|
+
return np.clip(r, 0, 1), np.clip(g, 0, 1), np.clip(b_, 0, 1)
|
|
480
|
+
|
|
481
|
+
# --- Convenience: sRGB uint8 <-> OKLAB ---
|
|
482
|
+
|
|
483
|
+
def rgb_to_oklab(R, G, B):
|
|
484
|
+
"""sRGB uint8 arrays to OKLAB."""
|
|
485
|
+
r = srgb_to_linear(R.astype(np.float32) / 255.0)
|
|
486
|
+
g = srgb_to_linear(G.astype(np.float32) / 255.0)
|
|
487
|
+
b = srgb_to_linear(B.astype(np.float32) / 255.0)
|
|
488
|
+
return linear_rgb_to_oklab(r, g, b)
|
|
489
|
+
|
|
490
|
+
def oklab_to_rgb(L, a, b):
|
|
491
|
+
"""OKLAB to sRGB uint8 arrays."""
|
|
492
|
+
r, g, b_ = oklab_to_linear_rgb(L, a, b)
|
|
493
|
+
R = np.clip(linear_to_srgb(r) * 255, 0, 255).astype(np.uint8)
|
|
494
|
+
G = np.clip(linear_to_srgb(g) * 255, 0, 255).astype(np.uint8)
|
|
495
|
+
B = np.clip(linear_to_srgb(b_) * 255, 0, 255).astype(np.uint8)
|
|
496
|
+
return R, G, B
|
|
497
|
+
|
|
498
|
+
# --- OKLCH (cylindrical form of OKLAB) ---
|
|
499
|
+
|
|
500
|
+
def oklab_to_oklch(L, a, b):
|
|
501
|
+
"""OKLAB to OKLCH. Returns (L, C, H) where H is in [0, 1] (normalized)."""
|
|
502
|
+
C = np.sqrt(a**2 + b**2)
|
|
503
|
+
H = (np.arctan2(b, a) / (2 * np.pi)) % 1.0
|
|
504
|
+
return L, C, H
|
|
505
|
+
|
|
506
|
+
def oklch_to_oklab(L, C, H):
|
|
507
|
+
"""OKLCH to OKLAB. H in [0, 1]."""
|
|
508
|
+
angle = H * 2 * np.pi
|
|
509
|
+
a = C * np.cos(angle)
|
|
510
|
+
b = C * np.sin(angle)
|
|
511
|
+
return L, a, b
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### Gradient Interpolation (OKLAB vs HSV)
|
|
515
|
+
|
|
516
|
+
Interpolating colors through OKLAB avoids the hue detours that HSV produces:
|
|
517
|
+
|
|
518
|
+
```python
|
|
519
|
+
def lerp_oklab(color_a, color_b, t_array):
|
|
520
|
+
"""Interpolate between two sRGB colors through OKLAB.
|
|
521
|
+
color_a, color_b: (R, G, B) tuples 0-255
|
|
522
|
+
t_array: float32 array [0,1] — interpolation parameter per pixel.
|
|
523
|
+
Returns (R, G, B) uint8 arrays."""
|
|
524
|
+
La, aa, ba = rgb_to_oklab(
|
|
525
|
+
np.full_like(t_array, color_a[0], dtype=np.uint8),
|
|
526
|
+
np.full_like(t_array, color_a[1], dtype=np.uint8),
|
|
527
|
+
np.full_like(t_array, color_a[2], dtype=np.uint8))
|
|
528
|
+
Lb, ab, bb = rgb_to_oklab(
|
|
529
|
+
np.full_like(t_array, color_b[0], dtype=np.uint8),
|
|
530
|
+
np.full_like(t_array, color_b[1], dtype=np.uint8),
|
|
531
|
+
np.full_like(t_array, color_b[2], dtype=np.uint8))
|
|
532
|
+
L = La + (Lb - La) * t_array
|
|
533
|
+
a = aa + (ab - aa) * t_array
|
|
534
|
+
b = ba + (bb - ba) * t_array
|
|
535
|
+
return oklab_to_rgb(L, a, b)
|
|
536
|
+
|
|
537
|
+
def lerp_oklch(color_a, color_b, t_array, short_path=True):
|
|
538
|
+
"""Interpolate through OKLCH (preserves chroma, smooth hue path).
|
|
539
|
+
short_path: take the shorter arc around the hue wheel."""
|
|
540
|
+
La, aa, ba = rgb_to_oklab(
|
|
541
|
+
np.full_like(t_array, color_a[0], dtype=np.uint8),
|
|
542
|
+
np.full_like(t_array, color_a[1], dtype=np.uint8),
|
|
543
|
+
np.full_like(t_array, color_a[2], dtype=np.uint8))
|
|
544
|
+
Lb, ab, bb = rgb_to_oklab(
|
|
545
|
+
np.full_like(t_array, color_b[0], dtype=np.uint8),
|
|
546
|
+
np.full_like(t_array, color_b[1], dtype=np.uint8),
|
|
547
|
+
np.full_like(t_array, color_b[2], dtype=np.uint8))
|
|
548
|
+
L1, C1, H1 = oklab_to_oklch(La, aa, ba)
|
|
549
|
+
L2, C2, H2 = oklab_to_oklch(Lb, ab, bb)
|
|
550
|
+
# Shortest hue path
|
|
551
|
+
if short_path:
|
|
552
|
+
dh = H2 - H1
|
|
553
|
+
dh = np.where(dh > 0.5, dh - 1.0, np.where(dh < -0.5, dh + 1.0, dh))
|
|
554
|
+
H = (H1 + dh * t_array) % 1.0
|
|
555
|
+
else:
|
|
556
|
+
H = H1 + (H2 - H1) * t_array
|
|
557
|
+
L = L1 + (L2 - L1) * t_array
|
|
558
|
+
C = C1 + (C2 - C1) * t_array
|
|
559
|
+
Lout, aout, bout = oklch_to_oklab(L, C, H)
|
|
560
|
+
return oklab_to_rgb(Lout, aout, bout)
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### Color Harmony Generation
|
|
564
|
+
|
|
565
|
+
Auto-generate harmonious palettes from a seed color:
|
|
566
|
+
|
|
567
|
+
```python
|
|
568
|
+
def harmony_complementary(seed_rgb):
|
|
569
|
+
"""Two colors: seed + opposite hue."""
|
|
570
|
+
L, a, b = rgb_to_oklab(np.array([seed_rgb[0]]), np.array([seed_rgb[1]]), np.array([seed_rgb[2]]))
|
|
571
|
+
_, C, H = oklab_to_oklch(L, a, b)
|
|
572
|
+
return [seed_rgb, _oklch_to_srgb_tuple(L[0], C[0], (H[0] + 0.5) % 1.0)]
|
|
573
|
+
|
|
574
|
+
def harmony_triadic(seed_rgb):
|
|
575
|
+
"""Three colors: seed + two at 120-degree offsets."""
|
|
576
|
+
L, a, b = rgb_to_oklab(np.array([seed_rgb[0]]), np.array([seed_rgb[1]]), np.array([seed_rgb[2]]))
|
|
577
|
+
_, C, H = oklab_to_oklch(L, a, b)
|
|
578
|
+
return [seed_rgb,
|
|
579
|
+
_oklch_to_srgb_tuple(L[0], C[0], (H[0] + 0.333) % 1.0),
|
|
580
|
+
_oklch_to_srgb_tuple(L[0], C[0], (H[0] + 0.667) % 1.0)]
|
|
581
|
+
|
|
582
|
+
def harmony_analogous(seed_rgb, spread=0.08, n=5):
|
|
583
|
+
"""N colors spread evenly around seed hue."""
|
|
584
|
+
L, a, b = rgb_to_oklab(np.array([seed_rgb[0]]), np.array([seed_rgb[1]]), np.array([seed_rgb[2]]))
|
|
585
|
+
_, C, H = oklab_to_oklch(L, a, b)
|
|
586
|
+
offsets = np.linspace(-spread * (n-1)/2, spread * (n-1)/2, n)
|
|
587
|
+
return [_oklch_to_srgb_tuple(L[0], C[0], (H[0] + off) % 1.0) for off in offsets]
|
|
588
|
+
|
|
589
|
+
def harmony_split_complementary(seed_rgb, split=0.08):
|
|
590
|
+
"""Three colors: seed + two flanking the complement."""
|
|
591
|
+
L, a, b = rgb_to_oklab(np.array([seed_rgb[0]]), np.array([seed_rgb[1]]), np.array([seed_rgb[2]]))
|
|
592
|
+
_, C, H = oklab_to_oklch(L, a, b)
|
|
593
|
+
comp = (H[0] + 0.5) % 1.0
|
|
594
|
+
return [seed_rgb,
|
|
595
|
+
_oklch_to_srgb_tuple(L[0], C[0], (comp - split) % 1.0),
|
|
596
|
+
_oklch_to_srgb_tuple(L[0], C[0], (comp + split) % 1.0)]
|
|
597
|
+
|
|
598
|
+
def harmony_tetradic(seed_rgb):
|
|
599
|
+
"""Four colors: two complementary pairs at 90-degree offset."""
|
|
600
|
+
L, a, b = rgb_to_oklab(np.array([seed_rgb[0]]), np.array([seed_rgb[1]]), np.array([seed_rgb[2]]))
|
|
601
|
+
_, C, H = oklab_to_oklch(L, a, b)
|
|
602
|
+
return [seed_rgb,
|
|
603
|
+
_oklch_to_srgb_tuple(L[0], C[0], (H[0] + 0.25) % 1.0),
|
|
604
|
+
_oklch_to_srgb_tuple(L[0], C[0], (H[0] + 0.5) % 1.0),
|
|
605
|
+
_oklch_to_srgb_tuple(L[0], C[0], (H[0] + 0.75) % 1.0)]
|
|
606
|
+
|
|
607
|
+
def _oklch_to_srgb_tuple(L, C, H):
|
|
608
|
+
"""Helper: single OKLCH -> sRGB (R,G,B) int tuple."""
|
|
609
|
+
La = np.array([L]); Ca = np.array([C]); Ha = np.array([H])
|
|
610
|
+
Lo, ao, bo = oklch_to_oklab(La, Ca, Ha)
|
|
611
|
+
R, G, B = oklab_to_rgb(Lo, ao, bo)
|
|
612
|
+
return (int(R[0]), int(G[0]), int(B[0]))
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
### OKLAB Hue Fields
|
|
616
|
+
|
|
617
|
+
Drop-in replacements for `hf_*` generators that produce perceptually uniform hue variation:
|
|
618
|
+
|
|
619
|
+
```python
|
|
620
|
+
def hf_oklch_angle(offset=0.0, chroma=0.12, lightness=0.7):
|
|
621
|
+
"""OKLCH hue mapped to angle from center. Perceptually uniform rainbow.
|
|
622
|
+
Returns (R, G, B) uint8 color array instead of a float hue.
|
|
623
|
+
NOTE: Use with _render_vf_rgb() variant, not standard _render_vf()."""
|
|
624
|
+
def fn(g, f, t, S):
|
|
625
|
+
H = (g.angle / (2 * np.pi) + offset + t * 0.05) % 1.0
|
|
626
|
+
L = np.full_like(H, lightness)
|
|
627
|
+
C = np.full_like(H, chroma)
|
|
628
|
+
Lo, ao, bo = oklch_to_oklab(L, C, H)
|
|
629
|
+
R, G, B = oklab_to_rgb(Lo, ao, bo)
|
|
630
|
+
return mkc(R, G, B, g.rows, g.cols)
|
|
631
|
+
return fn
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
### Compositing Helpers
|
|
635
|
+
|
|
636
|
+
```python
|
|
637
|
+
def mkc(R, G, B, rows, cols):
|
|
638
|
+
"""Pack 3 uint8 arrays into (rows, cols, 3) color array."""
|
|
639
|
+
o = np.zeros((rows, cols, 3), dtype=np.uint8)
|
|
640
|
+
o[:,:,0] = R; o[:,:,1] = G; o[:,:,2] = B
|
|
641
|
+
return o
|
|
642
|
+
|
|
643
|
+
def layer_over(base_ch, base_co, top_ch, top_co):
|
|
644
|
+
"""Composite top layer onto base. Non-space chars overwrite."""
|
|
645
|
+
m = top_ch != " "
|
|
646
|
+
base_ch[m] = top_ch[m]; base_co[m] = top_co[m]
|
|
647
|
+
return base_ch, base_co
|
|
648
|
+
|
|
649
|
+
def layer_blend(base_co, top_co, alpha):
|
|
650
|
+
"""Alpha-blend top color layer onto base. alpha is float array (0-1) or scalar."""
|
|
651
|
+
if isinstance(alpha, (int, float)):
|
|
652
|
+
alpha = np.full(base_co.shape[:2], alpha, dtype=np.float32)
|
|
653
|
+
a = alpha[:,:,None]
|
|
654
|
+
return np.clip(base_co * (1 - a) + top_co * a, 0, 255).astype(np.uint8)
|
|
655
|
+
|
|
656
|
+
def stamp(ch, co, text, row, col, color=(255,255,255)):
|
|
657
|
+
"""Write text string at position."""
|
|
658
|
+
for i, c in enumerate(text):
|
|
659
|
+
cc = col + i
|
|
660
|
+
if 0 <= row < ch.shape[0] and 0 <= cc < ch.shape[1]:
|
|
661
|
+
ch[row, cc] = c; co[row, cc] = color
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
---
|
|
665
|
+
|
|
666
|
+
## Section System
|
|
667
|
+
|
|
668
|
+
Map time ranges to effect functions + shader configs + grid sizes:
|
|
669
|
+
|
|
670
|
+
```python
|
|
671
|
+
SECTIONS = [
|
|
672
|
+
(0.0, "void"), (3.94, "starfield"), (21.0, "matrix"),
|
|
673
|
+
(46.0, "drop"), (130.0, "glitch"), (187.0, "outro"),
|
|
674
|
+
]
|
|
675
|
+
|
|
676
|
+
FX_DISPATCH = {"void": fx_void, "starfield": fx_starfield, ...}
|
|
677
|
+
SECTION_FX = {"void": {"vignette": 0.3, "bloom": 170}, ...}
|
|
678
|
+
SECTION_GRID = {"void": "md", "starfield": "sm", "drop": "lg", ...}
|
|
679
|
+
SECTION_MIRROR = {"drop": "h", "bass_rings": "quad"}
|
|
680
|
+
|
|
681
|
+
def get_section(t):
|
|
682
|
+
sec = SECTIONS[0][1]
|
|
683
|
+
for ts, name in SECTIONS:
|
|
684
|
+
if t >= ts: sec = name
|
|
685
|
+
return sec
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
---
|
|
689
|
+
|
|
690
|
+
## Parallel Encoding
|
|
691
|
+
|
|
692
|
+
Split frames across N workers. Each pipes raw RGB to its own ffmpeg subprocess:
|
|
693
|
+
|
|
694
|
+
```python
|
|
695
|
+
def render_batch(batch_id, frame_start, frame_end, features, seg_path):
|
|
696
|
+
r = Renderer()
|
|
697
|
+
cmd = ["ffmpeg", "-y", "-f", "rawvideo", "-pix_fmt", "rgb24",
|
|
698
|
+
"-s", f"{VW}x{VH}", "-r", str(FPS), "-i", "pipe:0",
|
|
699
|
+
"-c:v", "libx264", "-preset", "fast", "-crf", "18",
|
|
700
|
+
"-pix_fmt", "yuv420p", seg_path]
|
|
701
|
+
|
|
702
|
+
# CRITICAL: stderr to file, not pipe
|
|
703
|
+
stderr_fh = open(os.path.join(workdir, f"err_{batch_id:02d}.log"), "w")
|
|
704
|
+
pipe = subprocess.Popen(cmd, stdin=subprocess.PIPE,
|
|
705
|
+
stdout=subprocess.DEVNULL, stderr=stderr_fh)
|
|
706
|
+
|
|
707
|
+
for fi in range(frame_start, frame_end):
|
|
708
|
+
t = fi / FPS
|
|
709
|
+
sec = get_section(t)
|
|
710
|
+
f = {k: float(features[k][fi]) for k in features}
|
|
711
|
+
canvas = FX_DISPATCH[sec](r, f, t, r.S)
|
|
712
|
+
canvas = apply_mirror(canvas, sec, f)
|
|
713
|
+
canvas = apply_shaders(canvas, sec, f, t)
|
|
714
|
+
pipe.stdin.write(canvas.tobytes())
|
|
715
|
+
|
|
716
|
+
pipe.stdin.close()
|
|
717
|
+
status = pipe.wait()
|
|
718
|
+
stderr_fh.close()
|
|
719
|
+
if status != 0:
|
|
720
|
+
raise RuntimeError(f"ffmpeg failed: {status}")
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
Concatenate segments + mux audio:
|
|
724
|
+
|
|
725
|
+
```python
|
|
726
|
+
# Write concat file
|
|
727
|
+
with open(concat_path, "w") as cf:
|
|
728
|
+
for seg in segments:
|
|
729
|
+
cf.write(f"file '{seg}'\n")
|
|
730
|
+
|
|
731
|
+
subprocess.run(["ffmpeg", "-y", "-f", "concat", "-safe", "0", "-i", concat_path,
|
|
732
|
+
"-i", audio_path, "-c:v", "copy", "-c:a", "aac", "-b:a", "192k",
|
|
733
|
+
"-shortest", output_path])
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
## Effect Function Contract
|
|
737
|
+
|
|
738
|
+
### v2 Protocol (Current)
|
|
739
|
+
|
|
740
|
+
Every scene function: `(r, f, t, S) -> canvas_uint8` — where `r` = Renderer, `f` = features dict, `t` = time float, `S` = persistent state dict
|
|
741
|
+
|
|
742
|
+
```python
|
|
743
|
+
def fx_example(r, f, t, S):
|
|
744
|
+
"""Scene function returns a full pixel canvas (uint8 H,W,3).
|
|
745
|
+
Scenes have full control over multi-grid rendering and pixel-level composition.
|
|
746
|
+
"""
|
|
747
|
+
# Render multiple layers at different grid densities
|
|
748
|
+
canvas_a = _render_vf(r, "md", vf_plasma, hf_angle(0.0), PAL_DENSE, f, t, S)
|
|
749
|
+
canvas_b = _render_vf(r, "sm", vf_vortex, hf_time_cycle(0.1), PAL_RUNE, f, t, S)
|
|
750
|
+
|
|
751
|
+
# Pixel-level blend
|
|
752
|
+
result = blend_canvas(canvas_a, canvas_b, "screen", 0.8)
|
|
753
|
+
return result
|
|
754
|
+
```
|
|
755
|
+
|
|
756
|
+
See `references/scenes.md` for the full scene protocol, the Renderer class, `_render_vf()` helper, and complete scene examples.
|
|
757
|
+
|
|
758
|
+
See `references/composition.md` for blend modes, tone mapping, feedback buffers, and multi-grid composition.
|
|
759
|
+
|
|
760
|
+
### v1 Protocol (Legacy)
|
|
761
|
+
|
|
762
|
+
Simple scenes that use a single grid can still return `(chars, colors)` and let the caller handle rendering, but the v2 canvas protocol is preferred for all new code.
|
|
763
|
+
|
|
764
|
+
```python
|
|
765
|
+
def fx_simple(r, f, t, S):
|
|
766
|
+
g = r.get_grid("md")
|
|
767
|
+
val = np.sin(g.dist * 0.1 - t * 3) * f.get("bass", 0.3) * 2
|
|
768
|
+
val = np.clip(val, 0, 1); mask = val > 0.03
|
|
769
|
+
ch = val2char(val, mask, PAL_DEFAULT)
|
|
770
|
+
R, G, B = hsv2rgb(np.full_like(val, 0.6), np.full_like(val, 0.7), val)
|
|
771
|
+
co = mkc(R, G, B, g.rows, g.cols)
|
|
772
|
+
return g.render(ch, co) # returns canvas directly
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
### Persistent State
|
|
776
|
+
|
|
777
|
+
Effects that need state across frames (particles, rain columns) use the `S` dict parameter (which is `r.S` — same object, but passed explicitly for clarity):
|
|
778
|
+
|
|
779
|
+
```python
|
|
780
|
+
def fx_with_state(r, f, t, S):
|
|
781
|
+
if "particles" not in S:
|
|
782
|
+
S["particles"] = initialize_particles()
|
|
783
|
+
update_particles(S["particles"])
|
|
784
|
+
# ...
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
State persists across frames within a single scene/clip. Each worker process (and each scene) gets its own independent state.
|
|
788
|
+
|
|
789
|
+
### Helper Functions
|
|
790
|
+
|
|
791
|
+
```python
|
|
792
|
+
def hsv2rgb_scalar(h, s, v):
|
|
793
|
+
"""Single-value HSV to RGB. Returns (R, G, B) tuple of ints 0-255."""
|
|
794
|
+
h = h % 1.0
|
|
795
|
+
c = v * s; x = c * (1 - abs((h * 6) % 2 - 1)); m = v - c
|
|
796
|
+
if h * 6 < 1: r, g, b = c, x, 0
|
|
797
|
+
elif h * 6 < 2: r, g, b = x, c, 0
|
|
798
|
+
elif h * 6 < 3: r, g, b = 0, c, x
|
|
799
|
+
elif h * 6 < 4: r, g, b = 0, x, c
|
|
800
|
+
elif h * 6 < 5: r, g, b = x, 0, c
|
|
801
|
+
else: r, g, b = c, 0, x
|
|
802
|
+
return (int((r+m)*255), int((g+m)*255), int((b+m)*255))
|
|
803
|
+
|
|
804
|
+
def log(msg):
|
|
805
|
+
"""Print timestamped log message."""
|
|
806
|
+
print(msg, flush=True)
|
|
807
|
+
```
|