203 lines
5.1 KiB
Markdown
203 lines
5.1 KiB
Markdown
# Meatbag Desktop Agent Handoff
|
|
|
|
Date: 2026-06-30
|
|
Project: Meatbag
|
|
Ecosystem: WhetForge
|
|
Repository: http://localhost:3000/bill/meatbag
|
|
Branch: main
|
|
|
|
## Current State
|
|
|
|
Meatbag is a Kotlin/Compose Multiplatform MVP scaffold for a "Human Latency Optimization Tool." The intended flow is:
|
|
|
|
1. CLI agent or script sends an SDUI request to the backend.
|
|
2. Ktor backend evaluates active devices and user attention rules.
|
|
3. Backend pushes a JSON UI payload over WebSocket to the best device.
|
|
4. Human taps a response.
|
|
5. Client posts the response back to the backend.
|
|
6. Backend completes the pending agent callback.
|
|
|
|
The repository has three modules:
|
|
|
|
- `common`: shared kotlinx.serialization models for SDUI primitives, attention tiers, device context, callbacks, and responses.
|
|
- `backend`: stateful Ktor backend with in-memory device registry and routing engine.
|
|
- `client`: Compose Multiplatform stateless renderer and desktop simulator, plus Android/Wear attention hook scaffolding.
|
|
|
|
## Important Commit
|
|
|
|
Initial pushed commit:
|
|
|
|
```text
|
|
8b4cb8e Initialize Meatbag SDUI platform
|
|
```
|
|
|
|
This handoff should be committed after that initial push.
|
|
|
|
## Gitea Notes
|
|
|
|
The actual Gitea is containerized in Colima/Docker:
|
|
|
|
- URL: `http://localhost:3000`
|
|
- Repo: `http://localhost:3000/bill/meatbag`
|
|
- Container name: `gitea`
|
|
- SSH exposed by container: host port `2222` to container port `22`
|
|
|
|
If `localhost:3000` is down, check:
|
|
|
|
```sh
|
|
colima status
|
|
colima start
|
|
docker ps
|
|
```
|
|
|
|
Do not use the old top-level `/Users/blindmouse/gitea_setup.sh` as the source of truth. That was an older non-container setup path.
|
|
|
|
## What Works Conceptually
|
|
|
|
- `common/src/commonMain/kotlin/meatbag/common/UiPrimitive.kt`
|
|
- Strict sealed serializable SDUI model hierarchy:
|
|
- `ApprovalRequest`
|
|
- `ActionList`
|
|
- `TextInput`
|
|
- `Message`
|
|
- Attention schema:
|
|
- `SILENT_HAPTIC`
|
|
- `BACKGROUND_NOTIFICATION`
|
|
- `OVERRIDE_SCREEN`
|
|
- Payload/context types:
|
|
- `WebSocketPayload`
|
|
- `AttentionPolicy`
|
|
- `DeviceContext`
|
|
- `CallbackRequest`
|
|
- `ApprovalResponse`
|
|
|
|
- `backend/src/main/kotlin/meatbag/backend/RoutingEngine.kt`
|
|
- In-memory pending request map.
|
|
- Mock `UserRuleSet`.
|
|
- Watch-first routing for silent haptics.
|
|
- Override-screen fan-out to multiple active devices.
|
|
- Enriched payload context per target device.
|
|
|
|
- `backend/src/main/kotlin/meatbag/backend/Application.kt`
|
|
- `GET /api/status`
|
|
- `POST /api/request`
|
|
- `POST /api/respond`
|
|
- `WS /ws/connect?deviceType=WEAR_OS_WATCH|PHONE|DESKTOP`
|
|
|
|
- `client/src/commonMain/kotlin/meatbag/client/ComponentRegistry.kt`
|
|
- Stateless UDF renderer.
|
|
- No reflection.
|
|
- Typed `ComponentIntent` out, converted to `ApprovalResponse` at the client boundary.
|
|
|
|
- `client/src/desktopMain/kotlin/meatbag/client/Main.kt`
|
|
- Desktop simulator for local payload testing and WebSocket connection testing.
|
|
|
|
## Not Ready Yet
|
|
|
|
The repo is not yet a ready-to-install Android/Wear app for an S23 Ultra or watch.
|
|
|
|
Missing pieces:
|
|
|
|
- Android app packaging:
|
|
- `AndroidManifest.xml`
|
|
- `MainActivity`
|
|
- Compose app bootstrap for `MeatbagClient`
|
|
- internet permission
|
|
- cleartext HTTP allowance for local backend testing
|
|
|
|
- Wear app packaging:
|
|
- Wear entry point
|
|
- manifest
|
|
- real haptic implementation using Android vibrator APIs
|
|
- watch-specific UI constraints
|
|
|
|
- Build verification:
|
|
- Previous environment did not have a Java runtime available, so Gradle tests/builds were not run successfully.
|
|
|
|
## Recommended Next Task
|
|
|
|
Make the Android phone client installable first, then add Wear OS.
|
|
|
|
Suggested sequence:
|
|
|
|
1. Install/confirm JDK 17 on the machine doing the build.
|
|
2. Run:
|
|
|
|
```sh
|
|
./gradlew :common:jvmTest :backend:test :client:compileKotlinDesktop
|
|
```
|
|
|
|
3. Fix any compile issues from the recent scaffold.
|
|
4. Add Android app entry:
|
|
- `client/src/androidMain/AndroidManifest.xml`
|
|
- `client/src/androidMain/kotlin/meatbag/client/MainActivity.kt`
|
|
- Compose root that uses `MeatbagClient`
|
|
- host/IP configuration for the backend
|
|
5. Verify an S23 can connect to:
|
|
|
|
```text
|
|
ws://<computer-lan-ip>:8080/ws/connect?deviceType=PHONE
|
|
```
|
|
|
|
6. Add Wear OS entry after phone works:
|
|
|
|
```text
|
|
ws://<computer-lan-ip>:8080/ws/connect?deviceType=WEAR_OS_WATCH
|
|
```
|
|
|
|
7. Wire `WearAttentionFeedback` to real haptic APIs.
|
|
|
|
## Local Backend Smoke Test Shape
|
|
|
|
Once backend runs on the computer:
|
|
|
|
```sh
|
|
./gradlew :backend:run
|
|
```
|
|
|
|
Connect a client WebSocket:
|
|
|
|
```text
|
|
ws://localhost:8080/ws/connect?deviceType=WEAR_OS_WATCH&deviceId=watch_1
|
|
```
|
|
|
|
Send an approval request:
|
|
|
|
```sh
|
|
curl -X POST 'http://localhost:8080/api/request?urgent=true' \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{
|
|
"type": "ApprovalRequest",
|
|
"id": "req_1",
|
|
"prompt": "Allow agent to continue?",
|
|
"target": "desktop-agent"
|
|
}'
|
|
```
|
|
|
|
Respond:
|
|
|
|
```sh
|
|
curl -X POST 'http://localhost:8080/api/respond' \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{
|
|
"requestId": "req_1",
|
|
"approved": true
|
|
}'
|
|
```
|
|
|
|
## Caution
|
|
|
|
There is a mistakenly downloaded standalone Gitea binary at:
|
|
|
|
```text
|
|
/Users/blindmouse/bin/gitea
|
|
```
|
|
|
|
And old non-container setup files under:
|
|
|
|
```text
|
|
/Users/blindmouse/gitea
|
|
```
|
|
|
|
Those are not the active Gitea. The active Gitea is the Docker container named `gitea`.
|