@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,442 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Edit a .pptx in place (or save to --output).
|
|
3
|
+
|
|
4
|
+
Operations (repeatable / combinable):
|
|
5
|
+
--replace-text OLD NEW Replace text everywhere (slides, tables, notes).
|
|
6
|
+
Adjacent runs with identical formatting are
|
|
7
|
+
merged first, so matches PowerPoint split across
|
|
8
|
+
identically-formatted runs keep their formatting.
|
|
9
|
+
Only a match spanning genuinely different
|
|
10
|
+
formats falls back to a paragraph rewrite with
|
|
11
|
+
the first run's font (documented caveat).
|
|
12
|
+
--chart-data SPEC.json Update a chart. Full replace spec:
|
|
13
|
+
{"slide": 0, "chart": 0,
|
|
14
|
+
"categories": ["Q1", "Q2"],
|
|
15
|
+
"series": {"North": [1, 2], "South": [3, 4]}}
|
|
16
|
+
Or surgical ops (existing data is read, modified,
|
|
17
|
+
and written back via replace_data):
|
|
18
|
+
{"slide": 0, "chart": 0, "ops": [
|
|
19
|
+
{"op": "update_series", "name": "North",
|
|
20
|
+
"values": [5, 6]},
|
|
21
|
+
{"op": "add_series", "name": "East",
|
|
22
|
+
"values": [1, 2]},
|
|
23
|
+
{"op": "remove_series", "name": "South"},
|
|
24
|
+
{"op": "rename_category", "from": "Q1",
|
|
25
|
+
"to": "Q1 FY26"},
|
|
26
|
+
{"op": "set_title", "title": "New title"}]}
|
|
27
|
+
--swap-image SLIDE SHAPE_NAME NEW_IMAGE
|
|
28
|
+
Replace a picture's bits, keeping position/size.
|
|
29
|
+
--remove-slide N Delete slide at index N (0-based).
|
|
30
|
+
--move-slide FROM TO Reorder: move slide FROM to position TO.
|
|
31
|
+
--duplicate-slide N Append an independent deep copy of slide N
|
|
32
|
+
(text, images, tables, shapes, notes). Refuses
|
|
33
|
+
slides containing charts (a chart embeds an XLSX
|
|
34
|
+
workbook part that cannot be cloned reliably).
|
|
35
|
+
--set-background N HEX Solid background color for slide N.
|
|
36
|
+
--hyperlink N TEXT URL Make runs containing TEXT on slide N links.
|
|
37
|
+
--enable-slide-number N Copy the layout's slide-number placeholder in.
|
|
38
|
+
--set-footer N TEXT Enable the layout's footer placeholder with TEXT.
|
|
39
|
+
--set-notes N TEXT Replace slide N's speaker notes.
|
|
40
|
+
--append-notes N TEXT Append a paragraph to slide N's speaker notes.
|
|
41
|
+
"""
|
|
42
|
+
import argparse
|
|
43
|
+
import copy
|
|
44
|
+
import json
|
|
45
|
+
import sys
|
|
46
|
+
|
|
47
|
+
from lxml import etree
|
|
48
|
+
from pptx import Presentation
|
|
49
|
+
from pptx.chart.data import CategoryChartData
|
|
50
|
+
from pptx.dml.color import RGBColor
|
|
51
|
+
from pptx.enum.shapes import MSO_SHAPE_TYPE
|
|
52
|
+
from pptx.oxml.ns import qn
|
|
53
|
+
|
|
54
|
+
R_EMBED = "{http://schemas.openxmlformats.org/officeDocument/2006/relationships}"
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _run_format_key(r):
|
|
58
|
+
"""Canonical string for a run's <a:rPr>; None when absent."""
|
|
59
|
+
rPr = r.find(qn("a:rPr"))
|
|
60
|
+
if rPr is None:
|
|
61
|
+
return None
|
|
62
|
+
return etree.tostring(rPr)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def normalize_runs(para):
|
|
66
|
+
"""Merge adjacent runs whose formatting is byte-identical.
|
|
67
|
+
|
|
68
|
+
PowerPoint splits paragraph text into runs at spell-check and edit
|
|
69
|
+
boundaries even when formatting never changes; merging them back makes
|
|
70
|
+
cross-run text replacement lossless for the common case.
|
|
71
|
+
"""
|
|
72
|
+
runs = list(para.runs)
|
|
73
|
+
i = 0
|
|
74
|
+
while i + 1 < len(runs):
|
|
75
|
+
a, b = runs[i], runs[i + 1]
|
|
76
|
+
if (_run_format_key(a._r) == _run_format_key(b._r)
|
|
77
|
+
and a._r.getnext() is b._r):
|
|
78
|
+
a.text = a.text + b.text
|
|
79
|
+
b._r.getparent().remove(b._r)
|
|
80
|
+
runs.pop(i + 1)
|
|
81
|
+
else:
|
|
82
|
+
i += 1
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def replace_in_text_frame(text_frame, old, new):
|
|
86
|
+
if not old:
|
|
87
|
+
return 0
|
|
88
|
+
count = 0
|
|
89
|
+
for para in text_frame.paragraphs:
|
|
90
|
+
normalize_runs(para)
|
|
91
|
+
runs = list(para.runs)
|
|
92
|
+
joined = ''.join(run.text for run in runs)
|
|
93
|
+
matches, cursor = [], 0
|
|
94
|
+
while (start := joined.find(old, cursor)) >= 0:
|
|
95
|
+
matches.append(start)
|
|
96
|
+
cursor = start + len(old)
|
|
97
|
+
for start in reversed(matches):
|
|
98
|
+
end, pos, first = start + len(old), 0, True
|
|
99
|
+
for run in runs:
|
|
100
|
+
stop = pos + len(run.text)
|
|
101
|
+
if stop > start and pos < end:
|
|
102
|
+
a, b = max(start - pos, 0), min(end - pos, len(run.text))
|
|
103
|
+
run.text = run.text[:a] + (new if first else '') + run.text[b:]
|
|
104
|
+
first = False
|
|
105
|
+
pos = stop
|
|
106
|
+
count += len(matches)
|
|
107
|
+
return count
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def iter_shapes(shapes):
|
|
111
|
+
for shape in shapes:
|
|
112
|
+
yield shape
|
|
113
|
+
if shape.shape_type == MSO_SHAPE_TYPE.GROUP:
|
|
114
|
+
yield from iter_shapes(shape.shapes)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def iter_text_frames(slide):
|
|
118
|
+
for shape in iter_shapes(slide.shapes):
|
|
119
|
+
if shape.has_text_frame:
|
|
120
|
+
yield shape.text_frame
|
|
121
|
+
if shape.has_table:
|
|
122
|
+
for row in shape.table.rows:
|
|
123
|
+
for cell in row.cells:
|
|
124
|
+
yield cell.text_frame
|
|
125
|
+
if slide.has_notes_slide:
|
|
126
|
+
yield slide.notes_slide.notes_text_frame
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def replace_text(prs, old, new):
|
|
130
|
+
total = 0
|
|
131
|
+
for slide in prs.slides:
|
|
132
|
+
for tf in iter_text_frames(slide):
|
|
133
|
+
total += replace_in_text_frame(tf, old, new)
|
|
134
|
+
return total
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def _read_chart_data(chart):
|
|
138
|
+
"""Current categories and ordered (name, values) pairs of a chart."""
|
|
139
|
+
categories = [str(c) for c in chart.plots[0].categories]
|
|
140
|
+
series = []
|
|
141
|
+
for plot in chart.plots:
|
|
142
|
+
for s in plot.series:
|
|
143
|
+
try:
|
|
144
|
+
name = s.name
|
|
145
|
+
except (AttributeError, KeyError):
|
|
146
|
+
name = ""
|
|
147
|
+
series.append([name, list(s.values)])
|
|
148
|
+
return categories, series
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def update_chart(prs, spec_path):
|
|
152
|
+
"""Full replace ("categories"+"series") or surgical "ops".
|
|
153
|
+
|
|
154
|
+
python-pptx can only swap a chart's entire dataset (replace_data), so
|
|
155
|
+
surgical ops are implemented as read-existing -> modify -> replace.
|
|
156
|
+
"""
|
|
157
|
+
with open(spec_path, encoding="utf-8") as fh:
|
|
158
|
+
spec = json.load(fh)
|
|
159
|
+
slide = prs.slides[spec.get("slide", 0)]
|
|
160
|
+
charts = [s.chart for s in slide.shapes if s.has_chart]
|
|
161
|
+
if not charts:
|
|
162
|
+
raise SystemExit(f"no chart on slide {spec.get('slide', 0)}")
|
|
163
|
+
chart = charts[spec.get("chart", 0)]
|
|
164
|
+
|
|
165
|
+
if "ops" in spec:
|
|
166
|
+
categories, series = _read_chart_data(chart)
|
|
167
|
+
dirty = False
|
|
168
|
+
for op in spec["ops"]:
|
|
169
|
+
kind = op["op"]
|
|
170
|
+
if kind == "update_series":
|
|
171
|
+
match = [s for s in series if s[0] == op["name"]]
|
|
172
|
+
if not match:
|
|
173
|
+
raise SystemExit(f"no series named {op['name']!r}")
|
|
174
|
+
match[0][1] = op["values"]
|
|
175
|
+
dirty = True
|
|
176
|
+
elif kind == "add_series":
|
|
177
|
+
series.append([op["name"], op["values"]])
|
|
178
|
+
dirty = True
|
|
179
|
+
elif kind == "remove_series":
|
|
180
|
+
before = len(series)
|
|
181
|
+
series = [s for s in series if s[0] != op["name"]]
|
|
182
|
+
if len(series) == before:
|
|
183
|
+
raise SystemExit(f"no series named {op['name']!r}")
|
|
184
|
+
dirty = True
|
|
185
|
+
elif kind == "rename_category":
|
|
186
|
+
if "index" in op:
|
|
187
|
+
idx = int(op["index"])
|
|
188
|
+
else:
|
|
189
|
+
if op["from"] not in categories:
|
|
190
|
+
raise SystemExit(
|
|
191
|
+
f"no category named {op['from']!r}")
|
|
192
|
+
idx = categories.index(op["from"])
|
|
193
|
+
categories[idx] = op["to"]
|
|
194
|
+
dirty = True
|
|
195
|
+
elif kind == "set_title":
|
|
196
|
+
chart.has_title = True
|
|
197
|
+
chart.chart_title.text_frame.text = op["title"]
|
|
198
|
+
else:
|
|
199
|
+
raise SystemExit(f"unknown chart op {kind!r}")
|
|
200
|
+
if dirty:
|
|
201
|
+
data = CategoryChartData()
|
|
202
|
+
data.categories = categories
|
|
203
|
+
for name, values in series:
|
|
204
|
+
data.add_series(name, values)
|
|
205
|
+
chart.replace_data(data)
|
|
206
|
+
return
|
|
207
|
+
|
|
208
|
+
data = CategoryChartData()
|
|
209
|
+
data.categories = spec["categories"]
|
|
210
|
+
for name, values in spec["series"].items():
|
|
211
|
+
data.add_series(name, values)
|
|
212
|
+
chart.replace_data(data)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def swap_image(prs, slide_idx, shape_name, new_path):
|
|
216
|
+
slide = prs.slides[int(slide_idx)]
|
|
217
|
+
for shape in slide.shapes:
|
|
218
|
+
if (shape.shape_type == MSO_SHAPE_TYPE.PICTURE
|
|
219
|
+
and shape.name == shape_name):
|
|
220
|
+
image_part, rid = slide.part.get_or_add_image_part(new_path)
|
|
221
|
+
blip = shape._element.blipFill.blip
|
|
222
|
+
blip.set(R_EMBED + "embed", rid)
|
|
223
|
+
return True
|
|
224
|
+
raise SystemExit(f"no picture named {shape_name!r} on slide {slide_idx}")
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def remove_slide(prs, index):
|
|
228
|
+
sldIdLst = prs.slides._sldIdLst
|
|
229
|
+
slide_id = list(sldIdLst)[int(index)]
|
|
230
|
+
rid = slide_id.get(R_EMBED + "id")
|
|
231
|
+
prs.part.drop_rel(rid)
|
|
232
|
+
sldIdLst.remove(slide_id)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def move_slide(prs, src, dst):
|
|
236
|
+
"""Reorder by moving the <p:sldId> element inside <p:sldIdLst>."""
|
|
237
|
+
sldIdLst = prs.slides._sldIdLst
|
|
238
|
+
ids = list(sldIdLst)
|
|
239
|
+
element = ids[int(src)]
|
|
240
|
+
sldIdLst.remove(element)
|
|
241
|
+
sldIdLst.insert(int(dst), element)
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def duplicate_slide(prs, index):
|
|
245
|
+
"""Append an independent deep copy of slide `index`.
|
|
246
|
+
|
|
247
|
+
Copies the shape tree XML and re-creates image/media relationships on
|
|
248
|
+
the new slide part, remapping rIds. Charts are refused: each chart
|
|
249
|
+
relationship embeds a separate XLSX workbook part, and cloning that
|
|
250
|
+
graph reliably is not supported — better to refuse than corrupt.
|
|
251
|
+
"""
|
|
252
|
+
source = prs.slides[int(index)]
|
|
253
|
+
if any(sh.has_chart for sh in iter_shapes(source.shapes)):
|
|
254
|
+
raise SystemExit(
|
|
255
|
+
f"slide {index} contains a chart; duplication of chart slides "
|
|
256
|
+
"is not supported (chart XML embeds a workbook part that "
|
|
257
|
+
"cannot be cloned safely). Rebuild the chart on a new slide "
|
|
258
|
+
"with pptx_create.py / pptx_from_template.py instead.")
|
|
259
|
+
|
|
260
|
+
dest = prs.slides.add_slide(source.slide_layout)
|
|
261
|
+
if source._element.cSld.bg is not None:
|
|
262
|
+
dest._element.cSld.insert(0, copy.deepcopy(source._element.cSld.bg))
|
|
263
|
+
# drop the placeholders add_slide seeded from the layout
|
|
264
|
+
for shape in list(dest.shapes):
|
|
265
|
+
shape._element.getparent().remove(shape._element)
|
|
266
|
+
|
|
267
|
+
for shape in source.shapes:
|
|
268
|
+
dest.shapes._spTree.append(copy.deepcopy(shape._element))
|
|
269
|
+
|
|
270
|
+
# re-create the source slide's part relationships on the copy
|
|
271
|
+
rid_map = {}
|
|
272
|
+
for rel in list(source.part.rels.values()):
|
|
273
|
+
if rel.reltype.endswith(("/slideLayout", "/notesSlide")):
|
|
274
|
+
continue
|
|
275
|
+
if rel.is_external:
|
|
276
|
+
new_rid = dest.part.rels.get_or_add_ext_rel(
|
|
277
|
+
rel.reltype, rel.target_ref)
|
|
278
|
+
else:
|
|
279
|
+
new_rid = dest.part.relate_to(rel.target_part, rel.reltype)
|
|
280
|
+
rid_map[rel.rId] = new_rid
|
|
281
|
+
|
|
282
|
+
for el in dest.shapes._spTree.iter():
|
|
283
|
+
for attr, val in el.attrib.items():
|
|
284
|
+
if attr.startswith(R_EMBED) and val in rid_map:
|
|
285
|
+
el.set(attr, rid_map[val])
|
|
286
|
+
|
|
287
|
+
if source.has_notes_slide:
|
|
288
|
+
dest.notes_slide.notes_text_frame.text = (
|
|
289
|
+
source.notes_slide.notes_text_frame.text)
|
|
290
|
+
return len(prs.slides._sldIdLst) - 1
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def set_background(slide, hex_color):
|
|
294
|
+
fill = slide.background.fill
|
|
295
|
+
fill.solid()
|
|
296
|
+
fill.fore_color.rgb = RGBColor.from_string(hex_color)
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def add_hyperlink(prs, slide_idx, text, url):
|
|
300
|
+
"""Turn every run containing `text` on the slide into a hyperlink.
|
|
301
|
+
|
|
302
|
+
The link applies to the whole run (python-pptx links whole runs).
|
|
303
|
+
"""
|
|
304
|
+
slide = prs.slides[int(slide_idx)]
|
|
305
|
+
hits = 0
|
|
306
|
+
for shape in slide.shapes:
|
|
307
|
+
if not shape.has_text_frame:
|
|
308
|
+
continue
|
|
309
|
+
for para in shape.text_frame.paragraphs:
|
|
310
|
+
for run in para.runs:
|
|
311
|
+
if text in run.text:
|
|
312
|
+
run.hyperlink.address = url
|
|
313
|
+
hits += 1
|
|
314
|
+
if not hits:
|
|
315
|
+
raise SystemExit(f"no run containing {text!r} on slide {slide_idx}")
|
|
316
|
+
return hits
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def _copy_layout_placeholder(slide, ph_idx):
|
|
320
|
+
"""Copy the layout placeholder with idx `ph_idx` onto the slide.
|
|
321
|
+
|
|
322
|
+
Slide-number (idx 12) and footer (idx 11) placeholders exist on the
|
|
323
|
+
layout but are not inherited by a slide until the slide carries its
|
|
324
|
+
own copy — this enables them. Returns the new shape, or None when the
|
|
325
|
+
layout does not provide that placeholder.
|
|
326
|
+
"""
|
|
327
|
+
for ph in slide.slide_layout.placeholders:
|
|
328
|
+
if ph.placeholder_format.idx == ph_idx:
|
|
329
|
+
el = copy.deepcopy(ph._element)
|
|
330
|
+
slide.shapes._spTree.append(el)
|
|
331
|
+
for shape in slide.placeholders:
|
|
332
|
+
if shape.placeholder_format.idx == ph_idx:
|
|
333
|
+
return shape
|
|
334
|
+
return None
|
|
335
|
+
return None
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def enable_slide_number(slide):
|
|
339
|
+
if any(ph.placeholder_format.idx == 12 for ph in slide.placeholders):
|
|
340
|
+
return True
|
|
341
|
+
return _copy_layout_placeholder(slide, 12) is not None
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def set_footer(slide, text):
|
|
345
|
+
shape = next((ph for ph in slide.placeholders
|
|
346
|
+
if ph.placeholder_format.idx == 11), None)
|
|
347
|
+
if shape is None:
|
|
348
|
+
shape = _copy_layout_placeholder(slide, 11)
|
|
349
|
+
if shape is None:
|
|
350
|
+
raise SystemExit("layout provides no footer placeholder; add a "
|
|
351
|
+
"textbox instead")
|
|
352
|
+
shape.text_frame.text = text
|
|
353
|
+
return True
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
def set_notes(slide, text, append=False):
|
|
357
|
+
tf = slide.notes_slide.notes_text_frame
|
|
358
|
+
if append and tf.text:
|
|
359
|
+
para = tf.add_paragraph()
|
|
360
|
+
para.text = text
|
|
361
|
+
else:
|
|
362
|
+
tf.text = text
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
def main(argv=None):
|
|
366
|
+
if hasattr(sys.stdout, "reconfigure"):
|
|
367
|
+
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
|
368
|
+
parser = argparse.ArgumentParser(
|
|
369
|
+
description="Edit a .pptx: replace text, update chart data, swap "
|
|
370
|
+
"images, duplicate/remove/reorder slides, backgrounds, "
|
|
371
|
+
"hyperlinks, footers, slide numbers, speaker notes.",
|
|
372
|
+
epilog=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
373
|
+
parser.add_argument("pptx", help="path to the .pptx file")
|
|
374
|
+
parser.add_argument("--output", help="save to this path instead of "
|
|
375
|
+
"overwriting the input")
|
|
376
|
+
parser.add_argument("--replace-text", nargs=2, action="append",
|
|
377
|
+
metavar=("OLD", "NEW"), default=[])
|
|
378
|
+
parser.add_argument("--chart-data", metavar="SPEC_JSON")
|
|
379
|
+
parser.add_argument("--swap-image", nargs=3,
|
|
380
|
+
metavar=("SLIDE", "SHAPE_NAME", "IMAGE"))
|
|
381
|
+
parser.add_argument("--remove-slide", type=int, metavar="N")
|
|
382
|
+
parser.add_argument("--move-slide", nargs=2, type=int,
|
|
383
|
+
metavar=("FROM", "TO"))
|
|
384
|
+
parser.add_argument("--duplicate-slide", type=int, metavar="N")
|
|
385
|
+
parser.add_argument("--set-background", nargs=2,
|
|
386
|
+
metavar=("SLIDE", "HEX"))
|
|
387
|
+
parser.add_argument("--hyperlink", nargs=3,
|
|
388
|
+
metavar=("SLIDE", "TEXT", "URL"))
|
|
389
|
+
parser.add_argument("--enable-slide-number", type=int, metavar="N")
|
|
390
|
+
parser.add_argument("--set-footer", nargs=2, metavar=("SLIDE", "TEXT"))
|
|
391
|
+
parser.add_argument("--set-notes", nargs=2, metavar=("SLIDE", "TEXT"))
|
|
392
|
+
parser.add_argument("--append-notes", nargs=2, metavar=("SLIDE", "TEXT"))
|
|
393
|
+
args = parser.parse_args(argv)
|
|
394
|
+
|
|
395
|
+
prs = Presentation(args.pptx)
|
|
396
|
+
report = {"ok": True, "replacements": 0}
|
|
397
|
+
|
|
398
|
+
for old, new in args.replace_text:
|
|
399
|
+
report["replacements"] += replace_text(prs, old, new)
|
|
400
|
+
if args.chart_data:
|
|
401
|
+
update_chart(prs, args.chart_data)
|
|
402
|
+
report["chart_updated"] = True
|
|
403
|
+
if args.swap_image:
|
|
404
|
+
swap_image(prs, *args.swap_image)
|
|
405
|
+
report["image_swapped"] = True
|
|
406
|
+
if args.duplicate_slide is not None:
|
|
407
|
+
report["duplicated_to"] = duplicate_slide(prs, args.duplicate_slide)
|
|
408
|
+
if args.set_background:
|
|
409
|
+
set_background(prs.slides[int(args.set_background[0])],
|
|
410
|
+
args.set_background[1])
|
|
411
|
+
report["background_set"] = True
|
|
412
|
+
if args.hyperlink:
|
|
413
|
+
report["hyperlinked_runs"] = add_hyperlink(prs, *args.hyperlink)
|
|
414
|
+
if args.enable_slide_number is not None:
|
|
415
|
+
report["slide_number_enabled"] = enable_slide_number(
|
|
416
|
+
prs.slides[args.enable_slide_number])
|
|
417
|
+
if args.set_footer:
|
|
418
|
+
set_footer(prs.slides[int(args.set_footer[0])], args.set_footer[1])
|
|
419
|
+
report["footer_set"] = True
|
|
420
|
+
if args.set_notes:
|
|
421
|
+
set_notes(prs.slides[int(args.set_notes[0])], args.set_notes[1])
|
|
422
|
+
report["notes_set"] = True
|
|
423
|
+
if args.append_notes:
|
|
424
|
+
set_notes(prs.slides[int(args.append_notes[0])],
|
|
425
|
+
args.append_notes[1], append=True)
|
|
426
|
+
report["notes_appended"] = True
|
|
427
|
+
if args.remove_slide is not None:
|
|
428
|
+
remove_slide(prs, args.remove_slide)
|
|
429
|
+
report["slide_removed"] = args.remove_slide
|
|
430
|
+
if args.move_slide:
|
|
431
|
+
move_slide(prs, *args.move_slide)
|
|
432
|
+
report["slide_moved"] = args.move_slide
|
|
433
|
+
|
|
434
|
+
out = args.output or args.pptx
|
|
435
|
+
prs.save(out)
|
|
436
|
+
report["output"] = out
|
|
437
|
+
print(json.dumps(report))
|
|
438
|
+
return 0
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
if __name__ == "__main__":
|
|
442
|
+
sys.exit(main())
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Build a deck from a .pptx template (brand deck) and fill placeholders.
|
|
3
|
+
|
|
4
|
+
Two modes:
|
|
5
|
+
1) Token fill (default): open TEMPLATE, replace every {{token}} across
|
|
6
|
+
slides, tables, and notes using --values JSON ({"token": "value"}),
|
|
7
|
+
save to OUTPUT. Formatting of the token's run is preserved.
|
|
8
|
+
2) --add-slides SPEC.json: additionally append slides built from the
|
|
9
|
+
template's own layouts (referenced by layout name or index), so new
|
|
10
|
+
slides inherit the brand master. Spec:
|
|
11
|
+
{"slides": [{"layout": "Title and Content", "title": "New",
|
|
12
|
+
"bullets": ["a", {"text": "b", "level": 1}],
|
|
13
|
+
"notes": "presenter text"}]}
|
|
14
|
+
"""
|
|
15
|
+
import argparse
|
|
16
|
+
import json
|
|
17
|
+
import sys
|
|
18
|
+
|
|
19
|
+
from pptx import Presentation
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def fill_tokens(prs, values):
|
|
23
|
+
from pptx_edit import replace_text # same scripts/ directory
|
|
24
|
+
total = 0
|
|
25
|
+
for token, value in values.items():
|
|
26
|
+
total += replace_text(prs, "{{%s}}" % token, str(value))
|
|
27
|
+
return total
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def find_layout(prs, ref):
|
|
31
|
+
if isinstance(ref, int):
|
|
32
|
+
return prs.slide_layouts[ref]
|
|
33
|
+
for layout in prs.slide_layouts:
|
|
34
|
+
if layout.name == ref:
|
|
35
|
+
return layout
|
|
36
|
+
raise SystemExit(f"layout {ref!r} not found; available: "
|
|
37
|
+
f"{[la.name for la in prs.slide_layouts]}")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def add_slides(prs, spec):
|
|
41
|
+
from pptx_create import add_bullets
|
|
42
|
+
for slide_spec in spec.get("slides", []):
|
|
43
|
+
layout = find_layout(prs, slide_spec.get("layout", 1))
|
|
44
|
+
slide = prs.slides.add_slide(layout)
|
|
45
|
+
if slide_spec.get("title") is not None and slide.shapes.title:
|
|
46
|
+
slide.shapes.title.text = slide_spec["title"]
|
|
47
|
+
if slide_spec.get("bullets"):
|
|
48
|
+
body = next((ph for ph in slide.placeholders
|
|
49
|
+
if ph.placeholder_format.idx != 0), None)
|
|
50
|
+
if body is not None:
|
|
51
|
+
add_bullets(body.text_frame, slide_spec["bullets"])
|
|
52
|
+
if slide_spec.get("notes"):
|
|
53
|
+
slide.notes_slide.notes_text_frame.text = slide_spec["notes"]
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def main(argv=None):
|
|
57
|
+
if hasattr(sys.stdout, "reconfigure"):
|
|
58
|
+
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
|
59
|
+
parser = argparse.ArgumentParser(
|
|
60
|
+
description="Fill {{tokens}} in a .pptx template and optionally "
|
|
61
|
+
"append slides using the template's own layouts.",
|
|
62
|
+
epilog=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
63
|
+
parser.add_argument("template", help="path to the template .pptx")
|
|
64
|
+
parser.add_argument("output", help="output .pptx path")
|
|
65
|
+
parser.add_argument("--values", metavar="JSON",
|
|
66
|
+
help="JSON file mapping token -> replacement value")
|
|
67
|
+
parser.add_argument("--add-slides", metavar="SPEC_JSON",
|
|
68
|
+
help="JSON spec of slides to append")
|
|
69
|
+
args = parser.parse_args(argv)
|
|
70
|
+
|
|
71
|
+
prs = Presentation(args.template)
|
|
72
|
+
filled = 0
|
|
73
|
+
if args.values:
|
|
74
|
+
with open(args.values, encoding="utf-8") as fh:
|
|
75
|
+
filled = fill_tokens(prs, json.load(fh))
|
|
76
|
+
if args.add_slides:
|
|
77
|
+
with open(args.add_slides, encoding="utf-8") as fh:
|
|
78
|
+
add_slides(prs, json.load(fh))
|
|
79
|
+
prs.save(args.output)
|
|
80
|
+
print(json.dumps({"ok": True, "output": args.output,
|
|
81
|
+
"tokens_filled": filled}))
|
|
82
|
+
return 0
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
if __name__ == "__main__":
|
|
86
|
+
import os
|
|
87
|
+
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
88
|
+
sys.exit(main())
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Read a .pptx file: JSON outline, notes, or export embedded images.
|
|
3
|
+
|
|
4
|
+
Modes:
|
|
5
|
+
--outline JSON with per-slide layout, texts, tables, notes,
|
|
6
|
+
chart data, and image inventory (default mode).
|
|
7
|
+
--notes JSON list of speaker notes per slide.
|
|
8
|
+
--images DIR Export every embedded picture to DIR as files.
|
|
9
|
+
"""
|
|
10
|
+
import argparse
|
|
11
|
+
import json
|
|
12
|
+
import os
|
|
13
|
+
import sys
|
|
14
|
+
|
|
15
|
+
from pptx import Presentation
|
|
16
|
+
from pptx.enum.shapes import MSO_SHAPE_TYPE
|
|
17
|
+
from pptx.util import Emu
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def iter_shapes(shapes):
|
|
21
|
+
"""Yield shapes, descending into groups."""
|
|
22
|
+
for shape in shapes:
|
|
23
|
+
if shape.shape_type == MSO_SHAPE_TYPE.GROUP:
|
|
24
|
+
yield from iter_shapes(shape.shapes)
|
|
25
|
+
else:
|
|
26
|
+
yield shape
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def chart_info(chart):
|
|
30
|
+
info = {"type": str(chart.chart_type),
|
|
31
|
+
"categories": [str(c) for c in chart.plots[0].categories],
|
|
32
|
+
"series": []}
|
|
33
|
+
for plot in chart.plots:
|
|
34
|
+
for series in plot.series:
|
|
35
|
+
try:
|
|
36
|
+
name = series.name
|
|
37
|
+
except (AttributeError, KeyError):
|
|
38
|
+
name = None
|
|
39
|
+
info["series"].append({"name": name,
|
|
40
|
+
"values": list(series.values)})
|
|
41
|
+
return info
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def slide_record(index, slide):
|
|
45
|
+
rec = {"index": index, "layout": slide.slide_layout.name,
|
|
46
|
+
"texts": [], "tables": [], "images": [], "charts": [],
|
|
47
|
+
"notes": None}
|
|
48
|
+
for shape in iter_shapes(slide.shapes):
|
|
49
|
+
if shape.has_text_frame and shape.text_frame.text.strip():
|
|
50
|
+
rec["texts"].append(shape.text_frame.text)
|
|
51
|
+
if shape.has_table:
|
|
52
|
+
rec["tables"].append(
|
|
53
|
+
[[cell.text for cell in row.cells]
|
|
54
|
+
for row in shape.table.rows])
|
|
55
|
+
if shape.shape_type == MSO_SHAPE_TYPE.PICTURE:
|
|
56
|
+
try:
|
|
57
|
+
img = shape.image
|
|
58
|
+
rec["images"].append({"filename": img.filename,
|
|
59
|
+
"ext": img.ext,
|
|
60
|
+
"size_bytes": len(img.blob)})
|
|
61
|
+
except (KeyError, ValueError):
|
|
62
|
+
rec["images"].append({"filename": None, "ext": None,
|
|
63
|
+
"size_bytes": None,
|
|
64
|
+
"note": "linked or unreadable"})
|
|
65
|
+
if shape.has_chart:
|
|
66
|
+
rec["charts"].append(chart_info(shape.chart))
|
|
67
|
+
if slide.has_notes_slide:
|
|
68
|
+
rec["notes"] = slide.notes_slide.notes_text_frame.text
|
|
69
|
+
return rec
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def export_images(prs, out_dir):
|
|
73
|
+
os.makedirs(out_dir, exist_ok=True)
|
|
74
|
+
written = []
|
|
75
|
+
for i, slide in enumerate(prs.slides):
|
|
76
|
+
for j, shape in enumerate(iter_shapes(slide.shapes)):
|
|
77
|
+
if shape.shape_type != MSO_SHAPE_TYPE.PICTURE:
|
|
78
|
+
continue
|
|
79
|
+
try:
|
|
80
|
+
img = shape.image
|
|
81
|
+
except (KeyError, ValueError):
|
|
82
|
+
continue
|
|
83
|
+
path = os.path.join(out_dir, f"slide{i}_img{j}.{img.ext}")
|
|
84
|
+
with open(path, "wb") as fh:
|
|
85
|
+
fh.write(img.blob)
|
|
86
|
+
written.append(path)
|
|
87
|
+
return written
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def main(argv=None):
|
|
91
|
+
if hasattr(sys.stdout, "reconfigure"):
|
|
92
|
+
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
|
93
|
+
parser = argparse.ArgumentParser(
|
|
94
|
+
description="Read a .pptx: outline/notes as JSON, export images.")
|
|
95
|
+
parser.add_argument("pptx", help="path to the .pptx file")
|
|
96
|
+
parser.add_argument("--outline", action="store_true",
|
|
97
|
+
help="print full JSON outline (default)")
|
|
98
|
+
parser.add_argument("--notes", action="store_true",
|
|
99
|
+
help="print speaker notes only")
|
|
100
|
+
parser.add_argument("--images", metavar="DIR",
|
|
101
|
+
help="export embedded images into DIR")
|
|
102
|
+
args = parser.parse_args(argv)
|
|
103
|
+
|
|
104
|
+
prs = Presentation(args.pptx)
|
|
105
|
+
|
|
106
|
+
if args.images:
|
|
107
|
+
written = export_images(prs, args.images)
|
|
108
|
+
print(json.dumps({"ok": True, "exported": written}, indent=2))
|
|
109
|
+
return 0
|
|
110
|
+
if args.notes:
|
|
111
|
+
notes = [slide.notes_slide.notes_text_frame.text
|
|
112
|
+
if slide.has_notes_slide else None
|
|
113
|
+
for slide in prs.slides]
|
|
114
|
+
print(json.dumps({"ok": True, "notes": notes},
|
|
115
|
+
indent=2, ensure_ascii=True))
|
|
116
|
+
return 0
|
|
117
|
+
|
|
118
|
+
outline = {
|
|
119
|
+
"ok": True,
|
|
120
|
+
"slide_size_inches": [round(Emu(prs.slide_width).inches, 3),
|
|
121
|
+
round(Emu(prs.slide_height).inches, 3)],
|
|
122
|
+
"slide_count": len(prs.slides._sldIdLst),
|
|
123
|
+
"layouts_available": [lay.name for lay in prs.slide_layouts],
|
|
124
|
+
"slides": [slide_record(i, s) for i, s in enumerate(prs.slides)],
|
|
125
|
+
}
|
|
126
|
+
print(json.dumps(outline, indent=2, ensure_ascii=True))
|
|
127
|
+
return 0
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
if __name__ == "__main__":
|
|
131
|
+
sys.exit(main())
|