@prismer/runtime 2.2.55 → 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 +574 -0
- package/apc/skills/releasing-test/SKILL.md +9 -0
- package/built-in-skills/agent-coordination/SKILL.md +21 -4
- package/built-in-skills/agent-meta/SKILL.md +11 -0
- package/built-in-skills/assets/SKILL.md +1 -1
- package/built-in-skills/canvas-design/SKILL.md +3 -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 +7 -3
- package/built-in-skills/claude-api/SKILL.md +1 -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/SKILL.md +15 -1
- 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 +3 -0
- package/built-in-skills/council-creator/SKILL.md +4 -3
- package/built-in-skills/diagnosing-bugs/SKILL.md +12 -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/doc-coauthoring/SKILL.md +6 -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/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 +6 -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/image-generate/SKILL.md +5 -0
- package/built-in-skills/image-generate/scripts/generate-and-deliver.mjs +24 -3
- 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 +27 -3
- 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 +8 -15
- 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 +20 -0
- package/built-in-skills/office-artifacts/references/RESOURCE-LIMITS.md +44 -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/persona-generator/SKILL.md +9 -9
- package/built-in-skills/pkf-svg/SKILL.md +5 -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 +36 -14
- 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 +1 -1
- 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/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 +7 -1
- package/built-in-skills/role-builder/scripts/author-role.mjs +23 -7
- package/built-in-skills/role-builder/scripts/ingest-role.mjs +15 -117
- package/built-in-skills/role-builder/scripts/instantiate-and-run.mjs +15 -1
- package/built-in-skills/role-builder/scripts/operation-harness.mjs +6 -4
- 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 +20 -1
- 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/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-authoring/SKILL.md → skill-creator/references/skill-authoring/GUIDE.md} +1 -1
- package/built-in-skills/{skill-builder/SKILL.md → skill-creator/references/skill-builder/GUIDE.md} +8 -12
- 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 +30 -7
- 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/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 +2 -2
- package/built-in-skills/tdd/SKILL.md +7 -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/team/SKILL.md +1 -1
- package/built-in-skills/web-artifacts-builder/SKILL.md +3 -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 +9 -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/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 +7017 -3340
- package/dist/cli.js +6631 -2936
- package/dist/index.cjs +7863 -3830
- package/dist/index.d.cts +459 -5
- package/dist/index.d.ts +459 -5
- package/dist/index.js +7106 -3064
- package/package.json +7 -2
- package/plugins/memory/prismer/__init__.py +4 -0
- package/plugins/memory/prismer/tool-schemas.generated.json +8 -0
- package/built-in-skills/skill-builder/scripts/ingest.mjs +0 -265
- package/built-in-skills/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- /package/built-in-skills/{document-generation/SKILL.md → office-artifacts/references/document-generation/GUIDE.md} +0 -0
- /package/built-in-skills/{skill-authoring/skill.json → skill-creator/references/skill-authoring/draft-contract.json} +0 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: xlsx
|
|
3
|
+
description: Create, read, edit Excel .xlsx workbooks and CSVs.
|
|
4
|
+
version: 1.1.0
|
|
5
|
+
author: Nous Research
|
|
6
|
+
license: MIT
|
|
7
|
+
platforms: [linux, macos, windows]
|
|
8
|
+
metadata:
|
|
9
|
+
hermes:
|
|
10
|
+
tags: [excel, spreadsheet, xlsx, csv, openpyxl, productivity]
|
|
11
|
+
category: productivity
|
|
12
|
+
related_skills: [docx, pdf, powerpoint]
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Xlsx Skill
|
|
16
|
+
|
|
17
|
+
Work with Excel .xlsx workbooks using Python and openpyxl: build styled
|
|
18
|
+
multi-sheet workbooks with formulas and charts, inspect or dump existing
|
|
19
|
+
files, edit cells and structure, and convert to/from CSV. All helper
|
|
20
|
+
scripts are argparse CLIs that print JSON and use explicit UTF-8 I/O.
|
|
21
|
+
|
|
22
|
+
## When to Use
|
|
23
|
+
|
|
24
|
+
- Creating .xlsx reports: multiple sheets, number formats, styling,
|
|
25
|
+
merged cells, freeze panes, autofilter, conditional formatting,
|
|
26
|
+
charts, data-validation dropdowns, native Excel tables, defined
|
|
27
|
+
names, hyperlinks, cell notes, sheet protection.
|
|
28
|
+
- Reading a workbook: sheet inventory, dumping data as JSON or CSV,
|
|
29
|
+
listing formulas vs cached values, notes, defined names, tables.
|
|
30
|
+
- Editing existing files: set cells, append rows, insert/delete
|
|
31
|
+
rows/columns (reference-aware via `xlsx_restructure.py`),
|
|
32
|
+
copy/rename sheets, tables, names, notes, protection.
|
|
33
|
+
- Recalculating formulas headlessly via LibreOffice
|
|
34
|
+
(`xlsx_recalc.py`).
|
|
35
|
+
- CSV interop with type inference and non-UTF-8 encodings.
|
|
36
|
+
- Not for the legacy .xls binary format (use LibreOffice to convert
|
|
37
|
+
first: `soffice --headless --convert-to xlsx old.xls`).
|
|
38
|
+
|
|
39
|
+
## Prerequisites
|
|
40
|
+
|
|
41
|
+
- Python 3.10+ with `openpyxl` (`pip install openpyxl`). No other
|
|
42
|
+
third-party packages are needed; everything else is stdlib.
|
|
43
|
+
- Optional: LibreOffice (`soffice`) for headless recalculation or
|
|
44
|
+
format conversion.
|
|
45
|
+
|
|
46
|
+
## How to Run
|
|
47
|
+
|
|
48
|
+
Run the helper scripts with the `terminal` tool from this skill's
|
|
49
|
+
`scripts/` directory (every script supports `--help`):
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
python scripts/xlsx_create.py spec.json report.xlsx # build from JSON spec
|
|
53
|
+
python scripts/xlsx_read.py report.xlsx --sheets # inventory
|
|
54
|
+
python scripts/xlsx_read.py report.xlsx --json --sheet Data
|
|
55
|
+
python scripts/xlsx_read.py report.xlsx --formulas
|
|
56
|
+
python scripts/xlsx_edit.py report.xlsx --sheet Data --set B2=42 --recalc
|
|
57
|
+
python scripts/xlsx_restructure.py report.xlsx --sheet Data --insert-rows 3:2
|
|
58
|
+
python scripts/xlsx_recalc.py report.xlsx
|
|
59
|
+
python scripts/csv_to_xlsx.py data.csv out.xlsx --encoding utf-8
|
|
60
|
+
python scripts/xlsx_to_csv.py report.xlsx out.csv --sheet Data
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Author the JSON spec with `write_file`, inspect script JSON output with
|
|
64
|
+
`read_file` or directly from stdout.
|
|
65
|
+
|
|
66
|
+
## Quick Reference
|
|
67
|
+
|
|
68
|
+
| Task | Command |
|
|
69
|
+
|---|---|
|
|
70
|
+
| Create workbook from spec | `xlsx_create.py spec.json out.xlsx` |
|
|
71
|
+
| Sheet names + dimensions | `xlsx_read.py f.xlsx --sheets` |
|
|
72
|
+
| Dump sheet as JSON | `xlsx_read.py f.xlsx --json --sheet S` |
|
|
73
|
+
| Dump sheet as CSV | `xlsx_read.py f.xlsx --csv --out d.csv` |
|
|
74
|
+
| List formulas + cached values | `xlsx_read.py f.xlsx --formulas` |
|
|
75
|
+
| Set a cell / formula | `xlsx_edit.py f.xlsx --set "A1==SUM(B:B)"` |
|
|
76
|
+
| Append a row | `xlsx_edit.py f.xlsx --append '[1,"x",true]'` |
|
|
77
|
+
| Insert 2 rows, refs NOT shifted | `xlsx_edit.py f.xlsx --insert-rows 3:2` |
|
|
78
|
+
| Insert 2 rows, refs shifted | `xlsx_restructure.py f.xlsx --insert-rows 3:2` |
|
|
79
|
+
| Delete a column, refs shifted | `xlsx_restructure.py f.xlsx --delete-cols B` |
|
|
80
|
+
| Create a native table | `xlsx_edit.py f.xlsx --add-table Sales:A1:C9` |
|
|
81
|
+
| Append inside a table | `--table-append 'Sales=["West",5]'` |
|
|
82
|
+
| List tables | `xlsx_edit.py f.xlsx --list-tables` |
|
|
83
|
+
| Defined names | `--define-name "Rates='Data'!$B$2:$B$9"` / `--delete-name Rates` / `xlsx_read.py f.xlsx --names` |
|
|
84
|
+
| Hyperlink | `--hyperlink "A1=https://example.com|Docs"` |
|
|
85
|
+
| Cell note | `--note "B2=Check this|Reviewer"`; read via `xlsx_read.py f.xlsx --notes` |
|
|
86
|
+
| Protect sheet (see Pitfalls) | `--protect your-password --unlock B2:B9` |
|
|
87
|
+
| Recalculate via LibreOffice | `xlsx_recalc.py f.xlsx` |
|
|
88
|
+
| Copy / rename sheet | `--copy-sheet Src:New --rename-sheet Old:New` |
|
|
89
|
+
| Force recalc on open | `xlsx_edit.py f.xlsx --recalc` |
|
|
90
|
+
| CSV -> styled xlsx | `csv_to_xlsx.py in.csv out.xlsx` |
|
|
91
|
+
| xlsx -> CSV | `xlsx_to_csv.py f.xlsx out.csv --encoding utf-8` |
|
|
92
|
+
|
|
93
|
+
## Procedure
|
|
94
|
+
|
|
95
|
+
1. **Create**: write a JSON spec (schema documented in
|
|
96
|
+
`xlsx_create.py --help` and its docstring). Each sheet supports
|
|
97
|
+
`rows` (scalars or styled cell objects), sparse `cells` overrides,
|
|
98
|
+
`column_widths`, `row_heights`, `merges`, `freeze_panes`,
|
|
99
|
+
`autofilter`, `conditional_formats` (cell_is rules and color
|
|
100
|
+
scales), `charts` (bar/line/pie from cell ranges),
|
|
101
|
+
`validations` (list dropdowns), `tables` (native Excel tables with
|
|
102
|
+
a style name), and `protection`. Workbook-level `defined_names`
|
|
103
|
+
maps names to refs. Cell objects also take `hyperlink` and `note`.
|
|
104
|
+
Typed values: JSON numbers/bools
|
|
105
|
+
pass through; dates use `{"value": "2026-01-31", "type": "date"}`.
|
|
106
|
+
Number formats are Excel format strings: currency `"$#,##0.00"`,
|
|
107
|
+
percent `"0.0%"`, date `"yyyy-mm-dd"`.
|
|
108
|
+
2. **Formulas**: set with `"formula": "SUM(B2:B9)"` in the spec or
|
|
109
|
+
`--set "C1==SUM(A:A)"` in the editor. When writing formulas, add
|
|
110
|
+
`"full_calc_on_load": true` (spec) or `--recalc` (editor); this sets
|
|
111
|
+
the workbook's `fullCalcOnLoad` flag so Excel/LibreOffice recompute
|
|
112
|
+
everything on open. openpyxl itself NEVER evaluates formulas.
|
|
113
|
+
3. **Read**: `--sheets` for inventory (names, dimensions, merged
|
|
114
|
+
ranges, chart count, tables, protection, defined names),
|
|
115
|
+
`--json`/`--csv` for data, `--formulas` to
|
|
116
|
+
pair each formula string with its cached result, `--notes` for
|
|
117
|
+
cell comments, `--names` for defined names. Cached results
|
|
118
|
+
exist only if the file was last saved by a real spreadsheet app;
|
|
119
|
+
files fresh from openpyxl return `null` there. To materialize
|
|
120
|
+
results headlessly run `xlsx_recalc.py file.xlsx` (uses
|
|
121
|
+
LibreOffice; prints `{"recalculated": false, ...}` and exits 0
|
|
122
|
+
when `soffice` is absent), then reload with `--data-only`.
|
|
123
|
+
4. **Edit**: `xlsx_edit.py` applies renames/copies first, then
|
|
124
|
+
structural row/column changes, then `--set`/`--append`. It edits in
|
|
125
|
+
place unless `--out` is given — copy the file first if you need the
|
|
126
|
+
original.
|
|
127
|
+
5. **Restructure**: for insert/delete on sheets that have formulas,
|
|
128
|
+
merges, tables, or filters, use `xlsx_restructure.py` instead of
|
|
129
|
+
`xlsx_edit.py`. It rewrites formula references on ALL sheets
|
|
130
|
+
(absolute `$` refs, ranges, cross-sheet refs), shifts merges,
|
|
131
|
+
autofilter, freeze panes, validation and conditional-format
|
|
132
|
+
ranges, table refs, defined names, and row/column dimensions, then
|
|
133
|
+
prints a JSON report including a `not_shifted` list. Rules and
|
|
134
|
+
limits: `references/restructuring.md`.
|
|
135
|
+
6. **CSV interop**: `csv_to_xlsx.py` infers int/float/bool/ISO-date
|
|
136
|
+
per cell and styles the header row; `xlsx_to_csv.py` writes ISO
|
|
137
|
+
dates and blank strings for empty cells. Both default to UTF-8 and
|
|
138
|
+
accept `--encoding` (e.g. `utf-8-sig` for Excel-friendly BOM,
|
|
139
|
+
`cp1252` for legacy Windows exports).
|
|
140
|
+
|
|
141
|
+
## Converting to PDF
|
|
142
|
+
|
|
143
|
+
LibreOffice converts headlessly (also works for CSV export of a single
|
|
144
|
+
sheet):
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
soffice --headless --convert-to pdf report.xlsx --outdir out/
|
|
148
|
+
soffice --headless --convert-to csv report.xlsx --outdir out/ # 1st sheet only
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Only the first sheet lands in a CSV; for other sheets use
|
|
152
|
+
`xlsx_to_csv.py --sheet NAME`. If `soffice` is missing, install
|
|
153
|
+
LibreOffice or hand the file to the user unconverted.
|
|
154
|
+
|
|
155
|
+
## Pitfalls
|
|
156
|
+
|
|
157
|
+
- **openpyxl does not calculate.** Formula results are available only
|
|
158
|
+
via `load_workbook(path, data_only=True)` and only when the file was
|
|
159
|
+
previously saved by Excel/LibreOffice. Otherwise you get `None`.
|
|
160
|
+
- **`xlsx_edit.py` insert/delete does not shift references** (raw
|
|
161
|
+
openpyxl behavior). Use `xlsx_restructure.py`, which does — but even
|
|
162
|
+
it cannot move chart anchors, images, or conditional-format RULE
|
|
163
|
+
formulas; read its JSON report's `not_shifted` list and
|
|
164
|
+
`references/restructuring.md`.
|
|
165
|
+
- **Sheet protection is NOT security.** `--protect` sets the standard
|
|
166
|
+
xlsx sheet-protection hash: it signals "don't edit this" to
|
|
167
|
+
well-behaved apps and nothing more. Anyone can strip it by editing
|
|
168
|
+
the zip's XML or unchecking it in LibreOffice. Never rely on it for
|
|
169
|
+
confidentiality or integrity; it does not encrypt anything.
|
|
170
|
+
- **`data_only=True` then save** silently discards all formulas
|
|
171
|
+
(cached values replace them). Never save a workbook loaded that way
|
|
172
|
+
unless that is the goal.
|
|
173
|
+
- **Loading strips charts/images**: openpyxl does not round-trip
|
|
174
|
+
charts, so editing a charted workbook and saving drops the charts.
|
|
175
|
+
Re-add charts after editing, or avoid re-saving charted files.
|
|
176
|
+
- **CSV locale traps**: always pass explicit encodings (the scripts
|
|
177
|
+
already do) and remember European CSVs often use `;` delimiters and
|
|
178
|
+
decimal commas — use `--delimiter ';'` and expect strings like
|
|
179
|
+
`"12,5"` to stay strings.
|
|
180
|
+
- **Dates are datetimes**: Excel stores dates as serial numbers;
|
|
181
|
+
openpyxl returns `datetime`/`date` objects. Dumps here emit ISO
|
|
182
|
+
strings.
|
|
183
|
+
- Sheet names are capped at 31 chars and reject `[ ] : * ? / \`.
|
|
184
|
+
|
|
185
|
+
## Verification
|
|
186
|
+
|
|
187
|
+
- After creating: `xlsx_read.py out.xlsx --sheets` and confirm sheet
|
|
188
|
+
names, dimensions, merged ranges, and chart counts match intent.
|
|
189
|
+
- Dump data with `--json` and compare against the source values.
|
|
190
|
+
- After edits: re-dump the touched range; if formulas were written,
|
|
191
|
+
confirm `--formulas` lists them and that `--recalc` was applied.
|
|
192
|
+
- After `xlsx_restructure.py`: read its JSON report, then re-run
|
|
193
|
+
`--formulas` and `--sheets` to confirm references and ranges landed
|
|
194
|
+
where expected.
|
|
195
|
+
- For a full visual check, open in LibreOffice:
|
|
196
|
+
`soffice --headless --convert-to pdf out.xlsx` and inspect the PDF.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nous Research
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nous Research
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Reference-aware restructuring (xlsx_restructure.py)
|
|
2
|
+
|
|
3
|
+
`scripts/xlsx_restructure.py` performs one row/column insert or delete
|
|
4
|
+
and rewrites supported references to the moved cells. This document
|
|
5
|
+
gives the exact rewrite rules and honest limits.
|
|
6
|
+
|
|
7
|
+
## What gets rewritten
|
|
8
|
+
|
|
9
|
+
| Artifact | Scope | Behavior |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| Formula references | ALL sheets | A1 refs into the edited sheet are shifted; refs into a fully deleted region become `#REF!` |
|
|
12
|
+
| Merged-cell ranges | edited sheet | shifted; expanded when they span the insertion point; dropped (reported `to: null`) when fully deleted |
|
|
13
|
+
| Autofilter ref | edited sheet | shifted/expanded like a range |
|
|
14
|
+
| Freeze panes | edited sheet | anchor cell shifted (never below row/col of the pane's own minimum) |
|
|
15
|
+
| Data validations | edited sheet | each range in the sqref shifted; deleted ranges removed |
|
|
16
|
+
| Conditional formats | edited sheet | applied range (sqref) shifted |
|
|
17
|
+
| Native tables | edited sheet | ref/filter synchronized; column insertion adds matching tableColumns/header names; partial column deletion and header-only deletion refused before save |
|
|
18
|
+
| Defined names | workbook and sheet scope | supported `attr_text` refs into the edited sheet rewritten |
|
|
19
|
+
| Row heights / column widths | edited sheet | dimension keys re-indexed |
|
|
20
|
+
|
|
21
|
+
## Reference grammar handled
|
|
22
|
+
|
|
23
|
+
- Relative and absolute coordinates in any mix: `B2`, `$B2`, `B$2`,
|
|
24
|
+
`$B$2` — the `$` flags are preserved through the shift.
|
|
25
|
+
- Ranges `B2:D9`, including partial-absolute endpoints.
|
|
26
|
+
- Cross-sheet refs: `Data!B2`, `'My Sheet'!$A$1:$C$9` (quoted names may
|
|
27
|
+
contain doubled quotes `''`). Only refs whose sheet qualifier matches
|
|
28
|
+
the edited sheet are touched; unqualified refs are interpreted
|
|
29
|
+
relative to the formula's own sheet.
|
|
30
|
+
- String literals inside formulas (`"See B2"`) are never rewritten.
|
|
31
|
+
- Function names that look like cells (`LOG10(...)`) are not touched
|
|
32
|
+
(a reference is never followed by `(`).
|
|
33
|
+
- Whole-row/column refs (`B:B`, `2:2`) shift with the edited axis, preserving
|
|
34
|
+
absolute flags. External-workbook and structured references are not rewritten.
|
|
35
|
+
Three-dimensional sheet spans fail before save instead of being guessed.
|
|
36
|
+
|
|
37
|
+
## Shift semantics
|
|
38
|
+
|
|
39
|
+
Insert of N at index i: every coordinate >= i moves +N; range endpoints
|
|
40
|
+
move independently, so a range spanning i grows by N.
|
|
41
|
+
|
|
42
|
+
Delete of N at index i: coordinates before i are unchanged; coordinates
|
|
43
|
+
past the deleted block move -N; a single cell inside the block becomes
|
|
44
|
+
`#REF!`; a RANGE partially covering the block is clamped (Excel does the
|
|
45
|
+
same); a range entirely inside the block becomes `#REF!` (formulas) or
|
|
46
|
+
is removed (merges/validations).
|
|
47
|
+
|
|
48
|
+
## What it CANNOT shift (honest limits)
|
|
49
|
+
|
|
50
|
+
- **Chart anchors and plotted ranges** — openpyxl chart objects are not
|
|
51
|
+
reliably round-tripped; anchors stay where they were. Re-create
|
|
52
|
+
charts after restructuring if their data moved.
|
|
53
|
+
- **Images / drawings** — same reason.
|
|
54
|
+
- **Conditional-format RULE formulas** — the applied range (sqref) is
|
|
55
|
+
shifted, but formulas inside `cell_is`/`expression` rules (e.g.
|
|
56
|
+
`$B1>100`) are left as-is. Review them if they reference moved cells.
|
|
57
|
+
- **Validation formulas and table calculated-column formulas** require manual
|
|
58
|
+
review or explicit reconstruction; their ranges alone are updated.
|
|
59
|
+
- **Sheet-local defined names** and names using R1C1 or union/
|
|
60
|
+
intersection operators are rewritten only if they parse as plain A1
|
|
61
|
+
refs; anything else passes through untouched.
|
|
62
|
+
- **Structured table references** in formulas (`Table1[Sales]`) don't
|
|
63
|
+
need shifting (they follow the table), and are left alone.
|
|
64
|
+
|
|
65
|
+
Every run prints a JSON report listing exactly which formulas, merges,
|
|
66
|
+
tables, names, and ranges were changed, plus a fixed `not_shifted` list
|
|
67
|
+
of the above limits — inspect it after any structural edit.
|
|
68
|
+
|
|
69
|
+
## One op per invocation
|
|
70
|
+
|
|
71
|
+
The CLI takes exactly one of `--insert-rows/--delete-rows/
|
|
72
|
+
--insert-cols/--delete-cols` (as `IDX[:N]`; columns accept letters).
|
|
73
|
+
For multiple operations run it repeatedly — ordering compound shifts in
|
|
74
|
+
one pass is where spreadsheet tools historically corrupt references.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Convert a CSV file to a styled .xlsx workbook with type inference.
|
|
3
|
+
|
|
4
|
+
Type inference per cell (disable with --no-infer):
|
|
5
|
+
int, float, bool ("true"/"false", case-insensitive), ISO date
|
|
6
|
+
(YYYY-MM-DD) and ISO datetime; everything else stays a string.
|
|
7
|
+
|
|
8
|
+
Styling applied by default (disable with --plain):
|
|
9
|
+
bold header row with a light fill, frozen top row, autofilter over the
|
|
10
|
+
data range, and column widths sized to the longest cell (capped at 60).
|
|
11
|
+
|
|
12
|
+
Usage:
|
|
13
|
+
csv_to_xlsx.py data.csv out.xlsx
|
|
14
|
+
csv_to_xlsx.py data.csv out.xlsx --sheet-name Import --encoding cp1252
|
|
15
|
+
csv_to_xlsx.py data.csv out.xlsx --delimiter ';' --no-infer
|
|
16
|
+
"""
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import argparse
|
|
20
|
+
import csv
|
|
21
|
+
import json
|
|
22
|
+
import sys
|
|
23
|
+
from datetime import date, datetime
|
|
24
|
+
|
|
25
|
+
from openpyxl import Workbook
|
|
26
|
+
from openpyxl.styles import Font, PatternFill
|
|
27
|
+
from openpyxl.utils import get_column_letter
|
|
28
|
+
|
|
29
|
+
MAX_COL_WIDTH = 60
|
|
30
|
+
COL_PADDING = 2
|
|
31
|
+
DEFAULT_COL_WIDTH = 8
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def infer(text):
|
|
35
|
+
if text == "":
|
|
36
|
+
return None
|
|
37
|
+
low = text.lower()
|
|
38
|
+
if low in ("true", "false"):
|
|
39
|
+
return low == "true"
|
|
40
|
+
for caster in (int, float):
|
|
41
|
+
try:
|
|
42
|
+
return caster(text)
|
|
43
|
+
except ValueError:
|
|
44
|
+
pass
|
|
45
|
+
for parser in (date.fromisoformat, datetime.fromisoformat):
|
|
46
|
+
try:
|
|
47
|
+
return parser(text)
|
|
48
|
+
except ValueError:
|
|
49
|
+
pass
|
|
50
|
+
return text
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def main(argv=None):
|
|
54
|
+
ap = argparse.ArgumentParser(description="CSV -> styled .xlsx converter.")
|
|
55
|
+
ap.add_argument("csv_file", help="input CSV path")
|
|
56
|
+
ap.add_argument("output", help="output .xlsx path")
|
|
57
|
+
ap.add_argument("--sheet-name", default="Sheet1")
|
|
58
|
+
ap.add_argument("--encoding", default="utf-8",
|
|
59
|
+
help="CSV file encoding (default utf-8)")
|
|
60
|
+
ap.add_argument("--delimiter", default=",")
|
|
61
|
+
ap.add_argument("--no-infer", action="store_true",
|
|
62
|
+
help="keep every cell as a string")
|
|
63
|
+
ap.add_argument("--plain", action="store_true",
|
|
64
|
+
help="skip header styling / freeze / autofilter")
|
|
65
|
+
args = ap.parse_args(argv)
|
|
66
|
+
|
|
67
|
+
with open(args.csv_file, newline="", encoding=args.encoding) as fh:
|
|
68
|
+
rows = list(csv.reader(fh, delimiter=args.delimiter))
|
|
69
|
+
|
|
70
|
+
wb = Workbook()
|
|
71
|
+
ws = wb.active
|
|
72
|
+
ws.title = args.sheet_name
|
|
73
|
+
for i, row in enumerate(rows):
|
|
74
|
+
if args.no_infer or i == 0:
|
|
75
|
+
ws.append(row)
|
|
76
|
+
else:
|
|
77
|
+
ws.append([infer(cell) for cell in row])
|
|
78
|
+
# CSV is data, never executable formula input, including header cells.
|
|
79
|
+
for cell in ws[i + 1]:
|
|
80
|
+
if cell.data_type == 'f':
|
|
81
|
+
cell.data_type = 's'
|
|
82
|
+
|
|
83
|
+
if rows and not args.plain:
|
|
84
|
+
header_font = Font(bold=True)
|
|
85
|
+
header_fill = PatternFill("solid", fgColor="DDEBF7")
|
|
86
|
+
for cell in ws[1]:
|
|
87
|
+
cell.font = header_font
|
|
88
|
+
cell.fill = header_fill
|
|
89
|
+
ws.freeze_panes = "A2"
|
|
90
|
+
ws.auto_filter.ref = ws.dimensions
|
|
91
|
+
for col_idx in range(1, ws.max_column + 1):
|
|
92
|
+
longest = max((len(str(r[col_idx - 1])) for r in rows
|
|
93
|
+
if len(r) >= col_idx), default=DEFAULT_COL_WIDTH)
|
|
94
|
+
ws.column_dimensions[get_column_letter(col_idx)].width = \
|
|
95
|
+
min(longest + COL_PADDING, MAX_COL_WIDTH)
|
|
96
|
+
|
|
97
|
+
wb.save(args.output)
|
|
98
|
+
print(json.dumps({"ok": True, "output": args.output,
|
|
99
|
+
"rows": len(rows)}, ensure_ascii=False))
|
|
100
|
+
return 0
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
if __name__ == "__main__":
|
|
104
|
+
try:
|
|
105
|
+
sys.exit(main())
|
|
106
|
+
except Exception as exc: # noqa: BLE001
|
|
107
|
+
print(json.dumps({"ok": False, "error": str(exc)}), file=sys.stderr)
|
|
108
|
+
sys.exit(1)
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Create an .xlsx workbook from a JSON spec.
|
|
3
|
+
|
|
4
|
+
Spec (JSON object):
|
|
5
|
+
{
|
|
6
|
+
"full_calc_on_load": true, # force recalculation on open (optional)
|
|
7
|
+
"defined_names": {"Rates": "'Data'!$B$2:$B$4"}, # workbook scope
|
|
8
|
+
"sheets": [
|
|
9
|
+
{
|
|
10
|
+
"name": "Data",
|
|
11
|
+
"rows": [["Header", 1, true], ...], # scalars or cell objects (see below)
|
|
12
|
+
"cells": {"A1": {"value": 5, "format": "0.00%"}}, # sparse overrides
|
|
13
|
+
"column_widths": {"A": 22, "B": 12},
|
|
14
|
+
"row_heights": {"1": 24},
|
|
15
|
+
"merges": ["A1:C1"],
|
|
16
|
+
"freeze_panes": "A2",
|
|
17
|
+
"autofilter": "A1:C10",
|
|
18
|
+
"conditional_formats": [
|
|
19
|
+
{"range": "B2:B9", "type": "cell_is", "operator": "greaterThan",
|
|
20
|
+
"formula": ["100"], "fill": "FFC7CE"},
|
|
21
|
+
{"range": "C2:C9", "type": "color_scale"}
|
|
22
|
+
],
|
|
23
|
+
"charts": [
|
|
24
|
+
{"type": "bar", "title": "Sales", "anchor": "F2",
|
|
25
|
+
"data": "B1:B5", "categories": "A2:A5"}
|
|
26
|
+
],
|
|
27
|
+
"validations": [
|
|
28
|
+
{"range": "D2:D9", "type": "list", "formula1": "\"Yes,No,Maybe\""}
|
|
29
|
+
],
|
|
30
|
+
"tables": [
|
|
31
|
+
{"name": "Sales", "range": "A1:C4",
|
|
32
|
+
"style": "TableStyleMedium9"} # native Excel table
|
|
33
|
+
],
|
|
34
|
+
"protection": {"password": "your-password", # NOT security --
|
|
35
|
+
"unlock": ["B2:B9"]} # see SKILL.md Pitfalls
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
Cell object keys (all optional except value/formula):
|
|
41
|
+
value scalar; JSON true/false -> bool, numbers stay numeric
|
|
42
|
+
type "date" or "datetime" -> value parsed from ISO string
|
|
43
|
+
formula e.g. "=SUM(A2:A9)" (leading '=' optional)
|
|
44
|
+
hyperlink URL; value becomes the display text
|
|
45
|
+
note cell note text (or {"text": ..., "author": ...})
|
|
46
|
+
format Excel number format, e.g. "$#,##0.00", "0.0%", "yyyy-mm-dd"
|
|
47
|
+
bold, italic booleans
|
|
48
|
+
font_size points
|
|
49
|
+
font_color hex RGB like "FF0000"
|
|
50
|
+
fill solid fill hex RGB like "DDEBF7"
|
|
51
|
+
border "thin" | "medium" | "thick" (all four sides)
|
|
52
|
+
align "left" | "center" | "right"
|
|
53
|
+
valign "top" | "center" | "bottom"
|
|
54
|
+
wrap boolean (wrap text)
|
|
55
|
+
|
|
56
|
+
Usage:
|
|
57
|
+
xlsx_create.py spec.json out.xlsx
|
|
58
|
+
xlsx_create.py - out.xlsx (spec on stdin)
|
|
59
|
+
|
|
60
|
+
Prints a JSON summary to stdout; exits non-zero on failure.
|
|
61
|
+
"""
|
|
62
|
+
from __future__ import annotations
|
|
63
|
+
|
|
64
|
+
import argparse
|
|
65
|
+
import json
|
|
66
|
+
import sys
|
|
67
|
+
from datetime import date, datetime
|
|
68
|
+
|
|
69
|
+
from openpyxl import Workbook
|
|
70
|
+
from openpyxl.chart import BarChart, LineChart, PieChart, Reference
|
|
71
|
+
from openpyxl.comments import Comment
|
|
72
|
+
from openpyxl.formatting.rule import CellIsRule, ColorScaleRule
|
|
73
|
+
from openpyxl.styles import (Alignment, Border, Font, PatternFill,
|
|
74
|
+
Protection, Side)
|
|
75
|
+
from openpyxl.utils import column_index_from_string, range_boundaries
|
|
76
|
+
from openpyxl.workbook.defined_name import DefinedName
|
|
77
|
+
from openpyxl.worksheet.datavalidation import DataValidation
|
|
78
|
+
from openpyxl.worksheet.table import Table, TableStyleInfo
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def parse_typed(value, type_hint=None):
|
|
82
|
+
if type_hint == "date" and isinstance(value, str):
|
|
83
|
+
return date.fromisoformat(value)
|
|
84
|
+
if type_hint == "datetime" and isinstance(value, str):
|
|
85
|
+
return datetime.fromisoformat(value)
|
|
86
|
+
return value
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def apply_cell(ws, coord, spec):
|
|
90
|
+
cell = ws[coord]
|
|
91
|
+
if isinstance(spec, dict):
|
|
92
|
+
if "formula" in spec:
|
|
93
|
+
f = spec["formula"]
|
|
94
|
+
cell.value = f if f.startswith("=") else "=" + f
|
|
95
|
+
elif "value" in spec:
|
|
96
|
+
cell.value = parse_typed(spec["value"], spec.get("type"))
|
|
97
|
+
if "hyperlink" in spec:
|
|
98
|
+
cell.hyperlink = spec["hyperlink"]
|
|
99
|
+
if cell.value is None:
|
|
100
|
+
cell.value = spec["hyperlink"]
|
|
101
|
+
cell.style = "Hyperlink"
|
|
102
|
+
if "note" in spec:
|
|
103
|
+
note = spec["note"]
|
|
104
|
+
if isinstance(note, dict):
|
|
105
|
+
cell.comment = Comment(note.get("text", ""),
|
|
106
|
+
note.get("author", "xlsx-skill"))
|
|
107
|
+
else:
|
|
108
|
+
cell.comment = Comment(str(note), "xlsx-skill")
|
|
109
|
+
if "format" in spec:
|
|
110
|
+
cell.number_format = spec["format"]
|
|
111
|
+
font_kw = {}
|
|
112
|
+
if spec.get("bold"):
|
|
113
|
+
font_kw["bold"] = True
|
|
114
|
+
if spec.get("italic"):
|
|
115
|
+
font_kw["italic"] = True
|
|
116
|
+
if "font_size" in spec:
|
|
117
|
+
font_kw["size"] = spec["font_size"]
|
|
118
|
+
if "font_color" in spec:
|
|
119
|
+
font_kw["color"] = spec["font_color"]
|
|
120
|
+
if font_kw:
|
|
121
|
+
cell.font = Font(**font_kw)
|
|
122
|
+
if "fill" in spec:
|
|
123
|
+
cell.fill = PatternFill("solid", fgColor=spec["fill"])
|
|
124
|
+
if "border" in spec:
|
|
125
|
+
side = Side(style=spec["border"])
|
|
126
|
+
cell.border = Border(left=side, right=side, top=side, bottom=side)
|
|
127
|
+
align_kw = {}
|
|
128
|
+
if "align" in spec:
|
|
129
|
+
align_kw["horizontal"] = spec["align"]
|
|
130
|
+
if "valign" in spec:
|
|
131
|
+
align_kw["vertical"] = spec["valign"]
|
|
132
|
+
if spec.get("wrap"):
|
|
133
|
+
align_kw["wrap_text"] = True
|
|
134
|
+
if align_kw:
|
|
135
|
+
cell.alignment = Alignment(**align_kw)
|
|
136
|
+
else:
|
|
137
|
+
cell.value = spec
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def ref_from_range(ws, rng):
|
|
141
|
+
min_col, min_row, max_col, max_row = range_boundaries(rng)
|
|
142
|
+
return Reference(ws, min_col=min_col, min_row=min_row,
|
|
143
|
+
max_col=max_col, max_row=max_row)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def add_chart(ws, spec):
|
|
147
|
+
kind = spec.get("type", "bar")
|
|
148
|
+
chart = {"bar": BarChart, "line": LineChart, "pie": PieChart}[kind]()
|
|
149
|
+
if "title" in spec:
|
|
150
|
+
chart.title = spec["title"]
|
|
151
|
+
data = ref_from_range(ws, spec["data"])
|
|
152
|
+
chart.add_data(data, titles_from_data=spec.get("titles_from_data", True))
|
|
153
|
+
if "categories" in spec:
|
|
154
|
+
chart.set_categories(ref_from_range(ws, spec["categories"]))
|
|
155
|
+
ws.add_chart(chart, spec.get("anchor", "H2"))
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def add_conditional(ws, spec):
|
|
159
|
+
rng = spec["range"]
|
|
160
|
+
kind = spec.get("type", "cell_is")
|
|
161
|
+
if kind == "color_scale":
|
|
162
|
+
rule = ColorScaleRule(
|
|
163
|
+
start_type="min", start_color=spec.get("start_color", "FFF8696B"),
|
|
164
|
+
end_type="max", end_color=spec.get("end_color", "FF63BE7B"))
|
|
165
|
+
else:
|
|
166
|
+
fill = PatternFill("solid", fgColor=spec.get("fill", "FFC7CE"))
|
|
167
|
+
rule = CellIsRule(operator=spec.get("operator", "greaterThan"),
|
|
168
|
+
formula=spec.get("formula", ["0"]), fill=fill)
|
|
169
|
+
ws.conditional_formatting.add(rng, rule)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def build_sheet(ws, spec):
|
|
173
|
+
for row in spec.get("rows", []):
|
|
174
|
+
values, styled = [], []
|
|
175
|
+
for item in row:
|
|
176
|
+
if isinstance(item, dict):
|
|
177
|
+
values.append(None)
|
|
178
|
+
styled.append(item)
|
|
179
|
+
else:
|
|
180
|
+
values.append(item)
|
|
181
|
+
styled.append(None)
|
|
182
|
+
ws.append(values)
|
|
183
|
+
r = ws.max_row
|
|
184
|
+
for idx, item in enumerate(styled, start=1):
|
|
185
|
+
if item is not None:
|
|
186
|
+
apply_cell(ws, ws.cell(row=r, column=idx).coordinate, item)
|
|
187
|
+
for coord, cell_spec in spec.get("cells", {}).items():
|
|
188
|
+
apply_cell(ws, coord, cell_spec)
|
|
189
|
+
for col, width in spec.get("column_widths", {}).items():
|
|
190
|
+
ws.column_dimensions[col].width = width
|
|
191
|
+
for row, height in spec.get("row_heights", {}).items():
|
|
192
|
+
ws.row_dimensions[int(row)].height = height
|
|
193
|
+
for rng in spec.get("merges", []):
|
|
194
|
+
ws.merge_cells(rng)
|
|
195
|
+
if spec.get("freeze_panes"):
|
|
196
|
+
ws.freeze_panes = spec["freeze_panes"]
|
|
197
|
+
if spec.get("autofilter"):
|
|
198
|
+
ws.auto_filter.ref = spec["autofilter"]
|
|
199
|
+
for cf in spec.get("conditional_formats", []):
|
|
200
|
+
add_conditional(ws, cf)
|
|
201
|
+
for ch in spec.get("charts", []):
|
|
202
|
+
add_chart(ws, ch)
|
|
203
|
+
for dv_spec in spec.get("validations", []):
|
|
204
|
+
dv = DataValidation(type=dv_spec.get("type", "list"),
|
|
205
|
+
formula1=dv_spec["formula1"],
|
|
206
|
+
allow_blank=dv_spec.get("allow_blank", True))
|
|
207
|
+
dv.add(dv_spec["range"])
|
|
208
|
+
ws.add_data_validation(dv)
|
|
209
|
+
for t_spec in spec.get("tables", []):
|
|
210
|
+
table = Table(displayName=t_spec["name"], ref=t_spec["range"])
|
|
211
|
+
table.tableStyleInfo = TableStyleInfo(
|
|
212
|
+
name=t_spec.get("style", "TableStyleMedium9"),
|
|
213
|
+
showRowStripes=t_spec.get("row_stripes", True),
|
|
214
|
+
showColumnStripes=t_spec.get("column_stripes", False))
|
|
215
|
+
ws.add_table(table)
|
|
216
|
+
prot = spec.get("protection")
|
|
217
|
+
if prot:
|
|
218
|
+
for rng in prot.get("unlock", []):
|
|
219
|
+
for row in ws[rng]:
|
|
220
|
+
for cell in row:
|
|
221
|
+
cell.protection = Protection(locked=False)
|
|
222
|
+
if prot.get("password"):
|
|
223
|
+
ws.protection.password = prot["password"]
|
|
224
|
+
ws.protection.sheet = True
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def main(argv=None):
|
|
228
|
+
ap = argparse.ArgumentParser(description="Create .xlsx from a JSON spec.")
|
|
229
|
+
ap.add_argument("spec", help="path to JSON spec, or '-' for stdin")
|
|
230
|
+
ap.add_argument("output", help="output .xlsx path")
|
|
231
|
+
args = ap.parse_args(argv)
|
|
232
|
+
|
|
233
|
+
if args.spec == "-":
|
|
234
|
+
spec = json.load(sys.stdin)
|
|
235
|
+
else:
|
|
236
|
+
with open(args.spec, encoding="utf-8") as fh:
|
|
237
|
+
spec = json.load(fh)
|
|
238
|
+
|
|
239
|
+
wb = Workbook()
|
|
240
|
+
wb.remove(wb.active)
|
|
241
|
+
for sheet_spec in spec.get("sheets", []):
|
|
242
|
+
ws = wb.create_sheet(sheet_spec.get("name", "Sheet1"))
|
|
243
|
+
build_sheet(ws, sheet_spec)
|
|
244
|
+
for name, ref in spec.get("defined_names", {}).items():
|
|
245
|
+
wb.defined_names[name] = DefinedName(name, attr_text=ref)
|
|
246
|
+
if spec.get("full_calc_on_load"):
|
|
247
|
+
wb.calculation.fullCalcOnLoad = True
|
|
248
|
+
wb.save(args.output)
|
|
249
|
+
print(json.dumps({"ok": True, "output": args.output,
|
|
250
|
+
"sheets": wb.sheetnames}, ensure_ascii=False))
|
|
251
|
+
return 0
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
if __name__ == "__main__":
|
|
255
|
+
try:
|
|
256
|
+
sys.exit(main())
|
|
257
|
+
except Exception as exc: # noqa: BLE001
|
|
258
|
+
print(json.dumps({"ok": False, "error": str(exc)}), file=sys.stderr)
|
|
259
|
+
sys.exit(1)
|