Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,22 @@ The repo includes Playwright visual snapshots for the shipped viewer surfaces:
- Fully static export with Next.js App Router (default product)
- Fragment-based payloads (`#...`) so the static host never receives artifact contents
- Public-safe naming and MIT-compatible dependencies
- Optional self-hosted mode for server-backed UUID links (see below)
- Optional self-hosted mode for public/share-friendly UUID links (see below)

## Sharing Guidance

Use fragment links for trusted direct sharing when the artifact fits the URL budget and you want the static host kept out of the payload path.

Use UUID links for public, social, or corporate-proxy sharing when a short stable URL matters more than static zero-retention. UUID mode stores the payload server-side until it expires or is deleted, so treat the server as part of the sharing boundary.

## Self-Hosted UUID Mode (Optional)

In addition to the default static/fragment-based product, `agent-render` includes an optional self-hosted server mode that stores payloads in SQLite under UUID keys.
In addition to the default static/fragment-based product, `agent-render` includes an optional self-hosted server mode that stores payloads in SQLite under UUID keys. It is the recommended mode for public sharing contexts where long fragment links look risky, get truncated, or pass through URL-rewriting infrastructure.

**When to use it:**
- Payloads exceed the ~8 KB fragment budget
- Links are shared on platforms that mangle long URLs
- Links are posted publicly, sent to broad groups, or routed through corporate proxy/link-scanning systems
- You want short, stable links like `https://host/{uuid}`
- Agent-driven workflows that create and manage artifacts programmatically

Expand All @@ -92,6 +99,8 @@ See `skills/selfhosted-agent-render/SKILL.md` for agent workflow guidance.

The self-hosted mode is an add-on. The existing static fragment-based viewer remains the default product and continues to work as-is.

UUID links are not zero-retention in the current implementation because the server stores the encoded payload. A future encrypted short-link design could store only ciphertext server-side while keeping the decryption key in the URL fragment, but that is not implemented yet.

## Local Development

```bash
Expand Down
6 changes: 6 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ The static host does not receive fragment contents as part of the request, but t
- client-side analytics would still be able to observe decoded payloads if added later
- very large artifacts can exceed practical URL-sharing limits, which is why the shell enforces a fragment budget

Fragment links are best for trusted direct sharing where the URL length is acceptable and the static host should stay out of the payload path. They are not ideal for public feeds, broad corporate sharing, or chat systems that rewrite/truncate long URLs.

## Routing and hosting constraints

- `output: "export"`
Expand All @@ -123,6 +125,8 @@ The static host does not receive fragment contents as part of the request, but t

The repository includes an optional self-hosted server mode in `selfhosted/` that provides UUID-based artifact links backed by SQLite. This is a separate deployment mode — the static export remains the default product.

UUID mode is the public/share-friendly option. It trades static zero-retention for short stable links that survive public posts, email, Slack/Teams, and corporate proxy/link-scanning systems more predictably than long fragments.

### How it works

The self-hosted server is a standalone Node.js HTTP server that:
Expand All @@ -146,6 +150,8 @@ SQLite with a single `artifacts` table:

Artifacts use a 24-hour sliding TTL. Each successful read (API or viewer) extends `expires_at` by 24 hours. Expired entries are lazily deleted on read and can also be batch-cleaned via `POST /api/cleanup`.

UUID mode should not be described as zero-retention in its current form. The server stores the encoded payload until expiry or deletion. A future encrypted short-link mode could store ciphertext in SQLite while keeping the decryption key in the URL fragment, but that design is not implemented.

### Separation from static mode

The self-hosted mode does not alter the static export pipeline:
Expand Down
15 changes: 13 additions & 2 deletions docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,14 @@ If you deploy at the domain root on Cloudflare Pages, leave `NEXT_PUBLIC_BASE_PA

## Self-hosted UUID mode (optional)

The repository includes an optional self-hosted server that stores artifact payloads in SQLite and serves them under UUID links. This is a separate deployment from the static export and is intended for power users and agents.
The repository includes an optional self-hosted server that stores artifact payloads in SQLite and serves them under UUID links. This is a separate deployment from the static export and is intended for power users, agents, and public sharing contexts where short stable URLs work better than long fragments.

Choose the sharing mode by audience:

- **Fragment links**: best for trusted direct sharing when the payload fits the fragment budget and static zero-retention matters.
- **UUID links**: best for public, social, email, Slack/Teams, or corporate-proxy contexts where long fragment URLs look suspicious, get truncated, or are rewritten.

Current UUID links are server-retained: the server stores the encoded payload until the TTL expires or the artifact is deleted. Do not describe UUID mode as zero-retention unless an encrypted short-link design is implemented.

### Quick start

Expand Down Expand Up @@ -133,11 +140,15 @@ Artifacts have a 24-hour sliding TTL. Each successful view extends the expiry. E

The self-hosted server does not include built-in authentication. Options for protecting it:

- **Public**: No additional configuration. Fine for non-sensitive artifacts.
- **Public**: No additional configuration. Recommended for public/non-sensitive artifacts that benefit from short share-friendly links.
- **Cloudflare Tunnel + Zero Trust**: Expose the server through a Cloudflare Tunnel and add Access policies for authentication. This is the recommended approach for remote access with SSO.
- **Reverse proxy**: Place behind nginx, Caddy, or Traefik with HTTP basic auth, OAuth2 proxy, or mTLS.
- **Local only**: Set `HOST=127.0.0.1` to bind to localhost only.

### Future encrypted short links

A future mode could encrypt the payload in the browser or agent, store only ciphertext under the UUID, and keep the decryption key in the URL fragment. That would make the short-link server unable to read plaintext while still giving users a short public URL shape. This repository does not implement that mode today.

### Same-machine deployment

The simplest pattern is running the server on the same machine as the agent. The agent creates artifacts via `http://localhost:3000/api/artifacts` and returns viewer links. No network exposure required unless you want remote access.
Expand Down
4 changes: 4 additions & 0 deletions docs/payload-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ Supported codecs:

The encoder now also supports a packed wire representation (`p: 1`) that shortens key names before compression. Packed mode is transport-only; decoded envelopes normalize back to the standard shape.

Fragment payloads are the trusted direct-sharing transport. For public posts, broad group sharing, social surfaces, or corporate proxy/link-scanning environments, prefer self-hosted UUID links so the visible URL is short and stable.

## Envelope

```json
Expand Down Expand Up @@ -102,6 +104,8 @@ Tuple fields:
- Default async codec priority is `arx2 -> arx -> deflate -> lz -> plain`
- Optional budget-aware encoding can target strict limits like 1,500 chars and returns the shortest fragment when none fit

When a payload does not fit the fragment budget or the target surface is hostile to long URLs, use UUID mode instead of weakening the fragment protocol. Current UUID mode stores the encoded payload server-side and is not zero-retention.

### Codec benchmark

Running `npm run bench:codecs` checks a fixed corpus across markdown, code, diff, CSV, JSON, and multi-artifact bundles. The current committed baseline shows:
Expand Down
6 changes: 5 additions & 1 deletion skills/agent-render-linking/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,11 @@ When sharing a link:

## Self-hosted UUID mode

If the payload exceeds the fragment budget or links are getting mangled by chat platforms, consider using the self-hosted UUID mode instead of fragment links. The self-hosted server stores payloads in SQLite and serves short `https://host/{uuid}` links that render the same viewer UI.
Use fragment links for trusted direct sharing when the payload fits the budget and static zero-retention matters.

Use self-hosted UUID mode for public/social sharing, broad Slack/Teams/email distribution, corporate proxy/link-scanning environments, payloads that exceed the fragment budget, or any surface that mangles long URLs. The self-hosted server stores payloads in SQLite and serves short `https://host/{uuid}` links that render the same viewer UI.

Current UUID mode is not zero-retention because the server stores the encoded payload until TTL expiry or deletion. Do not claim zero-retention for UUID links unless an encrypted short-link mode exists where the server stores ciphertext and the key stays in the fragment.

See `skills/selfhosted-agent-render/SKILL.md` for API usage, deployment, and agent workflow guidance.

Expand Down
18 changes: 13 additions & 5 deletions skills/selfhosted-agent-render/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: selfhosted-agent-render
description: Create and manage agent-render artifacts via a self-hosted UUID-based server. Use when an agent needs to share rendered artifacts through short UUID links instead of fragment-encoded URLs. Ideal when payloads exceed the ~8 KB fragment budget, when links will be shared on platforms that mangle long URLs, or when the agent and viewer run on the same machine. Supports markdown, code, diffs, CSV, and JSON — same artifact kinds and envelope validation as the fragment-based product. The self-hosted server stores payloads in SQLite with a 24-hour sliding TTL.
description: Create and manage agent-render artifacts via a self-hosted UUID-based server. Use when an agent needs public/share-friendly rendered artifacts through short UUID links instead of fragment-encoded URLs. Ideal for public/social sharing, corporate proxy/link-scanning environments, payloads that exceed the ~8 KB fragment budget, platforms that mangle long URLs, or when the agent and viewer run on the same machine. Supports markdown, code, diffs, CSV, and JSON — same artifact kinds and envelope validation as the fragment-based product. The self-hosted server stores payloads in SQLite with a 24-hour sliding TTL.
---

# Self-Hosted Agent Render
Expand All @@ -11,13 +11,17 @@ Create, view, and manage agent-render artifacts through a self-hosted server tha

Use self-hosted UUID mode instead of fragment links when:

- Links will be posted publicly or shared with a broad audience
- Links will pass through corporate proxy, link-scanning, or URL-rewriting systems
- The artifact payload exceeds the ~8,192 character fragment budget
- Links will be shared on platforms that truncate or mangle long URLs (Slack, Teams, email)
- The agent and viewer run on the same machine or local network
- You want stable, short links that do not encode the payload in the URL
- You need to update or delete artifacts after creation

If the payload fits in a fragment and the link will work on the target surface, prefer fragment-based links using the `agent-render-linking` skill instead. Fragment links are zero-retention, require no server, and work on the public `agent-render.com` deployment.
If the payload fits in a fragment and the link is going to trusted direct recipients, prefer fragment-based links using the `agent-render-linking` skill instead. Fragment links are zero-retention by static-host design, require no server, and work on the public `agent-render.com` deployment.

Do not describe current UUID links as zero-retention. The self-hosted server stores the encoded payload until TTL expiry or deletion.

## API

Expand Down Expand Up @@ -316,7 +320,7 @@ Options for protecting the server:

### Public access

If you want the server to be publicly accessible, no additional configuration is needed. This is fine for non-sensitive artifacts.
If you want the server to be publicly accessible, no additional configuration is needed. This is the recommended setup for non-sensitive artifacts that need short, share-friendly public URLs.

### Cloudflare Tunnel + Zero Trust (recommended for remote access)

Expand Down Expand Up @@ -366,8 +370,12 @@ Artifacts auto-expire after 24 hours of inactivity. For proactive cleanup:

## Good defaults

- Use self-hosted mode for large payloads or agent-driven workflows
- Use fragment links for quick, one-off shares that fit in the budget
- Use self-hosted mode for public sharing, large payloads, corporate-proxy contexts, or agent-driven workflows
- Use fragment links for quick, trusted direct shares that fit in the budget
- Keep the server on the same machine as the agent for simplicity
- Use Cloudflare Tunnel if you need remote access with authentication
- Let TTL handle cleanup for most cases

## Future encrypted short-link mode

A future design could encrypt the payload before upload, store only ciphertext in SQLite, and keep the decryption key in the URL fragment. That would preserve the short UUID path while preventing the server from reading plaintext. This skill must not assume that mode exists until the implementation ships.
Loading