Skip to content

feat: show the agent's artifacts — live, sandboxed, never on TeamWork's origin - #81

Merged
praxagent merged 2 commits into
mainfrom
feat/artifact-viewer
Oct 3, 2026
Merged

praxagent merged 2 commits into
mainfrom
feat/artifact-viewer

Conversation

@praxagent

Copy link
Copy Markdown
Owner

TeamWork's half of artifacts: the viewer. The agent makes and stores the pages; Prax's half is praxagent/prax (feat/artifacts).

What

  • In chat and notes. A line that is exactly [artifact:<id>] renders the agent's page as a live card. It polls for new versions every 5 s and has a full-screen view (Esc closes it).
  • Where the page comes from. GET /api/artifacts[/<id>][?meta=1] proxies to {PRAX_URL}/teamwork/artifacts….
    • It sits behind TeamWork's login, and is not on the exemption list.
    • Failures are HTTP failures: 503 when the agent is unreachable, 404 when the artifact is unknown.
    • A malformed id never reaches the agent.

Why it's safe to render agent-written pages

TeamWork's origin holds your session, and an artifact may have been written while the agent was reading untrusted content. So the page never runs on TeamWork's origin:

  • The frame. srcdoc in an iframe with sandbox="allow-scripts" and no allow-same-origin, so it gets an opaque origin, and referrerpolicy=no-referrer.
  • The policy. A CSP is injected first in its <head>: no network, no forms, no base changes. The page's own tags can't loosen it, because every policy applies and the strictest wins.
  • Sizing. The frame sizes itself from a height message, accepted only from that frame's own window.

Verified in real headless Chromium (the prax-sandbox image), with the exact attribute and CSP: from inside the frame,

  • parent.document, document.cookie and localStorage → SecurityError;
  • self.origin → "null";
  • fetch('https://example.com/') → blocked by connect-src 'none'; Chromium logged the CSP violation.

Tests

  • Backend: 6 new router tests. make ci green: 500 passed.
  • Frontend:
    • CSP injection, marker splitting (code blocks and bad ids left alone), frame sandbox attributes, and size messages ignored from foreign windows;
    • vitest 98/98, tsc clean, vite build OK.

Docs: docs/artifacts.md. Idea credit: Telepath's Television (see #80).

…'s origin

A line '[artifact:<id>]' in a message or note renders the agent's page as a
live card (polls for new versions, full-screen view). The page comes from the
agent through /api/artifacts (behind TeamWork's login) and runs as srcdoc in
an iframe with sandbox='allow-scripts' and no allow-same-origin, under an
injected CSP with no network. Verified in headless Chromium: parent, cookies
and storage throw SecurityError, origin is null, fetch is refused.
Idea credit: Telepath's Television.
…t private

An agent shows its work in TeamWork without asking (Prax: TeamWork is
trusted, a public link needs a person's decision). That holds only if
TeamWork is deployed privately — login on, private reach — and no agent can
check it from the inside.
@praxagent
praxagent merged commit 8291054 into main Oct 3, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant