# Workbench agent docs

Workbench is an agent-first Markdown artifact service. Any agent can create an artifact without an account, token, or connector setup. Creation returns a private URL scoped to that one artifact. The unlisted review page is a deliberately tiny editor: humans can type, use Markdown-style heading shortcuts, edit table cells, select text and paste a URL to link it, open every link in a new tab, restore an earlier draft from the version dropdown, and copy the current document. Human changes sync immediately, while small edits stay staged against the last history checkpoint until they add up to a substantial passage, rewrite, or Markdown structure change. Agent updates and restores remain explicit checkpoints. Workbench deliberately stops before publishing. Agents can request deletion, but deletion is permanent and only happens after the human submits a short-lived confirmation page.

## Start at Workbench

If a human sends you https://workbench.foo, begin immediately:

1. GET https://workbench.foo/api/artifacts for the machine-readable creation contract.
2. POST a title and complete Markdown draft to that endpoint.
3. Keep the returned `agent_url` with this artifact. It is the agent's private, artifact-scoped URL for later reads and revisions.
4. Give the returned `review_url` to the human instead of pasting the full draft into chat.
5. Fetch `agent_url` with `Accept: application/json` and follow its artifact-scoped contract for later edits.
6. If the human later asks to delete the artifact, use the deletion-request link in that contract and give its confirmation URL back to the human.

No authentication is required to create. Anyone with a specific `review_url` can view and edit that artifact, but public access cannot list artifacts. Treat the review URL as an unlisted capability link.

Example create request:

```http
POST https://workbench.foo/api/artifacts
Content-Type: application/json
```

```json
{
  "title": "Draft title",
  "markdown": "# Draft title\n\nComplete Markdown here.",
  "status": "draft",
  "by": "ai:grok",
  "change_summary": "Created the first draft"
}
```

The response includes a clean, unlisted human `review_url` and a private `agent_url`. The human can edit Markdown from the review page; the agent URL can access only the newly created artifact. Workbench has no public artifact catalog or discovery endpoint.

## Supported Markdown

Use GitHub Flavored Markdown (GFM). Workbench parses, edits, and serializes these forms:

- Paragraphs separated by blank lines
- Headings: `# H1`, `## H2`, and `### H3`
- Bulleted and numbered lists, including nesting
- Blockquotes
- Fenced code blocks and inline code
- Horizontal rules
- Bold, italic, and strikethrough
- Links and autolinked URLs
- GFM pipe tables

Use a header row and delimiter row for tables. Keep cell content inline; portable GFM does not support merged cells, row spans, or multi-paragraph cells.

```markdown
| Item | Owner | Status |
| --- | --- | --- |
| Draft | Rich | Ready |
```

The Copy action writes both semantic HTML and the canonical Markdown to the clipboard. WordPress and Google Docs can use the HTML table. Slack messages do not support table formatting, so the plain-text clipboard flavor keeps the GFM pipe table readable; Slack Canvas supports native tables.

Do not rely on task lists, footnotes, or raw HTML as portable Workbench syntax.

## Images

Agents can upload a local PNG, JPEG, WebP, or GIF up to 20 MB. Humans can paste or drop files into the editor. Uploaded images have stable, unlisted URLs that work in copied Markdown. Anyone with the exact image URL can view it.

1. POST the artifact's `_links.upload_image` with `content_type`, `size` in bytes, and optional `alt`, using the artifact bearer token.
2. Upload directly to Blob using the returned `pathname` and short-lived `token` with `put` from `@vercel/blob/client`.
3. POST the returned `complete_url` with the artifact bearer token. The response contains `image.url` and `image.markdown`. Completion is safe to retry.
4. Read the latest document and insert that Markdown at the requested position using the existing version-checked update. An upload alone does not change the document.

A runnable Node.js 24 helper is available at `/upload-image.mjs`. Install `@vercel/blob` beside the downloaded script, set `WORKBENCH_AGENT_URL` to the private artifact link without printing it, then run:

```sh
node upload-image.mjs ./image.png 'Description of the image'
```

The helper uploads and returns the URL and Markdown; it does not edit the draft. For a new document, create the artifact first, then upload and insert its images. Ordinary HTTPS image links also work, but Workbench does not import those files. SVG uploads, base64 images, cropping, and resizing controls are unsupported.

Removing an image from the draft preserves the file for older versions. Human-confirmed document deletion schedules uploaded files for cleanup; unfinished uploads expire after 24 hours.


## Continue with the artifact link

The create response returns a URL shaped like:

```text
https://workbench.foo/share/<artifact-slug>?token=<token>
```

That URL is self-describing and contains an artifact-scoped credential.

1. Fetch it with `Accept: application/json`.
2. Read `agent.first_steps`, `contract`, and `_links` from the response.
3. Send the URL token as `Authorization: Bearer <token>`.
4. GET state immediately before editing. Its Markdown is authoritative and may contain human edits.
5. Apply your intended change to that latest Markdown, then POST with `expected_version`.
6. On HTTP 409, re-read state and merge your intended change into the latest Markdown before retrying. Never resend an older remembered draft.

The same shared URL returns raw Markdown when requested with `Accept: text/markdown`. A normal fetch returns the machine-readable state and exact API links. New artifact links last one year.

## Artifact-scoped API

All endpoints below require the bearer token from the artifact URL.

- `GET /api/agent/<artifact-id>/state`
- `POST /api/agent/<artifact-id>/update`
- `POST /api/agent/<artifact-id>/delete-request`

An update body accepts `expected_version` plus one or more of `markdown`, `title`, or `status`. Include `by` and `change_summary`. Human autosaves and agent updates increment the same optimistic version counter, so stale writes return HTTP 409 instead of overwriting newer work. That counter is for synchronization: the human-facing history picker stages small autosaves until their cumulative difference from the last checkpoint becomes meaningful. A substantial passage, a short-document rewrite, or a Markdown structure change creates a checkpoint. Every agent update remains an explicit checkpoint.

## Human-confirmed deletion

Only start this flow when the human explicitly asks to delete the artifact.

1. GET the latest state.
2. POST its `artifact.version` as `expected_version` to `_links.request_deletion`.
3. Give the returned `confirmation_url` to the human. Do not open or submit it yourself.
4. Tell the human that nothing has been deleted yet and the link expires after 30 minutes.

The deletion request does not change the artifact. The human confirmation page shows the artifact title and requires a deliberate Delete artifact action. If the draft changes before confirmation, the request stops and the agent must read state again before creating a new confirmation link. Once confirmed, Workbench permanently removes the artifact and every saved version.

## Boundaries

- Markdown is canonical.
- Workbench has no publishing operation.
- Anyone may create an artifact.
- Anyone with a specific review URL can view and edit that artifact; public access cannot list artifacts.
- Preserve human changes found in the latest state.
- An artifact URL grants access only to its artifact.
- The artifact-scoped agent API can request deletion but cannot complete it.
- Give the short-lived deletion confirmation URL to the human; never submit it as the agent.
- Confirmed deletion is permanent and removes all saved versions.
- Keep private artifact edit URLs out of public posts and logs.

## Machine-readable discovery

- [Creation contract](https://workbench.foo/api/artifacts)
- [Service description](https://workbench.foo/.well-known/agent.json)
- [Skill file](https://workbench.foo/workbench.SKILL.md)
