Commit Graph

88 Commits

Author SHA1 Message Date
6b83b661fa mansion: a moonlit villa estate (2.3.0)
My Mansion gets a CSS villa scene — dusk sky, glowing/flickering windows,
waving flag, garden hedge — with the live services (Showcase, File-mapper,
Net-disk) presented as 'chambers of the estate'.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 09:30:06 +08:00
e308c9be4d legion: war camp — class banners + alive/fallen soldier instances (2.2.0)
- LegionDashboard 'war camp': each class is a pennant banner (click =
  detail dialog), each instance a soldier grouped under its banner —
  bobbing 🪖 when online, 🧍 pending, 💀 fallen when down
- SoldierDialog: command a soldier in an ornate dialog — chat with your
  own running agent (skills shown), a live terminal snapshot polled every
  5s (the heartbeat tui field), rouse instructions when down, stand-down
- legion auto-refreshes every 15s so statuses stay live
- verified locally: 2 banners, 3 soldiers, ON DUTY chat dialog

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 09:22:56 +08:00
374440a392 browse: the roster door — mercenaries descend with bubble briefs (2.1.0)
- AgentBrowse is a doorway: a glowing open-door graphic, then mercs
  descend (staggered drop animation) hanging on wooden sign-bubbles that
  show each agent's brief; portraits carry a live/offline dot + managed crest
- ClassModal rebuilt on the shared GameDialog (extracted to GameDialog.jsx
  to avoid a Scene2D<->AgentPlatform circular import); instances render as
  a squad — living soldiers (online) vs fallen (down)
- verified locally against a seeded backend (6 mercs, squad dialog)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 09:14:10 +08:00
a350ae6884 home: the tavern becomes the interface (2.0.0)
Full-screen diegetic game home — the page IS the tavern:
- grand glowing door = Browse Agents; bar/barkeep = sign-in (greets a
  logged-in user by name); wall banners = My Legion; villa side-exit =
  My Mansion; dancer pitches the tour in a holographic panel
- persistent clickable speech bubbles (wood / holo / door variants),
  hover quips on patrons, live stats on the wall screen
- GameDialog: ornate gem-cornered dialog frame; the tour (HomeFeatures)
  and login (THE LEDGER) open in-game instead of navigating away
- stage scales to fill the viewport (768x432 buffer, pixelated upscale)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 03:33:28 +08:00
511bd25aa0 mansion: file-mapper + net-disk rooms; 100MB quota; broker jobs (1.3.0)
- file_maps table + agent fm register/list/delete; public GET /fm/:iid/:name
  relays the download live through the broker (consumer-first rendezvous,
  60s window, zero server storage); broker long-polls /instances/:id/jobs
- netdisk: 100MB per-account quota enforced on upload + /files/usage meter
- Mansion: File-mapper and Net-disk are live rooms (usage bar, embedded
  Netdisk browser); Netdisk relay soon-room retired
- kebab's real instance is ONLINE and replied 'pong' over native chat —
  gate path proven; jobs protocol spec sent to kebab

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 03:12:56 +08:00
b4b5df91f0 legion: agent cards reused + class runtime properties (1.2.0)
- AgentCard extracted; Browse and My Legion render the identical card;
  Legion cards open the same ClassModal (instances + Use + chat)
- class properties: managed (amerc-managed, loads amerc skills),
  terminal_mode new|shared per session, skills_reload for shared
  terminals — publish form, API create/patch, badges in the modal
- kebab coordination: broker spec delivered via TerminalMan 155; kebab
  already heartbeats instance 2 with the skills array (status lost ->
  stabilizing); monitor armed for online

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 02:58:51 +08:00
2941f14583 chat: native ChatPanel + chatlog + file relay UI (1.1.0)
- src/Chat.jsx: long-poll chat panel — skills-loaded chips, file/image
  send with streaming progress bar, expiring download links for received
  files, per-session chatlog with resume; no iframe, no external relay
- UsePanel: chatbox tab now uses the native panel (web-pty still rides
  the relay for now); Legion gains a 'My chatlog' card
- verified END-TO-END IN PRODUCTION via throwaway account + live broker:
  browser sent, broker echoed, skills rendered, chatlog listed; 2MB file
  relayed through nginx md5-identical with no server caching; all test
  data purged after

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 02:51:22 +08:00
c2a8616255 legion: rename My Booth -> My Legion, Mansion -> My Mansion (1.0.0)
Route 'legion' with a legacy '#/booth' alias; BoothDashboard -> LegionDashboard;
nav, footer, hotspots, WebMCP enum, gate copy all renamed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 02:33:41 +08:00
80d7140d1f booth: label every field in the publish form (0.99.0)
audited the Booth as a new publisher: the onboarding is good, but the publish
form was placeholder-only — and Kind (codex) + Launch command (codex --yolo)
come pre-filled, so their placeholders never show, leaving those two technical
fields with no visible label.

- added a persistent label above every field (Class name, Tags, Description,
  Kind, Visibility, Launch command) + clearer example placeholders
- a one-line hint explains the two technical fields
- verified live (throwaway account, cleaned up): all six labels render, form
  reads cleanly
- changelog entry (0.99) added with the bump
2026-06-10 15:19:04 +08:00
9c1aa73742 home: turn the API peek into a live console (0.98.0)
the agent-native callout's API peek showed a curl line + the JSON, but felt
static. made it feel like a real API client:

- after each call it shows the response status and timing (green dot, '200 OK
  · 47 ms') measured with performance.now() — the visitor's actual request time
- a '↻ run' button re-fetches the current endpoint (running… -> new status)
- endpoint tabs still switch (stats / roster / activity), all read-only & no-auth
- verified live: status '200 OK · 683 ms', run re-fetches (running… -> 200 OK),
  green dot on success
- changelog entry (0.98) added with the bump
2026-06-10 15:08:26 +08:00
d05a5b110c auth: clearer sign-in copy on the conversion gate (0.97.0)
the join form used confusing labels at the exact moment a visitor commits:
- the email field was labelled 'Guild handle email' (it is just an email)
- the password field was 'Access sigil'
- the login button was 'Enter Booth' (logging in does not go to the Booth)
- the card eyebrow was 'OPEN BOOTH' (publisher-biased; you might sign in to browse)

now: Email / Password, a clear 'Log in' button, and a neutral 'ONE ACCOUNT'
eyebrow that reinforces the single sign-on. theme stays in the heading
('Join the tavern', 'Welcome, mercenary') and the benefit points.

verified live: login shows Email/Password -> Log in; signup shows
Email/Display name/Password -> Create Account.
2026-06-10 15:01:44 +08:00
0775b79a1b home: fit the hero value prop above the fold (0.96.0)
on common laptops (1366x768, 1280x720, 1440x900) the tavern canvas reserved
only 210px for the topbar + caption, so the tagline + CTAs landed at the very
bottom edge and the live stats sat ~40px BELOW the fold — a visitor had to
scroll to see the value prop and the action buttons.

- reserve 290px instead of 210, so the canvas is sized to leave room for the
  full caption; the tavern is still the large, vivid centrepiece (478px tall
  at 768, down from 558)
- desktop-only: the canvas is width-capped (94vw) on phones, so mobile is
  untouched
- verified across all three laptop sizes: CTA ~80px clearance, stats ~40px
  clearance (was 40px below the fold)
- added the matching changelog entry (0.96) alongside the bump
2026-06-10 14:43:19 +08:00
22c7e4209f changelog: catch up to the version badge (0.95.0)
the in-app CHANGELOG array stopped at v0.89 while the badge (which links to it)
read v0.94 — five shipped versions missing: linkable agents, mobile docs nav,
the live API peek, full-text docs search, and the key 'try it' curl.

- added entries 0.90-0.95 so the changelog's newest version matches RELEASE
- verified live: badge v0.95, changelog tops out at v0.95 (37 entries)

(also saved a project note to add a CHANGELOG entry alongside each version bump —
this has now drifted 5 versions behind twice.)
2026-06-10 14:31:29 +08:00
63b1087042 account: show a runnable curl when you mint a key (0.94.0)
minting an agent key showed the key once with no hint of what to do with it —
you had to go dig through the docs to make your first call. great API products
hand you a working example right there.

- after minting, show a ready-to-run curl with YOUR key inlined, hitting a real
  read-only endpoint (GET /agents/classes), plus a one-click copy and a link to
  the API reference
- completes the get-key -> call-the-API loop and reinforces the agent-native pitch
- verified live (throwaway account, cleaned up after): the curl renders with the
  real minted key, copy button + api-reference link present
2026-06-10 14:16:26 +08:00
66ccd54d21 docs: full-text search with snippets + peek a11y (0.93.0)
the docs search only matched titles/folders, so searching a term that lives in
a doc's body (e.g. 'heartbeat') returned nothing — you had to already know
which doc to open.

- search now matches title AND body across all docs; results show the title
  plus a context snippet with the query highlighted (<mark>)
- doc bodies are fetched once on first search and cached (invalidated when the
  doc list changes); in-flight searches cancel on a new query
- clicking a result opens the doc (and updates the URL); clearing returns the
  folder tree
- a11y: the homepage API peek used role=tablist/tab without tabpanels (an
  incomplete ARIA pattern) — switched to a labeled button group with aria-pressed
- verified live: 'heartbeat' -> 3 body matches with highlighted snippets,
  click opens Connect-your-broker, clear restores the tree
2026-06-10 14:08:19 +08:00
ce9d2336f7 home: live API peek in the agent-native callout (0.92.0)
the callout claimed 'drive the whole platform over JSON' but only said it.
now it shows it: a compact terminal with tabs for the public read-only
endpoints (stats / roster / activity) that fetches the LIVE response and
pretty-prints it with JSON syntax highlighting.

- proves the agent-native differentiator with real data, not a mockup
- read-only public endpoints, no auth; switching tabs updates the curl line
  and refetches; cancels in-flight on unmount
- small self-contained jsonHl() highlighter (keys/strings/numbers/bools),
  output escaped before highlighting so it's injection-safe
- verified live: stats shows {classes:1,online:1,...}, roster shows
  Kebab Webagent, 9 key + 7 number spans highlighted, tabs refetch
2026-06-10 13:44:25 +08:00
e5e79d75aa docs: collapsible doc nav on mobile (0.91.0)
a mobile audit (no overflow anywhere; agent modal + on-this-page TOC both fine)
turned up one weak spot: on phones the doc tree was a cramped 210px scroll area
pinned above every page, and it never scrolled the active doc into view — so
you couldn't tell which doc you were reading or reach half of them easily.

- the sidebar now collapses to a compact bar showing the CURRENT doc + a
  chevron; tap to reveal the full tree (active doc highlighted), tap a doc to
  navigate and auto-collapse
- desktop is byte-for-byte unchanged: the collapsible wrapper is display:contents
  off-mobile, so the tree stays a normal flex child (sidebar still 280px)
- verified live: mobile collapsed shows 'API reference', expands to 8 docs,
  selecting Quickstart navigates + collapses + relabels; desktop toggle hidden,
  tree intact
2026-06-10 13:35:07 +08:00
0fd1ed2b5c agents: shareable per-agent URLs (0.90.0)
opening an agent only lived in component state, so you couldn't link to one,
and a refresh dropped the open agent — inconsistent with the now-shareable
docs. each agent modal now has a URL: amerc.ai/#/agents/<slug>.

- the hash router keys off the first path segment, so #/agents/<slug> still
  routes to Browse while exposing the slug as a sub-path (backward compatible)
- opening a card pushes #/agents/<slug>; loading that URL opens the modal;
  closing returns to #/agents; browser back/forward open & close it
- verified live: click updates URL + opens, Escape closes to #/agents, a fresh
  deep-link opens 'Kebab Webagent', back closes

also recorded a project memory: sandbox->amerc network path is slow (~0.65s
TLS) but the server is fast (~13ms loopback) — don't trust sandbox-measured
latency or Lighthouse-from-sandbox as the real user experience.
2026-06-10 13:23:35 +08:00
cd9c7f7e8c changelog: bring the trail up to date (0.89.0)
the changelog page stopped at v0.51 while the site shipped to v0.88 — so the
version badge (which links to the changelog) advertised ~37 versions that the
'trail' never showed, directly undercutting its 'ships continuously' line.

reconstructed the real history from git and added 17 curated milestones
(0.54 -> 0.89): the agent-native/WebMCP work, the accessibility & caching
sweeps, instant paint, the OG share card, docs routing + section nav, the
error boundary, mobile nav, lean build, and more.

- verified live: 31 entries, newest v0.89, matches the v0.89 badge
2026-06-10 13:02:57 +08:00
0e3c567c97 docs: on-this-page TOC + section deep links + heading anchors (0.88.0)
builds on per-doc routing: long docs (API reference has 6 sections, Roadmap 4)
are now navigable and section-shareable.

- each h2/h3 gets a slug id + a hover '#' anchor; URL form is
  #/<doc-slug>/<section-slug> (e.g. #/api-reference/keys-self-service)
- an 'On this page' TOC renders for docs with >=3 headings; click or deep-link
  scrolls to the section; browser back/forward still work
- decorations (anchors, ids, code copy buttons, syntax highlighting) are now
  baked into the memoized HTML string instead of mutated in post-render DOM

  WHY: the post-render mutation approach was being wiped. setToc() inside the
  decorate effect triggered a re-render that re-applied dangerouslySetInnerHTML,
  resetting the article's children and dropping every decoration, with the
  effect never re-running (deps unchanged). Doing it at the string level makes
  the markup self-contained and immune to re-injection. Copy buttons use event
  delegation; anchors are real links (work without JS).

- verified live: 6/6 heading ids + anchors on API reference, TOC navigates,
  3 copy buttons + highlighting on Connect-your-broker, deep-links land and
  scroll to the section, TOC hidden on short docs
2026-06-10 12:50:31 +08:00
60d045b55f docs: shareable URLs per document (0.87.0)
the docs site kept the selected document only in React state, so you couldn't
bookmark, share, or refresh-into a specific doc, and browser back/forward did
nothing — a real gap for a developer docs site people want to link into.

- each doc now has a slug URL: docs.amerc.ai/#/connect-your-broker
- selecting a doc pushes the slug to the URL (history.pushState)
- loading a #/<slug> URL lands directly on that doc; unknown/empty falls back
  to Quickstart as before
- hashchange + popstate listeners make browser back/forward switch docs
- the browser tab title now reflects the open doc (<title> · Docs · amerc)
- verified live on docs.amerc.ai: click updates URL+view+title, deep-links
  land correctly, back/forward navigate between docs
2026-06-10 12:22:10 +08:00
f0c8ea22cf share: purpose-built Open Graph card (0.86.0)
sharing amerc.ai in Slack/Discord/X/etc. showed a raw pixel-art tavern
screenshot — distinctive but cluttered at thumbnail size and missing the
wordmark and tagline. replaced it with a designed 1200x630 OG card:
gem + 'amerc' wordmark, the 'Hire agents like mercenaries.' tagline, a
one-line description, amerc.ai, and the three delivery modes — on the
brand's dark/cyan/gold palette over a deeply dimmed tavern backdrop.

- rendered headless at 1200x630 (Page.captureScreenshot, jpeg q88, 58KB)
- point og:image + twitter:image at /og-card.jpg, fix width/height to 1200x630
- verified live: meta tags resolve, image serves 200 image/jpeg
2026-06-10 12:16:41 +08:00
5e0eeb79c6 perf: paint branded loading screen from static HTML (0.85.0)
the <div id=root> was empty until the JS bundle downloaded and React mounted,
so the page was blank for ~2.4s (FCP). put the branded loading screen (pulsing
gem + 'amerc') directly in the static HTML, with its critical CSS inlined in
<head>, so it paints as soon as the CSS loads instead of waiting for JS.

- React's createRoot replaces #root on mount; the Suspense fallback renders the
  identical markup, so the static->React handoff is seamless (no flicker)
- inlined .app-loading critical CSS mirrors styles.css exactly + dark body bg
  so there's no white flash during load
- verified live: FCP 2.4s -> 1.4s, performance 86 -> 90, TBT 50 -> 0ms;
  app mounts cleanly, static loader replaced, 0 console errors
2026-06-10 12:09:50 +08:00
522ce6ec83 quality: fix heading order + asset caching (0.84.0)
measured the LIVE site with Lighthouse (best-practices 100, seo 100,
agentic-browsing 100; a11y 98, perf 86) and fixed two real flags:
- heading-order: the footer column labels were <h5> following an <h3>
  (skipping h4) — changed to <h4> so the page heading order is sequential;
  a11y 98 -> 100
- caching: every static asset was served with no cache lifetime (0s).
  added nginx cache locations on the amerc.ai vhost (server-side, not in repo):
  /assets/ -> 1y immutable (content-hashed chunks), /scene2d/ -> 30d;
  index.html stays uncached so it always points at the latest assets.
  repeat visitors now serve JS/CSS/images from cache. cache-insight -> PASS
- verified live: a11y 100, heading-order + cache-insight PASS, cache headers
  present on assets and absent on index.html
2026-06-10 12:02:06 +08:00
40624a2e30 home: agent-native callout (0.83.0)
- amerc is genuinely agent-native now (JSON API + self-service keys + WebMCP
  browser tools + llms.txt) but the home page never said so
- add a concise callout after the session preview: 'Agent-native by design —
  mint an API key and drive it over JSON, get callable WebMCP tools on the
  page, read llms.txt for the map. Agents can hire agents.'
- a real, differentiating positioning point, not filler; cyan-accented card,
  scroll-reveal, links to /llms.txt, stacks on mobile
- verified live: callout renders and reveals
2026-06-10 11:52:44 +08:00
c5fb9631c5 agent docs: surface WebMCP tools (0.82.0)
- llms.txt: add a 'Browser tools (WebMCP)' section listing the four callable
  tools (amerc_browse_agents / platform_stats / get_agent / open) so agents
  reading the file know they can act on the tavern, not just read about it
- footer: add a 'For agents ↗' link to /llms.txt so humans can discover
  amerc's agent-facing guide (keys, JSON API, WebMCP)
- verified live: llms.txt WebMCP section served, footer link in the bundle
2026-06-10 11:47:38 +08:00
b94ebb0962 WebMCP: make amerc agent-actionable as callable tools (0.81.0)
amerc is the agent mercenary tavern — so expose it to AI agents browsing the
page via Web Model Context Protocol (navigator.modelContext), the W3C browser
tool API. An agent on amerc.ai can now act on tools instead of scraping the DOM:
- amerc_browse_agents (query/tag) — list the roster
- amerc_platform_stats — live classes/online/sessions
- amerc_get_agent (id) — full class details + instances
- amerc_open (section) — navigate the tavern
- each has a valid JSON-Schema inputSchema; read tools carry readOnlyHint
- registered only on the main domain, feature-detected ('modelContext' in
  navigator) + try/catch, so it no-ops with zero risk where unsupported
- verified (polyfilled modelContext): all 4 tools register with valid schemas
  and their execute() calls hit the live API correctly
refs: W3C webmcp proposal, webfuse WebMCP cheat sheet
2026-06-10 11:43:24 +08:00
7cf9293bab agent-ready: llms.txt + charset — agentic-browsing 67->100 (0.80.0)
ran full Lighthouse: perf 97, a11y 100, best-practices 92->96, SEO 100,
and the new agentic-browsing category 67->100. amerc is for agents, so this
category matters most — its only fail was a missing llms.txt.
- add /llms.txt (llmstxt.org format): an agent-facing index of amerc — the
  class/instance/session model, the JSON API (base, auth, key endpoints),
  links to docs + source, and a 'for agents' note. genuinely on-brand for
  the agent mercenary tavern and useful for agents driving amerc via API
- add <meta charset=utf-8> as the first head element (was missing)
- re-ran Lighthouse: agentic-browsing 100, charset + llms-txt PASS
- verified live: /llms.txt 200 text/plain
2026-06-10 11:36:10 +08:00
c5e16205c5 a11y: fix Lighthouse-flagged issues — accessibility 93->100 (0.79.0)
ran Lighthouse (local preview): SEO 100, a11y 93->100, best-practices 92
(its one fail was console errors from the backend-less preview — a false
positive; live has 0 console errors). fixed the 3 real a11y flags:
- color-contrast: '.gm-scrollcue' was 4.33:1 (needs 4.5) — lightened the
  'how it works' cue colour and dropped the opacity dimming
- label-in-name: the logo button's aria-label='amerc home' didn't contain its
  visible text — removed it so the accessible name = visible text (+ title=Home)
- skip-link: the href='#content' had no target — gave the content host
  id='content' + tabindex=-1 so it's a valid focusable target
- re-ran Lighthouse: accessibility 100, all three audits pass
2026-06-10 11:31:00 +08:00
dbe3c383e3 branded app loading screen (0.78.0)
- the Suspense fallback (shown on every cold load while the app chunk loads,
  longer on slow/mobile connections) was a plain monospace 'Loading amerc…'
- replace with a branded screen: a pulsing cyan gem over 'amerc' in gold
  Georgia on a dark radial background, matching the logo + error-boundary look
- respects prefers-reduced-motion
- also audited the public mobile surfaces (agent modal, status, changelog) —
  all mobile-safe (modal is width:min(640px,96vw) + scroll)
- verified the loading screen renders (blocked the app chunk to capture it)
2026-06-10 11:20:37 +08:00
f063e9ae80 docs: responsive mobile layout (0.77.0)
- on phones the docs kept the desktop sidebar+content row, squeezing the prose
  into ~240px (sidebar ate the rest) — poor reading on a public docs surface
- stack on mobile (<=760px): sidebar becomes a compact scrollable doc-picker
  on top (max 210px), content goes full-width below with comfortable padding
- verified live (390px): layout column, content full-width (390 vs old 240),
  no horizontal overflow
2026-06-10 11:14:46 +08:00
1e387c270c docs: land on Quickstart instead of an empty pane (0.76.0)
- visiting docs.amerc.ai showed a blank 'Select or create a document' main
  area — a poor first impression for the public docs/onboarding surface
- auto-select a sensible default on load (Quickstart -> a 'start here' doc ->
  first doc) without overriding a user's later selection
- verified live: docs.amerc.ai lands on Quickstart, sidebar highlights it
2026-06-10 11:09:09 +08:00
9636545fb7 a11y/ux: modals close on Escape (0.75.0)
- the agent ClassModal and the booth 'instance created' modal could only be
  dismissed by clicking the backdrop or the X — no Escape, a standard
  keyboard/UX expectation
- add a keydown(Escape) -> close to both (ClassModal listens while mounted;
  the booth modal attaches the listener only while newInst is set)
- verified live: agent modal opens then closes on Escape
2026-06-10 11:05:16 +08:00
8542a98500 deps: drop lucide-react, inline the 2 icons (0.74.0)
- lucide-react was a runtime dependency used only for the mobile menu's
  hamburger + close icons in Scene2D.jsx
- replaced with two tiny inline SVG components (lucide's exact Menu/X paths),
  removed lucide-react from package.json — aligns with the project's
  minimal-dependency philosophy (zero-dep backend)
- build is clean with no lucide in the bundle; icons render identically
- (deploy note: re-deployed after a transient fail2ban block from this
  session's rapid deploy cadence — site stayed healthy on 0.73 throughout)
2026-06-10 10:58:49 +08:00
d9d652dfd5 browse: correct no-search-results state (0.73.0)
- searching (or tag-filtering) with no matches wrongly showed the 'No agents
  here yet — be the first' onboarding, implying the whole marketplace was
  empty even when agents exist
- now distinguishes: a query/tag with no matches shows 'No mercenaries match
  <term>' + a Clear search button; the be-the-first onboarding only shows when
  the roster is genuinely empty (no query, no tag)
- verified live: 'zzznomatch' shows the no-match state, Clear restores results
2026-06-10 10:41:03 +08:00
0f9d553deb a11y: skip-to-content link (0.72.0)
- keyboard/screen-reader users had to tab through the whole topbar before
  reaching page content (WCAG 2.4.1 Bypass Blocks gap)
- add a skip link as the first focusable element: hidden until focused, slides
  in as a cyan pill, and on activation focuses the visible content container
  (works with the persistent-home structure, and avoids the hash-route conflict
  by focusing programmatically instead of via href)
- verified live: Tab focuses it, it becomes visible, activation focuses content
2026-06-10 10:30:16 +08:00
696d727e44 dynamic per-route + per-subdomain document titles (0.71.0)
- the SPA had one static title, so every tavern route and the docs/pm
  subdomains all read 'amerc — hire agents like mercenaries' in the tab
- tavern now sets a descriptive title per route (Browse Agents · amerc,
  System status · amerc, etc.); docs/pm set 'Docs · amerc' / 'PM · amerc'
- clearer browser tabs, bookmarks and history
- verified live across home/agents/status + docs + pm
2026-06-10 09:36:44 +08:00
6d54d89a0b mobile: proper nav menu with backdrop + full-width targets (0.70.0)
- the mobile hamburger menu was a cramped narrow corner dropdown with no
  backdrop and no tap-to-close
- now a full-width panel (left+right anchored), comfortable full-width touch
  targets, a dimming tap-to-close backdrop, rounded card + shadow, fade-in
- verified live (390px): backdrop present, menu ~374px wide, tap-to-close works
2026-06-10 09:32:50 +08:00
344a3f7bb2 perf: preload tavern canvas tiles on the main domain (0.69.0)
- the LPC scene images only started downloading after the Scene2D chunk loaded
  and TavernGame mounted, extending the 'loading tavern…' flash
- preload them in main.jsx (gated to the main domain via App===Scene2DApp, so
  docs/pm don't fetch them) — they now download in parallel with the JS chunk
- verified live: images requested at 1461ms vs Scene2D chunk at 1467ms (before,
  in parallel), canvas renders correctly
2026-06-10 09:25:33 +08:00
910b536dd9 trim 1.9MB of dead scene assets (0.68.0)
- tavern-hero.png (1.75MB) was unused — the OG/social image is the .jpg
- removed leftover concept-art sprites (dwarf/elf/orc/dungeon, ~110KB)
- bartender.png was fetched by the canvas but never drawn (the bartender is
  rendered with the soldier sprite); dropped it from the loader + deleted it
- kept bg.png (CSS), tavern-hero.jpg (og:image), the LPC tiles, and the
  CC-BY-SA credits/license files
- scene2d 2.4MB -> 560KB, dist 2.9MB -> 1.1MB; canvas loads one fewer image
- verified live: tavern renders identically, 0 failed requests, og:image 200
2026-06-10 09:17:14 +08:00
2bbe9b9043 polish: inviting logged-out gates + full regression QA (0.67.0)
- the booth and account logged-out gates were the last plain 'Log in' surfaces
  (one line + a tiny pixel button). Reworked both into branded, inviting cards
  with an icon, a real pitch, and prominent CTAs (Log in/Sign up + Browse
  agents) — consistent with the gatehouse and hero
- regression QA: smoke-tested all 9 public surfaces (tavern, browse, mansion,
  booth gate, gatehouse, status, changelog, docs, PM gate) — every one renders
  with zero console errors; API, Git, Webagent all 200
- verified live: rich booth gate renders with both CTAs
2026-06-10 09:12:00 +08:00
26030b0a13 home: back-to-top button (0.66.0)
- the home page is long now (hero -> flow -> features -> session preview ->
  activity -> footer); add a floating back-to-top button that fades in once
  you scroll past the hero and smooth-scrolls the home container to top
- listens on the gm-home scroll container (not window); hidden by the
  persistent-home display:none when off-route; respects reduced-motion
- verified live: hidden at top, shows after scroll, returns to top on click
2026-06-10 09:04:48 +08:00
e73dbbe186 ux: keep the tavern mounted — instant returns, no reload flash (0.65.0)
- Home unmounted on every route change, so returning to the tavern reloaded
  the canvas (the 'loading tavern…' flash + image re-fetch each time)
- keep Home mounted in a persistent host, hidden (display:none) when off-route;
  non-home routes still render in the keyed transition wrapper
- the canvas IntersectionObserver pauses while Home is display:none, so a
  hidden tavern costs nothing — and resumes instantly (not reloaded) on return
- verified live: rAF 60→0 when hidden →60 on return, no loading flash, home
  renders + scrolls, inner routes + transitions intact
2026-06-10 09:00:51 +08:00
74edbb3e11 resilience: app-wide error boundary (0.64.0)
- previously, any render error would unmount the whole SPA to a blank white
  screen (no boundary)
- add a React error boundary around the routed app (all sub-apps: tavern,
  docs, pm) with an on-brand fallback — gem, 'Something went off-script',
  Reload + System status links — instead of a void
- verified the catch path locally (a temporary ?boom trigger rendered the
  fallback), confirmed the boundary is transparent in normal use, then
  removed the trigger; verified live renders normally
2026-06-10 08:55:46 +08:00
53331a40d4 docs: accurate public roadmap + themed task lists (0.63.0)
content (in the docs DB):
- the public Roadmap was factually wrong — git.amerc.ai and the embedded
  webagent shown as not-done though both shipped long ago. Rewrote it as an
  accurate Shipped / Next / Later roadmap that links to the changelog
- Welcome: agent keys are self-service now (was 'ask an admin')
- removed the redundant internal 'PM roadmap (impact x effort)' doc, most of
  whose items have shipped — consolidated to one clean public roadmap

code:
- theme docs task-list checkboxes with the accent color and drop the
  redundant bullet (li:has(> input[type=checkbox]))
- verified live: roadmap shows 8 shipped (checked) + next/later, clean render
2026-06-10 08:49:46 +08:00
e3e5cefd03 liveliness + consistency: activity reveal, gatehouse count-up (0.62.0)
- Reveal now accepts a tag prop so it can wrap semantic elements
- 'Live in the tavern' activity items stagger-fade-up as they scroll into
  view (as <li>, valid list semantics), matching the feature cards
- gatehouse stats now count up from 0, consistent with the home hero
- both respect prefers-reduced-motion
- verified live: 8 items reveal (opacity 1, not stuck), gatehouse Count
  renders, 0 exceptions
2026-06-10 08:37:52 +08:00
2d00cb4e63 docs: safe syntax highlighting (0.61.0)
- minimal dep-free highlighter for fenced code blocks: strings (green),
  numbers (amber), keywords (purple)
- deliberately NO comment rule, so '//' inside URLs (https://, wss://) is
  never mis-colored or mangled — the common micro-highlighter pitfall
- applied in the DocsApp post-render pass alongside the copy buttons; the
  copy button still yields the exact original text
- verified live: 22 tokens colored, both https:// and wss:// URLs preserved
  byte-for-byte, code intact
2026-06-10 08:31:47 +08:00
cf67af7131 perf: pause tavern canvas when off-screen (0.60.0)
- the 60fps canvas render loop ran continuously even when scrolled out of
  view (the home page is long now — wasted CPU/battery while reading below)
- IntersectionObserver pauses the rAF loop at 0% visibility and resumes it
  when the tavern scrolls back in; cleaned up on unmount
- verified live: ~60 rAF/s on-screen → 0 off-screen → 60 on resume, 0 errors
2026-06-10 08:26:48 +08:00
3ddbc76dfc a11y: keyboard focus indicators + canvas label (0.59.0)
- the site had focus styles only on inputs, so keyboard navigation was
  invisible across every button, link, nav item, card and CTA
- add a global :focus-visible ring (cyan, gold for primary CTAs) — shows for
  keyboard users only, follows each element's radius
- label the decorative tavern canvas (role=img + aria-label); its overlay
  hotspots remain separately focusable/labeled
- verified live: Tab focuses a nav button with a 2px cyan ring, matches
  :focus-visible, canvas announced as 'Animated tavern scene'
2026-06-10 08:21:16 +08:00
6a8fc0a5c0 docs: code-block copy buttons + 'Connect your broker' guide (0.58.0)
- fix fenced code blocks: reset the doubled inline-code background on
  'pre code', readable monospace styling (applies to all technical docs)
- DocsApp decorates rendered code blocks with a hover copy button
- seed a 'Connect your broker' guide (guides/) — the lasting reference for
  the supply-side last mile: heartbeat loop (curl + Node) to stay online,
  the relay WebSocket, and how it fits together (accurate from the API)
- verified live on docs.amerc.ai: guide renders, 3 code blocks, 3 copy
  buttons wired, clean styling
2026-06-10 08:17:15 +08:00