본문으로 건너뛰기
cccskills
무료GitHub에 공개

pdf-forms

Fill in a PDF form, annotate or redact a PDF, or add, remove or rotate its pages, when the office_edit tool is not available. Fills fillable and flat forms with the scripts FORMS.md walks through, puts notes and text on a page, blacks out words so they are gone from the file, and inserts, deletes and rotates pages with pypdf, qpdf or pdftk. Merging, splitting, creating, watermarking and encrypting PDFs are the pdf skill's.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(11)

  • SKILL.md4.9 KB
  • FORMS.md11.6 KB
  • LICENSE.txt1.4 KB
  • scripts/check_bounding_boxes.py2.7 KB
  • scripts/check_fillable_fields.py268 B
  • scripts/convert_pdf_to_images.py1008 B
  • scripts/create_validation_image.py1.2 KB
  • scripts/extract_form_field_info.py4.2 KB
  • scripts/extract_form_structure.py3.9 KB
  • scripts/fill_fillable_fields.py3.7 KB
  • scripts/fill_pdf_form_with_annotations.py3.2 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

PDF Forms, Notes, Redaction and Pages

Changes to an existing PDF, made with scripts. Merging, splitting, creating, watermarking and encrypting are in the pdf skill; reading a PDF is read_file.

Dependencies are pre-installed in the sandbox image — do NOT pip install or npm install anything.

  • Python libraries (always present): pypdf, pdfplumber, pypdfium2, Pillow.
  • CLI tools (present on current sandbox images): pdftoppm (poppler-utils), qpdf, pdftk. If one returns not found, use the pypdf way on this page rather than trying to install it.

Fill in a form

Follow FORMS.md, step by step and in order. It checks whether the PDF has fillable fields, then fills them, or writes the answers onto a flat form as annotations, with the scripts in scripts/.

Add a note or text to a page

from pypdf import PdfWriter
from pypdf.annotations import FreeText, Text

writer = PdfWriter(clone_from="input.pdf")
# A rect is (left, bottom, right, top) in PDF points, from the page's bottom-left corner.
writer.add_annotation(page_number=0, annotation=Text(rect=(50, 742, 70, 762), text="Check this total"))  # a comment icon
writer.add_annotation(page_number=0, annotation=FreeText(
    text="Approved", rect=(50, 700, 200, 720), font_size="12pt", border_color=None, background_color=None,
))  # text shown on the page
writer.write("annotated.pdf")

To put a note beside some words, find them with pdfplumber as the redaction below does: its top and bottom count from the page's top, so a rect's bottom is page.height - bottom.

Redact

A black box drawn over text leaves the text in the file, and anyone can still copy it out. Render the page, black out the words on the image, and put the image in the page's place:

import io
import subprocess

import pdfplumber
from PIL import Image, ImageDraw
from pypdf import PdfReader, PdfWriter

SRC, PAGE, DPI = "input.pdf", 1, 200  # PAGE counts from 1
WORDS = ["Jane Doe", "555-0142"]

with pdfplumber.open(SRC) as pdf:
    found = [hit for word in WORDS for hit in pdf.pages[PAGE - 1].search(word, regex=False)]
print(f"{len(found)} matches")  # 0 means the words are not in the text layer: a scanned page needs OCR first

subprocess.run(["pdftoppm", "-png", "-r", str(DPI), "-f", str(PAGE), "-l", str(PAGE), "-singlefile", SRC, "page"], check=True)
image = Image.open("page.png").convert("RGB")
draw, scale = ImageDraw.Draw(image), DPI / 72
for hit in found:
    draw.rectangle([hit["x0"] * scale - 2, hit["top"] * scale - 2, hit["x1"] * scale + 2, hit["bottom"] * scale + 2], fill="black")
flat = io.BytesIO()
image.save(flat, format="PDF", resolution=DPI)

writer = PdfWriter()
for number, page in enumerate(PdfReader(SRC).pages, start=1):
    writer.add_page(PdfReader(flat).pages[0] if number == PAGE else page)
writer.write("redacted.pdf")

The redacted page becomes a picture: its text can no longer be selected or searched. pdftotext -f 1 -l 1 redacted.pdf - (with your page number) must not print the words. The same words may also be on other pages, in the metadata (PdfReader(SRC).metadata), in form fields or in annotations.

Add, remove and rotate pages

pypdf

from pypdf import PdfReader, PdfWriter

writer = PdfWriter(clone_from="input.pdf")
writer.pages[0].rotate(90)  # Rotate page 1 by 90 degrees clockwise
del writer.pages[2]  # Remove page 3
writer.insert_page(PdfReader("cover.pdf").pages[0], index=0)  # cover.pdf's first page becomes page 1
writer.insert_blank_page(index=2)  # A blank page at position 3, the size of the last page
writer.write("output.pdf")

Page indexes count from 0, and each insert or removal moves the pages after it.

qpdf

qpdf input.pdf output.pdf --rotate=+90:1  # Rotate page 1 by 90 degrees
qpdf input.pdf --pages . 1-2,4-z -- output.pdf  # Remove page 3
qpdf input.pdf --pages . 1 cover.pdf 1 . 2-z -- output.pdf  # cover.pdf's first page after page 1

pdftk

pdftk input.pdf rotate 1east output rotated.pdf  # Rotate page 1; the other pages stay as they are
pdftk input.pdf cat 1-2 4-end output output.pdf  # Remove page 3
pdftk A=input.pdf B=cover.pdf cat A1 B1 A2-end output output.pdf  # cover.pdf's first page after page 1

Check what you changed

pdftoppm -png -r 80 output.pdf page && ls -1 "$PWD"/page-*.png

Ask vision_analyze about each page image once: a filled field, a note or a black box where it belongs, pages the right way up and in order.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

The Arbor research-coordinator protocol: the OBSERVE -> IDEATE -> SELECT -> DISPATCH -> DECIDE cycle over a durable Idea Tree. Preloaded automatically on /auto-research sessions. The coordinator never edits code or runs commands — executors do that in isolated worktrees; the coordinator steers the tree with idea_tree / dispatch_experiments / merge_experiment.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

invergent-ai/surogates282026년 10월 20일 업데이트

The Arbor executor workflow: clone the repo from the git bundle your brief hands you, implement and evaluate exactly ONE hypothesis with the file tools, then report structured results via worker_complete. Preloaded automatically on arbor-executor task workers. Never touch the held-out test split.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

invergent-ai/surogates282026년 10월 20일 업데이트

Hard-gated ideation for an Arbor research run. Load at the START of every IDEATE round, before drafting any hypothesis. Enforces the PI mindset (mechanism over knob), the four-question first-principles probe, the kill-filter, and the four-line hypothesis format. Ported from Arbor's idea_drafting + first_principles_probe.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

invergent-ai/surogates282026년 10월 20일 업데이트

DECIDE-phase doctrine for an Arbor research run: when to merge, prune, combine, or finalize; how the held-out merge gate works; and the rule that the final report uses TEST scores. Load before deciding what to do with completed experiments.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

invergent-ai/surogates282026년 10월 20일 업데이트

Intake for an autonomous research run (Arbor). Use when the user wants to optimize a metric in a repo over many isolated experiments — 'optimize this benchmark', 'improve the model F1 overnight', 'beat the leaderboard'. Discovers the repo/eval/splits, measures the baseline, confirms a Research Contract, then emits a ready-to-send /auto-research command. Does NOT start the run itself.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

invergent-ai/surogates282026년 10월 20일 업데이트

You MUST use this before any creative work — creating features, building components, drafting documents, designing workflows, or modifying behavior. Explores your human partner's intent, requirements, and design before any implementation begins.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

invergent-ai/surogates282026년 10월 20일 업데이트

invergent-ai의 스킬 모두 보기

이 스킬의 문제 신고