Files
c65bc9a9bf Release docs for paperclip v2026.916.0 (#125)
Brings **paperclip-docs** in line with paperclip **v2026.916.0**,
shipping the `v2026.831.1 → v2026.916.0` cycle drafted on `nightly`,
stamped to the release tag, with a documentation changelog entry.

This branch was cut from `nightly` **after** merging `origin/main` into
it, so it sits on top of the operator-first connectors catalog (#124)
rather than reverting it.

## Manifest

**New pages (4)**
- `docs/reference/api/connection-intents.md` — Connection Intents API
- `docs/reference/cli/connections.md` — `connections` command
- `docs/reference/cli/managed-agent.md` — `managed-agent` command
- `docs/reference/cli/test-drive.md` — `test-drive` command

**Updated pages (17)**
- Roles & Permissions + Company Administration — `tools:*` role-default
changes
- Connect an Agent to GitHub — managed GitHub connection (Connectors),
Option C
- Agents API — Managed/Remote Agent Profiles, `***REDACTED***` env
serialization
- Tool Gateway API — agent self-authorization (`start-authorization`,
`token`)
- Instance Admin API — instance-settings + task-drain routes
- Plugin SDK — `ctx.access` + `ctx.authorization` clients,
login-PTY/duplex streaming
- Environment Variables — Paperclip ID Connector block + HTTP adapter
allowlist var
- Adapters: Codex (`gpt-5.6-sol` default, Fast mode, auth cache), Claude
Code (Fable 5.1 + CLI floor), Grok Local (SuperGrok subscription auth),
HTTP (SSRF guard), Sandbox Providers (Daytona warm runner), OpenCode
(model pre-flight)
- CLI: `adapter detect-model`, `onboard` tool-action signing secret
- Command palette — recent tasks in sidebar
- `docs/reference/changelog.md` — new `v2026.916.0` accordion entry

All 21 touched pages stamped `paperclip_version: v2026.916.0`.

## Verification

**Tag-accuracy gate (Phase 5.7)** — `check-tag-accuracy.mjs --tag
v2026.916.0 --base main --head nightly` flagged 5 pages, **every one
verified present in the code at the release tag** and cleared as known
`verify-edit` false-positive classes. No content was quarantined; **no
post-tag leaks**:

| Page | Flagged claim(s) | Verified at tag |
|---|---|---|
| `cli/connections.md` | `PAPERCLIP_RUNTIME_TOOLS_*` (3) | present in
`cli/src/commands/client/connections.ts` (runtime-injected env) |
| `cli/managed-agent.md` | `--profile-key`, `--api-key-secret-id` |
present in `cli/src/commands/managed-agent.ts`
(`.requiredOption`/`.option`) |
| `cli/test-drive.md` | `--harness` | present in
`cli/src/commands/test-drive.ts` (`new Option`) |
| `deploy/environment-variables.md` | `PAPERCLIP_ID_CONNECTOR_*` (5) |
present in `.env.example` at tag |
| `plugins/sdk.md` | `PLUGIN_*` (6) | present in
`packages/plugins/sdk/src/index.ts` (exported constants) |

Rationale: nightly's drafts were authored from parent `af8439a`, **226
commits inside the tag**, so they document in-tag surfaces by
construction.

### ⚠ Drift
`check-drift.mjs --against v2026.916.0` returned 14 records — **all
verified present at the tag** (checker false positives), listed here for
the reviewer to confirm:

- **env-var (9, high-confidence in the tool, verified present):**
`PAPERCLIP_WORKSPACE_GIT_SCAN_{CONCURRENCY,QUEUE_CAPACITY,TIMEOUT_MS,CACHE_TTL_MS}`
and
`PAPERCLIP_ID_CONNECTOR_{BASE_URL,ENVIRONMENT,INSTANCE_ID,SIGN_PRIVATE_KEY,SEAL_PRIVATE_KEY}`
— all present in `.env.example` at the tag; the drift scanner's scoped
file scan missed them.
- **Verify: rest-route (5, medium-confidence):** `POST/PUT/GET
/api/companies/import/transfers*` — present at the tag in
`server/src/routes/companies.ts`, registered via the
`COMPANY_IMPORT_TRANSFERS_ROUTE_PATH` prefix constant (the documented
prefix/dynamic-registration blind spot).

### ⚠ Verification Failures
None. All tag-accuracy and drift flags above were verified present at
the tag.

### ↻ Renames detected
None. The connectors catalog (`docs/connectors/**`) arrived via the
`main` merge (#124), not as a renamed surface; no new top-level draft
directories were introduced this cycle.

## Screenshots
**238 of 342 screenshots** flagged stale across 50 routes (see
`SCREENSHOTS_PENDING.md`). This is a wide 16-day window touching ~921 UI
files, so most are dependency-touch flags rather than confirmed visual
changes. Recommend `npm run screenshots:refresh` on this release branch
as a dedicated follow-up before merge; PNGs go to a separate PR for
human review.

## Build gates (all green on this branch)
- `npm run docs:build` — 257 pages
- `npm run docs:test` — SEO metadata, crawlable-links (71,749 links
resolve), doc-link-resolution, skill-source-blocks, static-routes,
hierarchical-nav

## Post-merge checklist (Phase 9 — do NOT skip)
- [ ] Squash-merge this PR (repo is squash-only)
- [ ] `git checkout main && git pull`
- [ ] `git tag docs/v2026.916.0 && git push --tags`
- [ ] `node scripts/sync/realign-nightly.mjs release/v2026.916.0 --push`
(restore ancestry; keep nightly post-tag drafts)
- [ ] Flip `nightly` `.sync-state.json` back to `"branch_mode":
"nightly"` (leave `base_release_tag` at `v2026.916.0`)
- [ ] Verify `docs.paperclip.ing` serves the release: a new page
(`/reference/cli/test-drive/`), a changed page, and the changelog top
entry reads `Docs for v2026.916.0`
- [ ] If production is stale, republish: `npm run docs:build && npx
wrangler pages deploy .site --project-name paperclip-docs --branch main`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Co-authored-by: DevRel Gemini <[email protected]>
Co-authored-by: Paperclip <[email protected]>
Co-authored-by: Dotta <[email protected]>
Co-authored-by: ClaudeCoder <[email protected]>
2026-09-17 11:15:48 +02:00

133 lines
5.3 KiB
Markdown

---
paperclip_version: v2026.916.0
seo_title: HTTP Webhook Adapter
seo_description: Send a JSON webhook to a service you control. Use it when the runtime is remote, long-lived, or already exposed as an API rather than a local CLI.
---
# HTTP
The `http` adapter sends a JSON webhook request to a service you control. Use it when the runtime is remote, long-lived, or already exposed as an API instead of a local command.
> **Info:** `http` is a built-in internal adapter used by Paperclip's runtime. It's currently shown as **"Coming soon"** in the agent-config adapter-type dropdown and can't be selected manually. To target it today, configure the agent via the API or an imported company export.
---
## When To Use
- The agent runs in the cloud or behind another service.
- You want Paperclip to trigger a webhook and let the remote service do the rest.
- The runtime already expects a JSON body and returns a simple success or failure response.
## When Not To Use
- The runtime is just a local script or command. Use [Process](./process.md).
- You need session persistence or built-in CLI behavior. Use one of the local adapters instead.
- You need Paperclip to parse a rich stdout transcript from the remote runtime.
---
## Common Fields
| Field | Required | Notes |
|---|---:|---|
| `url` | yes | Absolute `http://` or `https://` endpoint. |
| `method` | no | HTTP method to use. Defaults to `POST`. |
| `headers` | no | Extra request headers. |
| `payloadTemplate` | no | JSON object merged into the request body before the standard Paperclip fields are added. |
| `timeoutMs` | no | Request timeout in milliseconds. `0` means no timeout. |
> **Note:** The HTTP adapter does not run a child process. It sends a single request, waits for the response, and treats any non-2xx response as a failure.
---
## Request Body
Paperclip sends a JSON payload that always includes:
- `runId`
- `agentId`
- `context`
Any `payloadTemplate` fields are merged in first, then Paperclip adds the standard fields above. If a key collides, the standard Paperclip field wins.
Example body shape:
```json
{
"runId": "run-123",
"agentId": "agent-123",
"context": {
"taskId": "issue-123",
"wakeReason": "scheduled",
"commentId": null
},
"customField": "value"
}
```
Your service can use `PAPERCLIP_API_URL` and a Paperclip API key to call back into the control plane after it finishes.
---
## Private vs public endpoints
Every request the HTTP adapter sends is checked at the socket boundary before it connects, so you can't accidentally point a webhook at something inside your own network. Public origins are allowed by default. Origins that resolve to private, reserved, or loopback addresses — including `localhost`, `10.0.0.0/8`, `192.168.0.0/16`, and friends — are rejected. Link-local metadata endpoints (like a cloud provider's `169.254.x.x`) are always blocked and can't be opted back in.
The check also pins the DNS result: the address the guard approves is the address the socket dials. That closes the door on a hostname that resolves to a public address during the check and a private one a moment later.
If your runtime genuinely lives on a private origin — an internal service, a webhook on your own subnet — you opt it in explicitly with the `PAPERCLIP_HTTP_ADAPTER_PRIVATE_ENDPOINT_ALLOWLIST` environment variable on the Paperclip host. It's a comma-separated list of **exact origins**, where an origin is the scheme, host, and port together (for example `http://hooks.internal.example:8080`). Matching is case-insensitive, and each entry must:
- use `http` or `https`,
- carry no path beyond `/`,
- include no userinfo, query string, or fragment.
Anything that doesn't parse as a clean origin is ignored rather than loosely matched, so a typo silently drops out of the allowlist instead of opening more than you meant. An origin only reaches private networking when it matches an allowlist entry exactly — a different port or scheme is a different origin. See the [environment variables reference](../deploy/environment-variables.md) for the full entry.
---
## Environment Test
The `Test Environment` button checks:
- The URL is present and uses `http` or `https`.
- The configured method is valid.
- The endpoint responds to a quick `HEAD` probe when reachable.
If the probe fails in a private network, that can still be acceptable — the important part is whether the runtime can actually receive the production request. Note that a private origin also has to be on the allowlist described in [Private vs public endpoints](#private-vs-public-endpoints), or the production request is rejected before it connects regardless of what the probe reported.
---
## Example
```json
{
"adapterType": "http",
"adapterConfig": {
"url": "https://agent.example.com/paperclip/heartbeat",
"method": "POST",
"headers": {
"Authorization": "Bearer <shared-secret>"
},
"payloadTemplate": {
"source": "paperclip"
},
"timeoutMs": 10000
}
}
```
---
## Practical Notes
- Use a shared secret or header-based auth on the remote service.
- Keep the endpoint idempotent when possible because retries are easier to support.
- Return a 2xx response when the webhook was accepted, not when all follow-up work is complete.
---
## Next Steps
- [Creating an Adapter](./creating-an-adapter.md)
- [External Adapters](./external-adapters.md)