v0.3.0: rename app Daybook -> AgentFeed

Removes the "Daybook" name from everything user- and agent-facing, since no
agents are configured yet and this is the cheap moment to do it.

- UI brand, docs, README, CLAUDE.md -> AgentFeed.
- Ingest env vars DAYBOOK_URL/TOKEN/SOURCE/DATA_DIR/BIND_ADDR/HOST_DATA_DIR/
  KEY_PROVISIONING_API -> AGENTFEED_* (token *values* unchanged).
- Skill: skills/daybook-posting -> skills/agentfeed-posting, daybook_post.py
  -> agentfeed_post.py (+ scripts/ wrapper and its test).
- static/daybook.css -> static/agentfeed.css; localStorage daybook.* ->
  agentfeed.*; templatetag daybook_extras -> agentfeed_extras; multipart
  boundaries; json/csv viewer element ids; daybook_exception_handler ->
  agentfeed_exception_handler; compose service/container -> agentfeed.
- Key-provisioning API now OFF by default (independent of DEBUG); enable with
  AGENTFEED_KEY_PROVISIONING_API=1 on test installs only.
- Posting helper now points at Settings -> API Keys.

Deferred on purpose (a later, separate step): the Django package
`daybook_project`, the `/opt/daybook` install path, and the Forgejo repo name.
The sibling AGENT_DAYBOOK__LLM_TEST name is intentionally untouched.

Full suite: 129 passing; live server verified serving under the new name.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
peter 2026-09-04 13:10:28 +01:00
parent 4cacd8f64e
commit d30e2436ab
39 changed files with 303 additions and 284 deletions

View file

@ -1,6 +1,6 @@
# Deployment
Daybook deploys the same way on any Linux host with Docker: a cloud VM, a home
AgentFeed deploys the same way on any Linux host with Docker: a cloud VM, a home
server, a Proxmox guest, whatever. It runs as a single Docker container
(Gunicorn) with all persistent state — the SQLite database and artifact files —
on a bind-mounted `./data` directory outside the image.
@ -8,7 +8,7 @@ on a bind-mounted `./data` directory outside the image.
```text
Target host (cloud VM, home server, ...)
Docker Engine
daybook container
agentfeed container
/app application code baked into the image
/data persistent volume: db.sqlite3, artifacts_store/
```
@ -17,8 +17,8 @@ Target host (cloud VM, home server, ...)
| File | Purpose |
|---|---|
| `Dockerfile` | Builds the Daybook image. |
| `docker-compose.yml` | Runs Daybook with a persistent `./data:/data` bind mount. |
| `Dockerfile` | Builds the AgentFeed image. |
| `docker-compose.yml` | Runs AgentFeed with a persistent `./data:/data` bind mount. |
| `entrypoint.sh` | Runs migrations, collects static files, then starts Gunicorn. |
| `env.example` | Template for deployment environment variables. |
@ -59,12 +59,12 @@ Edit `deploy/.env` and set at minimum:
DJANGO_DEBUG=0
DJANGO_SECRET_KEY=<generated-secret>
DJANGO_ALLOWED_HOSTS=<vm-ip-or-dns-name>,localhost,127.0.0.1
DAYBOOK_DATA_DIR=/data
AGENTFEED_DATA_DIR=/data
DATABASE_PATH=/data/db.sqlite3
ARTIFACTS_ROOT=/data/artifacts_store
```
There is no shared API token to configure — Daybook uses per-user API keys
There is no shared API token to configure — AgentFeed uses per-user API keys
created under Settings → API Keys once a user exists (each user can hold
several, one per agent, each individually revocable). Do not commit
`deploy/.env`.
@ -80,7 +80,7 @@ Create your first login (superuser) so you have something to log in with and
a personal API token to post through:
```bash
docker compose -f deploy/docker-compose.yml exec daybook python manage.py createsuperuser
docker compose -f deploy/docker-compose.yml exec agentfeed python manage.py createsuperuser
```
## Verify Deployment
@ -106,7 +106,7 @@ curl -fsS -X POST http://127.0.0.1:8000/api/artifacts \
"source": "deploy-smoke",
"kind": "markdown",
"title": "Deployment Smoke Test",
"content": "# Deployment Smoke Test\n\nDaybook accepted an artifact."
"content": "# Deployment Smoke Test\n\nAgentFeed accepted an artifact."
}'
```
@ -127,17 +127,17 @@ picked up automatically. `deploy/.env` and `deploy/data/` are untouched by
## Operational Commands
```bash
docker compose -f deploy/docker-compose.yml logs -f daybook
docker compose -f deploy/docker-compose.yml restart daybook
docker compose -f deploy/docker-compose.yml logs -f agentfeed
docker compose -f deploy/docker-compose.yml restart agentfeed
docker compose -f deploy/docker-compose.yml down
docker compose -f deploy/docker-compose.yml up -d
docker compose -f deploy/docker-compose.yml exec daybook python manage.py check
docker compose -f deploy/docker-compose.yml exec daybook sh
docker compose -f deploy/docker-compose.yml exec agentfeed python manage.py check
docker compose -f deploy/docker-compose.yml exec agentfeed sh
```
## Django Admin (`/admin/`)
Daybook ships Django's built-in admin at `/admin/` as an operator
AgentFeed ships Django's built-in admin at `/admin/` as an operator
break-glass tool — for raw-data fixes: reset a password, inspect or delete
any user's artifacts, adjust a quota, audit or revoke API keys. It is
separate from the in-app **Settings** area, which is the everyday product
@ -147,17 +147,17 @@ surface (see the in-app guide / `docs/` for normal use).
`is_staff = True`. The account you create with `createsuperuser` has it (plus
full superuser rights). Note the two different admin concepts:
- `is_superuser` — Daybook's *in-app* admin (can reach Settings → Users).
- `is_superuser` — AgentFeed's *in-app* admin (can reach Settings → Users).
- `is_staff` — can log into *Django's* `/admin/` site.
The `createsuperuser` account has **both**. A user promoted in-app via
Settings → Users ("Grant admin access") gets `is_superuser` only — so they
can administer Daybook through its own UI but **cannot** reach `/admin/`.
can administer AgentFeed through its own UI but **cannot** reach `/admin/`.
Regular users have neither. To grant someone `/admin/` access, set staff
explicitly:
```bash
docker compose -f deploy/docker-compose.yml exec daybook \
docker compose -f deploy/docker-compose.yml exec agentfeed \
python manage.py shell -c "from django.contrib.auth.models import User; u=User.objects.get(username='NAME'); u.is_staff=True; u.save()"
```
@ -172,23 +172,23 @@ Back up `deploy/data/` — it contains the SQLite database and all artifact
files:
```bash
tar -czf daybook-data-$(date +%Y%m%d-%H%M%S).tar.gz -C /opt/daybook/deploy data
tar -czf agentfeed-data-$(date +%Y%m%d-%H%M%S).tar.gz -C /opt/daybook/deploy data
```
For a consistent snapshot during heavy writes, stop the container first:
```bash
docker compose -f deploy/docker-compose.yml down
tar -czf daybook-data-$(date +%Y%m%d-%H%M%S).tar.gz -C /opt/daybook/deploy data
tar -czf agentfeed-data-$(date +%Y%m%d-%H%M%S).tar.gz -C /opt/daybook/deploy data
docker compose -f deploy/docker-compose.yml up -d
```
To restore: stop Daybook, replace `deploy/data/` with the backup contents,
To restore: stop AgentFeed, replace `deploy/data/` with the backup contents,
then start it again.
## Reverse Proxy Notes
If putting Daybook behind Nginx, Caddy, Traefik, or a cloud load balancer:
If putting AgentFeed behind Nginx, Caddy, Traefik, or a cloud load balancer:
- Proxy to `http://<vm-ip>:8000`.
- Add the public hostname to `DJANGO_ALLOWED_HOSTS`.
@ -200,8 +200,8 @@ If putting Daybook behind Nginx, Caddy, Traefik, or a cloud load balancer:
terminates TLS and forwards plain HTTP to the container.
```text
DJANGO_ALLOWED_HOSTS=daybook.example.com,localhost,127.0.0.1
DJANGO_CSRF_TRUSTED_ORIGINS=https://daybook.example.com
DJANGO_ALLOWED_HOSTS=agentfeed.example.com,localhost,127.0.0.1
DJANGO_CSRF_TRUSTED_ORIGINS=https://agentfeed.example.com
```
Forwarding the proto header, by proxy:
@ -220,7 +220,7 @@ Caddy: header_up X-Forwarded-Proto https
- If behind a reverse proxy: `DJANGO_CSRF_TRUSTED_ORIGINS` is set and the
proxy forwards `X-Forwarded-Proto: https` (login will 403 otherwise).
- `deploy/data/` exists and persists across `git pull` + rebuild.
- `docker compose -f deploy/docker-compose.yml ps` shows `daybook` healthy.
- `docker compose -f deploy/docker-compose.yml ps` shows `agentfeed` healthy.
- `GET /api/capabilities` returns 403 without auth, 200 with a valid token or
session (check the status code — don't use `curl -f`, which errors on 403).
- At least one superuser exists (`manage.py createsuperuser`) with a key