Agents can now put images inside markdown/HTML artifacts instead of only
posting them as standalone artifacts.
- New Asset model: an image uploaded ahead of the artifact that embeds it.
- POST /api/assets uploads an image (image/* only, 50 MB cap) and returns
a stable URL the agent references normally, e.g. . No custom
syntax; existing markdown/fragment rendering handles it.
- GET /assets/{id} serves the image, owner-scoped (404 for other users).
- On artifact creation the content is scanned for asset URLs and matching
assets are attached to it, so the image dies with the artifact it belongs
to. Uploads never referenced are swept after a 24h grace period.
- Quota: assets count toward the owner's quota at upload time and can
trigger eviction; evicting an artifact frees its assets too, and usage
now sums artifacts plus assets.
- daybook_post.py gains --upload-image, which prints the URL to embed.
- Docs and SKILL.md cover the upload-then-reference workflow.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Turns Daybook into a multi-user tool and reworks the feed UI:
- Multi-user: Django session login (username/password + remember-me),
per-user personal API tokens (DRF authtoken), whole app gated behind
login. Each artifact has an owner; feeds are private per user.
- Rename persona -> source (free-text label for whatever posted an
artifact: agent-profile, script, or person). source + tags form one
unified label system; single label filter matches tags, source has
its own filter/column/sidebar.
- Settings area (gear/user menu, top-right): Account (view/regenerate
token) and Demo Data (in-app button seeding one artifact per kind).
User account management via Django admin (superusers only).
- Feed rework: rolling 7-day window with sticky inline date separators
and infinite scroll; left sidebar is now a Sources list with per-source
unread counts; artifact type shown as text after title; source in its
own column.
- Unread tracking: read_at on Artifact, marked read when previewed,
bold titles for unread, sidebar unread badges, old banner removed.
- Tag colours: global shared registry, hash-based default with optional
per-tag override via tag_colors on POST/PATCH.
- Ingest: token resolves owner; same source name under two users' tokens
stays isolated. daybook_post.py renamed persona->source, requires a
real token, --check accepts a bearer token. Docs updated to match.
Migrations 0004-0008 rename persona, add owner (nullable -> backfill to
first superuser -> required), and add read_at. Fresh installs no-op the
backfill.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>