Viewer surface: browse generated images by date / backend / style / tag (Tailscale-internal) #6

Open
opened 2026-05-09 09:21:29 +00:00 by mAi · 1 comment
Collaborator

Idea (m, PWA-Voice 2026-05-09 11:25)

"Vielleicht direkt eine visuelle Oberfläche machen, beziehungsweise wir eine Webseite haben, auf der ich dann alle Bilder direkt einsehen kann, die generiert wurden. Das muss nicht mal eine richtige Webseite sein, es kann sein, dass es auf mRiver irgendwie läuft und dann durchgeroutet wird. Das ist was, was ich gerne direkt hätte. Also Output der generierten Bilder, einfach alles rein theoretisch. Wir machen dann so ein Output-Folder und der ist dann in sich strukturiert nach Datum und wir können natürlich auch Verschlagwortung filtern, sonst was."

Concept

A simple viewer surface for the local image-output folder (~/Pictures/imagen/ per ImaGen#1's output spec). m wants to scroll through everything that was generated, see it visually, filter by date / tag, jump back to a specific run.

Not a public product, not a polished web app — m's words: "muss nicht mal eine richtige Webseite sein, kann sein dass es auf mRiver irgendwie läuft und dann durchgeroutet wird". Tailscale-internal, single-user, low effort, high signal.

Surface options

  • A. Static directory listing (nginx autoindex or python -m http.server style) on mRiver. Simplest. Zero customisation, but works in 5 minutes.
  • B. Static site generator that rebuilds an index.html whenever a new image lands (e.g., a small inotify watcher writes a Hugo / Eleventy / hand-rolled HTML index). Better visual, no live runtime.
  • C. Tiny Go web service on mRiver that scans the folder + serves a frontend. Full filtering, search, tag UI. More code; cleanest experience.
  • D. Frontend bundled into ImaGen itself (imagen serve --port 8189 from internal/server/, which is already stubbed in the bootstrap from #1). Ships alongside the framework, accessible wherever ImaGen runs.

Recommendation pre-design: start with D (lowest setup, leverages the framework that already exists) — and route via Tailscale (http://mriver:8189) so m hits it from any of his machines.

Folder structure (input)

ImaGen#1's output writer already does:

  • Naming template: {date}-{slug}-{seed}.png
  • Sidecar JSON per image with prompt + backend + seed + latency + cost-estimate

Viewer reads both — image grid plus structured metadata available for filter / search.

Filter dimensions (initial set)

  • Date — day, week, month
  • Backendflux-schnell-local, flux-schnell-replicate, …
  • Style presetphoto, illustration, diagram, sketch, blog-header
  • Prompt full-text — substring match over the prompt
  • Tag — manual tags m adds post-generation (not yet in metadata; needs a tag-write path — see Open questions)
  • Cost-bucket — free (local) / paid (api)

Open questions for design phase

  1. Tag editing: where do tags live? Sidecar JSON (next to image), separate tags.yaml index, or a SQLite-let on the side? Tags should survive the image being moved or the sidecar being regenerated.
  2. Image preview size + lazy loading: 100+ images per day in a typical-use scenario — need thumbnails + virtualised grid.
  3. Re-run / fork from a saved image: should the viewer offer a "regenerate with same prompt + new seed" button that calls back into the ImaGen CLI?
  4. Delete / archive: is there a delete action, or is the folder append-only?
  5. Cross-machine view: m wants to see images generated on mRock from his mPebble laptop. Does the viewer run on mRiver and read from a shared volume, or run on each machine and read from a sync'd folder, or read directly from mRock via SSH?
  6. Auth: Tailscale-internal is m's preferred boundary today. If the viewer ever needs to leave Tailscale, an auth layer becomes load-bearing. Out of scope for v0.

This shares concept-DNA with two recently-parked issues:

If a "user-curates-AI-outputs" abstraction proves out across all three projects (chat outputs, judgment notes, generated images), there might be a shared storage / tag model worth lifting out. Premature to design that now — but worth noting that three independent issues are gravitating towards similar shape.

Out of scope (this issue)

  • Implementation
  • Public hosting / SEO / non-Tailscale access
  • Video / audio outputs (this is image-only)
  • Multi-user collaboration

Workflow

Park-only. When m wants to pursue:

  1. Inventor designs UX + surface choice (A/B/C/D) + answers Open Questions
  2. Coder implements stage 1: viewer with date + backend + style filter
  3. Coder implements stage 2: tag editing + full-text prompt search
  4. Coder implements stage 3 (optional): re-run / regenerate from viewer

Refs

  • m's voice via PWA 2026-05-09 11:25 (parking request)
  • ImaGen framework: ImaGen#1 (bootstrap) — depends-on for option D
  • yoUPC/youpc.org#129 (mini-DMS for AI text outputs) — concept-cousin
  • m/paliad#29 (mini-DMS for AI text outputs in Paliad) — concept-cousin
## Idea (m, PWA-Voice 2026-05-09 11:25) > "Vielleicht direkt eine visuelle Oberfläche machen, beziehungsweise wir eine Webseite haben, auf der ich dann alle Bilder direkt einsehen kann, die generiert wurden. Das muss nicht mal eine richtige Webseite sein, es kann sein, dass es auf mRiver irgendwie läuft und dann durchgeroutet wird. Das ist was, was ich gerne direkt hätte. Also Output der generierten Bilder, einfach alles rein theoretisch. Wir machen dann so ein Output-Folder und der ist dann in sich strukturiert nach Datum und wir können natürlich auch Verschlagwortung filtern, sonst was." ## Concept A simple **viewer surface** for the local image-output folder (`~/Pictures/imagen/` per ImaGen#1's output spec). m wants to scroll through everything that was generated, see it visually, filter by date / tag, jump back to a specific run. Not a public product, not a polished web app — m's words: *"muss nicht mal eine richtige Webseite sein, kann sein dass es auf mRiver irgendwie läuft und dann durchgeroutet wird"*. Tailscale-internal, single-user, low effort, high signal. ## Surface options - **A. Static directory listing** (nginx autoindex or `python -m http.server` style) on mRiver. Simplest. Zero customisation, but works in 5 minutes. - **B. Static site generator** that rebuilds an `index.html` whenever a new image lands (e.g., a small inotify watcher writes a Hugo / Eleventy / hand-rolled HTML index). Better visual, no live runtime. - **C. Tiny Go web service** on mRiver that scans the folder + serves a frontend. Full filtering, search, tag UI. More code; cleanest experience. - **D. Frontend bundled into ImaGen itself** (`imagen serve --port 8189` from `internal/server/`, which is already stubbed in the bootstrap from #1). Ships alongside the framework, accessible wherever ImaGen runs. Recommendation pre-design: start with **D** (lowest setup, leverages the framework that already exists) — and route via Tailscale (`http://mriver:8189`) so m hits it from any of his machines. ## Folder structure (input) ImaGen#1's output writer already does: - Naming template: `{date}-{slug}-{seed}.png` - Sidecar JSON per image with prompt + backend + seed + latency + cost-estimate Viewer reads both — image grid plus structured metadata available for filter / search. ## Filter dimensions (initial set) - **Date** — day, week, month - **Backend** — `flux-schnell-local`, `flux-schnell-replicate`, … - **Style preset** — `photo`, `illustration`, `diagram`, `sketch`, `blog-header` - **Prompt full-text** — substring match over the prompt - **Tag** — manual tags m adds post-generation (not yet in metadata; needs a tag-write path — see Open questions) - **Cost-bucket** — free (local) / paid (api) ## Open questions for design phase 1. **Tag editing**: where do tags live? Sidecar JSON (next to image), separate `tags.yaml` index, or a SQLite-let on the side? Tags should survive the image being moved or the sidecar being regenerated. 2. **Image preview size + lazy loading**: 100+ images per day in a typical-use scenario — need thumbnails + virtualised grid. 3. **Re-run / fork from a saved image**: should the viewer offer a "regenerate with same prompt + new seed" button that calls back into the ImaGen CLI? 4. **Delete / archive**: is there a delete action, or is the folder append-only? 5. **Cross-machine view**: m wants to see images generated on mRock from his mPebble laptop. Does the viewer run on mRiver and read from a shared volume, or run on each machine and read from a sync'd folder, or read directly from mRock via SSH? 6. **Auth**: Tailscale-internal is m's preferred boundary today. If the viewer ever needs to leave Tailscale, an auth layer becomes load-bearing. Out of scope for v0. ## Cross-link This shares concept-DNA with two recently-parked issues: - **yoUPC/youpc.org#129** — save AI outputs to user folder + tags (mini-DMS for AI artefacts) - **m/paliad#29** — same pattern for the Paliad AI assistants If a "user-curates-AI-outputs" abstraction proves out across all three projects (chat outputs, judgment notes, generated images), there might be a shared storage / tag model worth lifting out. Premature to design that now — but worth noting that three independent issues are gravitating towards similar shape. ## Out of scope (this issue) - Implementation - Public hosting / SEO / non-Tailscale access - Video / audio outputs (this is image-only) - Multi-user collaboration ## Workflow Park-only. When m wants to pursue: 1. Inventor designs UX + surface choice (A/B/C/D) + answers Open Questions 2. Coder implements stage 1: viewer with date + backend + style filter 3. Coder implements stage 2: tag editing + full-text prompt search 4. Coder implements stage 3 (optional): re-run / regenerate from viewer ## Refs - m's voice via PWA 2026-05-09 11:25 (parking request) - ImaGen framework: ImaGen#1 (bootstrap) — depends-on for option D - yoUPC/youpc.org#129 (mini-DMS for AI text outputs) — concept-cousin - m/paliad#29 (mini-DMS for AI text outputs in Paliad) — concept-cousin
Author
Collaborator

Superseded by joint flexsiebels integration

After m's voice note here on 2026-05-09 (Tailscale-internal viewer on mRiver), m re-framed the surface on 2026-05-11: the viewer lives inside flexsiebels.de instead of as a standalone service. flexsiebels is m's owner-side personal-web umbrella, already has the SvelteKit + Bun + Supabase + Dokploy stack + auth, and the schema-helper pattern (mb() / flex() / mh()) makes adding an imagen() reader cheap.

Decisions captured in the head-to-head thread (mai messages 1612/1613/1614/1615 between imagen/head and flexsiebels/head):

  • Architecture: hybrid Option B (read path via Supabase data plane) + Option A (write path, deferred to v2). Hard no on Option C (shell-out couples container lifecycles).
  • Schema: new imagen.* schema with an images table (NOT extending flexsiebels.images — different semantics). mai.imagen_usage stays as-is for cost-billing; join on prompt_hash when needed.
  • Storage: private Supabase Storage bucket imagen-generated. Signed URLs for owner-mode rendering.
  • v1 = owner-only, all routes behind requireAuth. No public surface (m confirmed 2026-05-11 01:35).
  • Future promotion path (separate v2 issue): explicit "promote to gallery" action that copies imagen.imagesflexsiebels.images with stripped semantics, exposing the curated image like any other public-eligible upload.

Replaced by

  • ImaGen#7 (imagen-side, this repo): cloud-sync — imagen.* schema migration, Supabase Storage upload, DB insert after each generation, --no-cloud flag for offline runs.
  • m/flexsiebels.de#64 (flexsiebels-side, paul's repo): imagen() schema helper, /imagine list + detail routes, owner-mode nav, requireAuth, disabled "Promote to gallery" stub for the future v2.

Both being scoped now. paul (flexsiebels/head) is starting #64 today in parallel — scaffolding against an empty imagen.images table while head delivers #7's upload-side. Schema shape is the contract.

Leaving this issue open for m to close once #7 and #64 both merge.

## Superseded by joint flexsiebels integration After m's voice note here on 2026-05-09 (Tailscale-internal viewer on mRiver), m re-framed the surface on 2026-05-11: the viewer lives inside flexsiebels.de instead of as a standalone service. flexsiebels is m's owner-side personal-web umbrella, already has the SvelteKit + Bun + Supabase + Dokploy stack + auth, and the schema-helper pattern (`mb()` / `flex()` / `mh()`) makes adding an `imagen()` reader cheap. Decisions captured in the head-to-head thread (mai messages 1612/1613/1614/1615 between imagen/head and flexsiebels/head): - **Architecture**: hybrid Option B (read path via Supabase data plane) + Option A (write path, deferred to v2). Hard no on Option C (shell-out couples container lifecycles). - **Schema**: new `imagen.*` schema with an `images` table (NOT extending `flexsiebels.images` — different semantics). `mai.imagen_usage` stays as-is for cost-billing; join on `prompt_hash` when needed. - **Storage**: private Supabase Storage bucket `imagen-generated`. Signed URLs for owner-mode rendering. - **v1 = owner-only**, all routes behind `requireAuth`. No public surface (m confirmed 2026-05-11 01:35). - **Future promotion path** (separate v2 issue): explicit "promote to gallery" action that copies `imagen.images` → `flexsiebels.images` with stripped semantics, exposing the curated image like any other public-eligible upload. ### Replaced by - **ImaGen#7** (imagen-side, this repo): cloud-sync — `imagen.*` schema migration, Supabase Storage upload, DB insert after each generation, `--no-cloud` flag for offline runs. - **m/flexsiebels.de#64** (flexsiebels-side, paul's repo): `imagen()` schema helper, `/imagine` list + detail routes, owner-mode nav, requireAuth, disabled "Promote to gallery" stub for the future v2. Both being scoped now. paul (flexsiebels/head) is starting #64 today in parallel — scaffolding against an empty `imagen.images` table while head delivers #7's upload-side. Schema shape is the contract. Leaving this issue open for m to close once #7 and #64 both merge.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: m/ImaGen#6
No description provided.