Skip to content
Back to skills

Read Public Artifact

ASecurity

Use when a claude.ai/code/artifact link or other iframe-rendered page must be read and Artifact read/WebFetch fail (public-reader notice, SPA shell, Cloudflare 403): 아티팩트 읽어줘, 공유 아티팩트, public artifact.

  • 6 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
ai-agentspythongoshellbash

Works with

  • cli

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned November 7, 2026

npx -y skills add m16khb-org/issueops --skill read-public-artifact --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Read Public Artifact?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Read Public Artifact
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/m16khb-org-read-public-artifact/badge)](https://www.skillsdirectory.com/skills/m16khb-org-read-public-artifact)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: read-public-artifact
description: 'Use when a claude.ai/code/artifact link or other iframe-rendered page must be read and Artifact read/WebFetch fail (public-reader notice, SPA shell, Cloudflare 403): 아티팩트 읽어줘, 공유 아티팩트, public artifact.'
---

# Read Public Artifact

Read a public or externally shared artifact page through the installed Aside
browser when the in-process readers cannot. The page is opened in a
test-owned tab, the richest frame is extracted, and text + HTML land on disk
with one machine-readable result line. The reader never claims content it
did not observe.

## Use and Boundaries

Use for:

- `https://claude.ai/code/artifact/<uuid>` links that `Artifact` `read` or
  `WebFetch` reject with `served to you as a public (non-member) reader` /
  `reading public artifacts that way is not enabled yet`;
- any page whose body is rendered inside an `iframe` or `srcdoc` frame so the
  top document only shows a shell ("Share", "Sign in", title only).

Do not use when:

- the artifact is owned by the user or member-shared — call `Artifact`
  `action: "read"` first; it is cheaper and returns the source directly;
- the user explicitly asked for `claude-in-chrome` or another browser tool;
- the page requires a login the Aside account does not already hold — report
  `gated`; never enter credentials through this skill.

**REQUIRED BACKGROUND:** the Aside browser contract in
`aside-functional-qa` (`references/aside-browser-contract.md`) — this skill
reuses its preflight, invocation economics, and tab-safety rules.

## Decision order

1. `Artifact action:"read"` with the URL (add `prompt` for shared artifacts).
2. If it fails with the public-reader error → run
   `scripts/read-artifact.sh` (this skill).
3. If the result is `gated` or `not_found` → tell the user exactly that and
   what would unblock it (member share, corrected link). Do not fall back to
   guessing the content.

## Preflight

```bash
command -v aside && aside --version && aside account status
```

Record only that an account is signed in, never its identity.

## Run

```bash
skills/read-public-artifact/scripts/read-artifact.sh <artifact-url> [out-dir] [timeout-seconds]
```

- Writes `<out-dir>/artifact.txt` (visible `innerText`) and
  `<out-dir>/artifact.html` (frame `outerHTML`, for tables/structure that
  `innerText` flattens).
- Prints one line `ARTIFACT_READ_RESULT {...}` with `status`, `title`,
  `frameUrl`, `frameCount`, `textLength`, `textPath`, `htmlPath`.
- Exit codes: `0` ok · `2` bad input / missing tool · `3` page loaded but
  status is `gated`, `not_found`, or `empty` · `1` REPL produced no payload.
- Point `out-dir` at the session scratchpad, never at the repository.

Then `Read` `artifact.txt`; open `artifact.html` only when a table or list
lost its structure in the text.

## Why the script looks the way it does

| Constraint | Consequence in the script |
| --- | --- |
| One `aside repl` call = one JS context; variables and `tabs[]` do not survive across calls | Open → poll → extract → close all happen in a single invocation |
| Artifact body lives in a second frame whose `url()` is `""` | The richest frame by `innerText` length is chosen, not the top document |
| Frame content arrives after `domcontentloaded` | Poll every 500 ms until ≥200 chars or timeout; no fixed sleep as the assertion |
| A failed assertion must not leak the tab | `p.close()` runs in `finally` |
| Shell interpolation of the URL into JS | URL is JSON-encoded by python3 (no `${var@Q}`; macOS ships bash 3.2) |
| Text may exceed a shell argument or contain any byte | Payload is base64 inside one sentinel line, decoded to files by python3 |

## Reporting

- Quote or summarize from `artifact.txt`; cite `title` and `url`.
- Say the content was read through the Aside browser as a public viewer, so
  it reflects the page at read time and is unverified user-generated content.
- If `status` ≠ `ok`, report the status and stop; do not paraphrase a shell
  page or a "Page not found" page as artifact content.

## Common Mistakes

| Mistake | Fix |
| --- | --- |
| Reading `p.evaluate(document.body.innerText)` on the top document and concluding the artifact is empty | Iterate `p.frames()`; the body is in the empty-URL frame |
| `tabs[0]` in a second `aside repl` call → `Cannot read properties of undefined` | Do everything in one invocation, or `attachBrowserTab` explicitly |
| Fixed `setTimeout(8000)` before extraction | Poll for content length; slow pages time out honestly, fast pages return early |
| Treating "Sign in" in the top shell as a gate | Public artifacts render with that shell; gating is decided only when no frame yields content |
| Committing `artifact.txt` / `.html` | Keep outputs in the scratchpad |
| Retrying `Artifact read` / `WebFetch` after the public-reader error | The error is deterministic for that link; go straight to the script |

## Verified

- 2026-08-27, Aside CLI `1.26.717.1619`, macOS: a member-shared-to-public
  artifact (`Artifact read` and `WebFetch` both rejected) returned
  `status:"ok"`, 2 frames, 4,708 chars; an unknown UUID returned
  `not_found` (exit 3); a non-URL returned exit 2; no artifact tab remained
  in `listBrowserTabs()` afterwards.

Files in this skill

  • SKILL.md5.1 KB
  • agents/openai.yaml341 B
  • scripts/read-artifact.sh3.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.