diff --git a/skills/.curated/doc/LICENSE.txt b/skills/.curated/doc/LICENSE.txt
deleted file mode 100644
index 13e25df..0000000
--- a/skills/.curated/doc/LICENSE.txt
+++ /dev/null
@@ -1,201 +0,0 @@
-Apache License
-Version 2.0, January 2004
-http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf of
- any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don\'t include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/skills/.curated/doc/SKILL.md b/skills/.curated/doc/SKILL.md
deleted file mode 100644
index c6d9612..0000000
--- a/skills/.curated/doc/SKILL.md
+++ /dev/null
@@ -1,80 +0,0 @@
----
-name: "doc"
-description: "Use when the task involves reading, creating, or editing `.docx` documents, especially when formatting or layout fidelity matters; prefer `python-docx` plus the bundled `scripts/render_docx.py` for visual checks."
----
-
-
-# DOCX Skill
-
-## When to use
-- Read or review DOCX content where layout matters (tables, diagrams, pagination).
-- Create or edit DOCX files with professional formatting.
-- Validate visual layout before delivery.
-
-## Workflow
-1. Prefer visual review (layout, tables, diagrams).
- - If `soffice` and `pdftoppm` are available, convert DOCX -> PDF -> PNGs.
- - Or use `scripts/render_docx.py` (requires `pdf2image` and Poppler).
- - If these tools are missing, install them or ask the user to review rendered pages locally.
-2. Use `python-docx` for edits and structured creation (headings, styles, tables, lists).
-3. After each meaningful change, re-render and inspect the pages.
-4. If visual review is not possible, extract text with `python-docx` as a fallback and call out layout risk.
-5. Keep intermediate outputs organized and clean up after final approval.
-
-## Temp and output conventions
-- Use `tmp/docs/` for intermediate files; delete when done.
-- Write final artifacts under `output/doc/` when working in this repo.
-- Keep filenames stable and descriptive.
-
-## Dependencies (install if missing)
-Prefer `uv` for dependency management.
-
-Python packages:
-```
-uv pip install python-docx pdf2image
-```
-If `uv` is unavailable:
-```
-python3 -m pip install python-docx pdf2image
-```
-System tools (for rendering):
-```
-# macOS (Homebrew)
-brew install libreoffice poppler
-
-# Ubuntu/Debian
-sudo apt-get install -y libreoffice poppler-utils
-```
-
-If installation isn't possible in this environment, tell the user which dependency is missing and how to install it locally.
-
-## Environment
-No required environment variables.
-
-## Rendering commands
-DOCX -> PDF:
-```
-soffice -env:UserInstallation=file:///tmp/lo_profile_$$ --headless --convert-to pdf --outdir $OUTDIR $INPUT_DOCX
-```
-
-PDF -> PNGs:
-```
-pdftoppm -png $OUTDIR/$BASENAME.pdf $OUTDIR/$BASENAME
-```
-
-Bundled helper:
-```
-python3 scripts/render_docx.py /path/to/file.docx --output_dir /tmp/docx_pages
-```
-
-## Quality expectations
-- Deliver a client-ready document: consistent typography, spacing, margins, and clear hierarchy.
-- Avoid formatting defects: clipped/overlapping text, broken tables, unreadable characters, or default-template styling.
-- Charts, tables, and visuals must be legible in rendered pages with correct alignment.
-- Use ASCII hyphens only. Avoid U+2011 (non-breaking hyphen) and other Unicode dashes.
-- Citations and references must be human-readable; never leave tool tokens or placeholder strings.
-
-## Final checks
-- Re-render and inspect every page at 100% zoom before final delivery.
-- Fix any spacing, alignment, or pagination issues and repeat the render loop.
-- Confirm there are no leftovers (temp files, duplicate renders) unless the user asks to keep them.
diff --git a/skills/.curated/doc/agents/openai.yaml b/skills/.curated/doc/agents/openai.yaml
deleted file mode 100644
index 27ce451..0000000
--- a/skills/.curated/doc/agents/openai.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-interface:
- display_name: "Word Docs"
- short_description: "Edit and review docx files"
- icon_small: "./assets/doc-small.svg"
- icon_large: "./assets/doc.png"
- default_prompt: "Edit or review this .docx file and return the updated file plus a concise change summary."
diff --git a/skills/.curated/doc/assets/doc-small.svg b/skills/.curated/doc/assets/doc-small.svg
deleted file mode 100644
index 97289eb..0000000
--- a/skills/.curated/doc/assets/doc-small.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/skills/.curated/doc/assets/doc.png b/skills/.curated/doc/assets/doc.png
deleted file mode 100644
index e165178..0000000
Binary files a/skills/.curated/doc/assets/doc.png and /dev/null differ
diff --git a/skills/.curated/doc/scripts/render_docx.py b/skills/.curated/doc/scripts/render_docx.py
deleted file mode 100755
index 907ec89..0000000
--- a/skills/.curated/doc/scripts/render_docx.py
+++ /dev/null
@@ -1,296 +0,0 @@
-import argparse
-import os
-import re
-import subprocess
-import tempfile
-import xml.etree.ElementTree as ET
-from os import makedirs, replace
-from os.path import abspath, basename, exists, expanduser, join, splitext
-from shutil import which
-import sys
-from typing import Sequence, cast
-from zipfile import ZipFile
-
-from pdf2image import convert_from_path, pdfinfo_from_path
-
-TWIPS_PER_INCH: int = 1440
-
-
-def ensure_system_tools() -> None:
- missing: list[str] = []
- for tool in ("soffice", "pdftoppm"):
- if which(tool) is None:
- missing.append(tool)
- if missing:
- tools = ", ".join(missing)
- raise RuntimeError(
- f"Missing required system tool(s): {tools}. Install LibreOffice and Poppler, then retry."
- )
-
-
-def calc_dpi_via_ooxml_docx(input_path: str, max_w_px: int, max_h_px: int) -> int:
- """Calculate DPI from OOXML `word/document.xml` page size (w:pgSz in twips).
-
- DOCX stores page dimensions in section properties as twips (1/1440 inch).
- We read the first encountered section's page size and compute an isotropic DPI
- that fits within the target max pixel dimensions.
- """
- with ZipFile(input_path, "r") as zf:
- xml = zf.read("word/document.xml")
- root = ET.fromstring(xml)
- ns = {"w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"}
-
- # Common placements: w:body/w:sectPr or w:body/w:p/w:pPr/w:sectPr
- sect_pr = root.find(".//w:sectPr", ns)
- if sect_pr is None:
- raise RuntimeError("Section properties not found in document.xml")
- pg_sz = sect_pr.find("w:pgSz", ns)
- if pg_sz is None:
- raise RuntimeError("Page size not found in section properties")
-
- # Values are in twips
- w_twips_str = pg_sz.get(
- "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}w"
- ) or pg_sz.get("w")
- h_twips_str = pg_sz.get(
- "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}h"
- ) or pg_sz.get("h")
-
- if not w_twips_str or not h_twips_str:
- raise RuntimeError("Page size attributes missing in pgSz")
-
- width_in = int(w_twips_str) / TWIPS_PER_INCH
- height_in = int(h_twips_str) / TWIPS_PER_INCH
- if width_in <= 0 or height_in <= 0:
- raise RuntimeError("Invalid page size values in document.xml")
- return round(min(max_w_px / width_in, max_h_px / height_in))
-
-
-def calc_dpi_via_pdf(input_path: str, max_w_px: int, max_h_px: int) -> int:
- """Convert input to PDF and compute DPI from its page size."""
- with tempfile.TemporaryDirectory(prefix="soffice_profile_") as user_profile:
- with tempfile.TemporaryDirectory(prefix="soffice_convert_") as convert_tmp_dir:
- stem = splitext(basename(input_path))[0]
- pdf_path = convert_to_pdf(input_path, user_profile, convert_tmp_dir, stem)
- if not (pdf_path and exists(pdf_path)):
- raise RuntimeError("Failed to convert input to PDF for DPI computation.")
-
- info = pdfinfo_from_path(pdf_path)
- size_val = info.get("Page size")
- if not size_val:
- for k, v in info.items():
- if isinstance(v, str) and "size" in k.lower() and "pts" in v:
- size_val = v
- break
- if not isinstance(size_val, str):
- raise RuntimeError("Failed to read PDF page size for DPI computation.")
-
- m = re.search(r"(\d+)\s*x\s*(\d+)\s*pts", size_val)
- if not m:
- raise RuntimeError("Unrecognized PDF page size format.")
- width_pts = int(m.group(1))
- height_pts = int(m.group(2))
- width_in = width_pts / 72.0
- height_in = height_pts / 72.0
- if width_in <= 0 or height_in <= 0:
- raise RuntimeError("Invalid PDF page size values.")
- return round(min(max_w_px / width_in, max_h_px / height_in))
-
-
-def run_cmd_no_check(cmd: list[str]) -> None:
- subprocess.run(
- cmd,
- check=False,
- stdout=subprocess.DEVNULL,
- stderr=subprocess.DEVNULL,
- env=os.environ.copy(),
- )
-
-
-def convert_to_pdf(
- doc_path: str,
- user_profile: str,
- convert_tmp_dir: str,
- stem: str,
-) -> str:
- # Try direct DOC(X) -> PDF
- cmd_pdf = [
- "soffice",
- "-env:UserInstallation=file://" + user_profile,
- "--invisible",
- "--headless",
- "--norestore",
- "--convert-to",
- "pdf",
- "--outdir",
- convert_tmp_dir,
- doc_path,
- ]
- run_cmd_no_check(cmd_pdf)
-
- pdf_path = join(convert_tmp_dir, f"{stem}.pdf")
- if exists(pdf_path):
- return pdf_path
-
- # Fallback: DOCX -> ODT, then ODT -> PDF
- cmd_odt = [
- "soffice",
- "-env:UserInstallation=file://" + user_profile,
- "--invisible",
- "--headless",
- "--norestore",
- "--convert-to",
- "odt",
- "--outdir",
- convert_tmp_dir,
- doc_path,
- ]
- run_cmd_no_check(cmd_odt)
-
- odt_path = join(convert_tmp_dir, f"{stem}.odt")
-
- if exists(odt_path):
- cmd_odt_pdf = [
- "soffice",
- "-env:UserInstallation=file://" + user_profile,
- "--invisible",
- "--headless",
- "--norestore",
- "--convert-to",
- "pdf",
- "--outdir",
- convert_tmp_dir,
- odt_path,
- ]
- run_cmd_no_check(cmd_odt_pdf)
- if exists(pdf_path):
- return pdf_path
-
- return ""
-
-
-def rasterize(
- doc_path: str,
- out_dir: str,
- dpi: int,
-) -> Sequence[str]:
- """Rasterise DOCX (or similar) to images placed in out_dir and return their paths.
-
- Images are named as page-. with pages starting at 1.
- """
- makedirs(out_dir, exist_ok=True)
- doc_path = abspath(doc_path)
- stem = splitext(basename(doc_path))[0]
-
- # Use a unique user profile to avoid LibreOffice profile lock when running concurrently
- with tempfile.TemporaryDirectory(prefix="soffice_profile_") as user_profile:
- # Write conversion outputs into a temp directory to avoid any IO oddities
- with tempfile.TemporaryDirectory(prefix="soffice_convert_") as convert_tmp_dir:
- pdf_path = convert_to_pdf(
- doc_path,
- user_profile,
- convert_tmp_dir,
- stem,
- )
-
- if not pdf_path or not exists(pdf_path):
- raise RuntimeError(
- "Failed to produce PDF for rasterization (direct and ODT fallback)."
- )
- paths_raw = cast(
- list[str],
- convert_from_path(
- pdf_path,
- dpi=dpi,
- fmt="png",
- thread_count=8,
- output_folder=out_dir,
- paths_only=True,
- output_file="page",
- ),
- )
-
- # Rename convert_from_path's output format f'page{thread_id:04d}-{page_num:02d}.' to 'page-.'
- pages: list[tuple[int, str]] = []
- for src_path in paths_raw:
- base = splitext(basename(src_path))[0]
- page_num_str = base.split("-")[-1]
- page_num = int(page_num_str)
- dst_path = join(out_dir, f"page-{page_num}.png")
- replace(src_path, dst_path)
- pages.append((page_num, dst_path))
- pages.sort(key=lambda t: t[0])
- final_paths = [path for _, path in pages]
- return final_paths
-
-
-def main() -> None:
- parser = argparse.ArgumentParser(description="Render DOCX-like file to PNG images.")
- parser.add_argument(
- "input_path",
- type=str,
- help="Path to the input DOCX file (or compatible).",
- )
- parser.add_argument(
- "--output_dir",
- type=str,
- default=None,
- help=(
- "Output directory for the rendered images. "
- "Defaults to a folder next to the input named after the input file (without extension)."
- ),
- )
- parser.add_argument(
- "--width",
- type=int,
- default=1600,
- help=(
- "Approximate maximum width in pixels after isotropic scaling (default 1600). "
- "The actual value may exceed slightly."
- ),
- )
- parser.add_argument(
- "--height",
- type=int,
- default=2000,
- help=(
- "Approximate maximum height in pixels after isotropic scaling (default 2000). "
- "The actual value may exceed slightly."
- ),
- )
- parser.add_argument(
- "--dpi",
- type=int,
- default=None,
- help=("Override computed DPI. If provided, skips DOCX/PDF-based DPI calculation."),
- )
- args = parser.parse_args()
-
- try:
- ensure_system_tools()
-
- input_path = abspath(expanduser(args.input_path))
- out_dir = (
- abspath(expanduser(args.output_dir)) if args.output_dir else splitext(input_path)[0]
- )
-
- if args.dpi is not None:
- dpi = int(args.dpi)
- else:
- try:
- if input_path.lower().endswith((".docx", ".docm", ".dotx", ".dotm")):
- dpi = calc_dpi_via_ooxml_docx(input_path, args.width, args.height)
- else:
- raise RuntimeError("Skip OOXML DPI; not a DOCX container")
- except Exception:
- dpi = calc_dpi_via_pdf(input_path, args.width, args.height)
-
- rasterize(input_path, out_dir, dpi)
- print("Pages rendered to " + out_dir)
- except RuntimeError as exc:
- print(f"Error: {exc}", file=sys.stderr)
- raise SystemExit(1)
-
-
-if __name__ == "__main__":
- main()