Files
archy/.claude/plans/reflective-meandering-castle.md
2026-03-05 14:00:43 +00:00

5.7 KiB

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:
{
  "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:
{
  "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