Commit graph

12 commits

Author SHA1 Message Date
ab3e92268a v0.6.1: pin Keep/Deleted folders to sidebar bottom; highlight All sources
- Move the Keep/Deleted system folders out of the scrolling source list into a
  pinned section at the bottom of the sidebar (only sources scroll now), so the
  folders stay reachable with many sources. Renamed .source-folders ->
  .system-folders; .source-list flexes to fill.
- "All sources" is visually distinct (bold + subtle blue tint) as the primary
  entry.

Template/CSS only. Feed/trash rendering tests pass; feed renders in all views.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 21:07:39 +01:00
548ba3a669 v0.6.0: per-artifact actions menu (⋯ + right-click)
A ⋯ button on row hover and right-click on a feed row open the same floating
menu: Keep / Open / Copy link / Delete. Dismisses on click-away/Escape,
edge-flips to stay on-screen. Standalone one-click Delete icon stays; the
Trash view keeps its dedicated Undelete.

- Row markup: actions grouped in a .row-actions container (delete + ⋯ in the
  feed/keep views; undelete in trash). Reuses the existing keep endpoint.
- Menu only in the normal/keep views, not trash. Keep-toggle syncs the row's
  kept badge + the preview Keep button, and (in the Keep folder) drops the row
  when unkept.
- Frontend-only (no backend change); inline JS validated with node --check;
  152 tests pass; feed renders in all views.

Share + Add-label join the menu in later slices.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 13:12:27 +01:00
4254164bef v0.5.0: Trash (soft-delete) + Keep folder
Delete now moves an artifact to a recoverable Trash instead of hard-removing.

- Model: Artifact.deleted_at (nullable, indexed) = in Trash.
- Soft-delete everywhere: DELETE /api/artifacts/{id} sets deleted_at
  (idempotent 204); session POST /a/{id}/delete for the feed's hover Delete
  icon; POST /a/{id}/undelete restores; POST /feed/empty-trash purges.
- Trashed artifacts are off-quota (deleting frees quota) and eviction-protected
  (never evicted early); hidden from feed, sources, counts, and all API reads
  (list/detail/raw).
- Sidebar: "Deleted" and "Keep" system folders at the bottom (counts, hidden
  when empty); ?folder=deleted / ?folder=keep views reuse the row rendering.
  Deleted view has hover Undelete + an Empty Trash button. Keep = view over
  is_kept. Live-poll disabled in folder views.
- Docs (api.md delete section, CLAUDE.md), 10 new/updated tests. 150 passing;
  API soft-delete lifecycle verified live.

Purge is manual (Empty Trash) this release; auto purge-on-delete (background,
~3-day retention) is the planned fast-follow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 12:48:43 +01:00
6c1823e65e v0.4.1: live updates also refresh the source sidebar
Extends v0.4.0 without a second request: the sidebar is updated client-side
from the rows the existing /feed/updates poll already returns.

- Each new row's data-source drives the sidebar: per-source + "All sources"
  unread counts bump; a first-time source is inserted into the list
  (alphabetically). Reuses the existing count-badge pattern.
- sourceLinks is now live-queried (was cached at load) so sources added live
  stay keyboard-navigable.
- No endpoint/model change. 142 tests pass; feed renders.

Caveat: while filtered to a single source, other new sources appear only on
reload (the poll is scoped to the selected view).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-05 14:37:45 +01:00
cae414c307 v0.4.0: live feed updates (auto-insert new posts)
New artifacts appear at the top of the feed without a manual refresh.

- GET /feed/updates (session-authed): new artifacts since a timestamp marker,
  owner-scoped and filter-aware (source/label/kind/q), returned as row HTML.
- Feed JS polls every 5s, paused while the tab is hidden (immediate poll on
  refocus). Prepends new rows into today's group without touching the selected
  row or the preview iframe — what you're reading stays put and selected.
- Fresh rows show "now", aging into their real time after ~3 min; brief
  highlight on arrival.
- Extracted _artifact_rows.html partial, shared by the day-group render and the
  updates endpoint, so live rows match exactly.
- Polling chosen over SSE/WebSockets: zero infra on sync-WSGI + SQLite (see
  planning/next_steps for the SSE upgrade path). 142 tests pass; feed page +
  endpoint verified.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-04 23:02:07 +01:00
d30e2436ab 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>
2026-09-04 13:10:28 +01:00
69a7e39c4b Auto-adjust artifact sidebar width when the source column drops
When a single source is selected the row's source column is hidden, so the
sidebar now renders 112px (7rem) narrower and the reclaimed space goes to
the preview pane — instead of the sidebar staying the same width and just
widening the title. One stored "base" width drives both modes (wide =
stored, source-selected = stored - 112, floored at 150px); dragging the
splitter in either mode adjusts that base directly, so the width stays
user-settable in whichever mode and the modes track each other by the fixed
offset. Avoids having to re-resize every time you switch modes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-03 13:45:02 +01:00
cf776d3f0b Add app icon: favicon, apple-touch icon, and top-bar logo
Generated a transparent PNG set from the source icon (a JPEG with a baked-in
checkerboard) by keying out the background on saturation — the arrow is
strongly saturated (0.47-0.68) while the grey/white background is 0.00, so
the cutout is clean. Produced static/logo.png (top-bar, natural aspect),
static/favicon.png (32px), and static/apple-touch-icon.png (180px).

Wired favicon + apple-touch links into all three page heads (feed, settings,
login) and placed the logo next to the "AgentFeed" title in the top bar.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-03 13:13:17 +01:00
fbc4b7249b Drop the redundant source column in the artifact list when a source is selected
When a single source is selected, every row in the middle sidebar repeats
that same source, so the source column is pure waste — the pane header
already names the source. The column now only shows under "All sources"
(where it's needed to tell rows apart); selecting a source hides it and
gives the width back to the artifact title. Also drops the now-dangling
row-main border-right in that state.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-03 12:30:49 +01:00
9a3b381f39 Add light/dark mode toggle for the UI
The UI stylesheet already centralized its palette in a :root block, so this
mostly meant (1) migrating the ~30 colors still hardcoded in rules into
variables so they flip in one place, and (2) adding a [data-theme="dark"]
override palette. Artifact rendering is untouched — those use the separate
static/themes/*.css and the preview backdrop stays white by design, since
artifacts (charts, reports) are authored light.

- Toggle lives in the gear-menu dropdown (Dark mode / Light mode), persists
  to localStorage.
- A tiny inline script in each page <head> (feed, settings, login) applies
  the stored theme before first paint, so dark-mode users never see a white
  flash on load.
- color-scheme: dark on the dark palette makes native form controls
  (inputs, buttons) render dark too.
- Semantic accents (kept=green, shared=blue, today, danger) got
  dark-appropriate variants; status/data-viz colors (usage bar, tag chips)
  and the white artifact backdrop are intentionally left as-is.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 17:14:56 +01:00
91ea19d26b Add per-artifact public sharing
Any artifact can now be made publicly viewable via a share link, no login
required - opt-in per artifact, toggled from the feed UI next to Keep.

- Artifact.share_token: nullable, unique, high-entropy (secrets.token_urlsafe(32)).
  NULL = not shared; SQL treats each NULL as distinct so uniqueness still
  holds for the many not-shared rows.
- New public route GET /s/<token> (shared_artifact_view), completely
  unauthenticated, serving the same rendered/raw content as the owner
  route via a shared serve_artifact_file() helper.
- toggle_artifact_share: generates/clears the token: mirrors
  toggle_artifact_keep's pattern.
- Fixed a real gap this surfaced: embedded images in a shared artifact's
  content would otherwise break for an anonymous visitor, since asset_view
  was owner-only. It now also allows access when the asset's parent
  artifact is currently shared - unattached (orphaned) assets stay private
  regardless.
- serialize_artifact now reports is_shared/share_url so the API reflects
  sharing status (read-only for now; toggling stays UI-only).
- Feed UI: Share button (mirrors Keep's toggle interaction), a copyable
  share-link box that appears when shared, and a "shared" badge on the
  artifact row - distinct blue accent from Keep's green so both can be
  visible on the same row without confusion.

Verified live end-to-end (toggle on/off, public access, fake-token 404,
old-link-dies-on-unshare, embedded-asset access before/after sharing)
before writing the 12 automated tests in tests/views/test_sharing.py.
Also fixed two unrelated stale spots noticed in docs/api.md while adding
the Sharing section: the example response was missing is_kept/size_bytes,
and the raw-content table didn't list json/csv (added earlier this
session but never documented there).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 16:00:39 +01:00
940a703cd7 Initial public commit
Daybook: a self-hosted, multi-user Django + DRF app where agents, scripts,
or people publish artifacts and each logged-in user browses their own
time-ordered, label-filterable feed.

This squashes prior local development history (kept privately on a separate
branch) into a single clean starting point for the public repository.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 21:55:02 +01:00