PDF Merge
Overview
Combine two or more PDF files into a single output PDF. Source order is preserved — all pages of the first input, then all pages of the second, and so on. Merging is done by scripts/merge_pdfs.py, which wraps pypdf and writes the result atomically.
When to use
Use this skill whenever the user wants several PDFs combined into one file: "merge", "combine", "join", "concatenate", "多份合成一份", "把 A.pdf 和 B.pdf 合并". Do not use it for splitting, compressing, rotating, or extracting pages — those are different operations.
Prerequisites
The script needs pypdf. Check first:
"C:/Users/Administrator/.workbuddy/binaries/python/envs/default/Scripts/python.exe" -c "import pypdf; print(pypdf.__version__)"
If the import fails, install it into the managed venv:
"C:/Users/Administrator/.workbuddy/binaries/python/envs/default/Scripts/python.exe" -m pip install pypdf
Use the managed venv interpreter above (not a bare python) so dependencies stay isolated.
Workflow
- Resolve every input path. Confirm each source PDF exists and get its absolute path. If the user referred to files vaguely ("the two reports I uploaded"), locate them and confirm which ones before merging.
- Confirm the order. The merge order matters. If the user did not state it, use the order they listed the files in, and say so when reporting the result. Ask only if the order is genuinely ambiguous.
- Choose the output path. Default to the directory of the first input, named after it plus
_merged.pdf(e.g.report_a.pdf+report_b.pdf→report_a_merged.pdf). Never overwrite an existing file unless the user asked for it (then pass--overwrite). - Run the script (see below).
- Verify and report. The script prints a JSON summary. On success, call
present_fileswith the merged PDF so the user can open it, and state the output path, total page count, and the per-file page breakdown.
Running the script
"C:/Users/Administrator/.workbuddy/binaries/python/envs/default/Scripts/python.exe" \
"<skill-dir>/scripts/merge_pdfs.py" \
"<out.pdf>" "<in1.pdf>" "<in2.pdf>" [<in3.pdf> ...] [--bookmarks] [--overwrite] [--quiet]
Positional arguments: output path first, then two or more input PDFs in the desired order.
Options:
| Option | Effect |
|---|---|
--bookmarks |
Add one bookmark per source file, titled with that file's name (without extension). Useful when merging long documents. |
--overwrite |
Allow replacing an existing output file. Without it, an existing output path is an error. |
--quiet |
Suppress the JSON summary on success. |
-h, --help |
Print usage. |
Exit codes: 0 success, 1 usage or input error, 2 dependency missing, 3 write error.
Example — merge two PDFs:
"C:/Users/Administrator/.workbuddy/binaries/python/envs/default/Scripts/python.exe" \
"C:/Users/Administrator/.workbuddy/skills/pdf-merge/scripts/merge_pdfs.py" \
"D:/docs/combined.pdf" "D:/docs/a.pdf" "D:/docs/b.pdf"
Success output:
{
"output": "D:\\docs\\combined.pdf",
"total_pages": 12,
"sources": [
{ "file": "D:\\docs\\a.pdf", "pages": 7 },
{ "file": "D:\\docs\\b.pdf", "pages": 5 }
],
"bookmarks": false
}
Handling problems
ERROR: input file not found— re-check the path; quote paths containing spaces.ERROR: output already exists— pick a different output name, or pass--overwriteonly if the user agreed to replace it.cannot read <file>— the PDF is corrupt or encrypted with a non-empty password. Report which file failed; do not silently skip it.WARNING: <file> has 0 pages— that input was blank and was dropped from the merge. Tell the user.- Write fails — the script keeps the original file intact (it writes to a temp file then renames), so nothing is corrupted. Report the underlying error.
- Page count does not match expectations — note that encrypted/anomalous PDFs may report or copy pages differently; report the actual JSON summary rather than assuming.
Notes
- Only pages are copied; per-document annotations like existing internal outlines are not carried over. Use
--bookmarksto add a fresh top-level entry per source file. - Files stay local — nothing is uploaded anywhere.
- Merging is lossless at the page level: page content, embedded fonts, and images are preserved by
pypdf's page copy.