Skip to content

feat(landing): add Hyperliquid-first public page#250

Merged
Whiteks1 merged 2 commits intomainfrom
codex/landing-hyperliquid-first
Apr 4, 2026
Merged

feat(landing): add Hyperliquid-first public page#250
Whiteks1 merged 2 commits intomainfrom
codex/landing-hyperliquid-first

Conversation

@Whiteks1
Copy link
Copy Markdown
Owner

@Whiteks1 Whiteks1 commented Apr 4, 2026

Summary

Adds a public landing page for QuantLab under /landing with a Hyperliquid-first product framing.

Changes included:

  • responsive static landing page markup
  • matching visual system and motion in landing/styles.css
  • lightweight reveal/interactions in landing/app.js
  • public copy aligned with the current Hyperliquid-first strategy

Scope

This PR is landing-page only. It does not change QuantLab runtime, broker logic, or CLI behavior.

Validation

Validated with local review of the static HTML/CSS/JS and git diff --check.

Notes

  • Kraken remains legacy compatibility in the repo, but not the active product framing
  • the landing page is intended as the public-facing surface for the current product direction

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Apr 4, 2026

Reviewer's Guide

Implements a new Hyperliquid-first public landing page under /landing with dedicated HTML/CSS/JS, and updates the desktop UI and documentation to align execution strategy, runtime surfaces, and internal messaging around Hyperliquid as the active venue while keeping Kraken as legacy compatibility.

Sequence diagram for desktop snapshot refresh and Hyperliquid frontier dashboard

sequenceDiagram
  participant UI as DesktopUI
  participant Timer as RefreshTimer
  participant Renderer as RendererModule
  participant Bridge as QuantlabDesktopBridge
  participant API as ResearchServerAPI

  %% Initial workspace state established elsewhere

  UI->>Renderer: ensureRefreshLoop()
  alt workspace serverUrl missing or refreshPaused
    Renderer-->>UI: return (no refresh)
  else ready
    Renderer->>Renderer: refreshSnapshot()
    Renderer->>Timer: setInterval(refreshSnapshot, refreshIntervalMs)
  end

  loop every refreshIntervalMs
    Timer->>Renderer: refreshSnapshot()
    par requestSnapshot
      Renderer->>Bridge: requestJson(runtimeSnapshotPath)
      Bridge->>API: GET /api/runtime-snapshot
      API-->>Bridge: runtimeSnapshot
      Bridge-->>Renderer: runtimeSnapshot
    and requestLaunchControl
      Renderer->>Bridge: requestJson(launchControlPath)
      Bridge->>API: GET /api/launch-control
      API-->>Bridge: launchControl
      Bridge-->>Renderer: launchControl
    and requestPaperHealth
      Renderer->>Bridge: requestJson(paperHealthPath)
      Bridge->>API: GET /api/paper-sessions-health
      API-->>Bridge: paperHealth
      Bridge-->>Renderer: paperHealth
    and requestBrokerHealth
      Renderer->>Bridge: requestJson(brokerHealthPath)
      Bridge->>API: GET /api/broker-submissions-health
      API-->>Bridge: brokerHealth
      Bridge-->>Renderer: brokerHealth
    and requestHyperliquidSurface
      Renderer->>Bridge: requestJson(hyperliquidSurfacePath)
      Bridge->>API: GET /api/hyperliquid-surface
      API-->>Bridge: hyperliquidSurface
      Bridge-->>Renderer: hyperliquidSurface
    and requestStepbitWorkspace
      Renderer->>Bridge: requestJson(stepbitWorkspacePath)
      Bridge->>API: GET /api/stepbit-workspace
      API-->>Bridge: stepbitWorkspace
      Bridge-->>Renderer: stepbitWorkspace
    end

    Renderer->>Renderer: update state.snapshot with all results
    Renderer->>Renderer: update state.snapshotStatus
    Renderer->>Renderer: renderWorkspaceState()
    Renderer->>Renderer: frontier = getFrontierSnapshot()
    Renderer->>Renderer: renderFrontierDashboard(frontier)
    Renderer->>UI: update frontierMeta, frontierSummary, frontierGrid, frontierCallout
  end
Loading

Sequence diagram for research UI process startup retry logic

sequenceDiagram
  participant Main as DesktopMain
  participant Launcher as launchResearchUiProcess
  participant Binder as bindResearchUiProcess
  participant Proc as ResearchUiProcess

  Main->>Launcher: launchResearchUiProcess(candidates, 0)
  activate Launcher
  Launcher->>Proc: spawn candidates[0]
  Launcher->>Binder: bindResearchUiProcess(processHandle, pythonCommand, candidates, 0)
  deactivate Launcher

  note over Binder,Proc: During startup, process may exit or emit spawn error

  alt process exit event
    Proc-->>Binder: exit(code, signal)
    Binder->>Binder: if researchServerProcess !== processHandle then return
    Binder->>Binder: researchServerProcess = null
    Binder->>Binder: researchServerOwned = false
    alt nonzero code and workspaceState.status is starting and more candidates remain
      Binder->>Main: appendLog(startup exit and retry message)
      Binder->>Launcher: launchResearchUiProcess(candidates, candidateIndex + 1)
      activate Launcher
      Launcher->>Proc: spawn next candidates[candidateIndex + 1]
      Launcher->>Binder: bindResearchUiProcess(newHandle, nextCommand, candidates, candidateIndex + 1)
      deactivate Launcher
    else no retry
      Binder->>Main: clearResearchStartupTimer()
      Binder->>Main: updateWorkspaceState(status stopped, error startup_error, source research_ui)
      Binder->>Main: appendLog(startup exit message)
    end
  else spawn error event
    Proc-->>Binder: error(errorObj)
    Binder->>Binder: if researchServerProcess === processHandle then researchServerProcess = null and researchServerOwned = false
    alt error.code in [EACCES, EPERM, ENOENT] and more candidates remain
      Binder->>Main: appendLog(spawn error retry message)
      Binder->>Launcher: launchResearchUiProcess(candidates, candidateIndex + 1)
      activate Launcher
      Launcher->>Proc: spawn next candidates[candidateIndex + 1]
      Launcher->>Binder: bindResearchUiProcess(newHandle, nextCommand, candidates, candidateIndex + 1)
      deactivate Launcher
    else no retry
      Binder->>Main: appendLog(spawn error without retry)
    end
  end
Loading

File-Level Changes

Change Details Files
Expose Hyperliquid execution frontier state in the desktop research UI.
  • Add hyperliquidSurfacePath to the renderer CONFIG and include it in the snapshot refresh pipeline.
  • Extend snapshot state with hyperliquidSurface and derive a consolidated frontier snapshot combining paper, broker, Hyperliquid, and Stepbit data.
  • Render a new Execution frontier dashboard in the desktop UI using summary cards, detailed cards, and a contextual callout, backed by new DOM elements and helper render functions.
desktop/renderer/app.js
desktop/renderer/index.html
desktop/renderer/styles.css
Improve research UI process startup robustness with retry-on-exit semantics.
  • On non-zero process exit while starting, retry the research UI with the next candidate command before marking the workspace stopped.
  • Tighten spawn error retry condition formatting while preserving behavior for EACCES/EPERM/ENOENT errors.
desktop/main.js
Introduce a standalone Hyperliquid-first marketing landing page.
  • Add a Spanish-language static landing page HTML that explains QuantLab’s workflow, layers, differentiation, and roadmap with a Hyperliquid-first framing.
  • Create a dedicated responsive visual system for the landing page, including layout, typography, cards, and motion-ready components.
  • Implement lightweight client-side interactions for scroll tracking, recording last CTA click, and reveal-on-scroll animations via IntersectionObserver.
landing/index.html
landing/styles.css
landing/app.js
Align docs and README with Hyperliquid as the active execution venue and Kraken as legacy.
  • Update execution-venue strategy, roadmap, and broker safety documents to describe Hyperliquid as the primary active venue, move Bitget/Binance to optional comparison work, and reposition Kraken as historical compatibility.
  • Revise README guidance to emphasize Hyperliquid credentials and supervised Hyperliquid submit as the active evidence path, while marking Kraken commands and adapters as legacy examples.
  • Adjust Hyperliquid boundary review and supervised broker runbook docs to talk about generic broker/venue boundaries and make Hyperliquid the main supervised corridor, with Kraken corridors clearly labeled as legacy.
docs/execution-venue-strategy.md
docs/roadmap.md
docs/broker-safety-boundary.md
docs/hyperliquid-boundary-review.md
docs/supervised-broker-runbook.md
README.md
Update internal agent state to reflect the Hyperliquid-first execution focus.
  • Change Stage D.2 descriptions and focus bullets from Kraken to Hyperliquid, including priorities and current work areas.
  • Clarify that the first dry-run backend is accessed generically via BrokerAdapter and that Kraken-specific work is legacy, with Hyperliquid as the active execution direction.
.agents/current-state.md

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="desktop/main.js" line_range="684-688" />
<code_context>
     if (researchServerProcess !== processHandle) return;
     researchServerProcess = null;
     researchServerOwned = false;
+    const shouldRetry = code !== 0 && workspaceState.status === "starting" && candidateIndex < candidates.length - 1;
+    if (shouldRetry) {
+      const nextCommand = candidates[candidateIndex + 1];
+      appendLog(`[startup-exit] ${pythonCommand} exited (${code ?? "null"}${signal ? `, ${signal}` : ""}). Retrying with ${nextCommand}.`);
+      launchResearchUiProcess(candidates, candidateIndex + 1);
+      return;
+    }
</code_context>
<issue_to_address>
**issue (bug_risk):** Clear the research startup timer before retrying on non-zero exit to avoid stale timeouts interfering with the new process.

In the `exit` handler, the retry branch returns before `clearResearchStartupTimer()` is called, so any existing startup timer from the original launch can still fire during the retry and incorrectly push the workspace into an error state. Clear the startup timer before (or immediately after) starting the retry, and recreate it within `launchResearchUiProcess` as needed so each attempt uses its own timer and there are no leftover timeouts from previous attempts.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

desktop/main.js Outdated
Comment on lines +684 to +688
const shouldRetry = code !== 0 && workspaceState.status === "starting" && candidateIndex < candidates.length - 1;
if (shouldRetry) {
const nextCommand = candidates[candidateIndex + 1];
appendLog(`[startup-exit] ${pythonCommand} exited (${code ?? "null"}${signal ? `, ${signal}` : ""}). Retrying with ${nextCommand}.`);
launchResearchUiProcess(candidates, candidateIndex + 1);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Clear the research startup timer before retrying on non-zero exit to avoid stale timeouts interfering with the new process.

In the exit handler, the retry branch returns before clearResearchStartupTimer() is called, so any existing startup timer from the original launch can still fire during the retry and incorrectly push the workspace into an error state. Clear the startup timer before (or immediately after) starting the retry, and recreate it within launchResearchUiProcess as needed so each attempt uses its own timer and there are no leftover timeouts from previous attempts.

@Whiteks1 Whiteks1 force-pushed the codex/landing-hyperliquid-first branch from 7249533 to 19175d4 Compare April 4, 2026 16:05
@Whiteks1 Whiteks1 merged commit 602c986 into main Apr 4, 2026
2 checks passed
@Whiteks1 Whiteks1 deleted the codex/landing-hyperliquid-first branch April 4, 2026 16:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant