Commit Graph
6 Commits
Author SHA1 Message Date
dguiducci ff298f1aef fix: renew a session that died under an open tab, instead of eating the message typed into it
Nightly Build / build (push) Successful in 7m34s
Sessions live in the server's RAM, so a restart logs everyone out while the
browser keeps sending a cookie nobody recognises. Nothing noticed: every gated
API call answered 401 into a component that shrugged, and the chat socket was
refused at the upgrade — which reaches `onclose` looking exactly like a flaky
network, so the loop retried every 2 s forever behind "Not connected —
reconnecting, please retry", against a server that would never accept it again.

Retrying was not even the expensive part. `_send()` cleared the composer and
dropped the attachment chips *before* testing the socket, so a long message was
already destroyed by the time the error bubble appeared. The connection test now
comes first and everything below it is unreachable while the socket is down, so
the text stays where the user left it; `/new` and `/clear` move above the guard
because they go over HTTP and reconnect the socket themselves, which is when
they are most wanted.

Detection is one module (`lib/session-expiry.js`) reporting a fact — `auth-expired`,
and `auth-restored` on the way back — with nothing in it that touches the DOM. A
`window.fetch` wrapper flags any 401 from a gated `/api` path, a wrapper rather
than a helper each call site opts into because the components call `fetch`
directly in dozens of places and a seam that must be remembered is one the next
page will forget; `auth/*` and `setup/*` are excluded, where 401 is the normal
answer. The socket's own path asks `probeSession()` before retrying, since it
cannot tell a refusal from a blip. The native mobile shell is guarded inside the
report, so no future caller can reintroduce a web login form there.

The answer is a modal over the page the user is already on, not the login
screen: bouncing to it would throw away everything the page was holding —
including the half-written message this commit exists to save. One password
field, prefilled with the last username this browser logged in as, not
dismissible (with no session nothing on the page works, and a dialog you can
wave away leaves a UI that silently fails every action). On success the chat
reconnects on `auth-restored` and reconciles like any other disconnection.

Known gap: pages that failed a fetch during the outage keep their stale data
until navigated to again. Only the chat re-arms itself.
2026-08-04 13:02:39 +01:00
dguiducci f6665ae49d mobile: show login screen for stock browsers when not authenticated
Nightly Build / build (push) Successful in 6m57s
Add an inline auth gate to mobile.html that checks /api/auth/me on load.
Skipped when ?native=true (the iOS shell handles auth in background).
Includes a vanilla JS login form (no Lit) reusing the existing login styles.

Bump version to 0.1.2.
2026-07-24 23:52:54 +01:00
dguiducci c11702c3d3 tool card UI redesign: semantic icons, inline diff persistence, tool detail page, MCP-friendly titles
Nightly Build / build (push) Successful in 6m38s
2026-07-21 23:39:41 +01:00
dguiducci 79a62c0b93 Add update.sh, release-channel tagging, mobile settings page
Nightly Build / build (push) Successful in 6m28s
install.sh / install-nightly.sh:
  - Write .release-channel file ('release' or 'nightly') for future updates
  - install.sh also writes .release-version (for update --check)

update.sh (new):
  - Reads .release-channel to determine which channel to pull from
  - Release: checks releases/LATEST vs .release-version, skips if current
  - Nightly: always downloads latest
  - Stops service before extraction, restarts after
  - Rebuilds Python venv on update

ci/package.sh:
  - Include update.sh in distribution tarball

Web / mobile:
  - Add settings-page component for mobile
  - Wire settings page into mobile-app navigation
  - Chat page: load current user (/api/auth/me) for sender identity
  - Full mobile.css redesign
  - i18n: add mobile settings strings (en/fr/it)
2026-07-20 22:31:41 +01:00
dguiducci 126886e309 Major rebranding, i18n, dashboard, shared folders, role capabilities
- Rebrand: new app/agent icons, SKALD.md, warm "paper" CSS palette
  (terracotta accent, --radius tokens, WCAG contrast, reduced-motion),
  updated favicon, tray icon, skaldkonur asset
- i18n: backend crate (i18n.rs, locale column, ui_locale config),
  frontend library (web/lib/i18n.js, I18nMixin, t(key)),
  translation files (web/i18n/), every component wired
- Dashboard: <dashboard-page> replaces old home-page content;
  <app-copilot> becomes the landing page (full/dock layout modes)
- Shared folders: API endpoints (shared_folders.rs), frontend page,
  can_write membership, container mount topology, user_fs routing
- Role capabilities: new db table & authorization seam (data not enums),
  roles.attrs JSON for ui_mode / interface select
- Setup: skald-setup prompts for language + password, sets ui_locale
- General: components migrated to CSS variables, Lit conventions cleanup,
  connectors/catalog/marketplace/approval refactoring
2026-07-18 21:38:42 +01:00
dguiducci 38494a85a9 First Version 2026-07-10 15:02:09 +01:00