Skip to content

[P1][macos-openworlds] WKWebView can blank the app when OpenWorlds loads without trailing slash #131

Description

@100yenadmin

Summary

The macOS WKWebView can show a blank OpenWorlds surface when Swift navigates to
/openworlds without a trailing slash. The OpenWorlds bundle uses relative asset
URLs like styles.css, app.jsx, and vendor/react-18.3.1.development.js.
When the browser treats /openworlds as a file path, those assets resolve from
/ instead of /openworlds/.

Release Impact

This makes the new native app look broken even though the same URL may appear to
work when manually corrected in Safari. It directly blocks the OpenWorlds-as-app
rollout because the main window can render blank while Safari renders the design.

Architecture Invariant Violated

OpenWorlds must be the normal in-app play surface. The native app must not rely on
manual Safari correction or a user knowing to add a slash.

Evidence

Relevant code paths:

  • macos/ClawDnDApp/Sources/ClawDnDApp/Models/LocalEndpoint.swift
  • viewer/server.py
  • viewer/tests/test_openworlds_static.py

Current behavior to guard:

Swift URL: http://127.0.0.1:<port>/openworlds
Expected canonical URL: http://127.0.0.1:<port>/openworlds/

Repro

  1. Launch the app.
  2. Navigate the embedded WKWebView to /openworlds.
  3. Observe a blank surface or missing styling/scripts.
  4. Manually open /openworlds/ and observe the designed UI.

Suspected Root Cause

LocalEndpoint.openWorldsURL appends openworlds without preserving directory
semantics, and the viewer did not canonicalize /openworlds to /openworlds/.

Fix Options

Minimal patch:

  • Make Swift construct /openworlds/.
  • Redirect /openworlds to /openworlds/ in viewer/server.py.
  • Add a route regression.

Broader hardening:

  • Add endpoint readiness and canonical-route tests for every app surface.
  • Make the app wait for /openworlds/ before navigation.

Recommended Solution

Take the minimal patch now, then include readiness waiting in the OpenWorlds host
PR.

Acceptance Criteria

  • GET /openworlds returns 301 or 302 to /openworlds/.
  • LocalEndpoint.openWorldsURL includes the trailing slash.
  • WKWebView loads OpenWorlds assets correctly.

Focused Validation

python3 -m unittest viewer.tests.test_openworlds_static -q
python3 -m py_compile viewer/server.py
swift build --package-path macos/ClawDnDApp
git diff --check

Original-Agent Handoff

Inspect first:

  • LocalEndpoint.openWorldsURL
  • _Handler.do_GET OpenWorlds route handling in viewer/server.py
  • OpenWorldsStaticRouteTests

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtier-1Tier 1: Claude Code plugin

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions