archy/loop/plan.md

86 lines
11 KiB
Markdown
Raw Normal View History

# Overnight Plan — AIUI ↔ Archy Full Integration
> **Format**: `- [x]` = pending, `- [x]` = done.
> Make at least 30 attempts on any difficult task before moving on. Loop reads this file.
> **Coordination**: A separate AIUI agent handles AIUI-side changes. This plan covers Archy-side only.
## Phase 1: Expand Protocol & Context Categories
The current protocol only has 5 categories (apps, system, network, wallet, files). We need to add media, search, and local AI categories so AIUI can access the node's full capabilities.
- [x] **T1** — Expand `aiui-protocol.ts` with new context categories. Add to `AIContextCategory` type: `'media'` (local media libraries — films, songs, podcasts from Plex/Jellyfin/Navidrome), `'search'` (SearXNG metasearch on the node), `'ai-local'` (Ollama local LLM info — available models, status), `'notes'` (user notes/documents), `'bitcoin'` (Bitcoin Core chain info — block height, sync status, mempool). Add corresponding request/response types. Keep the existing 5 categories unchanged.
- [x] **T2** — Expand `aiPermissions.ts` with new categories. Add entries to `AI_PERMISSION_CATEGORIES` for each new category with user-friendly descriptions: media ("Local media libraries — film, music, podcast titles and metadata, no file paths"), search ("Web search via your private SearXNG instance"), ai-local ("Local AI models via Ollama — model names and availability"), notes ("Document and note titles — no contents"), bitcoin ("Bitcoin node status — block height, sync progress, mempool stats, no wallet keys"). All default OFF.
- [x] **T3** — Update `Settings.vue` AI Data Access section. Add toggle rows for all new categories with appropriate SVG icons. Follow the existing pattern exactly — icon, label, description, toggle switch. Group them logically: Node Data (apps, system, network, bitcoin), Media & Files (media, files, notes), AI & Search (search, ai-local), Financial (wallet).
- [x] **TEST:P1** — Run `cd neode-ui && npm run type-check && npm run build`. Fix all errors. Deploy: `./scripts/deploy-to-target.sh --live`.
## Phase 2: Wire Real Data into ContextBroker
Currently `wallet` and `files` return placeholders. Wire up real data from stores and RPC for all categories.
- [x] **T4** — Wire `apps` category with full data. Currently returns basic app list. Enhance to include: app version, health status, port/URL for launching, whether app has a web UI. Read from `useAppStore().packages` and `useContainerStore()`. Sanitize: strip internal IPs (replace with relative paths like `/apps/btcpay-server/`), strip env vars, strip volume paths.
- [x] **T5** — Wire `system` category with real metrics. Fetch from `rpcClient.call('server.metrics')` and `rpcClient.call('server.time')`. Return: CPU usage %, RAM used/total, disk used/total, uptime, OS version. Sanitize: strip hostname, kernel version details, internal IPs.
- [x] **T6** — Wire `network` category with real data. Fetch peer count from `rpcClient.call('node-list-peers')`. Return: peer count, Tor status (connected/not, but NOT the .onion address), whether Tailscale is active. Sanitize: strip all IPs, onion addresses, pubkeys.
- [x] **T7** — Wire `bitcoin` category (NEW). Fetch from Bitcoin Core RPC if the bitcoin-core package is installed and running. Check `useAppStore().packages` for bitcoin-core status. If running, call the backend RPC to get: block height, sync progress %, mempool size, network (mainnet/testnet). If not installed/stopped, return `{ available: false, message: 'Bitcoin Core not running' }`. Sanitize: no peer IPs, no wallet data.
- [x] **T8** — Wire `media` category (NEW). This is the content handshake. Check which media apps are installed (Plex, Jellyfin, Navidrome, Nextcloud). For each running media app, query its API through the backend to get library summaries: film count + recent titles, song/album count + recent, podcast count. Return a structured object: `{ libraries: [{ source: 'plex', type: 'film', count: N, recent: [{title, year}] }] }`. If no media apps installed, return `{ available: false, libraries: [], message: 'No media apps installed. Install Plex or Jellyfin from the App Store.' }`. Sanitize: no file paths, no internal URLs.
- [x] **T9** — Wire `files` category with real data. If Nextcloud or the built-in file manager is available, list top-level folders and recent files (name + type + size, no contents). If Cloud storage route exists in the app, pull from that store. Return: `{ folders: [{name, itemCount}], recentFiles: [{name, type, size, modified}] }`. Sanitize: no absolute paths, no file contents.
- [x] **T10** — Wire `search` category (NEW). Check if SearXNG is installed and running. If yes, return `{ available: true, engine: 'searxng', endpoint: '/apps/searxng/' }` so AIUI knows it can proxy web searches through the node. If not, return `{ available: false }`. This tells AIUI whether to use its own search or the node's private search.
- [x] **T11** — Wire `ai-local` category (NEW). Check if Ollama is installed and running. If yes, query for available models (model names, sizes, quantization). Return: `{ available: true, models: [{name, size, quantization}] }`. If not, return `{ available: false }`. This lets AIUI offer local AI as a provider option.
- [x] **T12** — Wire `wallet` category with real data. If LND is installed and running, fetch basic wallet info through backend RPC: confirmed balance (sats), channel count, total inbound/outbound capacity. If not running, return `{ available: false }`. Sanitize: NO private keys, NO seed phrases, NO channel IDs, NO peer pubkeys. Only aggregate numbers.
- [x] **T13** — Wire `notes` category (NEW). Check if any note-taking or document apps are installed (OnlyOffice, or built-in notes if they exist). List document titles and types (PDF, doc, note). No contents. Return: `{ documents: [{title, type, modified}] }`. If no note apps, return `{ available: false }`.
- [x] **TEST:P2** — Run `cd neode-ui && npm run type-check && npm run build`. Fix all errors. Deploy: `./scripts/deploy-to-target.sh --live`. SSH to server and verify the deployed build loads.
## Phase 3: Nginx Proxies & Action Handlers
Critical: AIUI needs nginx proxies for API calls when deployed on the node. Also expand action handling.
- [x] **T14** — Add nginx proxy for AIUI Claude API calls. AIUI's Claude provider hits `/api/claude/v1/messages` which, when served from `/aiui/`, becomes `/aiui/api/claude/v1/messages`. Add an nginx location block in `image-recipe/configs/nginx-archipelago.conf` that proxies `/aiui/api/claude/` to `https://api.anthropic.com/` (pass-through). This lets AIUI make Claude API calls through the node's nginx without CORS issues. The user's API key is sent in the request header by AIUI — nginx just forwards it. Also update the local `nginx-archipelago.conf` on the live server.
- [x] **T15** — Add nginx proxy for AIUI web search. Proxy `/aiui/api/web-search` to the local SearXNG instance if installed (port from SearXNG manifest). If SearXNG isn't running, return 503. This gives AIUI private web search through the node.
- [x] **T16** — Add nginx proxy for AIUI OpenRouter API. Proxy `/aiui/api/openrouter` to `https://openrouter.ai/api/` for users who want to use OpenRouter models. Same pass-through pattern as Claude proxy.
- [x] **T17** — Add `launch-app` action in ContextBroker. When AIUI requests `action:request` with `action: 'launch-app'`, return the app's web UI URL so AIUI can tell the user where to go (or Archy can navigate to it). Validate appId exists and is running.
- [x] **T18** — Add `search-web` action in ContextBroker. When AIUI requests a web search action, proxy it through SearXNG if available. Accept `{ action: 'search-web', params: { query: '...' } }`, call SearXNG API, return results.
- [x] **T19** — Add `install-app` action enhancement. The existing install action is basic. Enhance: validate app exists in marketplace, check if already installed, return progress status. Handle errors gracefully.
- [x] **TEST:P3** — Type-check, build, deploy. Deploy nginx config to live server: `sshpass -p 'EwPDR8q45l0Upx@' scp -o StrictHostKeyChecking=no image-recipe/configs/nginx-archipelago.conf archipelago@192.168.1.228:/etc/nginx/sites-available/archipelago && sshpass -p 'EwPDR8q45l0Upx@' ssh -o StrictHostKeyChecking=no archipelago@192.168.1.228 'sudo nginx -t && sudo systemctl reload nginx'`. Verify proxies work.
## Phase 4: End-to-End Testing
Test the full integration by verifying the postMessage protocol works correctly between Archy and the deployed AIUI iframe.
- [x] **T20** — Create integration test script. Write a test page or script that: loads the Chat view, verifies iframe loads AIUI, sends test context requests for each category, verifies responses come back with correct structure. Can be a simple HTML page at `/test-aiui.html` or a Vue component at `/dashboard/test-aiui`. Log results to console.
- [x] **T21** — Test each context category end-to-end. For each of the 10 categories: enable permission in Settings, open Chat, verify AIUI receives the permission update, trigger a context request, verify data comes back. Document which categories return real data vs. placeholders (depends on what apps are installed on the server).
- [x] **T22** — Test action handlers. Test `navigate`, `open-app`, `launch-app`, `search-web` actions from within the AIUI iframe. Verify Archy responds correctly and performs the action.
- [x] **T23** — Test permission denial. Disable all permissions, open Chat, verify AIUI receives empty permissions list. Verify context requests return `{ permitted: false }`. Verify AIUI handles this gracefully (should show "Enable X access in Settings" messages).
- [x] **TEST:P4** — Final build, deploy, verify all tests pass on live server.
## Phase 5: UX Polish & Deploy
- [x] **T24** — Add loading state to Chat.vue iframe. Show a glass-card loading indicator while AIUI iframe is loading. Listen for the `ready` postMessage from AIUI to know when it's loaded, then hide the loader. Use existing glass styling.
- [x] **T25** — Add connection status indicator. Small pill/dot in the Chat close button area showing whether the ContextBroker has an active connection to AIUI (received `ready` message). Green dot = connected, no dot = loading.
- [x] **T26** — Final deploy and smoke test. Clean build both AIUI and Archy. Deploy both. Hard refresh on 192.168.1.228. Test: login → open chat → 3 panels animate in → close → panels animate out → dashboard returns. Verify all permissions toggles work in Settings. Verify Cmd+3 opens chat, Cmd+1/2 returns to dashboard.
- [x] **TEST:FINAL** — Run `cd neode-ui && npm run type-check && npm run build`. Deploy with `./scripts/deploy-to-target.sh --live`. Also rebuild and deploy AIUI: `cd /Users/dorian/Projects/AIUI && rm -rf .turbo packages/app/.turbo packages/core/.turbo packages/app/dist packages/core/dist && VITE_BASE_PATH=/aiui/ pnpm build` then `sshpass -p 'EwPDR8q45l0Upx@' scp -o StrictHostKeyChecking=no -r /Users/dorian/Projects/AIUI/packages/app/dist/* archipelago@192.168.1.228:/opt/archipelago/aiui/`. Verify at http://192.168.1.228.