release: bump version to 0.51.0

This commit is contained in:
rayd1o
2026-05-11 09:49:08 +08:00
parent 455b8360d0
commit 1cb51b1172
52 changed files with 4440 additions and 279 deletions

View File

@@ -98,6 +98,18 @@ Gesture recognition may run locally in the browser or inside the local Agent, bu
[motion-debug-panel.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/motion-debug-panel.js) owns the debug panel. It listens for `earth:motion-debug-frame` and draws normalized skeleton joints and bones on a canvas. The Browser Camera provider also emits `earth:motion-debug-video-source` with the local `<video>` element so the panel can show a local preview behind the skeleton; `shared.motionDebugSkeletonOnly` switches the panel back to skeleton-only rendering. `Stop Matching Gestures` dispatches `earth:motion-recognition-pause`, which suppresses gesture execution while video and skeleton drawing continue. Unmatched skeletons are red; matched gestures turn green and display the gesture name. Settings are persisted under `shared.motionDebugEnabled`, `shared.motionProvider`, and `shared.motionDebugSkeletonOnly` in `planet.earth.settings.v2`, and both the switch and provider selector reserve `data-gatekeeper-permission="earth.motion_debug"`.
The Browser Camera provider's gesture pipeline lives in `recognizeGesture()` inside [motion-browser-provider.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/motion-browser-provider.js). Detectors are evaluated in this order, first match wins:
1. **`getZoomTrend` (trend zoom)** — derived from the per-frame change in `Math.abs(rightWrist.x - leftWrist.x)`. Both wrists must cross the noise floor (`ZOOM_TREND_MIN_WRIST_DELTA = 0.010`) and stay within `ZOOM_TREND_HEIGHT_TOLERANCE` of each other vertically. Growing span → `zoom_in`, shrinking span → `zoom_out`. Trend has highest priority so mid-motion frames cannot be hijacked by the layer/focus/rotate detectors.
2. **`getZoomHoldPose` (sustained zoom)** — after motion stops, keeps emitting `zoom_in` while the wrists stay at chest level or above with span > `ZOOM_HOLD_SPREAD_FACTOR × shoulderWidth` (default 1.30), and `zoom_out` while elbows sit visibly outward and span < `ZOOM_HOLD_CLOSE_FACTOR × shoulderWidth` (default 0.85).
3. **layer / focus** — left-wrist raise + vertical motion fires `layer_prev/next`; head tilt fires `focus_prev/next`.
4. **`getRightArmPattern` (single-arm rotate)** — only considered when both `!isZoomCandidatePose(...)` and `isLeftArmAtRest(...)` hold. `isLeftArmAtRest` requires the left wrist to hang clearly below the shoulder line (≥ 0.13) and both left elbow and left wrist to stay near the body — any ambiguous left-arm posture (mid-spread, raised, held at chest) blocks single-arm rotate.
Two non-obvious decisions worth preserving:
- **Mirror-safe**: all zoom checks use `Math.abs(rightWrist.x - leftWrist.x)` and never rely on per-side x direction. `getUserMedia` returns the raw camera feed without horizontal flip, so a subject's anatomical left arm appears on the image right. A direction-based detector (e.g. "left wrist moves left, right wrist moves right") inverts on non-mirrored feeds — span-based detection is invariant.
- **Continuous vs. discrete**: `rotate`, `layer`, `focus`, and `confirm` go through `applyPoseLatch`, which emits each gesture once until the pose returns to neutral (one wave = one rotation step). Zoom intentionally bypasses the latch and re-matches every frame; downstream `GESTURE_POLICIES.zoom_in/out.cooldownMs = 120` rate-limits to ~8 emits/sec, so holding a spread pose keeps zooming in until the user changes their pose. Do not reuse the latch for zoom — that semantic difference is the point.
[presentation-controller.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/presentation-controller.js) is the new Presentation layer. In the first stage only Motion uses it: `motion-cruise-adapter.js` uses a persistent presentation that reuses the cruise fixed-card placement and connector, but mouse movement does not auto-hide the card. The connector recalculates source and target anchors every frame so dragged cards, globe rotation, and moving targets stay connected. BGP/News still use the existing `CruiseSequencer` auto-advance path to preserve the old cruise experience.
### 6. Globe and Terrain
@@ -134,6 +146,10 @@ The compute-center layer row has a notification badge for GeoJSON `unresolved` r
Location candidate state in the details card is cached in [info-card.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/info-card.js) by `entityType:entityId`. If the user closes the details card or unresolved queue and reopens the same compute center / BGP collector, previously collected candidates and status text are restored. Header-level `一键采用` prefers cached candidates, avoiding repeated online geocoding or LLM factcheck calls. After a location is saved, that entity's candidate list is cleared to a "refreshing layer" status so stale candidates do not keep misleading the user.
The `预览 / 保存` buttons on each candidate row use a single delegated `click` handler per candidate root (the `[data-collect-cache-key]` block in the details card, or `[data-unresolved-item]` in the unresolved queue), guarded by a `data-candidate-actions-bound` flag so it cannot be double-bound. Direct `pointerup` / `click` listeners on individual buttons and overlapping delegated handlers were removed. Candidate objects are no longer JSON-stringified into an HTML attribute and parsed back; buttons only carry `data-candidate-index`, and the handler resolves the candidate object from a module-level `Map` keyed by cache-key. This removes the entire class of failures caused by HTML entity escaping of `&` / `<` / `"` in candidate fields. Clicking `预览` dispatches `earth:preview-location-candidate`; `main.js`'s `previewLocationCandidate()` calls `showComputeCenterLocationPreview()`, which attaches a hollow breathing-ring sprite pair at the candidate coordinates (visually mirroring the BGP event ring) and focuses the camera on the candidate. Previewing another candidate replaces the ring; saving clears it and `spawnSavedComputeCenterLocation()` immediately spawns the formal compute-center interactable. Note that `main.js` has no module-level `earth` variable — every location-save / preview handler must call `const earth = getEarth();` first, otherwise the event handler throws a `ReferenceError` that the surrounding `.catch` swallows, producing the failure mode where the button "does nothing".
The `earth:compute-center-location-saved` reconciliation pipeline is deliberately silent on background-refresh failures. `spawnComputeCenterAfterLocationSave()` already presents the success toast and locked state; `refreshComputeCentersAfterLocationSave()` only reloads backend data when the scene is ready and no longer emits its own `已保存` toast. `handleComputeCenterLocationSaved()` runs refresh in the background after a successful spawn; only when spawn returns `null` (scene not ready) or throws does refresh take over the success toast. A refresh error is only `console.warn`'d — it must never surface as a `保存失败` message, because the save itself succeeded and the refresh is a follow-up sync.
### AIS Vessel Layer
The vessel layer fetches `/api/v1/visualization/geo/vessels` and renders the aggregated AIS GeoJSON through `createInteractableLayer()`. By default it does not send a `limit` parameter, and `VESSEL_CONFIG.maxRenderedMarkers = 0` means the frontend does not clip the result to 5000 vessels. A positive `options.limit` or positive `maxRenderedMarkers` can still be used as an explicit temporary cap.

View File

@@ -102,7 +102,15 @@ If both localhost checks pass but a phone or another computer cannot connect, st
./planet.sh start --allow-lan
```
Then configure portproxy and firewall from Administrator PowerShell:
The flag must be written as `--allow-lan`. `allowlan` or `--allowlan` is not recognized by the startup script. If Planet is already running and you only need to reopen the frontend on the LAN, restart the frontend explicitly:
```bash
./planet.sh restart -f 3000 --allow-lan
```
If `ss -ltnp` shows the frontend listening on `0.0.0.0:3000`, but `Test-NetConnection <Windows LAN IP> -Port 3000` still fails from Windows PowerShell, the problem is usually Windows-side forwarding or firewall policy rather than Vite or `.zshrc`.
For traditional WSL NAT networking, configure portproxy and firewall from Administrator PowerShell:
```powershell
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=3000 connectaddress=127.0.0.1 connectport=3000
@@ -111,6 +119,20 @@ New-NetFirewallRule -DisplayName "WSL Planet 3000" -Direction Inbound -Action Al
New-NetFirewallRule -DisplayName "WSL Planet 8000" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8000
```
If `wslinfo --networking-mode` prints `mirrored`, also check Hyper-V firewall. Even when ordinary Windows Firewall rules exist, Hyper-V firewall can still block external devices from reaching WSL. From Administrator PowerShell, allow the required ports:
```powershell
New-NetFirewallHyperVRule -Name "Planet-Frontend-3000" -DisplayName "Planet Frontend 3000" -Direction Inbound -VMCreatorId "{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}" -Protocol TCP -LocalPorts 3000 -Action Allow
New-NetFirewallHyperVRule -Name "Planet-Backend-8000" -DisplayName "Planet Backend 8000" -Direction Inbound -VMCreatorId "{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}" -Protocol TCP -LocalPorts 8000 -Action Allow
```
Use these commands to inspect the current Hyper-V firewall state:
```powershell
Get-NetFirewallHyperVVMSetting -Name "{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}"
Get-NetFirewallHyperVRule -VMCreatorId "{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}"
```
LAN devices should open the Windows LAN IP, for example `http://<Windows LAN IP>:3000/earth`, not the internal WSL IP.
### How do `--allow-lan` and the Motion Agent LAN URL fit together?

View File

@@ -32,7 +32,7 @@ Current admin-related routes:
- `/alerts/bgp`
- `/alerts/situational`
- `/bgp`
- `/playground`
- `/ai`
- `/settings`
`/earth` is a standalone display page and is not part of the console shell.
@@ -196,7 +196,24 @@ Responsibilities:
`App.tsx` uses it to decide whether to redirect to the login page. `/docs` remains a public route, but the backend decides the visible catalog and content from the token; anonymous visitors only receive public docs.
### 2. Business Data Gateway
### 2. AI
File:
- [AISettings.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/AISettings/AISettings.tsx)
Responsibilities:
- `/ai` now owns LLM Provider, AI Tool configuration, and the testbench instead of nesting them under `/settings`
- The `模型供应商` tab manages default provider, model, base URL, provider key, local `aiprovider` proxy, and connection test
- The `工具` tab manages WebSearch provider, search key, base URL, timeout, result count, and advanced provider options
- The `测试台` tab embeds the former Playground real session, preset prompts, and AI Provider status debugging
- The page reuses the Settings single-screen tabs, panel card, and internal scrolling style
Legacy `/settings?tab=ai` should redirect to `/ai?tab=providers`.
Legacy `/playground` should redirect to `/ai?tab=playground`.
### 3. Business Data Gateway
AI / situational awareness related services are currently in:

View File

@@ -19,7 +19,7 @@ After a default startup, the common URLs are:
| Docs | `http://localhost:3000/docs` | Partly | Usage docs are public; developer, backend, and operations docs require Gatekeeper groups |
| FAQ | `http://localhost:3000/docs/faq` | No | Windows / WSL, ports, dependencies, motion capture, credentials, and permission troubleshooting |
| Console | `http://localhost:3000/admin` | Yes | Data, config, alerts, logs, and situational observation |
| AI Playground | `http://localhost:3000/playground` | Yes | AI Provider status and debugging |
| AI | `http://localhost:3000/ai` | Yes | Model providers, AI tools, and testbench |
| Backend API Docs | `http://localhost:8000/docs` | Depends on endpoint | FastAPI / OpenAPI documentation |
## planet.sh
@@ -427,7 +427,7 @@ Common pages:
| System Alerts | `/alerts/system` | System-level alerts |
| BGP Alerts | `/alerts/bgp` | BGP-related alerts |
| Situational Alerts | `/alerts/situational` | Situational assessment alerts |
| AI Playground | `/playground` | AI Provider debugging |
| AI | `/ai` | Model providers, WebSearch-style tools, and testbench |
| System Logs | `/logs` | View system logs (typically super admin only) |
| Users | `/users` | User management |
| Settings | `/settings` | System config and TV live stream sources |
@@ -487,7 +487,18 @@ Current common uses:
- System settings
- TV live stream source configuration
- Collector settings
- External integrations and AI Provider configuration
### AI
`/ai` manages the AI runtime chain and is now separate from system settings. Legacy `/playground` redirects to `/ai?tab=playground`.
It currently contains:
- `模型供应商`: default LLM provider, model, base URL, API key, local `aiprovider` proxy, and connection test
- `工具`: WebSearch provider, search API key, base URL, max results, timeout, and advanced provider options
- `测试台`: AI Provider status, preset prompts, and real analysis-chain debugging
Legacy `/settings?tab=ai` redirects to `/ai?tab=providers`.
Available configuration depends on the current user's role.

View File

@@ -57,7 +57,7 @@ After startup, the key URLs are:
| Earth | `http://localhost:3000/earth` | Public 3D Earth visualization |
| Console | `http://localhost:3000/admin` | Admin console (login required) |
| Docs | `http://localhost:3000/docs` | Usage docs are public; developer and operations docs require Gatekeeper groups |
| AI Playground | `http://localhost:3000/playground` | AI debugging (login required) |
| AI | `http://localhost:3000/ai` | Model provider, tool, and testbench entry (login required) |
| Backend API Docs | `http://localhost:8000/docs` | FastAPI / OpenAPI interface docs |
If the default ports are taken, specify custom ports:
@@ -114,6 +114,7 @@ First-time inspection checklist:
- `/datasources`: data source directory and collection triggers; endpoint, headers, and credentials are configured under `/settings` collector settings
- `/data`: collected data
- `/bgp`: BGP situational view
- `/ai`: AI page for model providers, WebSearch-style tools, and the testbench
- `/alerts/system`: system alerts
- `/settings`: system configuration