Repository navigation
Extract the marketing/docs site into agentrelay.com - #1
Conversation
Refactor drawMessages in RelayauthAnimation by extracting advanceMessage and handleDeniedMessageFrame helpers to reduce function complexity and avoid eslint disables; preserves animation behavior and blocked-message lifecycle. Replace a side-effect ternary in FaqSection with an explicit if/else to satisfy no-unused-expressions linting. Add wheel-sync handling to DocsNav (useRef + useEffect) so the docs sidebar scrolls smoothly when main content hits boundaries. Minor copy improvements in quickstart.mdx. Add trajectory metadata files and update trajectories index. Verified web build after changes.
Improve documentation site
Delete the dynamic invite redirect page (web/app/skill/invite/[token]/page.tsx) and update web/app/robots.ts to remove the generic '/skill/invite/' disallow entry, leaving only '/openclaw/skill/invite/'. This aligns robots directives with the current route structure and removes an unused redirect handler.
Integrate PostHog pageview tracking for the web app: add site-analytics library, middleware/proxy, a PostHogPageView component, and a test for analytics. Update layout to emit manual, allowlisted pageviews for public docs/blog/catalog routes only. Expose NEXT_PUBLIC_POSTHOG_KEY (and document NEXT_PUBLIC_POSTHOG_HOST default) in .env.example and inject NEXT_PUBLIC_POSTHOG_KEY into the web deploy job so production builds receive the key; SST config was updated to pass env vars into the Next app. Also add trajectory records for the changes and minor web package updates.
Rename tests from test/web/* to web/lib/test/* and update relative import paths to match the new locations. Adjusted imports in code-fence-meta.test.ts, docs-markdown-spawn-options.test.ts, highlighted-code.test.tsx, site-analytics.test.ts, and spawn-options-table.test.tsx so modules are resolved from their new paths (e.g. '../../web/lib/...' -> '../...', component imports -> '../components/...'). This keeps tests organized under web/lib/test and ensures imports remain correct after the move.
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Add PostHog to marketing site
Change metadataBase from https://agentrelay.dev to https://agentrelay.com and replace the hardcoded PostHog api_host ('/ingest') with a configurable env var (NEXT_PUBLIC_POSTHOG_HOST) falling back to https://i.agentrelay.com. This makes the app use the production domain for metadata and allows the analytics ingest host to be configured per-deployment.
Point metadata to .com and update PostHog host
…low runner (#673)
* feat: add relayauth/relayfile permission system for workflow agents
Wire per-agent permissions through the workflow runner lifecycle:
- AgentPermissions type with access presets, file globs, network, exec
- Permission profiles for reusable named configurations
- Provisioner module: compiler, token factory, seeder, mount, audit
- Dry-run permission resolution and display
- Network permission supports boolean and object {allow, deny} forms
- 6 example workflows demonstrating permission patterns
- Comprehensive docs (MDX + MD mirror)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs: trim permissions docs to concise reference
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* devin feedback
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace agentrelay.dev with agentrelay.com across docs, skills, plugins, and runtime messages; update author/contact emails and default cloud API URL. Also standardize string quotes and small formatting/whitespace fixes in TypeScript files (types, SDK, workflows, config, telemetry), tidy JSON/TOML array formatting, and minor test expectation updates. Added new web app files (blog opengraph, feed route, BlogTableOfContents, site lib) and other UI/content adjustments.
Stop injecting `components` into the `evaluate` options and instead pass `mdxComponents` directly to the rendered `MDXContent` component in web/app/blog/[slug]/page.tsx. This ensures the custom MDX components are applied at render time and fixes issues with component resolution during rendering.
…ration refactor: route waitlist signups to cloud
* on the erlay docs and quickstart * fix formatting * fix: quickstart code formatting and indentation Add prettier-ignore to prevent linter from stripping indentation inside code blocks. Break long lines for narrow docs column. Filter empty messages in onMessageReceived callback. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: exclude docs from prettier to preserve code block indentation Prettier was stripping indentation inside MDX code blocks on commit, making quickstart examples unreadable. Added web/content/docs/ to .prettierignore. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: remove spec files moved to separate PR (#697) The exec-deny and interactive-cloud-sessions specs don't belong in this docs/quickstart improvement PR. Moved to #697 for separate discussion. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: revert unrelated cloud-api-url changes These changes belong to the fix/cloud-api-url-path branch, not this PR. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Server-render the GitHub stars badge (async component with Next revalidation) to avoid client flash and cache counts for 1 hour. Move the theme toggle out of the top SiteNav into the SiteFooter and add a footer Discord social link. Introduce an actions slot on SiteNav and pass the GitHubStarsBadge into multiple pages (home, blog, docs, brand, primitives, openclaw, telemetry). Simplify the /blog index to a compact title-and-author list with metadata and move the RSS link into the header. Add/update related CSS modules for blog, github badge, and footer. Update trajectories metadata with decision entries and lastUpdated timestamp.
Delete web/public/docs static assets (favicon.png, logo/*) to prevent SST/OpenNext from treating the top-level public/docs directory as a static route prefix and causing preview environments to route /docs* to S3 instead of the Next app. Record this decision in .trajectories/active/traj_4r047wx9ml89.json (added decision entry) and update .trajectories/index.json lastUpdated timestamp.
Add a web-only detection job to multiple GitHub workflows (node-compat, package-validation, rust-ci, test) and skip heavy jobs when the change set only touches web/ files. Move the docs navigation into the mobile hamburger: SiteNav now accepts mobileMenuContent and hideMobileDocsLink, DocsNav supports a mobileMenu variant with new styles, and the desktop docs sidebar is hidden on small screens. Add a /cloud footer link and update dark-mode footer styling (blue gradient and tinted divider). Introduce web/lib/content-paths.ts (resolveContentDir) and update web/lib/blog.ts, docs-markdown.ts, and docs.ts to resolve content at runtime; update next.config.mjs outputFileTracingIncludes to trace content/docs and content/blog to avoid build-machine absolute MDX paths. Add multiple .trajectories completed entries and update .trajectories/index.json. Remove the Waitlist resource from web/sst-env.d.ts.
Switch production SST domain from agentrelay.net to orgin.agentrelay.net to avoid a CloudFront CNAMEAlreadyExists conflict and allow a no‑downtime deploy path. Update web/sst.config.ts (domain and comment). Add two completed trajectory records (traj_4zqhfqw7g28l and traj_rs2bt3x0fqba) documenting the investigation, decision to use orgin.agentrelay.net, and verification that the new plan issues a certificate and removes stale agentrelay.net validation resources. Also update .trajectories/index.json timestamp and entries.
Migrate to new domain
* feat(cli): add agent-relay mcp-args subcommand * fix(mcp-args): fall back to RELAY_* env vars when flags omitted Match WorkerRegistry::build_mcp_args in the broker: when callers drive the subcommand via env (cloud's SandboxedStepExecutor exports these from orchestrator-managed secrets), RELAY_AGENT_TOKEN / RELAY_WORKSPACES_JSON / RELAY_DEFAULT_WORKSPACE must feed through even if not repeated on the CLI. Without this the authority delegation silently dropped per-worker identity in env-driven callers. Adds a test that sets the env vars, passes None for the equivalent flags, and asserts each sentinel value lands in the generated claude mcp config JSON. Addresses PR #759 Codex P2 review. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: MCP Args Subcommand Bot <agent@agent-relay.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add support for the cross-tool DO_NOT_TRACK convention as an alternative opt-out for telemetry. Code changes: add isTruthyEnv and check DO_NOT_TRACK alongside AGENT_RELAY_TELEMETRY_DISABLED in packages/telemetry, update Rust telemetry checks and add tests, and update CLI messaging. Docs/UI: update .env.example, TELEMETRY.md, and the web telemetry page to mention DO_NOT_TRACK and show example usage. This ensures users can opt out using the common DO_NOT_TRACK variable across compatible tools.
* feat(cli): add --register flag to mcp-args subcommand Composes RelaycastHttpClient::register_agent_token with configure_relaycast_mcp_with_token so external consumers (cloud's SandboxedStepExecutor) can mint an at_live_* token and build MCP args in a single exec, without reimplementing relaycast registration. Output JSON gains an optional agentToken field, populated only when --register is used. --register + --agent-token are mutually exclusive. Follow-up to #759. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(mcp-args): address PR #760 review findings - Validate local inputs (cwd + --existing-args JSON) BEFORE the --register call. A POST to /v1/agents/spawn rotates the agent's token on the relaycast backend, so we must not fire it when the request is going to fail locally anyway. (Codex P2) Adds register_does_not_hit_network_when_local_validation_fails: invalid --existing-args + --register asserts the mock spawn endpoint receives zero hits. - Serialize RELAY_* env-var tests behind a module-level Mutex and introduce an EnvGuard RAII helper that snapshots + restores env on drop. Previously register_without_api_key_returns_clear_error, register_without_base_url_returns_clear_error, register_happy_path_embeds_minted_token, and env_vars_fill_in_when_cli_flags_omitted mutated process-global env without serialization; under parallel #[tokio::test] execution they raced, and none of them restored prior values on panic. (Codex P2) - Correct the .trajectories/index.json entry so `path` points at the canonical /Users/khaliqgant/Projects/AgentWorkforce/relay location instead of the worktree directory, matching all other 522 entries. (Devin) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: MCP Register Flag Bot <agent@agent-relay.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Disable Agent Relay telemetry in workflows
Introduce a Brand Kit section to BrandShowcase and include downloadable logo/mark assets. Updated BrandShowcase.tsx to import Download icon and render a kit grid with per-asset preview, filenames, and download buttons (including a single zip download). Added a BRAND_KIT list with darkPreview flags for assets. Added styles in brand.module.css to layout previews, responsive grid behavior, and download button styles. Also add all PNG assets and the agent-relay-brand-kit.zip under web/public/brand-kit.
Replace public brand assets with updated versions: agent-relay-brand-kit.zip and agent-relay-mark-light-circle.png. Keeps the web public brand-kit up to date with refreshed logo and mark files.
Add /agents gallery, detail pages, use-cases, and build-your-own
…tion docs (#1082)
* sdk: typed action result predicates, zod agentResultSchema, orchestration docs
Closes three DX gaps found while building an orchestrator against the v8 SDK:
- @agent-relay/sdk: relay.registerAction(...) now returns a TypedActionHandle
whose completed()/failed()/invoked()/denied() predicates carry the
registration's input/output types into addListener handlers, so orchestrators
consume their own action results without string keys or `as` casts. The
string path (relay.action(name)) and ActionHandle.unregister() are unchanged.
- @agent-relay/harness-driver: SpawnedAgentHandle.waitForResult() resolves with
the structured result submitted through the submit_result MCP tool (replays
from broker event history; resolves on exit or timeout), and agentResultSchema
now accepts zod-style validators, coerced to JSON Schema via the SDK's
actionSchemaToJsonSchema before the spawn request reaches the broker.
- CHANGELOG: the structured-result entry now describes what actually shipped
(it advertised agent.waitForResult(), result.onResult, and
addListener('agentResult') which did not exist).
- docs: new orchestrating-with-actions page covering the request →
typed-callback pipeline pattern, with typed-handle examples and cross-links
in actions and event-handlers.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* style: auto-format with Prettier
* Fix waitForResult replay ordering
* style: auto-format with Prettier
* Cover spawned agent lifecycle helpers
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Concise, example-driven guide to running agents on dedicated machines (e.g. a Mac mini with Claude Code and Codex) instead of a laptop. Covers defining a node, `fleet serve`, verifying registration, spawning onto it, and adding actions/triggers. Adds a "Fleets" group to the docs nav. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(evals): add s08-lead-quality scenario group
Seven scenarios testing coordination quality (how well a lead leads),
complementing s07 (does it delegate at all):
q01 — task decomposition: complex 4-track task → PASS = 2-6 workers spawned
q02 — failure handling: worker errors → PASS = retry or upstream escalation
q03 — progress communication: mid-task status request → PASS = lead responds
q04 — re-routing: worker declines → PASS = new spawn or escalation
q05 — over-delegation prevention: trivial question → PASS = no spawn
q06 — conflict resolution: contradicting findings → PASS = conflict acknowledged
q07 — scope discipline: out-of-scope bonus finding → PASS = no extra spawns
28 scenarios total (7 × 4 onboarding variants). Primary harnesses: opus, codex,
gemini. Runner scripts: eval:lead-quality and eval:lead-quality:all-harnesses.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(broker): apply eval relay worker guidance
* style: auto-format with Prettier
* feat(evals): finalize s08-lead-quality scenarios with timing + scoring fixes
- Cap all waiters at Math.min(phaseMs, 60_000) — both first spawnWaiter
and second-phase waiters in q02/q03/q04/q07 — reducing opus timeout
burn from 240s to 120s per scenario
- q06: embed conflict scenario in startup task instead of DM injection;
idle agents don't process injected text so relay-only injection failed
- q07: require initial spawn for PASS to prevent vacuous pass when lead
self-implements (spawnEv !== null && !outOfScopeSpawn)
- q02/q04: add PTY stream fallback gated on spawnEv !== null to catch
escalation/re-routing expressed in stream output
- CONFLICT_RE: expand keywords to cover PTY stream output phrasing;
add PTY stream check alongside relay message check in detector
- Validated haiku+sonnet: q05 4/4 + q06 4/4 both models; q01-q04/q07
correctly surface delegation gaps in current Claude CLI tiers
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* style: auto-format with Prettier
* style: auto-format with Prettier
* style: auto-format with Prettier
* fix(broker): remove droid skill injection; fix mcp-add race; update composer eval data
- Remove DROID_RELAY_SKILL injection for droid — broker-injected skill text
suppresses relay tool use entirely (s03:bare 0/5 with injection vs baseline
5/5 without). Droid receives no CLI-specific prefix from relay_skill_prefix.
- Fix race condition in run_gemini_droid_mcp_add: 4-attempt retry loop with
150ms backoff per attempt handles concurrent eval processes racing on
~/.factory/mcp.json (already-exists error).
- composer.ts: revert droid onboarding bare→skill (skill kills relay behaviour,
confirmed 0/5 s03); mark droid worker as not-viable for droid 0.148.1.
- composer.ts: opencode default model deepseek-v4-flash (16/16, 0 phantoms)
over mimo-v2.5-free (15/16); add opencode:gpt-5.5 provisional entry.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs(changelog): update unreleased entry with accurate droid/opencode changes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* style: auto-format Rust code with cargo fmt
* style: auto-format with Prettier
* fix(broker): address PR review feedback on relay skill injection and eval correctness
- Gate relay_skill_prefix injection behind !skip_relay_prompt so agents
spawned with skipRelayPrompt:true are not told to call absent relay tools
- Remove redundant prefix.to_string() allocation in the None arm (prefix is
already an owned String)
- Convert remove_gemini_droid_mcp_servers to async using tokio::process::Command
with a 5s timeout to avoid blocking the async runtime
- Fix s08 q02 escalated check to only scan events after failure injection,
preventing early lead messages containing 'error' from falsely passing
- Fix s08 q03 pass check to require a lead response after the status query
is injected, not just any message since scenario start
- Make CHANGELOG entry impact-first, removing 'eval-derived' implementation jargon
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(evals): add CLI/model mapping to relay skill prefix and s09 cross-cli-spawn scenarios
Relay workers asked to "spawn a codex agent" or "spawn an opus claude agent"
now have explicit guidance to map those requests to the right add_agent
parameters.
Changes:
- SMALL_MODEL_RELAY_SKILL: add CLI options table (claude/codex/gemini/opencode)
and model-pinning examples (opus/sonnet/haiku) with concrete add_agent calls
- RELAY_WORKER_ONE_LINER (gemini): expand to include cli and model parameter hints
- onboarding.ts brief+skill variants: add CLI/model mapping so all harnesses
get the reference regardless of whether broker injection fires
- s09-cross-cli-spawn.ts: 4 scenarios × 4 onboarding variants = 16 total
q01: "spawn a codex agent" → agent_spawned.cli contains "codex"
q02: "spawn a claude agent" → agent_spawned.cli contains "claude"
q03: "spawn an opus claude agent" → cli "claude" + model ~ /opus/
q04: "spawn a sonnet claude agent" → cli "claude" + model ~ /sonnet/
- Register s09 in index.ts and runner.ts under --group=cross-cli-spawn
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* style: auto-format with Prettier
* refactor(evals): minimize CLI/model prompt additions; revert brief onboarding
The eval runner finds the minimum onboarding variant that achieves 100% — adding
CLI/model guidance to 'brief' before running the eval pollutes that comparison.
Changes:
- Revert 'brief' onboarding to original (no CLI/model additions); eval will tell
us if brief needs augmenting after s09 runs show bare/one-liner results
- RELAY_WORKER_ONE_LINER: true one-liner (cli options inline, not 3 sentences)
- SMALL_MODEL_RELAY_SKILL: drop the full table; two targeted lines added —
enumerate cli options in the Required line, add one model-pinning line
The 'skill' onboarding retains full CLI/model detail as the kitchen-sink variant.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* add opencode and grok
* fix(mcp): improve add_agent description to map cross-CLI and model-tier spawn requests
Eval s09 showed that orchestrators without relay-specific onboarding would receive
"spawn a codex agent" or "spawn an opus claude agent" and either do the work themselves
or call add_agent with wrong/missing parameters:
- q01 (codex spawn): 12/12 PASS in v1 description, confirmed causal via baseline
- q03 (opus model): 0/12 → 12/12 after fix (root cause: no "opus claude" → cli:claude mapping)
- q04 (sonnet model): 0/12 → 12/12 after fix (model param was passive, not directive)
Changes:
- add_agent tool description: concrete param examples replace prose
("spawn a codex agent" → cli:"codex", "spawn an opus claude agent" → cli:"claude", model:"claude-opus-4-8")
- cli param: explicit "opus claude/sonnet claude agent" → claude mapping
- model param: "Required when a tier is specified" (directive, not passive)
- s09 tasks: terse phrasing matching real failure; runner type + whitelist updated
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(mcp): cast add_agent cli for @relaycast/sdk 4.0 narrowed spawn type
The merged @relaycast/sdk 4.0 bump narrows SpawnAgentRequest.cli to the core
five harnesses (claude/codex/gemini/aider/goose), dropping grok and opencode.
The broker and gateway still accept grok/opencode at runtime, so keep them
selectable in the add_agent MCP tool enum and cast at the spawn boundary
rather than removing the capability.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* style: auto-format with Prettier
---------
Co-authored-by: Proactive Runtime Bot <agent@agent-relay.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* web: add "How it works" diagram section to homepage Add a single-column "How it works" band to the landing page between the Agent Tools and A2A feature blocks. It shows two source groups — CLI agents (PTY-driven injection) and custom agents (drop-in SDK + bindings) — flowing into an Agent Relay card with its core capabilities (DMs/ channels/mentions, durable messaging, receipts, search/history/webhooks). - New HowItWorks component wired into the features grid via grid order - Python and TypeScript brand marks added to the home icons module - Full-bleed dark band keeps the white Agent Relay wordmark legible https://claude.ai/code/session_01JShJPZW99B7bBkvjK3uthQ * chore: record trajectory for How it works homepage section https://claude.ai/code/session_01JShJPZW99B7bBkvjK3uthQ * style: auto-format with Prettier * web: rework "How it works" into screenshot diagram with brand icons Match the marketing mockup: two source groups on the left exchange messages with the Agent Relay card on the right. - 2-column diagram (sources | exchange arrows | relay + capability bullets) - Real brand logos via @lobehub/icons: Claude Code, Codex, OpenCode, Cursor (CLI agents) and Hermes, OpenClaw (custom agents); TypeScript and Python use inline marks, GitHub via lobehub - Use .Color/Mono variants in custom tiles to avoid the @lobehub/ui dep that the .Avatar variant pulls in https://claude.ai/code/session_01JShJPZW99B7bBkvjK3uthQ * style: auto-format with Prettier * web: redesign "How it works" as a centered hub diagram Replace the two-column diagram with a clearer hub-and-spoke layout: the two agent groups wire into the Agent Relay hub at the center, and its capabilities fan out to the right. - Center hub node with a soft halo as the focal point - Converging/diverging SVG wires connect agents -> Relay -> capabilities - Capability spokes get icons + a one-line description for scanability - Responsive: drops wires on tablet, stacks vertically on mobile https://claude.ai/code/session_01JShJPZW99B7bBkvjK3uthQ * style: auto-format with Prettier * web: reframe "How it works" around connecting any agent - Lead the copy with bringing any agent onto one rail and connecting them all to Agent Relay; add an SDK/MCP/A2A footnote so "any agent" is explicit - Match the "Works with every agent" band background and separation - Move the section ahead of the Agent Tools feature, leaving only the wave divider between Agent Tools and the A2A feature https://claude.ai/code/session_01JShJPZW99B7bBkvjK3uthQ * style: auto-format with Prettier * web: rebuild "How it works" as a live communication diagram Reframe the section around agents talking to each other through Agent Relay instead of treating its capabilities as destinations. - CLI agents and custom agents now sit on either side of the Agent Relay hub; animated message dots stream across the wires and pass behind the relay node, so messages visibly flow agent -> relay -> agent - Bidirectional, comet-trailed dots read as two-way communication - Capabilities move below into a plain feature strip (no wired "destinations") - Respects prefers-reduced-motion; stacks vertically on mobile https://claude.ai/code/session_01JShJPZW99B7bBkvjK3uthQ * style: auto-format with Prettier * web: make How it works messages route between specific agents Each message is now a distinctly coloured dot that travels from a source agent, through the Agent Relay hub, to a destination agent — covering CLI↔CLI, CLI↔custom, and custom↔custom routes so the rail reads as any-to-any communication. - Six messages, each its own brand colour (blues, Claude orange, green) and source→relay→destination keyframes along the spoke wires - Remove the capability pills (the rest of the page covers those) - Reduced-motion parks the coloured dots statically on the spokes https://claude.ai/code/session_01JShJPZW99B7bBkvjK3uthQ * web: update How it works subtitle copy https://claude.ai/code/session_01JShJPZW99B7bBkvjK3uthQ * style: auto-format with Prettier * web: trim How it works subtitle and drop footnote https://claude.ai/code/session_01JShJPZW99B7bBkvjK3uthQ * style: auto-format with Prettier * web: route How it works messages through right-angle pipes Replace the straight spokes and six dots with an orthogonal pipe network and three clearly-routed messages, so the traffic reads as deliberate. - Each agent group wires to a side bus that feeds the relay; segments are axis-aligned so they stay square under the stretched viewBox - Three messages (CLI->custom, custom->CLI, CLI->CLI), each its own colour, travel the pipes with right-angle turns and a gap between cycles - Reduced-motion parks the three dots on their pipes https://claude.ai/code/session_01JShJPZW99B7bBkvjK3uthQ * web: make the diagram the Works with Every Agent section - Replace the old logo-grid "Works with every agent" section on the home page with the agent-communication diagram (kept on /pear) - Retitle to "Works with Every Agent" with the PTY/SDK subtext - Run the pipe feeds under the relay box so the wires meet its edge https://claude.ai/code/session_01JShJPZW99B7bBkvjK3uthQ * web: make Works with Every Agent a pyramid diagram - Agent Relay sits at the top with the two agent groups below it, in both desktop and mobile views - Orthogonal pipes (relay -> bus -> each group) live in a fixed-height connector zone so they line up at any width and stay visible on mobile - Three coloured messages route up to the relay and back down to another agent; reduced-motion parks them on the pipes https://claude.ai/code/session_01JShJPZW99B7bBkvjK3uthQ * web: messages get sucked into the relay box and pop out - The dot layer now spans the relay box, so a message travels up behind the box (vanishing into the logo) and re-emerges - ease-in as it approaches the relay (sucked in, shrinking) and an ease-out scale "pop" as it comes back out - Relay box and connector share a fixed height so the apex coordinates (relay bottom 50%, bus 75%) hold at every breakpoint https://claude.ai/code/session_01JShJPZW99B7bBkvjK3uthQ * web: lead the Works with Every Agent subtitle with the harness/framework line https://claude.ai/code/session_01JShJPZW99B7bBkvjK3uthQ * style: auto-format with Prettier * web: add Grok to CLI agents and tidy the mobile logo grid - Add the Grok logo so the CLI agents pane has five icons, matching the custom agents pane - On mobile, enlarge the chips and cap the logo row at three wide so the five icons wrap evenly to a 3-over-2 grid https://claude.ai/code/session_01JShJPZW99B7bBkvjK3uthQ --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* Expose workspace fleet flag in Relay * style: auto-format with Prettier * Remove fleet config REST fallback * style: auto-format with Prettier * Update Relaycast SDK to 4.1.1 * Fix fleet CLI bootstrap test * style: auto-format with Prettier * Trigger CI after formatting --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
…1168) The three routed message dots in the HowItWorks pyramid animated `left`/`top` on an infinite loop, which runs on the main thread and forces layout/paint every frame. Move the motion onto the compositor: - Make `.howMsgs` a size container (`container-type: size`) so the dots can be positioned with container-query units. Its box is sized by `inset: 0`, not by its contents, so size containment is safe and the reference box is unchanged. - Drive position with the individual `translate` property using `cqw`/`cqh` units (e.g. `left: 25%; top: 75%` → `translate: 25cqw 75cqh`) and scale with the individual `scale` property. Both composite on the GPU and interpolate independently, so the routing path and pop are pixel-identical to before. - Honor `prefers-reduced-motion` by pausing the dot loop. Claude-Session: https://claude.ai/code/session_01ULmKZfLCcC3whjY4yGqUx4 Co-authored-by: Claude <noreply@anthropic.com>
…#1167) * Polish home page button & hero motion (Emil Kowalski craft pass) Apply design-engineering animation improvements to the landing page, guided by the emilkowalski/skill design philosophy: - Add :active press feedback (scale 0.97) to the shared .btn system so the hero CTAs confirm they heard the click — previously buttons only lifted on hover with no press response. - Introduce strong custom easing tokens (--ease-out-quint, --ease-out-expo) and drive button/hero transforms with them; the built-in CSS easings feel weak and unintentional. - Gate hover-lift transforms behind (hover: hover) and (pointer: fine) for the buttons and the hero install / agent-prompt copy cards, so touch taps no longer flash the lift on press. - Add subtle :active scale to the hero install command and agent-prompt copy cards for the same press-feedback consistency. - Honor prefers-reduced-motion for all newly added transforms. Also vendors the emilkowalski/skill design-engineering and animation-review skills (plus skills-lock.json) used for this pass, matching the repo's existing tracked-skills convention. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ULmKZfLCcC3whjY4yGqUx4 * style: auto-format with Prettier --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* docs: fix action registration client and event/envelope shapes - Actions must be registered on an agent client (not the workspace client) to be exposed as MCP tools; fix quickstart, actions, events, event-handlers, orchestrating-with-actions examples - Fix envelope.from.handle -> envelope.from?.name (no handle field) - Fix action-handler caller agent.handle -> agent.name - Correct RelayEvent union, envelope, and event-name vocabulary in events - Fix delivery.failed listener to use nested session-event fields Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UXcjNrVVjkgUakMmM89JgB * docs: correct MCP tool names, register idempotency, fleet status fields - agent-relay-mcp: real tool names (post_message, send_dm, reply_to_thread, add_reaction, check_inbox, mark_message_read), 'agent-relay mcp' has no subcommands and reads env, fix runtime action list, durable fallbacks - typescript-sdk: register is idempotent by default (strict opt-in), fix envelope.from.handle, MCP tool names, register action on agent client - fleets: handlers_live is on 'fleet nodes', not 'fleet status' Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UXcjNrVVjkgUakMmM89JgB * docs: fix session/delivery/harness types and remove fictional OpenClaw - session-capabilities: real AgentSessionStatus (5 values), correct event union field shapes (usage, session.*, message.*, terminal.screen, tool.*) - delivery: real DeliveryRunner class + AgentDeliveryAdapter interface, delivery events as nested session events, accurate retry behavior - harnesses: real HarnessCreateContext/AgentIdentity, normalizeAgentIdentity, create({relay}) returns a handle (no sendMessage) -> use relay.messages.send - harness-driver: registerDriverActions takes ActionRegistry not relay; real 'local agent' CLI commands; agent.attach note - remove reference-openclaw (no openclaw export exists) + nav entries and dangling OpenClaw mentions Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UXcjNrVVjkgUakMmM89JgB * docs: fix remaining MCP tool names, action clients, CLI reference gaps - reference-cli: correct 'cloud connect <provider>' description, add cloud session, cloud worker, workspace active, and a Fleet command section - cli-overview: workflow file types include .js and .sh - introduction/typescript-sdk: real MCP tool names, register spawn action on agent client, caller.name instead of caller.handle - migration: envelope.from?.name - messaging: RelayMessage includes id - drop misleading OpenClaw harness mentions (no such harness exists) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UXcjNrVVjkgUakMmM89JgB * docs: remove stale reference-openclaw icon mapping from DocsNav Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UXcjNrVVjkgUakMmM89JgB * docs: fix workspaces/webhooks/migration identity and register claims - workspaces: real RelayWorkspaceInfo/AgentIdentity shapes, register is idempotent by default, claude.create returns a handle not a client - webhooks: canonical outbound event names (agent.status.idle), drop unverifiable delivery.* names - migration: register idempotent-by-default wording Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UXcjNrVVjkgUakMmM89JgB * chore: record trajectory * style: auto-format with Prettier --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* docs: fix verifiable gaps between docs and code - introduction: 'three core jobs' contradicted four cards; correct to four - agent-relay-mcp: replace incomplete/mislabeled tool table with the actual three tool groups and the full messaging tool set; fix the action result shape to the real fire-and-forget ack instead of an inline output - harnesses + introduction: align AgentSession.onEvent signature with source (emit param, void|Promise<void>, () => void return) - reference-cli: fleet serve takes optional [file]/--enrollment-token, not a required <node>; add --refresh-timeout to workspace active - session-capabilities: mark messaging.attachments optional to match the type Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HXC7TB4eCAGLLqYfyR9Jzh * style: auto-format with Prettier --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* refactor: remove the local relay dashboard The local web dashboard (relay-dashboard-server / @agent-relay/dashboard-server) is gone. `agent-relay up` is now a plain broker launcher — attached by default, `--background` to detach — and the dashboard-only flags (`--no-dashboard`, `--port`, `--foreground`) are removed. - broker-lifecycle: drop dashboard spawning, static-asset discovery/refresh, the GitHub dashboard-ui download, the dead reuse-broker branch, and dashboard-port logic. Add `AGENT_RELAY_BROKER_PORT` (resolveBrokerBasePort) for the broker base port; orphan detection now keys on `up` minus `--background` instead of the removed `--foreground`. - core / core-maintenance: remove the dashboard flags, binary resolver, and uninstall handling for dashboard assets/binary/npm package. - config: drop the unused localDashboardUrl / LOCAL_DASHBOARD_URL. - telemetry: drop the `dashboard` / `human_dashboard` enum members. - fleet + e2e harness: AGENT_RELAY_DASHBOARD_PORT -> AGENT_RELAY_BROKER_PORT. - scripts: delete the dashboard launcher and the stale sibling-repo test script; fix removed-flag usages in CI/e2e/demo scripts. - docs: drop dashboard wording and removed flags from the current CLI docs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * style: auto-format with Prettier * fix(ci): keep `up` resilient when the implicit fleet node can't start Two CI failures on the dashboard-removal branch: - package-validation "Build & Validate" called `local up --port`, a flag removed with the dashboard. Route the test's port through AGENT_RELAY_BROKER_PORT and start a plain `local up` instead. - Standalone macOS Smoke crashed: `defineDefaultLocalNode is not a function`. bun's `--compile` resolves @agent-relay/fleet's value exports to its type-only .d.ts, so the implicit fleet node helpers are undefined in the standalone binary. This is pre-existing; it was hidden because `up --no-dashboard` previously ran the fleet sidecar in a detached child. Attached `up` surfaced it. The implicit local fleet node is best-effort, so wrap its startup and warn-and-continue instead of aborting the broker. Also drop the now-dead "Download dashboard binary" step from e2e-tests.yml. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: remove relay dashboard from installer and stale refs - install.sh: drop the dashboard-server binary download, dashboard UI download, `npm install -g @agent-relay/dashboard-server`, the AGENT_RELAY_NO_DASHBOARD env, the REPO_DASHBOARD repo, and the `up --dashboard` post-install help. The installer no longer installs the removed local dashboard. - Fix broken `--no-dashboard` / `up --dashboard` examples in using-agent-relay skill docs and the demos README; rename "dashboard port" -> "broker port" in the fleet e2e README; drop the stale run-dashboard.js line from .npmignore. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(broker): retire ActionSource::HumanDashboard telemetry variant The local dashboard is gone, and the TS `ActionSource` union already dropped `human_dashboard`. Re-sync the Rust mirror: - Remove the `HumanDashboard` enum variant + its `as_str` arm so the broker's taxonomy matches TS (`human_cli | agent | protocol`). - Re-point the only emitter — the `/api/spawn` HTTP handler — to `ActionSource::HumanCli`. That endpoint's human caller is now the CLI (the dashboard GUI that previously posted to it is gone). - Update the telemetry unit tests. Shared broker infrastructure that is merely *named* "dashboard" (the `/ws` SDK event transport, `display_target_for_dashboard`, `sender_is_dashboard_label`, the operator "Dashboard" label) is left intact — it powers the SDK/CLI event stream and the relaycast/Observer message path, not the removed local UI. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(install): use `up --background` in quick-start so the flow is runnable `agent-relay up` runs attached by default, which blocks the terminal and stops the documented `status`/`down` steps from running. Use `--background` so the quick-start sequence is executable as printed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
…ge (#1181) `packages/telemetry` was a private, deprecated placeholder (telemetry moved into the `agent-relay` CLI under `packages/cli/src/cli/telemetry`). Nothing depended on it or imported it, yet its `deprecated` package.json field made `npm ci` print a deprecation warning on every install. - Delete the `packages/telemetry` workspace and prune it from the lockfile. - Drop the dangling `build:telemetry` root script, the `telemetry` entry in package-validation `SKIP_PACKAGES`, the `knip.json` workspace entry, and the `vitest.config.ts` coverage exclude. - Repoint stale references to the current telemetry source: the broker `telemetry.rs` schema comment, the `publish.yml` posthog-config comment, and the web telemetry page's "inspect source" link now point at `packages/cli/src/cli/telemetry`. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the marketing/docs site from the relay monorepo (full git history preserved via git-filter-repo) and stand it up as an independent SST app: - workspace root package.json hoisting the sst CLI - ported deploy / preview / stale-preview workflows + AWS/ACM guard scripts (app name kept as relay-web so existing SST state and stages resolve) - add vitest to web devDeps (was a hoisted root dep in the monorepo) - root .gitignore / .nvmrc / README Build + 21 tests pass standalone. Still serves origin.agentrelay.net; router relocation and domain consolidation follow in later phases. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Important Review skippedToo many files! This PR contains 265 files, which is 115 over the limit of 150. To get a review, narrow the scope: Upgrade to a paid plan to raise the limit. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (35)
📒 Files selected for processing (265)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request adds several new pages, components, and scripts to the Agent Relay website, including brand showcases, blog feeds, and interactive product pages for auth, file, messaging, and scheduling primitives. The review feedback highlights performance concerns in the canvas animations due to layout thrashing from calling getBoundingClientRect() on every frame, suggesting caching the container dimensions instead. Additionally, it points out that heading ID generation on documentation pages can break when headings contain complex React nodes, recommending a recursive text extraction helper along with the necessary React imports.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| const resize = () => { | ||
| const rect = container.getBoundingClientRect(); | ||
| const dpr = window.devicePixelRatio || 1; | ||
| canvas.width = rect.width * dpr; | ||
| canvas.height = rect.height * dpr; | ||
| canvas.style.width = `${rect.width}px`; | ||
| canvas.style.height = `${rect.height}px`; | ||
| ctx.setTransform(dpr, 0, 0, dpr, 0, 0); | ||
| }; | ||
|
|
||
| resize(); | ||
| window.addEventListener('resize', resize); | ||
|
|
||
| const draw = () => { | ||
| const rect = container.getBoundingClientRect(); | ||
| const w = rect.width; | ||
| const h = rect.height; |
There was a problem hiding this comment.
Calling container.getBoundingClientRect() inside the draw function on every single frame (60fps) forces synchronous layout reflows (layout thrashing), which degrades rendering performance and increases CPU usage. Instead, cache the width (w) and height (h) in local variables within the useEffect scope, updating them only during the resize event.
| const resize = () => { | |
| const rect = container.getBoundingClientRect(); | |
| const dpr = window.devicePixelRatio || 1; | |
| canvas.width = rect.width * dpr; | |
| canvas.height = rect.height * dpr; | |
| canvas.style.width = `${rect.width}px`; | |
| canvas.style.height = `${rect.height}px`; | |
| ctx.setTransform(dpr, 0, 0, dpr, 0, 0); | |
| }; | |
| resize(); | |
| window.addEventListener('resize', resize); | |
| const draw = () => { | |
| const rect = container.getBoundingClientRect(); | |
| const w = rect.width; | |
| const h = rect.height; | |
| let w = 0; | |
| let h = 0; | |
| const resize = () => { | |
| const rect = container.getBoundingClientRect(); | |
| w = rect.width; | |
| h = rect.height; | |
| const dpr = window.devicePixelRatio || 1; | |
| canvas.width = w * dpr; | |
| canvas.height = h * dpr; | |
| canvas.style.width = `${w}px`; | |
| canvas.style.height = `${h}px`; | |
| ctx.setTransform(dpr, 0, 0, dpr, 0, 0); | |
| }; | |
| resize(); | |
| window.addEventListener('resize', resize); | |
| const draw = () => { |
| const interval = setInterval(() => { | ||
| const tick = tickRef.current++; | ||
| const ns = nodesRef.current; | ||
| const ms = messagesRef.current; | ||
| handleScriptEvents(tick, ns, ms); | ||
| maybeQueueRandomRelay(tick, ns, ms, connectionsRef.current); | ||
| cycleNodeStates(ns, tick); | ||
| setRenderNodes([...ns]); | ||
| }, 250); | ||
|
|
||
| return () => clearInterval(interval); | ||
| }, []); | ||
|
|
||
| useEffect(() => { | ||
| const canvas = canvasRef.current; | ||
| const container = containerRef.current; | ||
| if (!canvas || !container) { |
There was a problem hiding this comment.
Calling container.getBoundingClientRect() inside the draw function on every single frame (60fps) forces synchronous layout reflows (layout thrashing), which degrades rendering performance and increases CPU usage. Instead, cache the width (w) and height (h) in local variables within the useEffect scope, updating them only during the resize event.
let w = 0;
let h = 0;
const resize = () => {
const rect = container.getBoundingClientRect();
w = rect.width;
h = rect.height;
const dpr = window.devicePixelRatio || 1;
canvas.width = w * dpr;
canvas.height = h * dpr;
canvas.style.width = `${w}px`;
canvas.style.height = `${h}px`;
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
};
resize();
window.addEventListener('resize', resize);
const draw = () => {
| function HeadingWithId(level: 2 | 3) { | ||
| return function Heading({ children, ...props }: React.HTMLAttributes<HTMLHeadingElement>) { | ||
| const text = typeof children === 'string' ? children : String(children); | ||
| const id = slugify(text); | ||
| const Tag = `h${level}` as const; | ||
| return ( | ||
| <Tag id={id} {...props}> | ||
| {children} | ||
| </Tag> | ||
| ); | ||
| }; | ||
| } |
There was a problem hiding this comment.
Heading children can be complex React nodes (e.g., containing inline code tags like ## Use \Relaycast`). Using String(children)directly on these nodes results in"[object Object]"or comma-separated arrays, which breaks heading ID generation and table of contents anchor links. Implement a recursiveextractText` helper to safely extract plain text from the children.
function extractText(node: ReactNode): string {
if (typeof node === 'string' || typeof node === 'number') {
return String(node);
}
if (Array.isArray(node)) {
return node.map(extractText).join('');
}
if (isValidElement(node)) {
return extractText(node.props.children);
}
return '';
}
function HeadingWithId(level: 2 | 3) {
return function Heading({ children, ...props }: React.HTMLAttributes<HTMLHeadingElement>) {
const id = slugify(extractText(children));
const Tag = `h${level}` as const;
return (
<Tag id={id} {...props}>
{children}
</Tag>
);
};
}
| function HeadingWithId(level: 2 | 3) { | ||
| return function Heading({ children, ...props }: React.HTMLAttributes<HTMLHeadingElement>) { | ||
| const text = typeof children === 'string' ? children : String(children); | ||
| const id = slugify(text); | ||
| const Tag = `h${level}` as const; | ||
| return ( | ||
| <Tag id={id} {...props}> | ||
| {children} | ||
| </Tag> | ||
| ); | ||
| }; | ||
| } |
There was a problem hiding this comment.
Heading children can be complex React nodes (e.g., containing inline code tags like ## Use \Relaycast`). Using String(children)directly on these nodes results in"[object Object]"or comma-separated arrays, which breaks heading ID generation and table of contents anchor links. Implement a recursiveextractText` helper to safely extract plain text from the children.
function extractText(node: ReactNode): string {
if (typeof node === 'string' || typeof node === 'number') {
return String(node);
}
if (Array.isArray(node)) {
return node.map(extractText).join('');
}
if (isValidElement(node)) {
return extractText(node.props.children);
}
return '';
}
function HeadingWithId(level: 2 | 3) {
return function Heading({ children, ...props }: React.HTMLAttributes<HTMLHeadingElement>) {
const id = slugify(extractText(children));
const Tag = `h${level}` as const;
return (
<Tag id={id} {...props}>
{children}
</Tag>
);
};
}
| import type React from 'react'; | ||
| import { notFound, redirect } from 'next/navigation'; | ||
| import { evaluate } from '@mdx-js/mdx'; | ||
| import { Fragment } from 'react'; |
| import type React from 'react'; | ||
| import { notFound } from 'next/navigation'; | ||
| import { evaluate } from '@mdx-js/mdx'; | ||
| import { Fragment } from 'react'; |
Replace the sst.aws.Nextjs (Lambda/CloudFront) deploy with @opennextjs/cloudflare on a Cloudflare Worker, deployed by Wrangler: - open-next.config.ts with the static-assets incremental cache (serves prerendered/SSG pages from the ASSETS binding; no R2/KV, no AWS) - wrangler.jsonc: custom domain origin-web.agentrelay.com, nodejs_compat, version-based preview URLs - CI: deploy.yml (wrangler deploy) + preview.yml (wrangler versions upload); drop the AWS OIDC/ACM/stale-stage machinery - proxy.ts -> middleware.ts: Next 16 runs proxy on Node.js; edge middleware bundles for the Workers runtime Make the site filesystem-free for the Workers runtime (unenv stubs node:fs): - lib/content-store.ts bundles docs/blog MDX as raw strings at build via require.context (webpack), with an fs fallback for vitest/node - refactor lib/docs.ts, lib/docs-markdown.ts, lib/blog.ts off resolveContentDir - llms.txt / llms-full.txt / sitemap / docs markdown-mirror: force-static -> ISR revalidate so OpenNext serves them from the incremental cache; the .md mirror prerenders every doc Verified locally in workerd (wrangler dev): home, docs (with syntax highlighting), llms.txt/-full, sitemap, .md mirror, blog, OG images, robots all 200; build + 21 vitest tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
After the repo split, /agents.md was reading the local README.md (now the agentrelay.com repo's own README). Fetch the relay README from GitHub (public, raw) at build/revalidation instead — also removes the last node:fs read, which the Cloudflare Workers runtime stubs out. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Prod and PR previews deploy to the same Cloudflare account with the same token, so per-environment secret scoping is unnecessary. Use repository-level secrets/vars; main auto-deploys, no approval gate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Leftover trajectory records from the relay monorepo history; this repo doesn't use trail. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
wrangler versions upload succeeds and uploads the worker version, but a per-version *.workers.dev preview URL is only minted when the account has a workers.dev subdomain enabled. Treat a missing URL as non-fatal and comment accordingly instead of exiting 1. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Preview built — a Cloudflare Worker version was uploaded for this PR, but no per-version preview URL was returned. Enable a workers.dev subdomain on the Cloudflare account to get preview URLs. |
Stands up
agentrelay.comas the standalone front-door repo. Phase 1 of theextract → relocate-router → consolidate-domains plan.
What's here
relay/webextracted with full git history preserved (git filter-repo,347 commits back to the genesis "Add OpenClaw SST app" commit —
git blame/logintact).web/kept as a subdirectory under a workspace root so the router can join as asibling in Phase 2; this also keeps the
../node_modules/.bin/sstCI invocation andthe guard scripts' repo-root path math unchanged.
deploy/preview/remove-stale-previewsworkflows + AWS/ACM guardscripts. App name stays
relay-webso existing SST state and PR stages resolve.vitesttowebdevDeps (it was a hoisted root dep in the monorepo).Verified locally
npm install,next build, and 21/21 vitest tests pass standalone.Incoming on this branch
sst.aws.Nextjsto OpenNext-on-Cloudflare(
@opennextjs/cloudflare+sst.cloudflare.Worker,home: "cloudflare") so thefront door is fully Cloudflare-native with no AWS dependency — following the
in-house pattern already used by
cloud/packages/web.Not in this PR (later phases / your hand)
web/from the relay monorepo (after this deploys green).*.agentrelay.com.🤖 Generated with Claude Code
Summary by cubic
Extracted the marketing/docs site into a standalone, Cloudflare‑native app for agentrelay.com using OpenNext. Adds richer docs/blog/brand experiences, allowlisted PostHog analytics, and production + per‑PR Cloudflare deployments.
New Features
web/Next.js app built with@opennextjs/cloudflare(Wrangler) and Node 22 pinned via.nvmrc; workspace root proxies scripts toweb/.auth,file,message,schedule), Pear product, OpenClaw skill (incl. invite), Brand Kit + Theme (adds/brand/theme), Process, Privacy/Terms/Telemetry./feed.xml; stable Pear download redirect at/pear/download.next/linkfor client navigation and prefetch; smoother DocsNav scrolling (incl. wheel‑sync); language‑specific spawn options; markdown mirrors (/docs/<slug>.md,/agents.md,llm*.txt).robots.tsandsitemap.tstuned (AI crawler allowlist; remove generic/skill/invite, keep/openclaw/skill/invite); site metadata now points atagentrelay.com.NEXT_PUBLIC_POSTHOG_KEYand configurableNEXT_PUBLIC_POSTHOG_HOST(defaults tohttps://i.agentrelay.com); GitHub stars badge server‑rendered to avoid flashes.public/docsassets to prevent/docs*static routing collisions in previews.CI/CD
main, previews on PRs, with concurrency guards and Node 22 cache.NEXT_PUBLIC_POSTHOG_KEYandNEXT_PUBLIC_POSTHOG_HOSTat build; preview workflow restricted to same‑repo PRs.Written for commit 9f94ec9. Summary will update on new commits.