daybook/skills/daybook-posting/SKILL.md
peter caeb2bedc7 Rewrite posting skill to be location-agnostic
The skill was authored in this dev workspace, where the Daybook server,
the skill, and the posting agent all share one directory — so it read as
if the agent always runs from a Daybook source checkout on localhost.

- State up front that you post to a running instance that may be anywhere,
  need no source checkout, and are tied to it only via DAYBOOK_URL/TOKEN.
- Drop "from the project root"; reference the bundled helper by absolute
  path (DAYBOOK_POST=.../this-skill/scripts/daybook_post.py).
- Reframe DAYBOOK_URL as set-this-to-your-instance; label 127.0.0.1:8001
  as the local dev fallback only.
- Genericize the hardcoded localhost URL in the image-embed example.
- Add a raw curl fallback for environments without the Python helper.
- Keep frontmatter to name+description (the Skills-API-portable subset).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-03 15:43:58 +01:00

256 lines
12 KiB
Markdown

---
name: daybook-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 Daybook instance and returns a URL.
---
# Daybook Posting
Daybook 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 Daybook server**, which may be anywhere — a cloud VM, a container, or a workstation. You do **not** need a checkout of Daybook's source. The only things that tie you to a particular instance are two environment variables: `DAYBOOK_URL` (where the server is) and `DAYBOOK_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
DAYBOOK_URL=https://your-daybook-instance.example.com # your server's base URL
DAYBOOK_TOKEN=your-personal-api-token # from Settings -> Account
DAYBOOK_SOURCE=agent # a stable label for what's posting
```
- **`DAYBOOK_URL`** — the base URL of the Daybook 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 Daybook is running
locally on the same machine (its development default). For any remote or
deployed instance you **must** set this.
- **`DAYBOOK_TOKEN`** — your personal per-user API token, from Settings →
Account in the app (not a token shared by everyone). Artifacts posted with
your token land only in your feed.
- **`DAYBOOK_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/daybook_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).
DAYBOOK_POST=/abs/path/to/this/skill/scripts/daybook_post.py
```
Then:
```bash
python "$DAYBOOK_POST" --check
python "$DAYBOOK_POST" --kind markdown --title "Build Report" --content-file report.md
cat report.md | python "$DAYBOOK_POST" --kind markdown --title "Build Report"
python "$DAYBOOK_POST" --file diagram.svg --title "Architecture Diagram"
```
The artifact URL is printed as the final stdout line.
(If you *are* working inside a Daybook source checkout, a compatibility
wrapper also exists at `scripts/daybook_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 `<html>` (`<!doctype>` recommended, not required). See "CDN Snippets" below. |
| `deck` | Simple slide-like artifact | Top-level `<section>...</section>` 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 `<script>`, event
handlers, `<style>`, and `javascript:`/`data:` URLs are stripped. If you
need JavaScript (a chart library, an interactive widget), use `html_full`,
which is served verbatim — that's what it's for. Don't put scripts in the
themed kinds expecting them to run; they won't.
`--theme` (for `markdown`/`html_fragment` only) accepts `report` (default —
serif), `tasks`, or `base` (minimal sans-serif). They share the same
off-white background and differ mainly in typography and width.
`deck`/`html_full`/`json`/`csv` ignore `--theme` — each has its own fixed
presentation.
This script only **creates** artifacts — none of the following are
possible through it. Updating an existing artifact's title/tags/metadata,
or deleting one, requires the raw API (see the instance's `docs/api.md` or
`GET /api/capabilities`); enabling its public share link is feed-UI-only,
with no API equivalent at all yet.
## CDN Snippets For `html_full`
`html_full` is Daybook's escape hatch for custom pages — nothing is
injected into it, so a poster wanting Tailwind or a charting library has to
supply its own `<link>`/`<script>` tags. Known-good ones:
```html
<!-- Tailwind (Play CDN - compiles in-browser on every load; fine for a
one-off artifact, not something you'd want on a high-traffic page) -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
```
**Offline caveat:** Daybook 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:** Daybook 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
<link rel="stylesheet" href="/static/vendor/gridjs/mermaid.min.css">
<script src="/static/vendor/gridjs/gridjs.umd.js"></script>
<!-- or, for a collapsible JSON tree: -->
<script src="/static/vendor/renderjson/renderjson.js"></script>
```
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 Daybook, 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 "$DAYBOOK_POST" --upload-image chart.png
# 2. Reference that URL in your markdown, then post as usual.
# The printed URL is absolute against your DAYBOOK_URL, e.g.
# ![chart]($DAYBOOK_URL/assets/ab12cd34ef56)
python "$DAYBOOK_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 "$DAYBOOK_POST" results.csv
python "$DAYBOOK_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 "$DAYBOOK_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 "$DAYBOOK_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 `DAYBOOK_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 Daybook is reachable.
- Make sure `DAYBOOK_URL` points at the right instance and `DAYBOOK_TOKEN` is set before posting anything real.
- Use a stable `DAYBOOK_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 "$DAYBOOK_URL/api/artifacts" \
-H "Authorization: Bearer $DAYBOOK_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 "$DAYBOOK_URL/api/artifacts" \
-H "Authorization: Bearer $DAYBOOK_TOKEN" \
-F "kind=image" -F "title=Architecture Diagram" -F "source=agent" \
-F "file=@diagram.png"
```
`GET $DAYBOOK_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.