SKILL.md
Paperclip Page
Use this skill to publish a static directory to the configured Paperclip pages host, for example https://pages.paperclip.ing/<slug>/.
Requirements
- Source directory contains
index.htmlat its root. awsCLI v2,curl, andjqare available on PATH for live publishes.- Environment variables are configured:
- PAPERCLIPPAGEBUCKET - PAPERCLIPPAGEBASEURL - AWSREGION - PAPERCLIPPAGEAWSACCESSKEYID and PAPERCLIPPAGEAWSSECRETACCESSKEY with the page-uploader credentials from Paperclip Secrets
- Optional environment variables:
- PAPERCLIPPAGEDEFAULTPREFIX - PAPERCLIPPAGEAWSPROFILE (alternative to the namespaced key pair) - PAPERCLIPPAGEAWSSESSIONTOKEN (only together with the namespaced key pair)
Do not bind the page-uploader credentials as global AWSACCESSKEYID / AWSSECRETACCESSKEY: static env keys take precedence over AWSPROFILE in every AWS SDK, so global names silently replace the host identity for every process in the agent run. The namespaced variables scope the uploader identity to this helper only. The ambient credential chain still works as a fallback when none of the PAPERCLIPPAGEAWS* credential variables are set.
Workflow
- Inspect the source directory and confirm it is public static content only.
- Run
scripts/publish.sh <dir> --dry-runto validate local structure and see
the resolved URL/prefix.
- Choose a slug:
- Use --slug <slug> when the user gave a stable URL path. - Omit --slug to derive one from the source directory name.
- Publish:
.agents/skills/paperclip-page/scripts/publish.sh ./site --slug my-page
- Return the printed public URL and S3 prefix to the issue/user.
Update Workflow
Updates are additive overwrites only. The helper never deletes remote objects.
.agents/skills/paperclip-page/scripts/publish.sh ./site --slug my-page --update
When the target prefix already exists, --update requires local ownership proof from ./site/.paperclip-page/state.json generated by an earlier publish from that same source directory. Without that state, create a new slug instead of overwriting another page.
Safety Rules
- Publish public content only. Do not publish secrets, customer data, private
company material, credentials, or internal logs.
- Never print AWS secret values.
- Never change bucket policy, IAM, DNS, CloudFront, or ACM settings from this
skill. Setup belongs to an operator runbook, not the publish helper.
- Never upload outside the configured bucket and prefix.
- Never use
aws s3 sync --deleteor requires3:DeleteObjectin v1. - The helper forces
--no-follow-symlinksand fails if any source symlink is
present.
- The helper rejects hidden files and dot-segment paths except its own
.paperclip-page/state.json.
- Slugs and prefix segments must use lowercase ASCII letters, digits, and
hyphens only.
- Keep site-wide root objects such as
404.htmloperator-managed; publishes
always target <slug>/... or <default-prefix>/<slug>/....
Troubleshooting
Slug already exists: choose a different slug or use--updatefrom the
original source directory containing .paperclip-page/state.json.
Missing index.html: build the static site first or point the helper at the
directory that contains the root HTML file.
Found symlink: replace symlinks with real files before publishing.AccessDenied: confirm the uploader IAM policy allowsListBucket,
GetObject, and PutObject for the configured bucket/prefix, and that the agent received the Paperclip Secrets.
- Public URL verification failed: check CloudFront deployment/DNS, object
existence, and that the distribution uses HTTPS with the private S3 REST origin.
See README.md next to this skill for operator setup, AWS policy examples, credential rotation, and install/attach commands.