Uploads PR and validation media to a self-hosted attach Worker via the installed attach CLI (`attach` or `gh attach`): zero-config hosted device-flow login with an ATTACH_GITHUB_CLIENT_ID override for custom deployments, put/delete/logout of screenshots and artifacts, preview `/p/…` URLs, raw `/o/…` embeds via `--markdown`, and `--json`/`--url` output; or GitHub App JWT enroll then `att_` PUT for agents. Use when the user asks to attach a screenshot, upload PR media, put an image on attach.uinaf.dev (or ATTACH_API_BASE), share a validation screenshot URL, run attach login/put/delete/logout, use gh attach, host validation media, take down attach media, or enroll an App agent for attach. Do not use for Worker deploy, vault, Cloudflare ops, or inventing a second upload client.
—
—
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
attach / gh attach)brew install uinaf/tap/attach
# or: npm i -g @uinaf/attach-cli
# or:
gh extension install uinaf/gh-attachThe skill must not fetch install scripts. After install, attach and
gh attach share the same commands.
| Variable | Required | Purpose |
|---|---|---|
ATTACH_GITHUB_CLIENT_ID | custom | GitHub App client id override for a custom deployment |
ATTACH_API_BASE | no | Worker origin; default https://attach.uinaf.dev |
The hosted service bundles the public client id for the uinaf Attach GitHub App. A self-hosted deployment must set both variables for its own Worker and GitHub App.
attach login [--json]
attach put <file> [--repo owner/name] [--pr N] [--dry-run] [--json|--markdown|--url]
attach delete <url-or-key> [--dry-run] [--json]
attach logout [--json]
attach help [--json]gh auth tokens. Mints an att_ key via POST /v1/enroll/human. On a
headless host, immediately relay the emitted verification URL and short-lived
device code to the intended user, then keep the process running while they
authorize. Never copy the code into logs, issues, commits, or PRs.att_. Default stdout is the preview URL
(/p/…). --markdown embeds the raw object URL (/o/…). --url
prints raw URL only; --json prints the API body.curl -sI <url> (expect 404 or 410) before
reporting success.~/.config/attach/credentials.json (or
$XDG_CONFIG_HOME/attach/credentials.json).--json describes commands,
positionals, flags, types, exclusivity, and environment requirements.owner/name / PR metadata, and conflicting output modes exit 2.--json returns machine-readable command results and structured errors with
nonzero exit status. Login device-flow instructions remain on stderr; relay
their verification URL and code to the intended user instead of treating the
code as a credential that cannot cross the headless boundary.put --dry-run reads and validates the local file, reports detected type,
size, metadata, output mode, and target origin, but does not read credentials
or call the Worker.delete --dry-run validates the key/path/URL and target origin without
reading credentials or calling the Worker. Dry-run does not prove auth,
ownership, quota, or service availability.Stored at ~/.config/attach/credentials.json (mode 0600). Contains token
(att_…), key_id, principal, stamp, api_base. Do not cat or paste it
into chat.
| Symptom | Likely cause | Agent action |
|---|---|---|
| missing client id with custom API base | custom App override unset | ask operator for custom App client id |
| enroll / allowlist error | user not in ALLOWED_GITHUB_USER_IDS | stop; operator must allowlist |
| 401 on put after login | expired/revoked key | attach login once; then stop if still failing |
| command not found | CLI not installed | ask user to install; do not curl-upload |