archy/.claude/plans/reflective-meandering-castle.md
Dorian dfb81c0348 chore: mark AIUI node capabilities plan fully complete (Task 4 — LND deep data)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 14:00:43 +00:00

146 lines
5.7 KiB
Markdown

# 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