* fix(issue-5): add collision-aware pathfinding to Phaser office viewer
Agents in the Phaser office viewer previously moved in straight lines toward
zone anchors, ignoring walls, furniture, and collision geometry. This made
agents walk through rendered map obstacles.
Changes:
src/lib/office/pathfinding.ts (new):
- Shared 2D A* pathfinding module for OfficeMap surfaces
- Builds a nav grid from map objects (walls/furniture layers) and
collision polygons with configurable cell size and padding
- Diagonal corner-cutting prevention (checks both orthogonal neighbors)
- Returns empty path on failure instead of raw destination fallback
- Point-in-polygon rasterisation for collision polygon support
- Intentionally placed in src/lib/office/ for reuse across office stacks
src/features/office/phaser/systems/AgentEffectsSystem.ts:
- Computes A* waypoint paths when agent targets change
- Follows waypoints sequentially instead of linear interpolation
- Caches nav grid and invalidates on map identity change
- Agents stay put when no valid path exists (no wall clipping)
tests/unit/officePathfinding.test.ts (new):
- 12 unit tests covering grid construction, A* routing, corner-cutting
prevention, collision polygon support, blocked-start recovery, and
starter map integration
Fixes#5
* fix(test): remove unused NavGrid2D type import
---------
Co-authored-by: Neo <neo@openclaw.ai>
* Fix WS auth: wire accessGate.allowUpgrade via verifyClient
The allowWs callback was never actually calling accessGate.allowUpgrade
during the WS handshake - the ws library passes (info) not (req), and
verifyClient must be set on the WebSocketServer constructor options.
Fix: pass verifyClient to WebSocketServer constructor and wrap
allowUpgrade to extract info.req.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix TypeScript error and add gym release directive support
Add "release" value to OfficeGymDirective type for symmetry with
OfficeQaDirective ("qa_lab" | "release"). Previously OfficeGymDirective
was only "gym" with no release state, making the "!== 'release'"
check in eventTriggers.ts dead code that TypeScript flagged as an
unintentional comparison.
Changes:
- deskDirectives.ts: add "release" to OfficeGymDirective type
- deskDirectives.ts: add gym release patterns to skill and command
directive resolvers (e.g. "leave the gym", "done with skills")
- eventTriggers.ts: change !== "release" to === "gym" for clarity
and consistency with reduceOfficeGymHoldState pattern
This fixes: https://github.com/iamlukethedev/Claw3D/issues/15
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>