iofold/artifact-use
Publish agent output as stable, gated, reviewable links: HTML tools, dashboards, static folders, images and PDFs through the Artifact Use MCP server, with comments that come back to the agent.
Changelog
Notable changes to Artifact Use are documented here.
Unreleased
-
Author display names: comments carry
author_name(the name the author set, else their email's local part;Guestfor shared-link sessions) andauthor_role(workspacefor the publishing team, shown as a "Team" tag in the widget). Agent replies written with a workspace token show the person behind the token, or the workspace name when unknown.- Viewers set their name from the widget composer ("Commenting as … ·
Change"); only verified and recipient-link viewers and signed-in members
can. Publishers set theirs in the admin header or with
PATCH /api/v1/me {"display_name"}. GET/POST /_au/profile; names are at most 60 characters, never contain@, and drop invisible formatting characters. Migration 0020.
- Viewers set their name from the widget composer ("Commenting as … ·
Change"); only verified and recipient-link viewers and signed-in members
can. Publishers set theirs in the admin header or with
-
Admin: the artifact sheet stacks Feedback under Access, and its comment list shows author names.
-
Continue with Google on artifact gates (
GATE_GOOGLE_SIGNIN, off by default):email,verified_emailandallowlistgates offer Google sign-in through WorkOS (providerGoogleOAuth).- The gate shows the email form first, then an "or" divider, then the Google button.
- An address Google reports as verified passes the gate like a code (same allowlist, rate limit and verified session) and lands on the page; share link attribution is kept. Anything else falls back to the code with the address prefilled.
- The browser stays signed in for 30 days, renewed on use, so every other
gate is one "Continue as" click. "Not you? Sign out" or
/logoutclears the sign-in. - No workspace is created for the viewer.
-
"Continue as" on gates (publishers and Google viewers alike) now needs a consent token that only that artifact's gate page, loaded top-level in that browser, carries. A script on another artifact could previously fake the Referer (
history.pushState) and the navigation (form.submit()) and pass a gate with the visitor's email. Gate pages show a signed-in address only on top-level loads, never tofetch(). -
Viewer-session verification rejects any signed payload carrying a
typ, so gate state and consent tokens can never be replayed as sessions. -
Private feedback: an artifact can be set to
feedback: "private"(RESTPATCH, MCP and stdioartifact_manage set_access, CLIgate, and a Feedback select in the admin sidesheet). Each viewer then sees only the threads they started plus the workspace's replies; the workspace sees every thread. The rules are enforced in the comments query, so the widget, badge, pins, long-poll and agent API all follow.- Replying to, resolving or re-anchoring another viewer's thread answers
404; replaying another viewer'sclient_refanswers409. - Threads the workspace starts while private are internal.
- Threads written while private stay private after switching back.
- Verified and share-link viewers are matched by identity; unverified typed emails only within their own session.
- Comments carry
private,/_au/artifact-contextreturnsfeedback, and the widget shows one notice line. Migration 0019.
- Replying to, resolving or re-anchoring another viewer's thread answers
-
The comments and "Hand to your agent" routes now apply the page's own session checks: a revoked or expired share link's session can no longer read or post comments, and verified gates refuse unverified sessions there too.
-
Daily feedback digest: an optional second cron (
0 14 * * *) emails the operator the last 24 hours of reviewer comments across chosen workspaces, grouped by artifact with each thread's state, plus threads from the previous 14 days still waiting for a first reply. Configured withFEEDBACK_DIGEST_TOandFEEDBACK_DIGEST_ORGS; off by default, at most once per UTC day, skipped on quiet days. -
Versions carry a change note: every publish path (REST
publish/html,publish/start,publish/upload-session; MCPartifact_publishandartifact_upload_session; the stdio server, CLI and client-core) accepts an optional one-linechange_note(at most 280 characters after whitespace collapses; longer is400 change_note_too_longbefore anything is written). It is returned on the versions list,/_au/versionsand publish results, which also carrynext: how to republish with theurl_key,base_version_idand a note. Migration 0018. -
Admin Versions panel: each version leads with its change note (or a file summary such as "2 files: 1 added, 1 modified" when it has none) and reads the same history as the widget; "Compare with current" and its
/admin/artifact/diffroute are removed (the diff API and MCP action remain). The widget's publisher-only Versions section shows the note too. -
Upstream proxy: on
allowlistartifacts every_api/request re-checks the artifact's current allowlist against the viewer's gate email, so password and open share-link sessions, unlisted recipients and workspace members, and addresses removed after their session was minted get403 email_not_allowed; a malformed allowlist denies instead of throwing. -
Gates: "Send code" no longer sends two emails on a double tap. System pages submit each form once (the button disables and reads "Sending code…" until the page changes, and comes back after a back navigation), and a repeat
POST /_au/gate/startfor the same artifact and email within 30 seconds reuses the code already sent instead of mailing and voiding it; it costs no rate-limit quota and answersresent: falsewithretry_after. -
Prior versions are for the publishing workspace only:
_v/<id>/answers a workspace token or a signed-in member's browser and redirects everyone else to the stable URL, so viewers only ever see the current version. Publishers get a collapsed Versions line in the comments panel (which version this is, how many exist) that expands into the history with each publish's file changes and thread counts;GET /_au/versions?artifact_key=backs it and answers the workspace only. -
Comments: the "Send to agent" action is gone. Every comment already reaches the publishing agent, so the widget no longer asks viewers to send anything;
statusisopen,resolvedorall(a legacystatus=sentreads asopen), thecomment.sent_to_agentwebhook event is retired, and asent_to_agentPATCH from an older client is accepted and ignored. -
Share links are the sharing primitive:
recipient,passwordandopenkinds with expiry, max opens, open counts and revoke; passcode links pass the gate via a form, JSON or HTTP Basic; dead links answer 410. Migration 0014. -
Gates: a creator or OAuth token of the owning workspace reads pages and assets without a viewer session or a view row; the plain email gate checks syntax and MX records;
access_presetaliases the gate levels; admin views are labelled verified, via link or self-reported; the landing page and every publish response say that URLs are unlisted. -
Comment loop: signed webhooks with retries for
comment.created,replied,resolvedandreopened; long-poll withwait=<1..25>andnext_sinceon both comment endpoints; v3 element context (caption, heading, src, viewport) so image-grid comments stop reading as "div"; agent presence inartifact-contextand the widget;author_kindandagent_label;page_pathnormalised with a backfill. Migration 0015. -
Versions:
GET .../versions, prior versions served at_v/<id>/(workspace only) with a banner andX-Artifact-Version, promote (rollback), per-file diff with a bounded line diff,base_version_idon every publish path returning409 version_conflict, andlinks {artifact, version, review}on publish results and artifact reads; MCP actionsversions,promote,diff. -
Honest analytics: views carry
kind(human, agent, automation) andsource; public artifacts count one human view per day; the dashboard and stats API report people separately from agents. Migration 0017. -
Secret scan on publish: credential-like strings refuse the publish with
422 secrets_detectedunlessallow_secrets: true, in which case they are returned aswarnings. -
MCP tools carry
titleandreadOnlyHint/destructiveHint/openWorldHintannotations; a CI budget caps the tool schemas at 12 KB. -
CLI:
help,--help,-h,help <command>and--version. -
GET /.well-known/openai-apps-challengeserves the OpenAI plugin-directory domain-verification token fromOPENAI_APPS_CHALLENGE_TOKEN. -
Reserved or malformed segments under an artifact URL (
_au/…,_iof/…,cdn-cgi/…) answer 404 instead of surfacing as500 internal_error. -
The stdio MCP server, CLI and client-core no longer send a default
gate_levelon republish, so a public artifact stays public; the first package-level tests cover it (npm run test:packages). -
Upstream backends require a gated artifact: configuration refuses
public+ upstream from either direction and the_api/proxy returns 403 as a backstop. The proxy is rate-limited per viewer (120/min) and per artifact (1200/min) withRetry-After. -
Publish sessions accept optional
file_countandpackage_bytesfor an immediate 413 before any upload; a 413 at completion purges the draft's files instead of leaving them in R2. -
A six-hourly cron sweeps upload sessions older than 24 hours and deletes artifact shells with no versions (
[triggers]inwrangler.toml). -
/robots.txtkeeps crawlers off operator and machine paths;/favicon.icoresolves to the artifact icon. Both need routes in explicit-route deploys. -
Link-preview cards resolve any revision to the current card, so cached Slack unfurls no longer break after a republish.
-
npm run deployanddeploy:prodrefuse to deploy when a configured local legal-policy page is missing frompublic/legal/. -
Dependency audit advisories resolved;
npm audit --audit-level=highpasses again. -
Add per-artifact upstream backends:
PATCH /api/v1/artifacts/{key}withupstream,artifact_manageactionset_upstream, and the reserved_api/path under an artifact URL that forwards gated viewers' requests to the backend with a stored bearer secret and the viewer's gate email. -
Preserve the query string across the artifact gate so URL-addressed state survives the email form.
-
Agent documentation has one source:
docs/agent-guide.mdis rendered into/llms.txtand/llms-full.txtbyapps/worker/scripts/build-llms.mjs(wrangler[build],npm run build,npm run typecheck);docs/MCP.md,docs/API.md, the README and the skill link to it instead of repeating it. The guide adds the "publish only when asked" promise, anAGENTS.mdsnippet, and documents upstream backends, workspaces,url_keyrepublish, the 90-day token expiry withtoken_expired/renew_url,isErrortool results, and the early413. -
The agent-initiated device-code connect flow (
/api/v1/connect/*) is deprecated and removed from agent-facing docs; quick connect (/admin/connect) and OAuth are the two documented paths. -
The repository root is an Agent Plugins 1.0 package (
plugin.json,mcp.json) with a Claude Code plugin/marketplace (.claude-plugin/) and a Codex marketplace (.agents/plugins/marketplace.json). -
artifact-use-cli(CLI, binartifact-use),artifact-use-mcp(stdio MCP server) andartifact-use-core(shared client) are publishable at 0.2.0 as unscoped npm packages (renamed from@artifact-use/*; npm rejects the bare nameartifact-useas too similar to an unrelatedartifactusepackage) (fileslimited todist, READMEs,prepackbuilds); published to npm on 2026-09-25 asartifact-use-core,artifact-use-mcpandartifact-use-cli0.2.0.
0.1.0
- Publish single-file and multi-file static artifacts through HTTP, CLI, or MCP.
- Store immutable artifact versions in Cloudflare R2 with metadata in D1.
- Support public, email, verified-email, and allowlist access gates.
- Add targeted comments, replies, resolution, durable retries, and publisher administration.
- Add WorkOS/AuthKit publisher authentication and agent connection flows.
- Add public-safe link previews and project showcase artifacts.