# Expand AIUI Node Capabilities ## Context AIUI currently sees basic app status and file names but can't read files, check Bitcoin/LND details, or view app logs. Expanding these 4 capabilities makes AIUI a truly useful node assistant. --- ## 1. File Reading (frontend-only) [DONE] ### `neode-ui/src/api/filebrowser-client.ts` Add `readFileAsText(path, maxBytes = 102400)` method: - Fetch from existing `/app/filebrowser/api/raw{path}?auth={token}` endpoint - Limit response to 100KB (truncate with note) - Only allow text-like extensions: `.txt`, `.md`, `.json`, `.csv`, `.log`, `.conf`, `.yaml`, `.yml`, `.toml`, `.xml`, `.html`, `.css`, `.js`, `.ts`, `.py`, `.sh` - Return `{ content: string, truncated: boolean, size: number }` ### `neode-ui/src/types/aiui-protocol.ts` Add `'read-file'` and `'tail-logs'` to `AIActionType` union. ### `neode-ui/src/services/contextBroker.ts` Add `read-file` action handler: - Check `files` permission is enabled - Validate path param exists, validate extension - Call `fileBrowserClient.readFileAsText(path)` - Return content in action response ### `AIUI/packages/app/src/composables/useArchy.ts` - Add `readFile(path: string)` helper that calls `archyBridge.requestAction('read-file', { path })` - Update `buildArchyContext()` files section: mention "You can read file contents by requesting the read-file action with a file path." --- ## 2. App Log Viewing (frontend-only) [DONE] ### `neode-ui/src/services/contextBroker.ts` Add `tail-logs` action handler: - Check `apps` permission is enabled - Params: `{ appId: string, lines?: string }` (default 50, max 200) - Call existing `rpcClient.call({ method: 'container-logs', params: { app_id, lines } })` - Return log lines in action response ### `AIUI/packages/app/src/composables/useArchy.ts` - Add `tailLogs(appId: string, lines?: number)` helper - Update `buildArchyContext()` apps section: "You can view recent app logs by requesting the tail-logs action with an appId." --- ## 3. Bitcoin Deep Data (backend + frontend) [DONE] ### `core/archipelago/src/api/rpc/mod.rs` Add routing: `"bitcoin.getinfo" => self.handle_bitcoin_getinfo().await` ### New: `core/archipelago/src/api/rpc/bitcoin.rs` Add `handle_bitcoin_getinfo()`: - Use `reqwest` to POST to `http://127.0.0.1:8332` with Basic Auth `archipelago:archipelago123` - Call `getblockchaininfo` JSON-RPC method - Call `getmempoolinfo` JSON-RPC method - Return sanitized JSON: ```json { "block_height": 800000, "sync_progress": 0.9999, "chain": "main", "difficulty": 72006146, "mempool_size": 45000000, "mempool_tx_count": 12500, "verification_progress": 0.9999 } ``` - Handle connection errors gracefully (Bitcoin Core might be syncing or down) ### `neode-ui/src/services/contextBroker.ts` Enrich `bitcoin` category sanitizer: - Call `rpcClient.call({ method: 'bitcoin.getinfo' })` - Merge with existing container status data - Return block height, sync %, chain, mempool stats ### `AIUI/packages/app/src/composables/useArchy.ts` - Add `bitcoinInfo` ref with block height, sync %, etc. - Update `buildArchyContext()`: "**Bitcoin:** Block 800,000 (99.99% synced), mainnet, mempool: 12,500 txs" --- ## 4. LND Deep Data (backend + frontend) [DONE] ### `core/archipelago/src/api/rpc/mod.rs` Add routing: `"lnd.getinfo" => self.handle_lnd_getinfo().await` ### New: `core/archipelago/src/api/rpc/lnd.rs` Add `handle_lnd_getinfo()`: - Read admin macaroon from `/var/lib/archipelago/lnd/data/chain/bitcoin/mainnet/admin.macaroon` - Use `reqwest` to GET `https://127.0.0.1:8080/v1/getinfo` with `Grpc-Metadata-macaroon` header (hex-encoded) - GET `https://127.0.0.1:8080/v1/balance/channels` for channel balance - GET `https://127.0.0.1:8080/v1/balance/blockchain` for on-chain balance - Accept self-signed cert (`reqwest::Client::builder().danger_accept_invalid_certs(true)`) - Return sanitized JSON: ```json { "alias": "my-node", "num_active_channels": 5, "num_peers": 8, "synced_to_chain": true, "block_height": 800000, "balance_sats": 1500000, "channel_balance_sats": 3000000, "pending_open_balance": 0 } ``` - **Never expose**: private keys, seed, macaroon, node pubkey (optional — could include for identification) - Handle errors: LND might be locked, syncing, or not installed ### `neode-ui/src/services/contextBroker.ts` Enrich `wallet` category: - Call `rpcClient.call({ method: 'lnd.getinfo' })` - Return alias, channels, balances, sync status ### `AIUI/packages/app/src/composables/useArchy.ts` - Add `lndInfo` ref - Update `buildArchyContext()`: "**Lightning:** 5 channels, 3M sats in channels, 1.5M on-chain, synced" --- ## File Summary | File | Change | |------|--------| | `neode-ui/src/api/filebrowser-client.ts` | Add `readFileAsText()` | | `neode-ui/src/types/aiui-protocol.ts` | Add `read-file`, `tail-logs` action types | | `neode-ui/src/services/contextBroker.ts` | Add 2 action handlers + enrich bitcoin/wallet categories | | `neode-ui/src/stores/aiPermissions.ts` | Update category descriptions | | `core/archipelago/src/api/rpc/mod.rs` | Add 2 route entries | | `core/archipelago/src/api/rpc/bitcoin.rs` | New: Bitcoin Core RPC proxy | | `core/archipelago/src/api/rpc/lnd.rs` | New: LND REST proxy | | `AIUI/packages/app/src/composables/useArchy.ts` | Add helpers + enrich buildArchyContext() | ## Verification 1. `cd neode-ui && npm run build` — frontend builds 2. `./scripts/deploy-to-target.sh --live` — deploys + builds Rust backend on server 3. Test in AIUI chat: - "What files do I have?" → sees file list - "Read my config.txt" → gets file content - "How's my Bitcoin node?" → block height, sync %, mempool - "What's my Lightning balance?" → channel count, sats balance - "Why is Mempool not working?" → views recent logs - "Show me the last 50 lines of Bitcoin logs" → log output