From c0e8d4fa0af39a9e862275d416aca987eb603a58 Mon Sep 17 00:00:00 2001 From: bill Date: Tue, 30 Jun 2026 17:31:59 -0600 Subject: [PATCH] Add desktop agent handoff --- handoffs/2026-06-30-desktop-agent-handoff.md | 202 +++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 handoffs/2026-06-30-desktop-agent-handoff.md diff --git a/handoffs/2026-06-30-desktop-agent-handoff.md b/handoffs/2026-06-30-desktop-agent-handoff.md new file mode 100644 index 0000000..9d48d81 --- /dev/null +++ b/handoffs/2026-06-30-desktop-agent-handoff.md @@ -0,0 +1,202 @@ +# 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://:8080/ws/connect?deviceType=PHONE + ``` + +6. Add Wear OS entry after phone works: + + ```text + ws://: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`.