A merge left the v0.2.0 and v0.1.0 growth-log entries duplicated. Keep one
entry per version in descending order and add the v0.5.0 line covering this
release: readable handles in messages, sidebar with real last message/time,
and the documented `pnpm dev` setup. Frontmatter version 0.4.0 -> 0.5.0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Same-origin (Caddy) means the SPA reaches /api and /nats through its own
origin in production, but those relative paths do not exist on the bare Vite
dev server, so `pnpm dev` no longer connects. busService already reads
VITE_BUS_HTTP / VITE_BUS_WS as overrides of the same-origin defaults — this
documents that path (Option A, no proxy code) and moves the dev server off the
port reserved by an unrelated local app.
- vite.config: dev server port 5173 -> 5174 (5173 is in use by another local
app). strictPort left off so Vite falls back to the next free port. Comment
explains the same-origin/dev split and the env-var override.
- app.md: Ejemplo and the CORS gotcha document the exact dev command
(VITE_BUS_HTTP/WS pointing at a cluster node) on :5174 and the same-origin
production model.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Session persistence (web/src/session.ts): the unlocked wallet identity is kept
across reloads so an F5 no longer forces a password re-unlock. By default it lives
in sessionStorage (survives F5, cleared with the tab); with 'keep me signed in' it
lives in localStorage (survives closing the browser) bounded by a 30-day absolute
TTL and a 12-hour inactivity auto-lock. logout clears it; activity (send/createRoom)
refreshes the idle timer. No cookie is ever used — the private key never travels to
any server. WalletLogin gains the 'keep me signed in' checkbox; Recover/Join keep
the session by default (recovering/creating on a device implies it is yours).
App.tsx restores the session on mount before falling back to the unlock screen.
ACL reconnect: a room created while connected was not in the NATS per-subject ACL
grant (subjects are frozen at connect time), so its first messages silently did not
deliver until a re-login. WsNatsTransport gains reconnect(); BusClient.refresh()
calls it; busService.createRoom reconnects after creating so the new room is usable
immediately. Bumps uniweb to 0.4.0.
Phase 2 of issue 0001. uniweb becomes a pure frontend (web/ only), like
unibus_android: the SPA talks directly to the bus and the Go gateway is gone.
- busService.ts: the new data layer over the bus SDK, replacing the old api module.
It holds the user's wallet identity and a connected BusClient IN THE BROWSER and
opens the session locally — the private key is never sent anywhere (closes the
gateway-era hole where the browser POSTed its private key to /api/session).
- Wire account/App/ChatShell/ChatPanel/WalletLogin/Recover/Join to busService;
subscribeRoom replaces the SSE streamRoom; ApiError -> SessionError.
- SDK: ControlPlane.createRoom + listMemberRooms, and fetchRoom mapped to the real
control-plane wire shape (snake_case, no id) — all verified by the live round-trip.
- Delete cmd/webgw, go.mod, go.sum, src/api.ts and the orphan operator Login. uniweb
now has zero Go and no dependency on unibus as a module.
- vite: drop the /api proxy, dev server on 5173 to match the bus CORS allowlist; add
vite-env typings. app.md: lang ts, no uses_functions, e2e_checks are now web-only.
Bump 0.3.0.
Onboarding by token is now admin-side (the bus has no self-register endpoint; the
gateway only mocked it). tsc + pnpm build + 19/19 unit green.
Second half of the browser-native bus SDK (issue 0001, Phase 1), making uniweb a
peer of the bus in its own right (like unibus_android) without the Go gateway:
- busauth.ts: NATS user nkey from the Ed25519 key (base32 + crc16, no nkeys dep)
and control-plane request signing (CanonicalRequest + X-Unibus-* headers).
- room.ts: Policy / Room types (ModeNATS, ModeMatrix).
- client.ts: the pure room ENVELOPE (sealRoomMessage/openRoomMessage — AEAD with
the subject as AAD, Ed25519 sign, drop on verify/decrypt failure), a transport-
agnostic BusClient, and a signed ControlPlane HTTP client (fetch room/key/members,
open the sealed room key locally).
- wstransport.ts: concrete nats.ws WebSocket transport (validated E2E in Phase 3).
- index.ts: public SDK surface.
Parity pinned by vectors from unibus cmd/busvectors (extended with nkey + signed
control-request vectors): 19/19 green. The user's private key signs everything in
the browser and is never sent to any server. Bumps uniweb to 0.2.0.
Remaining for Phase 1 completion: the live nats.ws connection + control-plane,
which need a running unibus with the WebSocket listener — exercised in Phase 3.
Extracted from unibus v0.13.0: the chat SPA (web/, React+Mantine, per-user
BIP39 wallet) and the web gateway (cmd/webgw, REST+SSE) that acts as a bus
peer for the browser. Consumes unibus as a Go module via replace => ../unibus,
keeping its own replace fn-registry for the cybersecurity primitives.
go build/vet/test and pnpm build green in the new location.