--- name: agentfeed-posting description: Use when you have produced a finished deliverable such as a report, summary, brief, diagram, generated HTML, PDF, deck, or status update that a human should review later outside this chat. Publishes the artifact to a AgentFeed instance and returns a URL. --- # AgentFeed Posting AgentFeed is a private artifact journal for completed agent outputs. It stores, indexes, and displays artifacts for human review. It does not execute commands, run workflows, or continue conversations. You post to a **running AgentFeed server**, which may be anywhere — a cloud VM, a container, or a workstation. You do **not** need a checkout of AgentFeed's source. The only things that tie you to a particular instance are two environment variables: `AGENTFEED_URL` (where the server is) and `AGENTFEED_TOKEN` (who you are). Set those and the rest of this skill works unchanged regardless of where you or the server run. ## Configuration Set these as real process/shell environment variables (`export` on Linux/macOS, `$env:` or `set` on Windows, or your agent harness's own env config) — the helper reads `os.environ` directly. There is no `.env` file support; a `.env` file in the working directory is not read automatically. ```text AGENTFEED_URL=https://your-agentfeed-instance.example.com # your server's base URL AGENTFEED_TOKEN=your-personal-api-key # from Settings -> API Keys AGENTFEED_SOURCE=agent # a stable label for what's posting ``` - **`AGENTFEED_URL`** — the base URL of the AgentFeed instance you're posting to. Set it to your server. If it's unset, the helper falls back to `http://127.0.0.1:8001`, which is only correct when AgentFeed is running locally on the same machine (its development default). For any remote or deployed instance you **must** set this. - **`AGENTFEED_TOKEN`** — a personal API key, created in the app under Settings → API Keys (name one per agent so you can revoke them individually). Not a key shared by everyone; artifacts posted with it land only in your feed. - **`AGENTFEED_SOURCE`** — a free-text label for whatever is posting (agent-profile, script, or person name). Optional; can also be passed per call with `--source`. ## The Helper Always use the bundled helper script. Do not hand-build curl, JSON, PowerShell multipart, or inline shell content (a `curl` fallback for environments without the helper is documented at the end — the script is still preferred everywhere it's available). The helper lives at **`scripts/agentfeed_post.py` inside this skill's own directory** — not in any project you happen to be working in. Invoke it by its absolute path. For brevity, the examples below assume you've captured that path once: ```bash # Point this at the helper inside THIS skill directory (absolute path). AGENTFEED_POST=/abs/path/to/this/skill/scripts/agentfeed_post.py ``` Then: ```bash python "$AGENTFEED_POST" --check python "$AGENTFEED_POST" --kind markdown --title "Build Report" --content-file report.md cat report.md | python "$AGENTFEED_POST" --kind markdown --title "Build Report" python "$AGENTFEED_POST" --file diagram.svg --title "Architecture Diagram" ``` The artifact URL is printed as the final stdout line. (If you *are* working inside a AgentFeed source checkout, a compatibility wrapper also exists at `scripts/agentfeed_post.py` in the repo root, but the canonical helper is the one bundled in this skill.) ## Kind Cheat Sheet | Kind | Use for | Content shape | |---|---|---| | `markdown` | Reports, briefs, notes | Markdown text. Fenced code blocks get syntax highlighting; tables (pipe syntax) render styled automatically. | | `html_fragment` | Themed HTML reports/cards/tables | Body-only HTML. No `html/head/body`. Tables render styled automatically, same as markdown. | | `html_full` | Complete custom pages/frameworks | Full HTML document containing `` (`` recommended, not required). See "CDN Snippets" below. | | `deck` | Simple slide-like artifact | Top-level `
...
` blocks. | | `json` | Structured data, metrics, run summaries | Valid JSON text. Renders as a collapsible tree. | | `csv` | Tabular data | CSV text, first row as header. Renders as a sortable/searchable table. `.xlsx` files convert to this automatically — see below. | For images, PDFs, SVGs, and other files, use `--file`; the helper infers multipart and content type. **HTML in `markdown`, `html_fragment`, and `deck` is sanitized** — ordinary formatting, tables, links, and images are kept, but ` ``` **Offline caveat:** AgentFeed can run fully self-hosted/air-gapped. Any artifact that links a CDN script won't render fully (or at all, for Tailwind's in-browser compiler) without internet access. If the deployment target is offline, don't reach for these — use `markdown`/`html_fragment` instead, which are styled entirely server-side with no external requests. **Self-hosted alternative for tables/JSON — no CDN needed:** AgentFeed already vendors Grid.js and renderjson locally (used to render `csv`/`json` artifacts), and they're reachable as plain static files from any artifact, including `html_full`: ```html ``` Prefer these over an external CDN for table/JSON rendering inside a custom `html_full` page — same libraries, but self-hosted, so they work offline and don't depend on a third party staying up. This only covers tables/JSON; there's no vendored equivalent for Tailwind/Chart.js, so the CDN snippets above are still the only option for those. Only use this for `html_full` specifically — never add CDN references to `markdown`/`html_fragment`/`deck`. Those kinds exist so AgentFeed, not the poster, owns styling; injecting a default CDN habit into them would undermine that. ## Images Inside Content To embed an image *within* a markdown or HTML artifact (rather than posting it as its own artifact), upload it first and reference the returned URL: ```bash # 1. Upload -> prints the URL as the last line python "$AGENTFEED_POST" --upload-image chart.png # 2. Reference that URL in your markdown, then post as usual. # The printed URL is absolute against your AGENTFEED_URL, e.g. # ![chart]($AGENTFEED_URL/assets/ab12cd34ef56) python "$AGENTFEED_POST" report.md ``` The image is linked to the artifact that references it and is deleted along with it. Unreferenced uploads are cleaned up after 24 hours. ## CSV, JSON, And Spreadsheets For CSV and JSON, use `--kind csv`/`--kind json` with `--content-file` — or just post the file positionally; auto-mode detects `.csv`/`.json` and picks the right kind automatically: ```bash python "$AGENTFEED_POST" results.csv python "$AGENTFEED_POST" --kind json --title "Run Summary" --content-file summary.json ``` `.xlsx` spreadsheets work too, with no special flag needed — just `--file` (or post it positionally, same as any other file): ```bash python "$AGENTFEED_POST" balance_sheet.xlsx ``` The server converts it to a `csv` artifact automatically. Known limitations (see the instance's `docs/api.md` for the full list): - Only the workbook's **active sheet** converts; other sheets are dropped. - Formula cells need to have been calculated and saved by real spreadsheet software (Excel, LibreOffice, etc.) — a workbook a script wrote but never opened in a real spreadsheet app will show those cells blank. - Rich formatting (bold, colors, merged cells) isn't preserved — it's a plain sortable/searchable table either way. - Legacy `.xls` isn't supported, only `.xlsx`. ## Other Code For code that isn't CSV/JSON but should render today rather than download as a binary, use `--file path --as-markdown` to wrap it in a Markdown fenced code block (still gets syntax highlighting): ```bash python "$AGENTFEED_POST" --file script.py --as-markdown --title "Generated Script" ``` Without `--as-markdown`, it uploads as a downloadable binary file instead. ## Source & Provenance Fields All optional, all default to something reasonable if omitted: | Flag | Default | Notes | |---|---|---| | `--source-type` | `agent` | One of `agent`, `person`, `system`. | | `--source-name` | Same as the effective source (`--source`, or `AGENTFEED_SOURCE` if `--source` wasn't given) | Human-readable name, e.g. "Hermes Agent". | | `--source-id` | Empty string | A stable external ID, if the poster has one. | | `--source-prompt` | Empty string | The prompt/instruction that produced this artifact — useful for later tracing why something was posted. | Use `--meta key=value` (repeatable) or `--meta-json '{"key": "value"}'` (merged together if both are given) for structured, machine-readable context like `run_id` or `model` — these end up in the artifact's `metadata` field, distinct from tags. ## Rules - Run `--check` first if unsure AgentFeed is reachable. - Make sure `AGENTFEED_URL` points at the right instance and `AGENTFEED_TOKEN` is set before posting anything real. - Use a stable `AGENTFEED_SOURCE` or pass `--source` (the agent-profile, script, or person name that produced this artifact). - Use `--tags a,b,c` for filtering. - Use `--meta run_id=... --meta model=...` for machine-readable context. - Never inline multiline content into the shell command; use a file or stdin. - Add `--dry-run` to see exactly what would be sent (method, headers, payload) without actually posting — useful when unsure a payload is well-formed. ## `curl` Fallback (No Helper Available) Prefer the helper above — it handles multipart, content-type inference, JSON shaping, and provenance flags for you. Use raw `curl` **only** when you genuinely can't run the bundled Python script (e.g. a minimal environment with no Python). Text artifacts post as JSON to `POST /api/artifacts` with bearer-token auth: ```bash curl -sS -X POST "$AGENTFEED_URL/api/artifacts" \ -H "Authorization: Bearer $AGENTFEED_TOKEN" \ -H "Content-Type: application/json" \ -d '{"kind":"markdown","title":"Build Report","source":"agent","content":"# Hello\n\nBody text."}' ``` File/image artifacts use multipart instead: ```bash curl -sS -X POST "$AGENTFEED_URL/api/artifacts" \ -H "Authorization: Bearer $AGENTFEED_TOKEN" \ -F "kind=image" -F "title=Architecture Diagram" -F "source=agent" \ -F "file=@diagram.png" ``` `GET $AGENTFEED_URL/api/capabilities` (no auth needed beyond a login/token per that instance's config) lists supported kinds, methods, and the server version if you need to confirm the contract before posting.