@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.
Files changed (563) hide show
  1. package/CHANGELOG.md +574 -0
  2. package/apc/skills/releasing-test/SKILL.md +9 -0
  3. package/built-in-skills/agent-coordination/SKILL.md +21 -4
  4. package/built-in-skills/agent-meta/SKILL.md +11 -0
  5. package/built-in-skills/assets/SKILL.md +1 -1
  6. package/built-in-skills/canvas-design/SKILL.md +3 -3
  7. package/built-in-skills/canvas-design/canvas-fonts/IBMPlexSerif-OFL.txt +93 -0
  8. package/built-in-skills/canvas-design/canvas-fonts/InstrumentSerif-OFL.txt +93 -0
  9. package/built-in-skills/canvas-design/canvas-fonts/LICENSE-SOURCES.md +16 -0
  10. package/built-in-skills/claim-agent-ownership/SKILL.md +7 -3
  11. package/built-in-skills/claude-api/SKILL.md +1 -1
  12. package/built-in-skills/claude-api/python/claude-api/README.md +2 -2
  13. package/built-in-skills/claude-api/python/claude-api/tool-use.md +9 -5
  14. package/built-in-skills/claude-api/python/managed-agents/README.md +11 -1
  15. package/built-in-skills/claude-api/shared/error-codes.md +4 -4
  16. package/built-in-skills/claude-api/shared/managed-agents-client-patterns.md +4 -2
  17. package/built-in-skills/claude-api/shared/managed-agents-core.md +1 -2
  18. package/built-in-skills/claude-api/shared/managed-agents-events.md +41 -22
  19. package/built-in-skills/claude-api/shared/managed-agents-multiagent.md +5 -3
  20. package/built-in-skills/claude-api/shared/managed-agents-self-hosted-sandboxes.md +1 -1
  21. package/built-in-skills/claude-api/shared/managed-agents-tools.md +2 -3
  22. package/built-in-skills/claude-api/shared/model-migration.md +3 -3
  23. package/built-in-skills/claude-api/shared/models.md +1 -1
  24. package/built-in-skills/claude-api/typescript/claude-api/batches.md +1 -1
  25. package/built-in-skills/claude-api/typescript/claude-api/files-api.md +3 -1
  26. package/built-in-skills/claude-api/typescript/claude-api/tool-use.md +8 -2
  27. package/built-in-skills/claude-api/typescript/managed-agents/README.md +8 -2
  28. package/built-in-skills/codebase-design/SKILL.md +15 -1
  29. package/built-in-skills/codebase-design/references/requesting-code-review/GUIDE.md +291 -0
  30. package/built-in-skills/codebase-design/references/requesting-code-review/LICENSE +21 -0
  31. package/built-in-skills/codebase-design/references/requesting-code-review/LICENSE.superpowers +21 -0
  32. package/built-in-skills/codebase-design/references/requesting-code-review/NOTICE.md +37 -0
  33. package/built-in-skills/codebase-design/references/sdlc-review/GUIDE.md +130 -0
  34. package/built-in-skills/codebase-design/references/sdlc-review/LICENSE +21 -0
  35. package/built-in-skills/codebase-design/references/sdlc-review/NOTICE.md +17 -0
  36. package/built-in-skills/codebase-design/references/simplify-code/GUIDE.md +269 -0
  37. package/built-in-skills/codebase-design/references/simplify-code/LICENSE +21 -0
  38. package/built-in-skills/codebase-design/references/simplify-code/NOTICE.md +37 -0
  39. package/built-in-skills/competitor-intelligence/LICENSE +21 -0
  40. package/built-in-skills/competitor-intelligence/NOTICE.md +6 -0
  41. package/built-in-skills/competitor-intelligence/SKILL.md +125 -0
  42. package/built-in-skills/competitor-intelligence/scripts/watch_state.py +160 -0
  43. package/built-in-skills/conversation-compaction/SKILL.md +3 -0
  44. package/built-in-skills/council-creator/SKILL.md +4 -3
  45. package/built-in-skills/diagnosing-bugs/SKILL.md +12 -0
  46. package/built-in-skills/diagnosing-bugs/references/desktop-dom/GUIDE.md +64 -0
  47. package/built-in-skills/diagnosing-bugs/references/desktop-dom/LICENSE +21 -0
  48. package/built-in-skills/diagnosing-bugs/references/desktop-dom/NOTICE.md +17 -0
  49. package/built-in-skills/diagnosing-bugs/references/systematic-debugging/GUIDE.md +410 -0
  50. package/built-in-skills/diagnosing-bugs/references/systematic-debugging/LICENSE +21 -0
  51. package/built-in-skills/diagnosing-bugs/references/systematic-debugging/LICENSE.superpowers +21 -0
  52. package/built-in-skills/diagnosing-bugs/references/systematic-debugging/NOTICE.md +37 -0
  53. package/built-in-skills/doc-coauthoring/SKILL.md +6 -0
  54. package/built-in-skills/doc-coauthoring/references/humanizer/GUIDE.md +647 -0
  55. package/built-in-skills/doc-coauthoring/references/humanizer/LICENSE +21 -0
  56. package/built-in-skills/doc-coauthoring/references/humanizer/LICENSE.hermes +21 -0
  57. package/built-in-skills/doc-coauthoring/references/humanizer/PROVENANCE.md +7 -0
  58. package/built-in-skills/document-actions/LICENSE +21 -0
  59. package/built-in-skills/document-actions/NOTICE.md +21 -0
  60. package/built-in-skills/document-actions/SKILL.md +46 -0
  61. package/built-in-skills/evidence-citations/LICENSE +21 -0
  62. package/built-in-skills/evidence-citations/NOTICE.md +21 -0
  63. package/built-in-skills/evidence-citations/SKILL.md +46 -0
  64. package/built-in-skills/evidence-citations/references/citation-formats.md +68 -0
  65. package/built-in-skills/evidence-citations/references/grounding-rationale.md +64 -0
  66. package/built-in-skills/evidence-citations/scripts/sources.py +720 -0
  67. package/built-in-skills/frontend-design/SKILL.md +6 -0
  68. package/built-in-skills/frontend-design/references/claude-design/GUIDE.md +650 -0
  69. package/built-in-skills/frontend-design/references/claude-design/LICENSE +21 -0
  70. package/built-in-skills/frontend-design/references/claude-design/LICENSE.hermes +21 -0
  71. package/built-in-skills/frontend-design/references/claude-design/PROVENANCE.md +7 -0
  72. package/built-in-skills/image-generate/SKILL.md +5 -0
  73. package/built-in-skills/image-generate/scripts/generate-and-deliver.mjs +24 -3
  74. package/built-in-skills/mcp-builder/reference/evaluation.md +11 -2
  75. package/built-in-skills/mcp-builder/reference/node_mcp_server.md +34 -5
  76. package/built-in-skills/mcp-builder/reference/python_mcp_server.md +6 -2
  77. package/built-in-skills/mcp-builder/scripts/connections.py +1 -1
  78. package/built-in-skills/mcp-builder/scripts/evaluation.py +52 -34
  79. package/built-in-skills/mcp-builder/scripts/requirements.txt +2 -2
  80. package/built-in-skills/meeting-actions/LICENSE +21 -0
  81. package/built-in-skills/meeting-actions/NOTICE.md +21 -0
  82. package/built-in-skills/meeting-actions/SKILL.md +48 -0
  83. package/built-in-skills/memory/SKILL.md +27 -3
  84. package/built-in-skills/memory/references/llm-wiki/GUIDE.md +468 -0
  85. package/built-in-skills/memory/references/llm-wiki/LICENSE +21 -0
  86. package/built-in-skills/memory/references/llm-wiki/NOTICE.md +4 -0
  87. package/built-in-skills/memory/references/llm-wiki/scripts/lint_wiki.py +84 -0
  88. package/built-in-skills/memory/references/llm-wiki/scripts/requirements.txt +1 -0
  89. package/built-in-skills/memory/references/llm-wiki/templates/SCHEMA.md +19 -0
  90. package/built-in-skills/memory/references/llm-wiki/templates/index.md +9 -0
  91. package/built-in-skills/memory/references/llm-wiki/templates/log.md +4 -0
  92. package/built-in-skills/memory-dream/SKILL.md +8 -15
  93. package/built-in-skills/memory-import/SKILL.md +51 -0
  94. package/built-in-skills/office-artifacts/NOTICE.md +15 -0
  95. package/built-in-skills/office-artifacts/SKILL.md +20 -0
  96. package/built-in-skills/office-artifacts/references/RESOURCE-LIMITS.md +44 -0
  97. package/built-in-skills/office-artifacts/references/docx/GUIDE.md +196 -0
  98. package/built-in-skills/office-artifacts/references/docx/LICENSE +21 -0
  99. package/built-in-skills/office-artifacts/references/docx/NOTICE.md +21 -0
  100. package/built-in-skills/office-artifacts/references/docx/references/revisions-and-comments.md +88 -0
  101. package/built-in-skills/office-artifacts/references/docx/scripts/docx_comments.py +292 -0
  102. package/built-in-skills/office-artifacts/references/docx/scripts/docx_common.py +93 -0
  103. package/built-in-skills/office-artifacts/references/docx/scripts/docx_create.py +177 -0
  104. package/built-in-skills/office-artifacts/references/docx/scripts/docx_edit.py +250 -0
  105. package/built-in-skills/office-artifacts/references/docx/scripts/docx_read.py +169 -0
  106. package/built-in-skills/office-artifacts/references/docx/scripts/docx_revisions.py +149 -0
  107. package/built-in-skills/office-artifacts/references/docx/scripts/docx_template.py +70 -0
  108. package/built-in-skills/office-artifacts/references/docx/scripts/docx_validate.py +155 -0
  109. package/built-in-skills/office-artifacts/references/docx/tests/test_docx_skill.py +525 -0
  110. package/built-in-skills/office-artifacts/references/pdf/GUIDE.md +125 -0
  111. package/built-in-skills/office-artifacts/references/pdf/LICENSE +21 -0
  112. package/built-in-skills/office-artifacts/references/pdf/NOTICE.md +21 -0
  113. package/built-in-skills/office-artifacts/references/pdf/references/forms.md +99 -0
  114. package/built-in-skills/office-artifacts/references/pdf/references/nano-pdf-editing.md +40 -0
  115. package/built-in-skills/office-artifacts/references/pdf/references/ocr-extraction.md +165 -0
  116. package/built-in-skills/office-artifacts/references/pdf/scripts/_raster.py +87 -0
  117. package/built-in-skills/office-artifacts/references/pdf/scripts/extract_marker.py +95 -0
  118. package/built-in-skills/office-artifacts/references/pdf/scripts/extract_pymupdf.py +107 -0
  119. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_create.py +153 -0
  120. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_fill_form.py +97 -0
  121. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_form_layout.py +168 -0
  122. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_make_form.py +145 -0
  123. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_merge.py +50 -0
  124. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_meta.py +123 -0
  125. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_page_image.py +101 -0
  126. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_read.py +153 -0
  127. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_secure.py +71 -0
  128. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_split.py +86 -0
  129. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_stamp.py +145 -0
  130. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_watermark.py +51 -0
  131. package/built-in-skills/office-artifacts/references/pdf/tests/test_pdf_skill.py +414 -0
  132. package/built-in-skills/office-artifacts/references/powerpoint/GUIDE.md +220 -0
  133. package/built-in-skills/office-artifacts/references/powerpoint/LICENSE +21 -0
  134. package/built-in-skills/office-artifacts/references/powerpoint/NOTICE.md +21 -0
  135. package/built-in-skills/office-artifacts/references/powerpoint/scripts/pptx_create.py +214 -0
  136. package/built-in-skills/office-artifacts/references/powerpoint/scripts/pptx_edit.py +442 -0
  137. package/built-in-skills/office-artifacts/references/powerpoint/scripts/pptx_from_template.py +88 -0
  138. package/built-in-skills/office-artifacts/references/powerpoint/scripts/pptx_read.py +131 -0
  139. package/built-in-skills/office-artifacts/references/powerpoint/scripts/pptx_render.py +104 -0
  140. package/built-in-skills/office-artifacts/references/powerpoint/tests/test_powerpoint_skill.py +478 -0
  141. package/built-in-skills/office-artifacts/references/xlsx/GUIDE.md +196 -0
  142. package/built-in-skills/office-artifacts/references/xlsx/LICENSE +21 -0
  143. package/built-in-skills/office-artifacts/references/xlsx/NOTICE.md +21 -0
  144. package/built-in-skills/office-artifacts/references/xlsx/references/restructuring.md +74 -0
  145. package/built-in-skills/office-artifacts/references/xlsx/scripts/csv_to_xlsx.py +108 -0
  146. package/built-in-skills/office-artifacts/references/xlsx/scripts/xlsx_create.py +259 -0
  147. package/built-in-skills/office-artifacts/references/xlsx/scripts/xlsx_edit.py +269 -0
  148. package/built-in-skills/office-artifacts/references/xlsx/scripts/xlsx_read.py +160 -0
  149. package/built-in-skills/office-artifacts/references/xlsx/scripts/xlsx_recalc.py +111 -0
  150. package/built-in-skills/office-artifacts/references/xlsx/scripts/xlsx_restructure.py +418 -0
  151. package/built-in-skills/office-artifacts/references/xlsx/scripts/xlsx_to_csv.py +69 -0
  152. package/built-in-skills/office-artifacts/references/xlsx/tests/test_xlsx_skill.py +542 -0
  153. package/built-in-skills/office-artifacts/tests/test_resource_regressions.py +272 -0
  154. package/built-in-skills/persona-generator/SKILL.md +9 -9
  155. package/built-in-skills/pkf-svg/SKILL.md +5 -0
  156. package/built-in-skills/pkf-svg/references/architecture-diagram/GUIDE.md +148 -0
  157. package/built-in-skills/pkf-svg/references/architecture-diagram/LICENSE +21 -0
  158. package/built-in-skills/pkf-svg/references/architecture-diagram/LICENSE.hermes +21 -0
  159. package/built-in-skills/pkf-svg/references/architecture-diagram/PROVENANCE.md +7 -0
  160. package/built-in-skills/pkf-svg/references/architecture-diagram/templates/template.html +345 -0
  161. package/built-in-skills/pkf-writing/SKILL.md +36 -14
  162. package/built-in-skills/prismer-airtable/LICENSE +21 -0
  163. package/built-in-skills/prismer-airtable/NOTICE.md +11 -0
  164. package/built-in-skills/prismer-airtable/SKILL.md +248 -0
  165. package/built-in-skills/prismer-airtable/scripts/airtable_client.py +76 -0
  166. package/built-in-skills/prismer-apple-notes/LICENSE +21 -0
  167. package/built-in-skills/prismer-apple-notes/NOTICE.md +17 -0
  168. package/built-in-skills/prismer-apple-notes/SKILL.md +118 -0
  169. package/built-in-skills/prismer-apple-notes/scripts/readiness.py +47 -0
  170. package/built-in-skills/prismer-apple-reminders/LICENSE +21 -0
  171. package/built-in-skills/prismer-apple-reminders/NOTICE.md +17 -0
  172. package/built-in-skills/prismer-apple-reminders/SKILL.md +155 -0
  173. package/built-in-skills/prismer-apple-reminders/scripts/readiness.py +47 -0
  174. package/built-in-skills/prismer-ascii-video/LICENSE +21 -0
  175. package/built-in-skills/prismer-ascii-video/LICENSE.hermes +21 -0
  176. package/built-in-skills/prismer-ascii-video/PROVENANCE.md +7 -0
  177. package/built-in-skills/prismer-ascii-video/README.md +290 -0
  178. package/built-in-skills/prismer-ascii-video/SKILL.md +252 -0
  179. package/built-in-skills/prismer-ascii-video/provenance/category-DESCRIPTION.md +3 -0
  180. package/built-in-skills/prismer-ascii-video/references/architecture.md +807 -0
  181. package/built-in-skills/prismer-ascii-video/references/composition.md +900 -0
  182. package/built-in-skills/prismer-ascii-video/references/effects.md +1877 -0
  183. package/built-in-skills/prismer-ascii-video/references/inputs.md +693 -0
  184. package/built-in-skills/prismer-ascii-video/references/optimization.md +688 -0
  185. package/built-in-skills/prismer-ascii-video/references/scenes.md +1018 -0
  186. package/built-in-skills/prismer-ascii-video/references/shaders.md +1408 -0
  187. package/built-in-skills/prismer-ascii-video/references/troubleshooting.md +360 -0
  188. package/built-in-skills/prismer-baoyu-infographic/LICENSE +21 -0
  189. package/built-in-skills/prismer-baoyu-infographic/LICENSE.hermes +21 -0
  190. package/built-in-skills/prismer-baoyu-infographic/LICENSE.origin +21 -0
  191. package/built-in-skills/prismer-baoyu-infographic/PORT_NOTES.md +37 -0
  192. package/built-in-skills/prismer-baoyu-infographic/PROVENANCE.md +7 -0
  193. package/built-in-skills/prismer-baoyu-infographic/SKILL.md +240 -0
  194. package/built-in-skills/prismer-baoyu-infographic/references/analysis-framework.md +182 -0
  195. package/built-in-skills/prismer-baoyu-infographic/references/base-prompt.md +43 -0
  196. package/built-in-skills/prismer-baoyu-infographic/references/layouts/bento-grid.md +41 -0
  197. package/built-in-skills/prismer-baoyu-infographic/references/layouts/binary-comparison.md +48 -0
  198. package/built-in-skills/prismer-baoyu-infographic/references/layouts/bridge.md +41 -0
  199. package/built-in-skills/prismer-baoyu-infographic/references/layouts/circular-flow.md +41 -0
  200. package/built-in-skills/prismer-baoyu-infographic/references/layouts/comic-strip.md +41 -0
  201. package/built-in-skills/prismer-baoyu-infographic/references/layouts/comparison-matrix.md +41 -0
  202. package/built-in-skills/prismer-baoyu-infographic/references/layouts/dashboard.md +41 -0
  203. package/built-in-skills/prismer-baoyu-infographic/references/layouts/dense-modules.md +72 -0
  204. package/built-in-skills/prismer-baoyu-infographic/references/layouts/funnel.md +41 -0
  205. package/built-in-skills/prismer-baoyu-infographic/references/layouts/hierarchical-layers.md +48 -0
  206. package/built-in-skills/prismer-baoyu-infographic/references/layouts/hub-spoke.md +41 -0
  207. package/built-in-skills/prismer-baoyu-infographic/references/layouts/iceberg.md +41 -0
  208. package/built-in-skills/prismer-baoyu-infographic/references/layouts/isometric-map.md +41 -0
  209. package/built-in-skills/prismer-baoyu-infographic/references/layouts/jigsaw.md +41 -0
  210. package/built-in-skills/prismer-baoyu-infographic/references/layouts/linear-progression.md +48 -0
  211. package/built-in-skills/prismer-baoyu-infographic/references/layouts/periodic-table.md +41 -0
  212. package/built-in-skills/prismer-baoyu-infographic/references/layouts/story-mountain.md +41 -0
  213. package/built-in-skills/prismer-baoyu-infographic/references/layouts/structural-breakdown.md +48 -0
  214. package/built-in-skills/prismer-baoyu-infographic/references/layouts/tree-branching.md +41 -0
  215. package/built-in-skills/prismer-baoyu-infographic/references/layouts/venn-diagram.md +41 -0
  216. package/built-in-skills/prismer-baoyu-infographic/references/layouts/winding-roadmap.md +41 -0
  217. package/built-in-skills/prismer-baoyu-infographic/references/structured-content-template.md +244 -0
  218. package/built-in-skills/prismer-baoyu-infographic/references/styles/aged-academia.md +36 -0
  219. package/built-in-skills/prismer-baoyu-infographic/references/styles/bold-graphic.md +36 -0
  220. package/built-in-skills/prismer-baoyu-infographic/references/styles/chalkboard.md +61 -0
  221. package/built-in-skills/prismer-baoyu-infographic/references/styles/claymation.md +29 -0
  222. package/built-in-skills/prismer-baoyu-infographic/references/styles/corporate-memphis.md +29 -0
  223. package/built-in-skills/prismer-baoyu-infographic/references/styles/craft-handmade.md +44 -0
  224. package/built-in-skills/prismer-baoyu-infographic/references/styles/cyberpunk-neon.md +29 -0
  225. package/built-in-skills/prismer-baoyu-infographic/references/styles/hand-drawn-edu.md +63 -0
  226. package/built-in-skills/prismer-baoyu-infographic/references/styles/ikea-manual.md +29 -0
  227. package/built-in-skills/prismer-baoyu-infographic/references/styles/kawaii.md +29 -0
  228. package/built-in-skills/prismer-baoyu-infographic/references/styles/knolling.md +29 -0
  229. package/built-in-skills/prismer-baoyu-infographic/references/styles/lego-brick.md +29 -0
  230. package/built-in-skills/prismer-baoyu-infographic/references/styles/morandi-journal.md +60 -0
  231. package/built-in-skills/prismer-baoyu-infographic/references/styles/origami.md +29 -0
  232. package/built-in-skills/prismer-baoyu-infographic/references/styles/pixel-art.md +29 -0
  233. package/built-in-skills/prismer-baoyu-infographic/references/styles/pop-laboratory.md +48 -0
  234. package/built-in-skills/prismer-baoyu-infographic/references/styles/retro-pop-grid.md +47 -0
  235. package/built-in-skills/prismer-baoyu-infographic/references/styles/storybook-watercolor.md +29 -0
  236. package/built-in-skills/prismer-baoyu-infographic/references/styles/subway-map.md +29 -0
  237. package/built-in-skills/prismer-baoyu-infographic/references/styles/technical-schematic.md +36 -0
  238. package/built-in-skills/prismer-baoyu-infographic/references/styles/ui-wireframe.md +29 -0
  239. package/built-in-skills/prismer-blocked-page-recovery/LICENSE +21 -0
  240. package/built-in-skills/prismer-blocked-page-recovery/NOTICE.md +17 -0
  241. package/built-in-skills/prismer-blocked-page-recovery/SKILL.md +158 -0
  242. package/built-in-skills/prismer-blocked-page-recovery/scripts/recover_page.py +311 -0
  243. package/built-in-skills/prismer-box/LICENSE +21 -0
  244. package/built-in-skills/prismer-box/NOTICE.md +11 -0
  245. package/built-in-skills/prismer-box/SKILL.md +147 -0
  246. package/built-in-skills/prismer-box/references/bulk-operations.md +43 -0
  247. package/built-in-skills/prismer-box/references/cli-guide.md +133 -0
  248. package/built-in-skills/prismer-box/references/content-workflows.md +86 -0
  249. package/built-in-skills/prismer-box/references/hubs.md +77 -0
  250. package/built-in-skills/prismer-box/references/oauth-setup.md +92 -0
  251. package/built-in-skills/prismer-box/references/rest-api.md +37 -0
  252. package/built-in-skills/prismer-box/references/sdk-development.md +85 -0
  253. package/built-in-skills/prismer-box/references/search-and-ai.md +147 -0
  254. package/built-in-skills/prismer-box/references/troubleshooting.md +33 -0
  255. package/built-in-skills/prismer-box/references/webhooks-and-events.md +43 -0
  256. package/built-in-skills/prismer-codebase-inspection/LICENSE +21 -0
  257. package/built-in-skills/prismer-codebase-inspection/NOTICE.md +17 -0
  258. package/built-in-skills/prismer-codebase-inspection/SKILL.md +141 -0
  259. package/built-in-skills/prismer-computer-use/LICENSE +21 -0
  260. package/built-in-skills/prismer-computer-use/NOTICE.md +17 -0
  261. package/built-in-skills/prismer-computer-use/SKILL.md +372 -0
  262. package/built-in-skills/prismer-design-md/LICENSE +21 -0
  263. package/built-in-skills/prismer-design-md/LICENSE.hermes +21 -0
  264. package/built-in-skills/prismer-design-md/PROVENANCE.md +7 -0
  265. package/built-in-skills/prismer-design-md/SKILL.md +227 -0
  266. package/built-in-skills/prismer-design-md/templates/starter.md +99 -0
  267. package/built-in-skills/prismer-email-inbox-triage/LICENSE +21 -0
  268. package/built-in-skills/prismer-email-inbox-triage/NOTICE.md +11 -0
  269. package/built-in-skills/prismer-email-inbox-triage/SKILL.md +116 -0
  270. package/built-in-skills/prismer-findmy/LICENSE +21 -0
  271. package/built-in-skills/prismer-findmy/NOTICE.md +17 -0
  272. package/built-in-skills/prismer-findmy/SKILL.md +150 -0
  273. package/built-in-skills/prismer-findmy/scripts/readiness.py +47 -0
  274. package/built-in-skills/prismer-gif-search/LICENSE +21 -0
  275. package/built-in-skills/prismer-gif-search/LICENSE.hermes +21 -0
  276. package/built-in-skills/prismer-gif-search/PROVENANCE.md +7 -0
  277. package/built-in-skills/prismer-gif-search/SKILL.md +97 -0
  278. package/built-in-skills/prismer-gif-search/scripts/tenor.py +81 -0
  279. package/built-in-skills/prismer-github/LICENSE +21 -0
  280. package/built-in-skills/prismer-github/NOTICE.md +17 -0
  281. package/built-in-skills/prismer-github/SKILL.md +74 -0
  282. package/built-in-skills/prismer-github/references/auth.md +91 -0
  283. package/built-in-skills/prismer-github/references/ci-troubleshooting.md +193 -0
  284. package/built-in-skills/prismer-github/references/code-review.md +465 -0
  285. package/built-in-skills/prismer-github/references/conventional-commits.md +81 -0
  286. package/built-in-skills/prismer-github/references/github-api-cheatsheet.md +177 -0
  287. package/built-in-skills/prismer-github/references/issue-to-pr.md +74 -0
  288. package/built-in-skills/prismer-github/references/issues.md +336 -0
  289. package/built-in-skills/prismer-github/references/pr-workflow.md +346 -0
  290. package/built-in-skills/prismer-github/references/repo-management.md +484 -0
  291. package/built-in-skills/prismer-github/references/review-output-template.md +84 -0
  292. package/built-in-skills/prismer-github/scripts/ensure-gh.py +132 -0
  293. package/built-in-skills/prismer-github/scripts/gh-env.sh +25 -0
  294. package/built-in-skills/prismer-github/scripts/git-credential-token.py +68 -0
  295. package/built-in-skills/prismer-github/scripts/github-api.py +71 -0
  296. package/built-in-skills/prismer-github/scripts/github-context.py +28 -0
  297. package/built-in-skills/prismer-github/templates/bug-report.md +35 -0
  298. package/built-in-skills/prismer-github/templates/feature-request.md +31 -0
  299. package/built-in-skills/prismer-github/templates/pr-body-bugfix.md +35 -0
  300. package/built-in-skills/prismer-github/templates/pr-body-feature.md +33 -0
  301. package/built-in-skills/prismer-google-workspace/LICENSE +21 -0
  302. package/built-in-skills/prismer-google-workspace/NOTICE.md +11 -0
  303. package/built-in-skills/prismer-google-workspace/SKILL.md +369 -0
  304. package/built-in-skills/prismer-google-workspace/references/daily-brief.md +65 -0
  305. package/built-in-skills/prismer-google-workspace/references/gmail-search-syntax.md +63 -0
  306. package/built-in-skills/prismer-google-workspace/scripts/_hermes_home.py +17 -0
  307. package/built-in-skills/prismer-google-workspace/scripts/_private_state.py +39 -0
  308. package/built-in-skills/prismer-google-workspace/scripts/google_api.py +1339 -0
  309. package/built-in-skills/prismer-google-workspace/scripts/gws_bridge.py +121 -0
  310. package/built-in-skills/prismer-google-workspace/scripts/setup.py +563 -0
  311. package/built-in-skills/prismer-google-workspace/tests/test_productivity_regressions.py +214 -0
  312. package/built-in-skills/prismer-hermes-agent/LICENSE +21 -0
  313. package/built-in-skills/prismer-hermes-agent/NOTICE.md +17 -0
  314. package/built-in-skills/prismer-hermes-agent/SKILL.md +247 -0
  315. package/built-in-skills/prismer-hermes-agent/references/background-systems.md +108 -0
  316. package/built-in-skills/prismer-hermes-agent/references/cli-reference.md +158 -0
  317. package/built-in-skills/prismer-hermes-agent/references/configuration.md +96 -0
  318. package/built-in-skills/prismer-hermes-agent/references/contributor-guide.md +151 -0
  319. package/built-in-skills/prismer-hermes-agent/references/delegate-task-concurrency-diagnosis.md +47 -0
  320. package/built-in-skills/prismer-hermes-agent/references/desktop-plugins.md +215 -0
  321. package/built-in-skills/prismer-hermes-agent/references/native-mcp.md +351 -0
  322. package/built-in-skills/prismer-hermes-agent/references/petdex.md +82 -0
  323. package/built-in-skills/prismer-hermes-agent/references/portal-auth-for-third-party-apps.md +135 -0
  324. package/built-in-skills/prismer-hermes-agent/references/project-context-files.md +55 -0
  325. package/built-in-skills/prismer-hermes-agent/references/providers-and-models.md +81 -0
  326. package/built-in-skills/prismer-hermes-agent/references/security-privacy.md +73 -0
  327. package/built-in-skills/prismer-hermes-agent/references/slash-commands.md +119 -0
  328. package/built-in-skills/prismer-hermes-agent/references/themes.md +134 -0
  329. package/built-in-skills/prismer-hermes-agent/references/troubleshooting.md +87 -0
  330. package/built-in-skills/prismer-hermes-agent/references/tui-widgets.md +144 -0
  331. package/built-in-skills/prismer-hermes-agent/references/webhooks.md +219 -0
  332. package/built-in-skills/prismer-hermes-agent/references/windows-quirks.md +64 -0
  333. package/built-in-skills/prismer-hermes-agent/templates/clock.mjs +51 -0
  334. package/built-in-skills/prismer-hermes-agent/templates/plugin.js +97 -0
  335. package/built-in-skills/prismer-hermes-agent/templates/skin.yaml +49 -0
  336. package/built-in-skills/prismer-himalaya/LICENSE +21 -0
  337. package/built-in-skills/prismer-himalaya/NOTICE.md +11 -0
  338. package/built-in-skills/prismer-himalaya/SKILL.md +340 -0
  339. package/built-in-skills/prismer-himalaya/references/configuration.md +227 -0
  340. package/built-in-skills/prismer-himalaya/references/message-composition.md +206 -0
  341. package/built-in-skills/prismer-himalaya/scripts/compose_draft.py +48 -0
  342. package/built-in-skills/prismer-im-collab/SKILL.md +1 -1
  343. package/built-in-skills/prismer-imessage/LICENSE +21 -0
  344. package/built-in-skills/prismer-imessage/NOTICE.md +17 -0
  345. package/built-in-skills/prismer-imessage/SKILL.md +128 -0
  346. package/built-in-skills/prismer-imessage/scripts/readiness.py +47 -0
  347. package/built-in-skills/prismer-manim-video/LICENSE +21 -0
  348. package/built-in-skills/prismer-manim-video/LICENSE.hermes +21 -0
  349. package/built-in-skills/prismer-manim-video/PROVENANCE.md +7 -0
  350. package/built-in-skills/prismer-manim-video/README.md +23 -0
  351. package/built-in-skills/prismer-manim-video/SKILL.md +279 -0
  352. package/built-in-skills/prismer-manim-video/references/animation-design-thinking.md +161 -0
  353. package/built-in-skills/prismer-manim-video/references/animations.md +282 -0
  354. package/built-in-skills/prismer-manim-video/references/camera-and-3d.md +135 -0
  355. package/built-in-skills/prismer-manim-video/references/decorations.md +202 -0
  356. package/built-in-skills/prismer-manim-video/references/equations.md +216 -0
  357. package/built-in-skills/prismer-manim-video/references/graphs-and-data.md +163 -0
  358. package/built-in-skills/prismer-manim-video/references/mobjects.md +333 -0
  359. package/built-in-skills/prismer-manim-video/references/paper-explainer.md +255 -0
  360. package/built-in-skills/prismer-manim-video/references/production-quality.md +190 -0
  361. package/built-in-skills/prismer-manim-video/references/rendering.md +187 -0
  362. package/built-in-skills/prismer-manim-video/references/scene-planning.md +118 -0
  363. package/built-in-skills/prismer-manim-video/references/troubleshooting.md +135 -0
  364. package/built-in-skills/prismer-manim-video/references/updaters-and-trackers.md +260 -0
  365. package/built-in-skills/prismer-manim-video/references/visual-design.md +124 -0
  366. package/built-in-skills/prismer-manim-video/scripts/setup.sh +15 -0
  367. package/built-in-skills/prismer-maps/LICENSE +21 -0
  368. package/built-in-skills/prismer-maps/NOTICE.md +11 -0
  369. package/built-in-skills/prismer-maps/SKILL.md +240 -0
  370. package/built-in-skills/prismer-maps/scripts/maps_client.py +1324 -0
  371. package/built-in-skills/prismer-node-inspect-debugger/LICENSE +21 -0
  372. package/built-in-skills/prismer-node-inspect-debugger/NOTICE.md +17 -0
  373. package/built-in-skills/prismer-node-inspect-debugger/SKILL.md +347 -0
  374. package/built-in-skills/prismer-notion/LICENSE +21 -0
  375. package/built-in-skills/prismer-notion/NOTICE.md +11 -0
  376. package/built-in-skills/prismer-notion/SKILL.md +495 -0
  377. package/built-in-skills/prismer-notion/references/block-types.md +112 -0
  378. package/built-in-skills/prismer-obsidian/LICENSE +21 -0
  379. package/built-in-skills/prismer-obsidian/LICENSE.hermes +21 -0
  380. package/built-in-skills/prismer-obsidian/PROVENANCE.md +7 -0
  381. package/built-in-skills/prismer-obsidian/SKILL.md +80 -0
  382. package/built-in-skills/prismer-obsidian/provenance/category-DESCRIPTION.md +3 -0
  383. package/built-in-skills/prismer-obsidian/scripts/write_note.py +84 -0
  384. package/built-in-skills/prismer-p5js/LICENSE +21 -0
  385. package/built-in-skills/prismer-p5js/LICENSE.hermes +21 -0
  386. package/built-in-skills/prismer-p5js/PROVENANCE.md +7 -0
  387. package/built-in-skills/prismer-p5js/README.md +64 -0
  388. package/built-in-skills/prismer-p5js/SKILL.md +574 -0
  389. package/built-in-skills/prismer-p5js/references/animation.md +439 -0
  390. package/built-in-skills/prismer-p5js/references/color-systems.md +355 -0
  391. package/built-in-skills/prismer-p5js/references/core-api.md +410 -0
  392. package/built-in-skills/prismer-p5js/references/export-pipeline.md +534 -0
  393. package/built-in-skills/prismer-p5js/references/interaction.md +398 -0
  394. package/built-in-skills/prismer-p5js/references/shapes-and-geometry.md +300 -0
  395. package/built-in-skills/prismer-p5js/references/troubleshooting.md +532 -0
  396. package/built-in-skills/prismer-p5js/references/typography.md +302 -0
  397. package/built-in-skills/prismer-p5js/references/visual-effects.md +905 -0
  398. package/built-in-skills/prismer-p5js/references/webgl-and-3d.md +423 -0
  399. package/built-in-skills/prismer-p5js/scripts/export-frames.js +91 -0
  400. package/built-in-skills/prismer-p5js/scripts/render.sh +113 -0
  401. package/built-in-skills/prismer-p5js/scripts/serve.sh +25 -0
  402. package/built-in-skills/prismer-p5js/scripts/setup.sh +87 -0
  403. package/built-in-skills/prismer-p5js/templates/viewer.html +401 -0
  404. package/built-in-skills/prismer-popular-web-designs/LICENSE +21 -0
  405. package/built-in-skills/prismer-popular-web-designs/LICENSE.hermes +21 -0
  406. package/built-in-skills/prismer-popular-web-designs/LICENSE.origin +21 -0
  407. package/built-in-skills/prismer-popular-web-designs/PROVENANCE.md +7 -0
  408. package/built-in-skills/prismer-popular-web-designs/SKILL.md +218 -0
  409. package/built-in-skills/prismer-popular-web-designs/templates/airbnb.md +259 -0
  410. package/built-in-skills/prismer-popular-web-designs/templates/airtable.md +102 -0
  411. package/built-in-skills/prismer-popular-web-designs/templates/apple.md +326 -0
  412. package/built-in-skills/prismer-popular-web-designs/templates/bmw.md +193 -0
  413. package/built-in-skills/prismer-popular-web-designs/templates/cal.md +272 -0
  414. package/built-in-skills/prismer-popular-web-designs/templates/claude.md +325 -0
  415. package/built-in-skills/prismer-popular-web-designs/templates/clay.md +317 -0
  416. package/built-in-skills/prismer-popular-web-designs/templates/clickhouse.md +294 -0
  417. package/built-in-skills/prismer-popular-web-designs/templates/cohere.md +279 -0
  418. package/built-in-skills/prismer-popular-web-designs/templates/coinbase.md +142 -0
  419. package/built-in-skills/prismer-popular-web-designs/templates/composio.md +320 -0
  420. package/built-in-skills/prismer-popular-web-designs/templates/cursor.md +322 -0
  421. package/built-in-skills/prismer-popular-web-designs/templates/elevenlabs.md +278 -0
  422. package/built-in-skills/prismer-popular-web-designs/templates/expo.md +294 -0
  423. package/built-in-skills/prismer-popular-web-designs/templates/figma.md +233 -0
  424. package/built-in-skills/prismer-popular-web-designs/templates/framer.md +259 -0
  425. package/built-in-skills/prismer-popular-web-designs/templates/hashicorp.md +291 -0
  426. package/built-in-skills/prismer-popular-web-designs/templates/ibm.md +345 -0
  427. package/built-in-skills/prismer-popular-web-designs/templates/intercom.md +159 -0
  428. package/built-in-skills/prismer-popular-web-designs/templates/kraken.md +138 -0
  429. package/built-in-skills/prismer-popular-web-designs/templates/linear.app.md +380 -0
  430. package/built-in-skills/prismer-popular-web-designs/templates/lovable.md +311 -0
  431. package/built-in-skills/prismer-popular-web-designs/templates/minimax.md +270 -0
  432. package/built-in-skills/prismer-popular-web-designs/templates/mintlify.md +339 -0
  433. package/built-in-skills/prismer-popular-web-designs/templates/miro.md +121 -0
  434. package/built-in-skills/prismer-popular-web-designs/templates/mistral.ai.md +274 -0
  435. package/built-in-skills/prismer-popular-web-designs/templates/mongodb.md +279 -0
  436. package/built-in-skills/prismer-popular-web-designs/templates/notion.md +322 -0
  437. package/built-in-skills/prismer-popular-web-designs/templates/nvidia.md +306 -0
  438. package/built-in-skills/prismer-popular-web-designs/templates/ollama.md +280 -0
  439. package/built-in-skills/prismer-popular-web-designs/templates/opencode.ai.md +294 -0
  440. package/built-in-skills/prismer-popular-web-designs/templates/pinterest.md +243 -0
  441. package/built-in-skills/prismer-popular-web-designs/templates/posthog.md +269 -0
  442. package/built-in-skills/prismer-popular-web-designs/templates/raycast.md +281 -0
  443. package/built-in-skills/prismer-popular-web-designs/templates/replicate.md +274 -0
  444. package/built-in-skills/prismer-popular-web-designs/templates/resend.md +316 -0
  445. package/built-in-skills/prismer-popular-web-designs/templates/revolut.md +198 -0
  446. package/built-in-skills/prismer-popular-web-designs/templates/runwayml.md +257 -0
  447. package/built-in-skills/prismer-popular-web-designs/templates/sanity.md +370 -0
  448. package/built-in-skills/prismer-popular-web-designs/templates/sentry.md +275 -0
  449. package/built-in-skills/prismer-popular-web-designs/templates/spacex.md +207 -0
  450. package/built-in-skills/prismer-popular-web-designs/templates/spotify.md +259 -0
  451. package/built-in-skills/prismer-popular-web-designs/templates/stripe.md +335 -0
  452. package/built-in-skills/prismer-popular-web-designs/templates/supabase.md +268 -0
  453. package/built-in-skills/prismer-popular-web-designs/templates/superhuman.md +265 -0
  454. package/built-in-skills/prismer-popular-web-designs/templates/together.ai.md +276 -0
  455. package/built-in-skills/prismer-popular-web-designs/templates/uber.md +308 -0
  456. package/built-in-skills/prismer-popular-web-designs/templates/vercel.md +323 -0
  457. package/built-in-skills/prismer-popular-web-designs/templates/voltagent.md +336 -0
  458. package/built-in-skills/prismer-popular-web-designs/templates/warp.md +266 -0
  459. package/built-in-skills/prismer-popular-web-designs/templates/webflow.md +105 -0
  460. package/built-in-skills/prismer-popular-web-designs/templates/wise.md +186 -0
  461. package/built-in-skills/prismer-popular-web-designs/templates/x.ai.md +270 -0
  462. package/built-in-skills/prismer-popular-web-designs/templates/zapier.md +341 -0
  463. package/built-in-skills/prismer-product-price-monitor/LICENSE +21 -0
  464. package/built-in-skills/prismer-product-price-monitor/NOTICE.md +11 -0
  465. package/built-in-skills/prismer-product-price-monitor/SKILL.md +97 -0
  466. package/built-in-skills/prismer-product-price-monitor/scripts/watch_state.py +116 -0
  467. package/built-in-skills/prismer-python-debugpy/LICENSE +21 -0
  468. package/built-in-skills/prismer-python-debugpy/NOTICE.md +17 -0
  469. package/built-in-skills/prismer-python-debugpy/SKILL.md +377 -0
  470. package/built-in-skills/prismer-python-debugpy/scripts/dap_client.py +68 -0
  471. package/built-in-skills/prismer-songsee/LICENSE +21 -0
  472. package/built-in-skills/prismer-songsee/LICENSE.hermes +21 -0
  473. package/built-in-skills/prismer-songsee/PROVENANCE.md +7 -0
  474. package/built-in-skills/prismer-songsee/SKILL.md +91 -0
  475. package/built-in-skills/prismer-songwriting-and-ai-music/LICENSE +21 -0
  476. package/built-in-skills/prismer-songwriting-and-ai-music/LICENSE.hermes +21 -0
  477. package/built-in-skills/prismer-songwriting-and-ai-music/PROVENANCE.md +7 -0
  478. package/built-in-skills/prismer-songwriting-and-ai-music/SKILL.md +317 -0
  479. package/built-in-skills/prismer-spike/LICENSE +21 -0
  480. package/built-in-skills/prismer-spike/LICENSE.gsd +21 -0
  481. package/built-in-skills/prismer-spike/NOTICE.md +17 -0
  482. package/built-in-skills/prismer-spike/SKILL.md +212 -0
  483. package/built-in-skills/prismer-teams-meeting-pipeline/LICENSE +21 -0
  484. package/built-in-skills/prismer-teams-meeting-pipeline/NOTICE.md +11 -0
  485. package/built-in-skills/prismer-teams-meeting-pipeline/SKILL.md +156 -0
  486. package/built-in-skills/prismer-xurl/LICENSE +21 -0
  487. package/built-in-skills/prismer-xurl/LICENSE.hermes +21 -0
  488. package/built-in-skills/prismer-xurl/PROVENANCE.md +7 -0
  489. package/built-in-skills/prismer-xurl/SKILL.md +444 -0
  490. package/built-in-skills/prismer-xurl/provenance/category-DESCRIPTION.md +3 -0
  491. package/built-in-skills/prismer-youtube-content/LICENSE +21 -0
  492. package/built-in-skills/prismer-youtube-content/LICENSE.hermes +21 -0
  493. package/built-in-skills/prismer-youtube-content/PROVENANCE.md +7 -0
  494. package/built-in-skills/prismer-youtube-content/SKILL.md +86 -0
  495. package/built-in-skills/prismer-youtube-content/provenance/category-DESCRIPTION.md +3 -0
  496. package/built-in-skills/prismer-youtube-content/references/output-formats.md +56 -0
  497. package/built-in-skills/prismer-youtube-content/scripts/fetch_transcript.py +146 -0
  498. package/built-in-skills/research-arxiv/LICENSE +21 -0
  499. package/built-in-skills/research-arxiv/NOTICE.md +4 -0
  500. package/built-in-skills/research-arxiv/SKILL.md +263 -0
  501. package/built-in-skills/research-arxiv/scripts/search_arxiv.py +111 -0
  502. package/built-in-skills/role-builder/SKILL.md +7 -1
  503. package/built-in-skills/role-builder/scripts/author-role.mjs +23 -7
  504. package/built-in-skills/role-builder/scripts/ingest-role.mjs +15 -117
  505. package/built-in-skills/role-builder/scripts/instantiate-and-run.mjs +15 -1
  506. package/built-in-skills/role-builder/scripts/operation-harness.mjs +6 -4
  507. package/built-in-skills/skill-creator/LICENSE.prismer +21 -0
  508. package/built-in-skills/skill-creator/NOTICE.md +18 -0
  509. package/built-in-skills/skill-creator/SKILL.md +20 -1
  510. package/built-in-skills/skill-creator/eval-viewer/generate_review.py +20 -31
  511. package/built-in-skills/skill-creator/eval-viewer/viewer.html +35 -23
  512. package/built-in-skills/skill-creator/references/hermes-agent-skill-authoring/GUIDE.md +220 -0
  513. package/built-in-skills/skill-creator/references/hermes-agent-skill-authoring/LICENSE +21 -0
  514. package/built-in-skills/{skill-authoring/SKILL.md → skill-creator/references/skill-authoring/GUIDE.md} +1 -1
  515. package/built-in-skills/{skill-builder/SKILL.md → skill-creator/references/skill-builder/GUIDE.md} +8 -12
  516. package/built-in-skills/skill-creator/references/skill-builder/scripts/ingest.mjs +93 -0
  517. package/built-in-skills/skill-creator/scripts/aggregate_benchmark.py +3 -2
  518. package/built-in-skills/skill-creator/scripts/import-library.mjs +30 -7
  519. package/built-in-skills/skill-creator/scripts/improve_description.py +14 -16
  520. package/built-in-skills/skill-creator/scripts/package_skill.py +16 -9
  521. package/built-in-skills/skill-creator/scripts/quick_validate.py +22 -5
  522. package/built-in-skills/skill-creator/scripts/run_eval.py +63 -144
  523. package/built-in-skills/skill-creator/scripts/run_loop.py +24 -16
  524. package/built-in-skills/slack-gif-creator/core/gif_builder.py +13 -2
  525. package/built-in-skills/slack-gif-creator/core/validators.py +17 -7
  526. package/built-in-skills/tasks/SKILL.md +2 -2
  527. package/built-in-skills/tdd/SKILL.md +7 -0
  528. package/built-in-skills/tdd/references/test-driven-development/GUIDE.md +356 -0
  529. package/built-in-skills/tdd/references/test-driven-development/LICENSE +21 -0
  530. package/built-in-skills/tdd/references/test-driven-development/LICENSE.superpowers +21 -0
  531. package/built-in-skills/tdd/references/test-driven-development/NOTICE.md +37 -0
  532. package/built-in-skills/team/SKILL.md +1 -1
  533. package/built-in-skills/web-artifacts-builder/SKILL.md +3 -3
  534. package/built-in-skills/web-artifacts-builder/scripts/bundle-artifact.sh +9 -7
  535. package/built-in-skills/web-artifacts-builder/scripts/init-artifact.sh +28 -55
  536. package/built-in-skills/webapp-qa/LICENSE +21 -0
  537. package/built-in-skills/webapp-qa/NOTICE.md +37 -0
  538. package/built-in-skills/webapp-qa/SKILL.md +41 -0
  539. package/built-in-skills/webapp-qa/references/dogfood/GUIDE.md +161 -0
  540. package/built-in-skills/webapp-qa/references/issue-taxonomy.md +109 -0
  541. package/built-in-skills/webapp-qa/templates/dogfood-report-template.md +86 -0
  542. package/built-in-skills/webapp-testing/SKILL.md +9 -2
  543. package/built-in-skills/webapp-testing/examples/console_logging.py +10 -4
  544. package/built-in-skills/webapp-testing/examples/element_discovery.py +11 -4
  545. package/built-in-skills/webapp-testing/examples/static_html_automation.py +14 -9
  546. package/built-in-skills/webapp-testing/scripts/with_server.py +34 -10
  547. package/built-in-skills/weekly-review/LICENSE +21 -0
  548. package/built-in-skills/weekly-review/NOTICE.md +21 -0
  549. package/built-in-skills/weekly-review/SKILL.md +49 -0
  550. package/components/eaas-pi-components.manifest.json +37 -0
  551. package/dist/cli.cjs +7017 -3340
  552. package/dist/cli.js +6631 -2936
  553. package/dist/index.cjs +7863 -3830
  554. package/dist/index.d.cts +459 -5
  555. package/dist/index.d.ts +459 -5
  556. package/dist/index.js +7106 -3064
  557. package/package.json +7 -2
  558. package/plugins/memory/prismer/__init__.py +4 -0
  559. package/plugins/memory/prismer/tool-schemas.generated.json +8 -0
  560. package/built-in-skills/skill-builder/scripts/ingest.mjs +0 -265
  561. package/built-in-skills/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  562. /package/built-in-skills/{document-generation/SKILL.md → office-artifacts/references/document-generation/GUIDE.md} +0 -0
  563. /package/built-in-skills/{skill-authoring/skill.json → skill-creator/references/skill-authoring/draft-contract.json} +0 -0
@@ -0,0 +1,542 @@
1
+ """End-to-end tests for the xlsx skill helper scripts.
2
+
3
+ Runs each script as a subprocess under LC_ALL=C to prove all text I/O
4
+ uses explicit UTF-8 rather than locale defaults. No network access.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import csv
9
+ import json
10
+ import os
11
+ import shutil
12
+ import subprocess
13
+ import sys
14
+ from datetime import date
15
+ from pathlib import Path
16
+
17
+ import pytest
18
+ from openpyxl import load_workbook
19
+
20
+ SCRIPTS = Path(__file__).resolve().parent.parent / "scripts"
21
+
22
+
23
+ def run(script, *args, expect_ok=True):
24
+ env = dict(os.environ, LC_ALL="C", LANG="C")
25
+ env.pop("PYTHONIOENCODING", None)
26
+ proc = subprocess.run(
27
+ [sys.executable, str(SCRIPTS / script), *map(str, args)],
28
+ capture_output=True, text=True, env=env, encoding="utf-8")
29
+ if expect_ok:
30
+ assert proc.returncode == 0, f"{script} failed: {proc.stderr}"
31
+ return proc
32
+
33
+
34
+ SPEC = {
35
+ "full_calc_on_load": True,
36
+ "sheets": [
37
+ {
38
+ "name": "Data",
39
+ "rows": [
40
+ [
41
+ {"value": "Region", "bold": True, "fill": "DDEBF7",
42
+ "border": "thin", "align": "center", "valign": "center"},
43
+ {"value": "Sales", "bold": True, "fill": "DDEBF7"},
44
+ {"value": "Growth", "bold": True},
45
+ {"value": "Audited", "bold": True},
46
+ {"value": "Closed", "bold": True},
47
+ {"value": "Status", "bold": True},
48
+ ],
49
+ ["North", 1500.5, {"value": 0.125, "format": "0.0%"}, True,
50
+ {"value": "2026-01-31", "type": "date",
51
+ "format": "yyyy-mm-dd"}, "Yes"],
52
+ ["South", 900, {"value": -0.03, "format": "0.0%"}, False,
53
+ {"value": "2026-02-28", "type": "date",
54
+ "format": "yyyy-mm-dd"}, "No"],
55
+ ["East", 2100, {"value": 0.4, "format": "0.0%"}, True,
56
+ {"value": "2026-03-31", "type": "date",
57
+ "format": "yyyy-mm-dd"}, "Yes"],
58
+ ],
59
+ "cells": {
60
+ "A6": {"value": "Total", "bold": True, "italic": True,
61
+ "font_size": 12, "font_color": "1F4E78"},
62
+ "B6": {"formula": "SUM(B2:B4)", "format": "$#,##0.00"},
63
+ },
64
+ "column_widths": {"A": 18, "B": 14},
65
+ "row_heights": {"1": 24},
66
+ "merges": ["A8:C8"],
67
+ "freeze_panes": "A2",
68
+ "autofilter": "A1:F4",
69
+ "conditional_formats": [
70
+ {"range": "B2:B4", "type": "cell_is",
71
+ "operator": "greaterThan", "formula": ["1000"],
72
+ "fill": "C6EFCE"},
73
+ {"range": "C2:C4", "type": "color_scale"},
74
+ ],
75
+ "charts": [
76
+ {"type": "bar", "title": "Sales by region", "anchor": "H2",
77
+ "data": "B1:B4", "categories": "A2:A4"},
78
+ {"type": "line", "title": "Growth", "anchor": "H18",
79
+ "data": "C1:C4", "categories": "A2:A4"},
80
+ {"type": "pie", "title": "Share", "anchor": "P2",
81
+ "data": "B2:B4", "categories": "A2:A4",
82
+ "titles_from_data": False},
83
+ ],
84
+ "validations": [
85
+ {"range": "F2:F10", "type": "list",
86
+ "formula1": '"Yes,No,Maybe"'},
87
+ ],
88
+ },
89
+ {"name": "Notes", "rows": [["Zürich", "Фамилия", "12,5%"]]},
90
+ ],
91
+ }
92
+
93
+
94
+ @pytest.fixture
95
+ def workbook(tmp_path):
96
+ spec_path = tmp_path / "spec.json"
97
+ spec_path.write_text(json.dumps(SPEC), encoding="utf-8")
98
+ out = tmp_path / "report.xlsx"
99
+ proc = run("xlsx_create.py", spec_path, out)
100
+ summary = json.loads(proc.stdout)
101
+ assert summary["ok"] and summary["sheets"] == ["Data", "Notes"]
102
+ return out
103
+
104
+
105
+ def test_create_features_roundtrip(workbook):
106
+ wb = load_workbook(workbook)
107
+ ws = wb["Data"]
108
+ # typed values
109
+ assert ws["B2"].value == 1500.5
110
+ assert ws["D2"].value is True
111
+ e2 = ws["E2"].value
112
+ assert (e2.date() if hasattr(e2, "date") else e2) == date(2026, 1, 31)
113
+ # formula + number formats
114
+ assert ws["B6"].value == "=SUM(B2:B4)"
115
+ assert ws["B6"].number_format == "$#,##0.00"
116
+ assert ws["C2"].number_format == "0.0%"
117
+ assert ws["E2"].number_format == "yyyy-mm-dd"
118
+ # styling
119
+ assert ws["A1"].font.bold is True
120
+ assert ws["A1"].fill.fgColor.rgb.endswith("DDEBF7")
121
+ assert ws["A1"].border.left.style == "thin"
122
+ assert ws["A1"].alignment.horizontal == "center"
123
+ assert ws["A6"].font.italic is True and ws["A6"].font.size == 12
124
+ # dimensions
125
+ assert ws.column_dimensions["A"].width == 18
126
+ assert ws.row_dimensions[1].height == 24
127
+ # merges / freeze / autofilter
128
+ assert "A8:C8" in [str(r) for r in ws.merged_cells.ranges]
129
+ assert ws.freeze_panes == "A2"
130
+ assert ws.auto_filter.ref == "A1:F4"
131
+ # conditional formatting, charts, validation
132
+ assert len(list(ws.conditional_formatting)) == 2
133
+ assert len(ws._charts) == 3
134
+ types = {type(c).__name__ for c in ws._charts}
135
+ assert types == {"BarChart", "LineChart", "PieChart"}
136
+ assert len(ws.data_validations.dataValidation) == 1
137
+ # recalc flag
138
+ assert wb.calculation.fullCalcOnLoad is True
139
+
140
+
141
+ def test_read_sheets_json_formulas(workbook, tmp_path):
142
+ inv = json.loads(run("xlsx_read.py", workbook, "--sheets").stdout)
143
+ names = [s["name"] for s in inv["sheets"]]
144
+ assert names == ["Data", "Notes"]
145
+ data_info = inv["sheets"][0]
146
+ assert data_info["charts"] == 3
147
+ assert "A8:C8" in data_info["merged"]
148
+ assert data_info["freeze_panes"] == "A2"
149
+
150
+ dump = json.loads(
151
+ run("xlsx_read.py", workbook, "--json", "--sheet", "Data").stdout)
152
+ assert dump["rows"][1][0] == "North"
153
+ assert dump["rows"][1][4] == "2026-01-31T00:00:00"
154
+
155
+ notes = json.loads(
156
+ run("xlsx_read.py", workbook, "--json", "--sheet", "Notes").stdout)
157
+ assert notes["rows"][0] == ["Zürich", "Фамилия", "12,5%"]
158
+
159
+ formulas = json.loads(run("xlsx_read.py", workbook, "--formulas").stdout)
160
+ entry = [f for f in formulas["formulas"] if f["cell"] == "B6"][0]
161
+ assert entry["formula"] == "=SUM(B2:B4)"
162
+ # openpyxl never computes: cached value absent on a fresh file
163
+ assert entry["cached"] is None
164
+
165
+ csv_out = tmp_path / "data.csv"
166
+ run("xlsx_read.py", workbook, "--csv", "--sheet", "Notes",
167
+ "--out", csv_out)
168
+ text = csv_out.read_text(encoding="utf-8")
169
+ assert "Zürich" in text and "Фамилия" in text
170
+
171
+
172
+ def test_csv_roundtrip_nonascii(tmp_path):
173
+ src = tmp_path / "src.csv"
174
+ with open(src, "w", newline="", encoding="utf-8") as fh:
175
+ w = csv.writer(fh)
176
+ w.writerow(["City", "Share", "Surname", "Active", "When"])
177
+ w.writerow(["Zürich", "12,5%", "Фамилия", "true", "2026-05-01"])
178
+ w.writerow(["Oslo", "7", "Ås", "false", "2026-06-01"])
179
+ xlsx = tmp_path / "conv.xlsx"
180
+ run("csv_to_xlsx.py", src, xlsx, "--sheet-name", "Import")
181
+
182
+ wb = load_workbook(xlsx)
183
+ ws = wb["Import"]
184
+ assert ws["A2"].value == "Zürich"
185
+ assert ws["B2"].value == "12,5%" # decimal comma stays a string
186
+ assert ws["C2"].value == "Фамилия"
187
+ assert ws["D2"].value is True # bool inferred
188
+ assert ws["E2"].value.date() == date(2026, 5, 1) # date inferred
189
+ assert ws["B3"].value == 7 # int inferred
190
+ assert ws["A1"].font.bold is True # styled header
191
+ assert ws.freeze_panes == "A2"
192
+
193
+ back = tmp_path / "back.csv"
194
+ run("xlsx_to_csv.py", xlsx, back, "--sheet", "Import")
195
+ with open(back, newline="", encoding="utf-8") as fh:
196
+ rows = list(csv.reader(fh))
197
+ assert rows[1][0] == "Zürich"
198
+ assert rows[1][2] == "Фамилия"
199
+ assert rows[1][3] == "True"
200
+ assert rows[1][4] == "2026-05-01"
201
+
202
+ # encoding override
203
+ latin = tmp_path / "latin.csv"
204
+ run("xlsx_to_csv.py", xlsx, latin, "--sheet", "Import",
205
+ "--encoding", "utf-8-sig")
206
+ assert latin.read_bytes().startswith(b"\xef\xbb\xbf")
207
+
208
+
209
+ def test_edit_existing(workbook, tmp_path):
210
+ edited = tmp_path / "edited.xlsx"
211
+ proc = run("xlsx_edit.py", workbook, "--sheet", "Notes",
212
+ "--out", edited,
213
+ "--copy-sheet", "Notes:Backup",
214
+ "--rename-sheet", "Data:Main",
215
+ "--set", "B1=Änderung",
216
+ "--set", "C1=99.5",
217
+ "--set", "D1=2026-12-24",
218
+ "--set", "E1==SUM(C1:C1)",
219
+ "--append", '["appended", 1, false]',
220
+ "--insert-rows", "1:1",
221
+ "--recalc")
222
+ result = json.loads(proc.stdout)
223
+ assert result["ok"]
224
+
225
+ wb = load_workbook(edited)
226
+ assert set(wb.sheetnames) == {"Main", "Notes", "Backup"}
227
+ ws = wb["Notes"]
228
+ # insert-rows ran before --set per documented order, so row 1 is blank
229
+ # and original data moved to row 2... check documented ordering:
230
+ # structural ops run before --set, so B1 etc. were written after insert.
231
+ assert ws["B1"].value == "Änderung"
232
+ assert ws["C1"].value == 99.5
233
+ assert ws["D1"].value.date() == date(2026, 12, 24)
234
+ assert ws["E1"].value == "=SUM(C1:C1)"
235
+ assert wb.calculation.fullCalcOnLoad is True
236
+ # appended row present
237
+ found = [r for r in ws.iter_rows(values_only=True)
238
+ if r and r[0] == "appended"]
239
+ assert found and found[0][1] == 1 and found[0][2] is False
240
+ # copy preserved data
241
+ assert wb["Backup"]["A1"].value == "Zürich"
242
+
243
+
244
+ def test_help_and_errors():
245
+ for script in ["xlsx_create.py", "xlsx_read.py", "xlsx_edit.py",
246
+ "csv_to_xlsx.py", "xlsx_to_csv.py",
247
+ "xlsx_restructure.py", "xlsx_recalc.py"]:
248
+ proc = run(script, "--help")
249
+ assert "usage" in proc.stdout.lower()
250
+ bad = run("xlsx_read.py", "/nonexistent.xlsx", "--sheets",
251
+ expect_ok=False)
252
+ assert bad.returncode != 0
253
+ assert json.loads(bad.stderr)["ok"] is False
254
+
255
+
256
+ # ---------------------------------------------------------------------------
257
+ # Reference-aware restructuring (xlsx_restructure.py)
258
+ # ---------------------------------------------------------------------------
259
+
260
+ RESTRUCTURE_SPEC = {
261
+ "defined_names": {"SalesRange": "'Data'!$B$2:$B$4"},
262
+ "sheets": [
263
+ {
264
+ "name": "Data",
265
+ "rows": [
266
+ ["Region", "Sales", "Weight"],
267
+ ["North", 100, 0.5],
268
+ ["South", 200, 0.3],
269
+ ["East", 300, 0.2],
270
+ [None, None, None],
271
+ ["Total", None, None],
272
+ ],
273
+ "cells": {
274
+ "B6": {"formula": "SUM(B2:B4)"},
275
+ "C6": {"formula": "$B$2*C2"},
276
+ "D6": {"formula": "LOG10(B4)"},
277
+ "E6": {"formula": "SUM(B:B)"},
278
+ "F6": {"formula": '"row B2: "&B2'},
279
+ },
280
+ "merges": ["E2:E4", "A7:B7"],
281
+ "freeze_panes": "A2",
282
+ "autofilter": "A1:C4",
283
+ "conditional_formats": [
284
+ {"range": "B2:B4", "type": "cell_is",
285
+ "operator": "greaterThan", "formula": ["150"],
286
+ "fill": "C6EFCE"},
287
+ ],
288
+ "validations": [
289
+ {"range": "C2:C4", "type": "list",
290
+ "formula1": '"0.2,0.3,0.5"'},
291
+ ],
292
+ "tables": [
293
+ {"name": "SalesTbl", "range": "A1:C4"},
294
+ ],
295
+ },
296
+ {
297
+ "name": "Summary",
298
+ "rows": [["Grand total"]],
299
+ "cells": {
300
+ "B1": {"formula": "SUM(Data!B2:B4)"},
301
+ "B2": {"formula": "'Data'!$B$3"},
302
+ "B3": {"formula": "SUM(A1:A1)"},
303
+ },
304
+ },
305
+ ],
306
+ }
307
+
308
+
309
+ @pytest.fixture
310
+ def restructure_book(tmp_path):
311
+ spec_path = tmp_path / "rspec.json"
312
+ spec_path.write_text(json.dumps(RESTRUCTURE_SPEC), encoding="utf-8")
313
+ out = tmp_path / "restructure.xlsx"
314
+ run("xlsx_create.py", spec_path, out)
315
+ return out
316
+
317
+
318
+ def test_restructure_insert_rows_shifts_everything(restructure_book):
319
+ # merge A6:C6 gets pushed down; A1:A1 merge is before the insert point
320
+ proc = run("xlsx_restructure.py", restructure_book,
321
+ "--sheet", "Data", "--insert-rows", "3:2")
322
+ report = json.loads(proc.stdout)
323
+ assert report["ok"] and report["op"] == "insert"
324
+
325
+ wb = load_workbook(restructure_book)
326
+ data, summary = wb["Data"], wb["Summary"]
327
+ # values physically moved
328
+ assert data["A2"].value == "North"
329
+ assert data["A5"].value == "South" # was row 3
330
+ assert data["A8"].value == "Total" # was row 6
331
+ # same-sheet formulas rewritten (range expanded across insert point)
332
+ assert data["B8"].value == "=SUM(B2:B6)"
333
+ # absolute ref before insert point unchanged; relative arm shifted
334
+ assert data["C8"].value == "=$B$2*C2"
335
+ # function names, whole-column refs, string literals untouched
336
+ assert data["D8"].value == "=LOG10(B6)"
337
+ assert data["E8"].value == "=SUM(B:B)"
338
+ assert data["F8"].value == '="row B2: "&B2'
339
+ # cross-sheet formulas on the OTHER sheet rewritten
340
+ assert summary["B1"].value == "=SUM(Data!B2:B6)"
341
+ assert summary["B2"].value == "='Data'!$B$5"
342
+ # Summary-local refs not confused with Data refs
343
+ assert summary["B3"].value == "=SUM(A1:A1)"
344
+ # merges: E2:E4 spans the insert point -> expanded; A7:B7 -> shifted
345
+ merged = [str(r) for r in data.merged_cells.ranges]
346
+ assert "E2:E6" in merged and "A9:B9" in merged
347
+ # autofilter expanded, freeze panes intact
348
+ assert data.auto_filter.ref == "A1:C6"
349
+ assert data.freeze_panes == "A2"
350
+ # validation + conditional format ranges shifted
351
+ dv = data.data_validations.dataValidation[0]
352
+ assert str(dv.sqref) == "C2:C6"
353
+ cf = list(data.conditional_formatting)[0]
354
+ assert str(cf.sqref) == "B2:B6"
355
+ # native table expanded
356
+ assert data.tables["SalesTbl"].ref == "A1:C6"
357
+ # defined name rewritten
358
+ assert wb.defined_names["SalesRange"].attr_text == "'Data'!$B$2:$B$6"
359
+ # report is honest about limits
360
+ assert "chart anchors" in report["not_shifted"]
361
+ assert any(f["cell"] == "B1" and f["sheet"] == "Summary"
362
+ for f in report["formulas"])
363
+
364
+
365
+ def test_restructure_delete_rows_and_ref_errors(restructure_book):
366
+ run("xlsx_restructure.py", restructure_book,
367
+ "--sheet", "Data", "--delete-rows", "3")
368
+ wb = load_workbook(restructure_book)
369
+ data, summary = wb["Data"], wb["Summary"]
370
+ assert data["A3"].value == "East" # South deleted
371
+ assert data["B5"].value == "=SUM(B2:B3)" # range clamped
372
+ # single-cell ref into the deleted row becomes #REF!
373
+ assert summary["B2"].value == "='Data'!#REF!"
374
+ assert summary["B1"].value == "=SUM(Data!B2:B3)"
375
+ assert data.tables["SalesTbl"].ref == "A1:C3"
376
+
377
+
378
+ def test_restructure_insert_cols(restructure_book):
379
+ proc = run("xlsx_restructure.py", restructure_book,
380
+ "--sheet", "Data", "--insert-cols", "B:1")
381
+ report = json.loads(proc.stdout)
382
+ assert report["axis"] == "cols" and report["index"] == 2
383
+ wb = load_workbook(restructure_book)
384
+ data, summary = wb["Data"], wb["Summary"]
385
+ assert data["C2"].value == 100 # Sales moved B->C
386
+ assert data["C6"].value == "=SUM(C2:C4)"
387
+ assert data["D6"].value == "=$C$2*D2"
388
+ assert summary["B1"].value == "=SUM(Data!C2:C4)"
389
+ assert wb.defined_names["SalesRange"].attr_text == "'Data'!$C$2:$C$4"
390
+ merged = [str(r) for r in data.merged_cells.ranges]
391
+ assert "F2:F4" in merged # merge shifted right
392
+ assert "A7:C7" in merged # merge expanded across col B
393
+
394
+
395
+ # ---------------------------------------------------------------------------
396
+ # Tables, defined names, hyperlinks, notes, protection (edit + read paths)
397
+ # ---------------------------------------------------------------------------
398
+
399
+ def test_tables_create_append_list(tmp_path):
400
+ spec = {"sheets": [{"name": "T",
401
+ "rows": [["Item", "Qty"], ["a", 1], ["b", 2]],
402
+ "tables": [{"name": "Stock", "range": "A1:B3",
403
+ "style": "TableStyleLight1"}]}]}
404
+ spec_path = tmp_path / "tspec.json"
405
+ spec_path.write_text(json.dumps(spec), encoding="utf-8")
406
+ book = tmp_path / "tables.xlsx"
407
+ run("xlsx_create.py", spec_path, book)
408
+
409
+ wb = load_workbook(book)
410
+ tbl = wb["T"].tables["Stock"]
411
+ assert tbl.ref == "A1:B3"
412
+ assert tbl.tableStyleInfo.name == "TableStyleLight1"
413
+
414
+ # --add-table + --table-append auto-extends the range
415
+ run("xlsx_edit.py", book, "--sheet", "T",
416
+ "--add-table", "Extra:D1:E2",
417
+ "--table-append", 'Stock=["c", 3]')
418
+ wb = load_workbook(book)
419
+ ws = wb["T"]
420
+ assert ws.tables["Stock"].ref == "A1:B4"
421
+ assert ws["A4"].value == "c" and ws["B4"].value == 3
422
+ assert ws.tables["Extra"].ref == "D1:E2"
423
+
424
+ listing = json.loads(
425
+ run("xlsx_edit.py", book, "--sheet", "T", "--list-tables").stdout)
426
+ assert listing["tables"]["Stock"]["ref"] == "A1:B4"
427
+ assert set(listing["tables"]) == {"Stock", "Extra"}
428
+ # tables also appear in the read inventory
429
+ inv = json.loads(run("xlsx_read.py", book, "--sheets").stdout)
430
+ assert inv["sheets"][0]["tables"]["Stock"] == "A1:B4"
431
+
432
+
433
+ def test_names_hyperlinks_notes(tmp_path):
434
+ spec = {
435
+ "defined_names": {"Rate": "'D'!$B$1"},
436
+ "sheets": [{"name": "D", "cells": {
437
+ "A1": {"value": "docs",
438
+ "hyperlink": "https://example.com/docs"},
439
+ "B1": {"value": 0.07, "note": "quarterly rate"},
440
+ "C1": {"value": 1, "note": {"text": "check", "author": "QA"}},
441
+ }}],
442
+ }
443
+ spec_path = tmp_path / "nspec.json"
444
+ spec_path.write_text(json.dumps(spec), encoding="utf-8")
445
+ book = tmp_path / "names.xlsx"
446
+ run("xlsx_create.py", spec_path, book)
447
+
448
+ wb = load_workbook(book)
449
+ ws = wb["D"]
450
+ assert ws["A1"].hyperlink.target == "https://example.com/docs"
451
+ assert ws["B1"].comment.text == "quarterly rate"
452
+ assert ws["C1"].comment.author == "QA"
453
+ assert wb.defined_names["Rate"].attr_text == "'D'!$B$1"
454
+
455
+ # edit path: add/delete names, hyperlink, note, clear note
456
+ run("xlsx_edit.py", book, "--sheet", "D",
457
+ "--define-name", "Extra='D'!$C$1",
458
+ "--delete-name", "Rate",
459
+ "--hyperlink", "D1=https://example.com/more|More",
460
+ "--note", "D1=see more|Reviewer",
461
+ "--clear-note", "B1")
462
+ wb = load_workbook(book)
463
+ ws = wb["D"]
464
+ assert "Rate" not in wb.defined_names
465
+ assert wb.defined_names["Extra"].attr_text == "'D'!$C$1"
466
+ assert ws["D1"].hyperlink.target == "https://example.com/more"
467
+ assert ws["D1"].value == "More"
468
+ assert ws["D1"].comment.author == "Reviewer"
469
+ assert ws["B1"].comment is None
470
+
471
+ # read path: --notes and --names JSON output
472
+ notes = json.loads(run("xlsx_read.py", book, "--notes").stdout)["notes"]
473
+ coords = {(n["cell"], n["author"]) for n in notes}
474
+ assert ("D1", "Reviewer") in coords and ("C1", "QA") in coords
475
+ names = json.loads(run("xlsx_read.py", book, "--names").stdout)
476
+ assert names["defined_names"] == {"Extra": "'D'!$C$1"}
477
+
478
+
479
+ def test_sheet_protection(tmp_path):
480
+ spec = {"sheets": [{"name": "P", "rows": [["locked", "open"]],
481
+ "protection": {"password": "your-password",
482
+ "unlock": ["B1:B1"]}}]}
483
+ spec_path = tmp_path / "pspec.json"
484
+ spec_path.write_text(json.dumps(spec), encoding="utf-8")
485
+ book = tmp_path / "prot.xlsx"
486
+ run("xlsx_create.py", spec_path, book)
487
+
488
+ wb = load_workbook(book)
489
+ ws = wb["P"]
490
+ assert ws.protection.sheet is True
491
+ assert ws.protection.password # hash stored
492
+ assert ws["B1"].protection.locked is False
493
+ assert ws["A1"].protection.locked is not False
494
+ inv = json.loads(run("xlsx_read.py", book, "--sheets").stdout)
495
+ assert inv["sheets"][0]["protected"] is True
496
+
497
+ # edit path on a fresh unprotected sheet
498
+ plain = tmp_path / "plain.xlsx"
499
+ spec_path.write_text(json.dumps(
500
+ {"sheets": [{"name": "P", "rows": [["a", "b"]]}]}), encoding="utf-8")
501
+ run("xlsx_create.py", spec_path, plain)
502
+ run("xlsx_edit.py", plain, "--sheet", "P",
503
+ "--protect", "your-password", "--unlock", "B1:B1")
504
+ ws = load_workbook(plain)["P"]
505
+ assert ws.protection.sheet is True and ws["B1"].protection.locked is False
506
+
507
+
508
+ # ---------------------------------------------------------------------------
509
+ # Headless recalculation (xlsx_recalc.py) — branches on soffice presence
510
+ # ---------------------------------------------------------------------------
511
+
512
+ def test_recalc_reports_json_both_ways(tmp_path):
513
+ spec = {"sheets": [{"name": "R", "rows": [[2], [3]],
514
+ "cells": {"A3": {"formula": "SUM(A1:A2)"}}}]}
515
+ spec_path = tmp_path / "cspec.json"
516
+ spec_path.write_text(json.dumps(spec), encoding="utf-8")
517
+ book = tmp_path / "calc.xlsx"
518
+ run("xlsx_create.py", spec_path, book)
519
+
520
+ # absent-soffice branch is always testable by hiding PATH
521
+ env = dict(os.environ, LC_ALL="C", LANG="C", PATH=str(tmp_path))
522
+ proc = subprocess.run(
523
+ [sys.executable, str(SCRIPTS / "xlsx_recalc.py"), str(book)],
524
+ capture_output=True, text=True, env=env, encoding="utf-8")
525
+ assert proc.returncode == 0
526
+ absent = json.loads(proc.stdout)
527
+ assert absent["recalculated"] is False and "soffice" in absent["reason"]
528
+ assert "guidance" in absent
529
+
530
+ if not shutil.which("soffice"):
531
+ pytest.skip("LibreOffice not installed; absent branch covered above")
532
+
533
+ out = tmp_path / "calced.xlsx"
534
+ proc = run("xlsx_recalc.py", book, "--out", out, "--timeout", "300")
535
+ result = json.loads(proc.stdout)
536
+ assert result["recalculated"] is True
537
+ assert result["formula_cells"] == 1
538
+ assert result["with_cached_values"] == 1
539
+ # cached value now visible to --formulas
540
+ formulas = json.loads(run("xlsx_read.py", out, "--formulas").stdout)
541
+ entry = formulas["formulas"][0]
542
+ assert entry["formula"] == "=SUM(A1:A2)" and entry["cached"] == 5