Security hardening:
- The gateway no longer sends arbitrary shell to nodes. The WSS exec op is
replaced by a typed `verify` op the daemon runs itself (fixed host+docker
check); future container ops are typed too. cm-api NodeHub.verify() + the
daemon's handle_command only dispatches vetted ops.
BYO Tailscale:
- migrations/0019_workspace_tailscale.sql + cm-db fleet_tailscale repo (store the
user's Tailscale API key + tailnet, server-side only).
- cm-api routes/tailscale.rs: POST/GET/DELETE /api/fleet/tailscale + GET
/api/fleet/tailscale/devices (proxies api.tailscale.com device list).
- Daemon: --tailscale-authkey → `tailscale up --authkey … --ssh` (enables
Tailscale SSH for keyless user access); else `tailscale set --ssh=true`. Reports
its tailscale IP (already).
UI:
- Fleet overview gains a Tailscale section: connect (key+tailnet) + live tailnet
device status (online/last-seen/IP/os). Node cards show a copyable Tailscale SSH
target (ssh <ip>).
Remaining: P2 — RemoteDriver + placement (run agents on nodes) and the in-UI
remote terminal (PTY proxied over the WSS channel).
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Promote Infrastructure to a first-class tier that mirrors the Agent template:
a left rail tab + crumb, an Infra category sidebar, a center stage, and the
right slide-out computer — the SAME device chrome as the agent, driven by a
swappable app catalog.
- Parameterize the computer by a ComputerCatalog (computer/catalog.ts): grid,
dock, icons, tile, title, render, theme. DevicePanel + HomeScreen are now
catalog-driven; the agent computer is unchanged via agentCatalog() (today's
grid/dock/tiles/AppRouter, extracted verbatim into computer/tiles.tsx).
- Infra catalog (computer/catalogs/infra.tsx): grid = AWS/GCP/Azure/Add, dock =
Hosts/Status/Settings, original colored lettermark tiles (not the trademarked
logos), placeholder app screens (computer/apps/infra/InfraApp.tsx). APP_IDS
gains aws/gcp/azure/hosts/status.
- Infra tier in Dashboard.tsx: "infra" Tier + Server rail tab + crumb; an
InfraSidebar/InfraStage/InfraConsole (InfraStage.tsx) mirroring the claw
center+chat; the right pull-out is <DevicePanel catalog={INFRA_CATALOG}/> with
the same launchers, size presets and drag-resize.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The top-right user menu's dropdown shared zIndex 50 with the claw-view
computer/chat launcher buttons, so paint order hid it behind them. Lift the
menu (nav 210, close-overlay 200) so it sits on top.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
- Nodes/pawns are now solid (opaque): the standard material is opaque, idle pawns
dim via emissiveIntensity instead of transparency, and node spheres only fade on
appear/disappear (alpha<1) rather than rendering see-through.
- Drag any node (Live view): pointerdown on a node pins it under the pointer
(OrbitControls paused), and the force layout — edges, pawns, beams — re-settles
around its new position. A drag leaves the node pinned (sticky) so the new layout
persists; a tap still selects.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Switch the Live view's structure nodes + agent pawns from flat CircleGeometry
to lit SphereGeometry (MeshStandardMaterial with emissive + ambient/directional
lights), so they read as 3D balls from any orbit angle instead of going edge-on.
The additive glow sprites + particle effects are unlit, so the neon look is kept.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Replaces the random per-id ellipsoid scatter with a fixed, deterministic brain
scaffold (frontend/src/components/world/brain.ts): two folded cerebral hemispheres
split by a longitudinal fissure (multi-octave noise = gyri/sulci), a cerebellum,
and a brain-stem — ~430 nodes wired into a k-nearest-neighbour edge network.
WorldCanvas Hierarchy renderer: the scaffold is one Points cloud + one LineSegments
(the dormant brain), with an activation field over the nodes. Agents seat into a
deterministic fixed region (agentRegion hash); their seat brightens on work and
fires activity-coloured signals along the real edges, which chain through the mesh
and light its pathways. Idle → a dim, gently-breathing brain. Same brain every
reload; orbit/pinch to see the 3D anatomy.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Each agent carries a fireColor for its most recent activity — reasoning (purple),
tool (cyan), file op (coral), run (green) — derived in the engine from the touch
weight/node + reasoning events (now wired into the engine). The brain fires
signals in that colour, and the HUD shows a small colour key in Hierarchy, so you
can read WHAT KIND of work is lighting up the mesh.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Clicking a neuron/pawn now focuses the Observe panel on that agent: a header with
its role + live status + a "← System" back button, then that agent's filtered
REASONING STREAM and TOOL CALLS. Feed items are tagged by agentId; the system
view shows the agent id per line. Wired via worldSel in Dashboard.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
A small bottom-left overlay on all three views: the view title + a one-line key
(Live = Gource tree, Flat = 2D graph, Hierarchy = brain mesh) plus live counts —
agents, currently-working, tokens/min and pending doors (from the telemetry feed).
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
- brain edges now use per-vertex colors driven by endpoint activity, so a firing
neuron lights its pathways (gradient from the brighter end) while dormant
connections stay faint — the wiring visibly comes alive.
- neuron size now grows with cumulative activity (experience), so the agents that
do the most work read as the largest, most-developed neurons.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Hierarchy (neural-brain) v2:
- structure nodes (org/company/team) join as dim support-neurons, so the brain
has body even with one or two agents (a real mesh, not a few dots).
- a resting-state shimmer: every neuron occasionally self-activates a touch, so a
dormant brain still breathes.
- agents brighten on working status AND on a recent touch (real activity), then
fire signals along pathways that chain through the support mesh.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
- Explosive sparks on file/project I/O: /api/world/live tags file-ish tools
(read/write/drive/vault/obsidian/edit/save) with touch weight 1; the engine
carries it as a node "burst" and the renderer fires a big fast particle blast.
- The formation tabs are now genuinely different views:
- Flat — the previous 2D React-Flow forest (WorldFlow), overlaid.
- Live — the WebGL Gource clone (glow sprites + sparks + trails + beams).
- Hierarchy — a NEW neural-brain view: agents are neurons in a dormant
two-hemisphere mesh; active agents fire signal particles along pathway edges
to their nearest neighbours (chaining), so the brain lights up as agents work.
- Render groups (gource/brain) + 3D particle system so signals travel in depth;
shared particle update; OrbitControls (rotate + pinch-zoom) across all WebGL views.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Effects (matching Gource's technique — additive radial-gradient glow + particles,
not just post-processing):
- additive glow sprites on every node + pawn (a precomputed radial-gradient
texture, AdditiveBlending), scaled/brightened by heat — the soft Gource glow.
- a particle system (THREE.Points, additive, ring buffer): spark bursts on each
beam, ambient sparkle from hot nodes, and fading motion trails behind pawns.
- additive beams (brightness by life); UnrealBloom retuned (low threshold) so the
additive glow blooms.
Camera: PerspectiveCamera + OrbitControls — drag/one-finger to rotate (orbit),
pinch / wheel to zoom, two-finger / right-drag to pan; auto-frames until you grab
it. Tap-vs-drag raycast selection.
Formations now each behave distinctly:
- hierarchy — strong parent spring, low repulsion → clean structured tree (calm
pawns/effects).
- flat — spring to center + high repulsion → a spread peer mesh.
- live — balanced activity view with full pawns/beams/sparks/trails.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
frontend/src/components/observe/ObservePanel.tsx — a live mission-control view
driven entirely by the taxonomy feed (telemetry strip, doors awaiting approval,
agent statuses, and a rolling activity stream of real reasoning + tool calls;
the feed is ref-buffered + flushed on an interval so reasoning bursts don't
re-render per token). Rendered as the World slide-out's system view (replaces
the empty-state placeholder). With the run_events normalization, this shows
REAL agent reasoning, tool calls, and doors.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
- /api/world/replay?hours= — reconstructs a sorted, timestamped taxonomy timeline
from the workspace's run history (agent_runs ⋈ sessions) for client playback.
- engine.clearWorldNodes() — drop transient world nodes/targets for a loop restart.
- WorldCanvas: a WorldClock control (Live ⇄ Replay) feeding the same engine —
play/pause, 1x/2x/4x speed, seek bar, loop. Live subscriptions detach in replay.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
- engine: when there are no service/event touch-nodes (a quiet feed), pawns roam
the real org/company/team structure so the view is always alive with zero
synthetic data; real touch-nodes take priority when present.
- /api/world/live: emit world.touch + node.activity per currently-running run
(agent_runs joined to sessions, state='running') so each working agent visibly
converges on its active-run node; fold running agents into working status;
telemetry.loops = active run count.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Replaces the static React-Flow world forest with a real-time WebGL view of the
swarm working, plus the live event contract that feeds it.
Phase A — the live contract + feed:
- frontend/src/lib/live/taxonomy.ts — the 13-event Clawmates Event Taxonomy as
typed TS (the shared World/Observe contract).
- frontend/src/lib/live/useClawmatesLive.ts — native shared-singleton live client
(EventSource to /api/world/live, typed fan-out, replay-of-last-state to late
subscribers, refcounted, synthetic fallback so views are always alive).
- crates/cm-api/src/routes/world.rs — GET /api/world/live, authed + workspace-
scoped SSE emitting the taxonomy (real agent.status from live-container state,
a topology.update of the workspace's agents, telemetry with real doorsPending),
mirroring run_events_sse. normalize() seam documented for run_events->world.touch.
Phase B — the WebGL engine:
- frontend/src/components/world/engine.ts — Gource-inspired force-directed model:
org/company/team tree (sibling repulsion + parent spring + friction), agent
pawns that converge on the touched node and beam it, world nodes that glow with
heat and fade when idle. Framework-agnostic (renderer-independent) state+math.
- frontend/src/components/world/WorldCanvas.tsx — three.js scene (ortho cam,
UnrealBloom), render loop syncing engine state, camera auto-fit, HTML labels,
raycast click->select, Hierarchy/Flat/Live formation switch.
- Dashboard.tsx: swap <WorldFlow/> -> <WorldCanvas/> at the world-tier seam
(shared claw-tier pieces untouched; WorldFlow.tsx kept for now).
- Adds three (+ @types/three).
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Terminal app (xterm ⇄ WebSocket ⇄ per-agent themed container):
- zsh + oh-my-zsh + powerlevel10k image (agent-terminal), runs as uid 65532 to
share read-write ownership of the file-drive volume with the server.
- Interactive PTY in cm-sandbox (bollard exec tty/attach + resize) + a
TerminalManager; ticket-authed WS bridge routed straight to the backend via a
Traefik PathRegexp(/ws) rule. MOTD greets the user by name.
- tmux resumable sessions; multi-tab (one tmux session per tab, same container),
drag-to-reorder, rename, and a Save that persists named tabs to the server
(terminal_tabs, migration 0014) so they survive logout / a new device.
- Files drives mounted per-agent (subpath) at ~/drives/{documents,received,
shared}; a reconciler keeps the Files app's index in sync with terminal writes.
Storage moved to a shared `filedata` volume (CLAWMATES_STORAGE__DATA_DIR).
Obsidian vault (a markdown "second brain" per agent):
- New `vault` FileDrive (migration 0015) mounted into the terminal at ~/obsidian;
a file-content read route; a purple Obsidian tile + a vault viewer app.
Computer UI:
- Draggable computer-panel width (min = phone preset) keeping the size presets.
- Green Terminal glyph, "Claw Chat" → "Chat", colored gradient-outline app icons.
- Agent page: avatar↔activity-grid spacing + larger, uniform section fonts with
colored section-tinted tag chips.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Replaces the approximation with an exact port of Clawmates Dashboard.html:
- breadcrumb Acme Org / Acme Corp / Growth Team / <claw> (active-tier highlight)
- ORG/CO/TEAM/CLAW tier rail; clicking a tier shows the example structure
(org→3 companies, company→4 teams, team→6 agents)
- morphing topology canvas with all 6 patterns (hub-spoke/pipeline/ring/mesh/
swarm/debate) + exact POS/LNK tables + animated links
- company grid canvas (team cards) + org radial canvas (company nodes)
- claw view: left compartment panel + ANATOMY canvas (Skills/Personality/Memory/
Tools·Doors/Capabilities/Safety) + the agent "Computer" slide-out
(apps / now-running / dock), matching the doc
- exact status colours, gradients, animations, status bar
Example workspace data baked in (as in the doc) so every tier is populated;
real-workspace wiring is a follow-up layer.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Login landed on an empty "Pick a claw" stub — the integrated dashboard from the
design comp was never assembled as the home. Now `/` IS the dashboard.
- public/sw.js: cache v2→v3; RegisterServiceWorker reloads once when a new
worker activates, so deploys are picked up without a manual hard-refresh
- (workspace)/layout: ShellChrome renders the dashboard bare on "/" (it's
self-contained) and the shared TopBar/LeftRail/StatusBar on every other route
- components/dashboard: Dashboard (state machine + data) — top bar w/ breadcrumb,
ORG/CO/TEAM/CLAW tier rail, tier-aware context list, TopologyCanvas (6-mode
view-as selector, generalized layouts), and the agent "computer" slide-out
(cm-fade) wrapping the existing ComputerPanel; status bar
- motion.css: cm-fade keyframe
Wired to existing endpoints (/api/teams|companies|orgs, /api/structure/*,
/api/team/claws, /api/structure/stats, + ComputerPanel's apps/runtime-config/
routines). Defaults to the most-recent team; claw click opens the slide-out.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The token redesign couldn't touch static rasters/config — these were still the
old claw mark + old coral. Regenerate favicon (icon.svg + icon.png) and PWA
icons (192/512) as the node-mesh glyph; manifest theme_color #f96565→#ff6f61,
background #121212→#08080a; refresh the description/tagline.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The "+" deploy flow now opens a scope selector (Single / Team / Company-soon /
Org-soon). Single = the existing CreateClawForm. Team = TeamWizard: pick a
baseline topology (from the catalog + role distribution), set size, auto-staff
editable claw cards (name / role / model / persona), preview the topology
graph, then POST /api/teams → land on the Team page.
Team page (/teams/[id]): topology SVG + claw roster (each links to its chat) +
a Run panel that drives the team on the durable runner with live SSE progress
(reuses the topology-run streaming). /teams list page + a Teams nav entry.
lint + typecheck + next build clean.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
#2 GLM judge (closes#114): registry NamedProvider gains a `format` field;
build_provider_registry builds an AnthropicProvider for format="anthropic".
GLM's coding/OpenAI endpoint is ToS-throttled for raw SDK, but its Anthropic
endpoint (api.z.ai/api/anthropic) accepts raw API calls (verified x-api-key
-> glm-4.7), so CLAWMATES_JUDGE_MODEL=glm:glm-4.7 routes the door governor /
topology judge through GLM with no runtime-routing. (Kimi-as-judge still needs
a Platform key — coding key is agent-only.)
#3 run-control: POST /api/topology-runs/{id}/cancel (workspace-scoped,
queued/running only); the worker honors it at the step boundary (checks
current_status in the checkpoint callback) and won't clobber a cancel with
`failed`. Frontend Run tab gains a Cancel button and clickable recent runs
that deep-link into a live/replayed stream (SSE replays from checkpoint).
cm-* tests (incl. new cancel test) + clippy + frontend lint/typecheck green.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Backend: GET /api/topology-runs/{id}/events streams Server-Sent Events by
tailing the durable per-step checkpoint the worker already writes — a `step`
event per newly-completed step (replayed on connect so reload/reconnect
re-attaches), then a terminal `done` event with the final output/error. Each
step carries its index as the SSE id, so the browser's Last-Event-ID resumes
without duplicates on reconnect. No new table, no worker change — reuses the
checkpoint; avoids run_events' agent_runs FK.
Frontend: the Run tab now opens an EventSource (through the same-origin proxy,
which adds the bearer) instead of polling — appending steps as they stream and
finalizing on `done`. One streaming connection, lower latency, auto-resume.
cm-api builds + clippy clean; frontend lint + typecheck + next build clean.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
New TopologyRun component: pick a topology + roles + task, enqueue via
POST /api/topologies/run (202), then poll GET /api/topology-runs/{id} for
live turn-by-turn progress — rendering the per-step checkpoint while running
and the final RunRecord (+ final output) when completed, with a status badge
and recent-runs list. Added as the middle "run" tab in the workbench.
Since the work runs server-side as a durable job, a long-horizon run survives
navigation/restarts; the UI just re-attaches by polling. lint + typecheck +
next build clean. (Also fixed a pre-existing set-state-in-effect lint error in
TopologyCompare surfaced by the Next 16 toolchain.)
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Save each comparison and let users reload past ones.
- migration 0008: topology_runs (workspace-scoped; full comparison as JSONB).
- cm-db repo::topology_runs (insert / list_recent / get) + regenerated .sqlx.
- cm-api: compare persists best-effort (never loses the LLM result on a DB
hiccup); GET /api/topology-runs (recent) + GET /api/topology-runs/{id}.
Integration test asserts persist → list → get.
- frontend: "Recent comparisons" list on the Compare tab; click to reload a
saved run. e2e p8 green (39 suite); offline build + clippy clean.
Server self-migrates at boot (cm_db::MIGRATOR), so 0008 applies on deploy.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Add a Compare tab to /topologies: pick a task + roles + topology kinds, build a
graph per kind, run POST /api/topologies/compare, and render a leaderboard table
+ a quality/cost Pareto scatter (SVG, no deps). Wrap Build + Compare in a tabbed
TopologyWorkbench. e2e p8 extended to run a comparison end-to-end (build×N →
compare → leaderboard + Pareto). Full suite 39 green; build + TS clean.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
New authed workspace page (/topologies, in the global nav) that browses the
topology catalog and builds + visualizes a topology from a kind + roles:
- lib/api/topology.ts: zod schemas + fetchTopologyCatalog (server, authed).
- TopologyGraphView: lightweight SVG renderer (no new deps), laid out per kind
(row for pipeline/ring, star for delegation kinds, circle otherwise).
- TopologyExplorer (client): catalog list + roles input → POST
/api/topologies/build via the /api proxy → render the graph.
- ShellNav: add the Topologies nav item.
- e2e (p8): sign in → nav → browse catalog → build a pipeline → graph renders.
Full suite green (38); npm build + TS clean. Goes live with the next server+
frontend deploy (compare/Pareto UI to follow).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Replace the floating rounded nav pill with an edge-to-edge sticky header:
solid bg, bottom border, square corners, content centered to max-w-[1392px].
Drop the hero's -mt-[98px] underlap so it sits below the solid bar. Refresh
the @visual baseline.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Swap the clawmates-mark.png image in the nav (mobile + desktop) for a lucide
Waypoints icon in an ink chip beside the wordmark — reads as a network/mesh of
agents, matching the infrastructure theme. Refresh the @visual baseline.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Page is now Hero → Hierarchy → Scale → Why → Use cases → FAQ → CTA → footer.
- Scale: per-tenant runtime / scale-to-zero / delegation hierarchy.
- WhyGoverned: humans-in-the-loop, single audit journal, delegation, no rogue access.
- UseCases: support / marketing / research / engineering / finance / data.
- FinalCta: dark ink band bookending the hero ("Build your agent company").
- Trim FAQ to 4 (keep the e2e-referenced Qs); repoint nav/footer anchors to
the live section ids. Refresh the @visual baseline.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Completes 02cde39: remove the CrewStrip and Security functions, their consts,
and the now-unused AgentToken/lucide imports from Sections.tsx; render only
Hero → Hierarchy → FAQ in the marketing page; refresh the @visual baseline.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Page is now Hero → Hierarchy → FAQ → footer. Delete the CrewStrip and
Security section functions + their consts (CREW, SECURITY), drop the now-
unused AgentToken component and the lucide imports. Refresh the @visual
baseline.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Remove the Pitch, One-click, Works, Always-on and Skills sections and the
"Build your AI crew" footer CTA banner. Page is now Hero → CrewStrip →
Hierarchy → Security → FAQ → footer (dark tier kept). Prune the now-dead
section functions, consts, and imports (Image, skills icons). Repoint the
"marketing rendered" heading assertion (p0/p7/visual) from the removed
Pitch heading to the hero h1 (/agentic systems/); refresh the @visual baseline.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Re-skins the playful/consumer feel into disciplined agent-infrastructure,
keeping the animated hero canvas (re-themed) and adding the hierarchy story.
- Palette: re-point coral→ember (#E0584A); add ink/surface/mist/slate-light/
azure/teal tokens. One accent per viewport; retire the black/coral split-
headline pattern across all 8 headings (single ink color).
- Typography: hero/section weights 800→~650-675, tighter tracking, smaller
hero size; uppercase eyebrow label.
- Hero: dark ink base with glowing azure/indigo + faint ember canvas blooms;
light copy; new positioning ("Build safe, scalable agentic systems" + the
single-agent-to-company subhead); ember primary CTA + ghost "Read the docs".
- Imagery overhaul (code-built, no mascots): AgentToken chips (CrewStrip,
OneClick card, footer), AlwaysOn rebuilt as a terminal/log with an approval
line, SkillsShowcase as duotone lucide cards on Mist, Security as a shield/
lock motif.
- New HierarchyDiagram section ("One agent, or a whole org chart"): SVG org
chart with an azure active path and teal human-approval checkpoints on
sandbox-leaving actions.
- Tests: dark-hero/terminal/eyebrow contrast fixed to AA; refreshed the
marketing @visual baseline (hero masked).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
- Headline → "Scale your Large World" (coral on "Large World").
- Subtext → "Building safe and scalable systems of claws for any domain of work."
- Drop the "Get started for free" hero button; keep "Book a demo".
- Remove the three hero trust pills (free credits / no card / self-hostable).
- Point the p7 hero CTA assertion at "Book a demo"; refresh the @visual baseline.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Port of crnacura/AmbientCanvasBackgrounds' shift effect: large circles drift
at random with hue driven by 3D simplex noise, drawn to an offscreen buffer
then blurred and composited onto the visible canvas. Re-tuned to a light brand
palette (pale periwinkle base; blue→violet→coral blooms) so the dark hero copy
stays readable. Self-contained (vendored simplex noise), scoped to the hero,
respects prefers-reduced-motion, and pauses when scrolled out of view / tab
hidden.
- Replace claws-at-desk.png with <HeroAmbient/>; add a soft fade into the
section below.
- Mask the animated hero region in the marketing @visual snapshot (keeps the
baseline deterministic) and refresh the baseline.
- Fix a latent AA contrast bug the old illustration was hiding: the CrewStrip
caption (#77879e on white, 3.65:1) → #647289 (4.87:1).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Sign-out only cleared the local cm_session cookie via DELETE /auth/session.
In Clerk mode the real session is Clerk's, so that left it intact and the
push to /login bounced the user straight back into the app (Clerk's <SignIn>
auto-redirects when a session exists). Detect clerk-js at runtime
(window.Clerk) and sign out through it; local/air-gapped builds have no
window.Clerk and keep the cookie flow (never loading the Clerk SDK).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The frontend is documented as a single image whose AUTH_MODE env var
selects local vs Clerk auth per deployment (docs/clerk.md). But the root
layout and /login read AUTH_MODE during render with no request-time
signal, so Next 16 statically prerendered them at build time in the
build host's mode (local). The deployed image then served the local
login form forever, ignoring AUTH_MODE=clerk at runtime — ClerkProvider
and <SignIn/> never appeared.
Add `await connection()` (the v16 way to read env at request time) in
the layout's IdentityProvider and in /login so both render per-request
and honor the runtime AUTH_MODE.
Also add a root .dockerignore: the repo had none, so every image build
shipped the 67GB Rust target/ dir as build context.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Swapped the placeholder PawPrint icon for the new claw logo everywhere it
appears: the marketing nav (mobile + desktop), the footer, the login card,
and the app left rail. The supplied PNG was a red claw on a solid near-black
background, so I flood-filled the background to transparent (the dark-red
outline survives the black threshold) and exported a trimmed, optimized
public/images/clawmates-mark.png (321x256, 88KB from 1.7MB). It reads cleanly
on both light (nav/login) and dark (footer/rail) surfaces.
Also regenerated the favicon + PWA icons from the new mark:
- src/app/icon.png (Next uses it as the favicon; removed the old favicon.ico)
- public/icons/icon-192.png and icon-512.png (claw on #0a0a0a, maskable)
Roster-card avatars on the login panel stay as PawPrint (decorative, not the
brand). Regenerated all seven @visual baselines that contain the mark — the
swap is sub-threshold for maxDiffPixelRatio, so I deleted and recaptured them
rather than relying on update-snapshots.
typecheck/lint/build green · all @visual green · deployed and verified live
(mark, /icon.png, and PWA icons all 200).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The live /sign-in is a Clerk-rendered SignInForm (SSR is just a spinner); the
rendered design is the email-first progressive form. Reworked our /login to
match it visually while keeping our real email+password auth underneath.
- Email step: "Sign up with Slack" (cosmetic), OR, Work Email / Phone Number
tabs, work-email field, "Continue with work email →", "Other SSO Options".
Slack / Phone / SSO are cosmetic placeholders we don't support yet.
- Password step: "Continue" reveals the password field + "Sign in" (our actual
POST to /auth/session). A Back link returns to the email step.
- Headline now mirrors WorkClaw ("Multiply your team's brainpower" / "Sign up
to get early access").
- Right panel is now the role-card roster grid (PawPrint avatars, our own
roles) + "The AI crew for your team" + the claws-at-desk art.
- Updated all eight E2E signIn helpers (and the load assertions) for the new
two-step flow: fill Email → Continue → fill Password → Sign in. Labels
(Email/Password) and the "Sign in" button name are preserved.
- A11y: bumped the inactive tab text to full slate (was 3.41:1).
typecheck/lint/build green · p0-shell (full sign-in) green · p6-a11y (login
clean) green · all six @visual baselines green (login regenerated) · deployed
and verified live.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Restyled /login into WorkClaw's two-panel auth design: a white form card on
the left, a periwinkle "meet the crew" panel on the right (claw roster strip,
"Your AI crew, all hands on deck", the claws-at-desk art), light-themed via
the marketing palette. The right panel is hidden on mobile.
- Kept /login as the canonical route (workspace redirect, /api/auth/login,
and the whole E2E sign-in flow depend on it) and kept our email/password
mechanism — only the chrome changed. Field labels (Email/Password) and the
"Sign in" button are preserved so p0–p6 keep passing.
- Added /sign-in → /login redirect so WorkClaw's URL resolves.
- New AuthShell wraps both the local form and the Clerk SignIn branch.
- LoginForm restyled to the light card aesthetic (rounded inputs, full-width
ink button); uses AA-safe coral-strong for the focus ring / error.
- Regenerated the login visual baseline.
typecheck/lint/build green · p0-shell (full sign-in flow) green · p6-a11y
green · login + marketing @visual green · deployed and verified live
(/login 200, /sign-in 307 → /login).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Re-scanned the live workclaw.com (same content as our prior capture; they
redeployed but shipped no landing changes) and rebuilt our landing to mirror
its full structure section-for-section, keeping Clawmates branding and honest
claims (no borrowed customer logos, no unverified SOC 2).
Now matches the real layout: sticky pill nav (Product/Blog/Pricing/FAQ +
Sign In + dark Get Started) · light-blue hero with the claws-at-desk art ·
crew strip (honest stand-in for the customer-logo marquee) · "Multiply your
brainpower…" + four trait badges · One-click setup with the create-claw card
(Sandy Clawson) · Works where you do with the 13-app icon grid + Slack
conversation mockup · Always on (dark, moon + composite art) · Your work,
your way skills tiles · Enhanced security (hand-key + key-snap, 4 icon
columns) · FAQ on the textured field · two-tier footer (Build your AI crew
+ dark footer with socials).
- Pulled the WorkClaw assets the public capture missed (claws-at-desk,
support-claw, slack-convos/cards, always-composite, 13 app icons, security
icons, footer-team). Dropped WorkClaw's own logo mark for our PawPrint.
- Honest substitutions where WorkClaw's claims aren't ours: no SOC 2 (4th
security column is "Air-gappable"; trust pill is "Self-hostable &
air-gapped"), and the FAQ keeps our self-host/air-gap positioning.
- A11y: consolidated to AA-safe coral-strong (#d23a3a) for button fills and
small coral text; axe reports zero serious/critical.
- Regenerated the marketing visual baseline.
typecheck/lint/build green · p7-marketing (render + a11y) green · @visual
green · deployed via Compose and verified live on :3000.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Rebuilt the public landing to mirror WorkClaw's complete section layout
(verified against tools/wc-capture/out/shots/marketing.png), with original
"clawmates crew on a ship" copy and captured WorkClaw art wired as
swappable placeholders.
Sections (top to bottom): sticky pill nav (dark Get-started CTA) · hero
(dual CTA + trust row + crew banner) · crew strip · positioning headline +
four trait badges · One-click setup (periwinkle panel) · Works where you do
· Always on watch (dark panel) · Your work, your way (3 skill tiles) ·
Safety built into the hull (security columns) · FAQ on the blue field · Build
your AI crew CTA on the dotted field · dark footer.
- No SOC 2 / compliance claims (p7-marketing enforces this); honesty kept by
replacing WorkClaw's customer-logo marquee with our own crew strip.
- A11y: AA contrast fixes — text-xl coral CTAs (large-text bar), darker
coral-strong accent on periwinkle, deeper FAQ blue for white text.
- New tokens: marketing-blue, marketing-coral-strong.
- visual.spec marketing test scrolls + waits for lazy art before the shot;
regenerated the marketing baseline. (Deepest <img> — the security art —
renders for users but is blank only in Playwright's full-page capture.)
- Vendored the captured WorkClaw asset bundle under public/images/.
Built, typechecked, linted, p7-marketing + @visual green, deployed via
Compose and verified live on :3000.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The rail's middle scroll container was a plain block (flex-1 overflow-y-auto
py-4), so the claws clustered at the top with empty space below. Match
WorkClaw: make it a centered flex column —
flex w-full flex-col items-center [justify-content:safe_center] overscroll-contain
[&::-webkit-scrollbar]:hidden — so the stack sits in the vertical middle with
balanced space above/below (safe = no clipping on overflow).
To preserve last commit's left-aligned rows under items-center, the RosterList
ul and the New-claw link are now w-full (else they'd shrink/center). Row gap
0.5→1 to match WorkClaw. (Capture shows no gap on the container itself — the
reviewer's suggested gap-1 there was dropped.)
typecheck/lint(0)/86 unit/30 E2E/6 visual green; workspace-home baseline updated.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Verified against the dark chat/welcome captures:
- Active form wrapper: pb-4 → px-4 pt-4 pb-8 + bg-gradient-to-t from-background
to-transparent (32px bottom gap with a fade, was a flush 16px).
- Textarea: rest at 44px and grow-then-scroll via [field-sizing:content] (we
had no auto-grow). Per-variant caps — active min-h-11 max-h-[180px], welcome
max-h-[88px]; + pl-1. (Reviewer said keep max-h-40, but prod is 180/88, and
field-sizing is the actual grow mechanism.)
- Box surface kept as-is (#1F1F1F + shadow) per the decision — not switching to
WorkClaw's flat #262626.
typecheck/lint(0)/86 unit/p1-chat/6 visual green; no baseline change.
Co-Authored-By: Claude Opus 4.8 <[email protected]>