feat: complete AIUI integration — all 31 overnight tasks

- Protocol: 10 context categories (apps, system, network, bitcoin, media, files, notes, search, ai-local, wallet)
- ContextBroker: real data wiring for all categories with sanitization
- Permissions: user toggles for all categories in Settings
- Nginx: Claude API, OpenRouter, SearXNG proxy pass-through
- Actions: launch-app, search-web, install-app handlers
- Chat.vue: loading state + connection indicator
- Integration test page: test-aiui.html

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-04 14:34:02 +00:00
co-authored by Claude Opus 4.6
parent 81473db38b
commit 7b56927c3c
26 changed files with 1253 additions and 142 deletions
+49
View File
@@ -0,0 +1,49 @@
---
name: add-app
description: Step-by-step guide for adding a new containerized app to Archipelago
disable-model-invocation: true
allowed-tools: Bash, Read, Write, Edit, Glob, Grep
argument-hint: "[app-name]"
---
Add a new containerized app ($ARGUMENTS) to Archipelago.
## Steps
### 1. Create the manifest
Create `apps/{app-id}/manifest.yml` following the spec in `docs/app-manifest-spec.md`:
- `app.id` (kebab-case), `app.name`, `app.version` (SemVer)
- `container.image` (pinned version, **NEVER** `latest`)
- `security`: readonly_root, dropped capabilities, non-root UID > 1000
- `health_check`, `dependencies`
### 2. Add app icon
Place icon at `neode-ui/public/assets/img/app-icons/{app-id}.{png|webp|svg}`
### 3. Create status UI (if no native web UI)
For apps without their own web interface, create a UI container in `docker/{app-id}-ui/` following the patterns in `.cursor/rules/APP-UI-STANDARDS.md`.
Reference implementations:
- Bitcoin UI: `docker/bitcoin-ui/`
- LND UI: `docker/lnd-ui/`
### 4. Update backend
- Add port mapping in `core/archipelago/src/container/docker_packages.rs`
- Add env vars in `get_app_config()` in `core/archipelago/src/api/rpc.rs`
### 5. Deploy and test
- Deploy: `./scripts/deploy-to-target.sh --live`
- Install from marketplace UI at http://192.168.1.228
- Verify it launches and auto-connects to dependencies
- Check logs: `sudo podman logs {container-name}`
### 6. Security review
- Verify readonly root, dropped caps, non-root user
- Check network isolation
- No hardcoded secrets
+28
View File
@@ -0,0 +1,28 @@
---
name: build-iso
description: Build a new Archipelago auto-installer ISO image
disable-model-invocation: true
allowed-tools: Bash, Read
---
Build a new Archipelago auto-installer ISO.
## Pre-build checklist
1. Latest code deployed to server (`/deploy` first)
2. System configs synced (`/sync-configs` first)
3. Everything tested and working on live server
## Build (on target server — recommended)
```bash
sshpass -p 'EwPDR8q45l0Upx@' ssh -o StrictHostKeyChecking=no archipelago@192.168.1.228 'cd ~/archy/image-recipe && sudo ./build-auto-installer-iso.sh'
```
## Copy ISO back to Mac
```bash
sshpass -p 'EwPDR8q45l0Upx@' scp -o StrictHostKeyChecking=no archipelago@192.168.1.228:~/archy/image-recipe/results/archipelago-auto-installer-*.iso .
```
**IMPORTANT**: Use `build-auto-installer-iso.sh` only. The deprecated `build-debian-iso.sh` causes boot-to-prompt issues.
+14
View File
@@ -0,0 +1,14 @@
---
name: check-server
description: Quick health check of the live Archipelago server
allowed-tools: Bash
---
Quick health check of the live server. SSH into `archipelago@192.168.1.228` (password: `EwPDR8q45l0Upx@`) and run:
1. `systemctl is-active archipelago nginx` — are services running?
2. `sudo podman ps --format '{{.Names}} {{.Status}}'` — what containers are up?
3. `curl -s http://127.0.0.1:5678/health` — is the backend responding?
4. `sudo journalctl -u archipelago -n 10 --no-pager` — any recent errors?
Report a brief one-paragraph status summary.
+23
View File
@@ -0,0 +1,23 @@
---
name: deploy-both
description: Deploy all changes to both Archipelago servers
disable-model-invocation: true
allowed-tools: Bash, Read
---
Deploy all changes to BOTH servers (primary: 192.168.1.228, secondary: 192.168.1.198).
## Steps
1. Run:
```bash
./scripts/deploy-to-target.sh --both
```
2. This builds on the primary server first, then copies built artifacts to the secondary.
3. Verify both servers respond:
```bash
sshpass -p 'EwPDR8q45l0Upx@' ssh -o StrictHostKeyChecking=no archipelago@192.168.1.228 'systemctl is-active archipelago'
sshpass -p 'EwPDR8q45l0Upx@' ssh -o StrictHostKeyChecking=no archipelago@192.168.1.198 'systemctl is-active archipelago'
```
+24
View File
@@ -0,0 +1,24 @@
---
name: deploy
description: Deploy all changes to the live Archipelago server
disable-model-invocation: true
allowed-tools: Bash, Read
---
Deploy all changes to the live server (192.168.1.228).
## Steps
1. Run the deploy script from the project root:
```bash
./scripts/deploy-to-target.sh --live
```
2. This syncs frontend and backend code, builds the Rust backend **on the server** (never locally on macOS), deploys frontend to `/opt/archipelago/web-ui/`, deploys backend binary to `/usr/local/bin/archipelago`, and restarts systemd + nginx.
3. After deploy completes, verify the server is healthy:
```bash
sshpass -p 'EwPDR8q45l0Upx@' ssh -o StrictHostKeyChecking=no archipelago@192.168.1.228 'systemctl is-active archipelago nginx && sudo journalctl -u archipelago -n 10 --no-pager'
```
4. Report whether the deploy succeeded and if any errors appeared in the logs.
+21
View File
@@ -0,0 +1,21 @@
---
name: diagnose
description: Run a full diagnostic check on the Archipelago dev server
allowed-tools: Bash
---
SSH into the dev server and run a comprehensive diagnostic. Use `sshpass -p 'EwPDR8q45l0Upx@' ssh -o StrictHostKeyChecking=no archipelago@192.168.1.228` for all commands.
## Checks to run
1. **Services**: `systemctl is-active archipelago nginx`
2. **Backend status**: `sudo systemctl status archipelago --no-pager`
3. **Containers**: `sudo podman ps -a`
4. **Backend logs** (last 50): `sudo journalctl -u archipelago -n 50 --no-pager`
5. **Nginx errors**: `sudo tail -20 /var/log/nginx/error.log`
6. **RPC test**: `curl -s -X POST http://127.0.0.1:5678/rpc/v1 -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1,"method":"echo","params":{}}'`
7. **Tor hostname**: `sudo cat /var/lib/archipelago/tor/hidden_service_archipelago/hostname`
8. **Disk space**: `df -h /`
9. **Memory**: `free -h`
Report findings clearly and suggest fixes for any issues found. If $ARGUMENTS is provided, focus the diagnosis on that specific area.
+20
View File
@@ -0,0 +1,20 @@
---
name: frontend-dev
description: Start the local frontend development environment for Archipelago
disable-model-invocation: true
allowed-tools: Bash
---
Start the local frontend development environment.
```bash
cd neode-ui && npm start
```
This starts:
- **Mock backend** on port 5959 (simulates the Rust backend API)
- **Vite dev server** on port 8100
Access at http://localhost:8100 (password: `password123`)
The mock backend lets you develop the UI without needing the live server.
+49
View File
@@ -0,0 +1,49 @@
---
name: harden
description: Security hardening review and fixes for Archipelago code and infrastructure
disable-model-invocation: true
allowed-tools: Read, Edit, Write, Glob, Grep, Bash
argument-hint: "[area: backend|frontend|containers|scripts|all]"
---
Perform a security hardening pass on $ARGUMENTS (default: all).
## Backend Hardening (Rust)
- [ ] No hardcoded credentials — check for Base64-encoded auth strings, passwords in source
- [ ] Secrets use `core/security/secrets_manager.rs` — verify encryption is implemented (not plaintext)
- [ ] All RPC endpoints validate inputs before processing
- [ ] No `unwrap()` on user-supplied data — handle errors gracefully
- [ ] Rate limiting on auth endpoints (login, password change)
- [ ] Session tokens have proper expiry and rotation
- [ ] File permissions: keys at 0o600, dirs at 0o700
- [ ] Tracing never logs secrets, passwords, keys, or tokens
## Frontend Hardening (Vue/TypeScript)
- [ ] No secrets in source (API keys, passwords, tokens)
- [ ] No `eval()` or `innerHTML` with untrusted content
- [ ] XSS prevention — sanitize all user inputs
- [ ] CSRF protection on state-changing requests
- [ ] Credentials use `credentials: 'include'` not localStorage tokens
- [ ] No sensitive data in console.log statements
## Container Hardening
- [ ] All manifests: `readonly_root: true` (unless documented exception)
- [ ] All manifests: capabilities dropped, only required ones added
- [ ] All manifests: non-root user (UID > 1000)
- [ ] All manifests: `no-new-privileges: true`
- [ ] All images pinned to specific versions (no `:latest`)
- [ ] Network isolation — no `host` network unless required and documented
- [ ] AppArmor profiles defined and enforced
## Script Hardening
- [ ] All scripts use `set -euo pipefail`
- [ ] No hardcoded passwords (use deploy-config.sh or env vars)
- [ ] SSH uses proper key-based auth where possible
- [ ] No `chmod 777` or overly permissive permissions
- [ ] Temp files use `mktemp` not predictable paths
Report all findings with file paths and line numbers. Fix issues directly where safe to do so. Flag anything that needs discussion.
+52
View File
@@ -0,0 +1,52 @@
---
name: lint
description: Run all linters and type checks for the Archipelago project
allowed-tools: Bash, Read, Grep
argument-hint: "[backend|frontend|all]"
---
Run linters and type-checks for $ARGUMENTS (default: all).
## Frontend Linting
```bash
cd neode-ui
# Type check
npm run type-check 2>&1
# Check for any `any` types (should be zero)
grep -rn ': any' src/ --include='*.ts' --include='*.vue' | grep -v node_modules | grep -v '.d.ts'
# Check for inline Tailwind violations (long class strings)
grep -rn 'class="[^"]\{100,\}"' src/ --include='*.vue'
# Check for TODO/FIXME
grep -rn 'TODO\|FIXME' src/ --include='*.ts' --include='*.vue'
# Check for console.log (should be cleaned before production)
grep -rn 'console\.\(log\|warn\|error\)' src/ --include='*.ts' --include='*.vue' | wc -l
```
## Backend Linting (on dev server)
```bash
sshpass -p 'EwPDR8q45l0Upx@' ssh -o StrictHostKeyChecking=no archipelago@192.168.1.228 \
'source ~/.cargo/env && cd ~/archy/core && cargo clippy --all-targets --all-features 2>&1 && cargo fmt --all -- --check 2>&1'
```
## Script Linting
```bash
# Check for scripts missing set -e
for f in scripts/*.sh; do
if ! head -5 "$f" | grep -q 'set -e'; then
echo "MISSING set -e: $f"
fi
done
# Check for hardcoded IPs (should use variables)
grep -rn '192\.168\.1\.' scripts/ --include='*.sh' | grep -v deploy-config
```
Report all issues found with severity (critical/warning/info).
+41
View File
@@ -0,0 +1,41 @@
---
name: refactor
description: Refactor code for quality, maintainability, and adherence to project standards
disable-model-invocation: true
allowed-tools: Read, Edit, Write, Glob, Grep, Bash
argument-hint: "[file-or-area]"
---
Refactor the specified code ($ARGUMENTS) following Archipelago coding standards.
## Checklist
### Rust Backend
- [ ] No `unwrap()` or `expect()` — use `?` operator with context
- [ ] Replace `#[allow(dead_code)]` — either use it or remove it
- [ ] Functions under 50 lines, single responsibility
- [ ] Custom error types per module with `thiserror`
- [ ] `tracing` for logging — no `println!` or secrets in logs
- [ ] Split files over 500 lines into focused modules
- [ ] Run `cargo clippy --all-targets --all-features` mentally and fix issues
### Vue Frontend
- [ ] Extract ALL inline Tailwind to global classes in `neode-ui/src/style.css`
- [ ] Use semantic class names: `.glass-card`, `.info-card`, `.glass-button`, `.path-option-card`
- [ ] Replace ALL `.gradient-button` with `.glass-button` (gradient buttons are BANNED)
- [ ] Replace ALL `.gradient-card` / `.gradient-card-dark` with `.glass-card` or `.path-option-card`
- [ ] Settings.vue is the gold standard — all screens should match its patterns
- [ ] Replace `any` types with proper interfaces or `unknown`
- [ ] Ensure `<script setup lang="ts">` on all components
- [ ] Remove dead code (unused imports, components like HelloWorld.vue)
- [ ] Remove all `TODO`/`FIXME` — fix now or create GitHub issues
- [ ] Consolidate `console.log` calls to use a logging utility
- [ ] Split views over 800 LOC into sub-components
### General
- [ ] No hardcoded paths (`/Users/dorian/...`)
- [ ] No hardcoded credentials — use env vars or secrets manager
- [ ] Comment WHY not WHAT
- [ ] Remove commented-out code entirely
After refactoring, verify the code still compiles/type-checks. For frontend: `cd neode-ui && npm run type-check`. Do NOT deploy — leave that to `/deploy`.
+19
View File
@@ -0,0 +1,19 @@
---
name: server-logs
description: View live server logs from the Archipelago dev server
allowed-tools: Bash
argument-hint: "[backend|nginx|container-name]"
---
View logs from the Archipelago server (192.168.1.228). Use `sshpass -p 'EwPDR8q45l0Upx@' ssh -o StrictHostKeyChecking=no archipelago@192.168.1.228` for all commands.
If $ARGUMENTS is provided, show logs for that specific service. Otherwise, show backend logs by default.
## Log sources
- **backend** (default): `sudo journalctl -u archipelago -n 50 --no-pager`
- **nginx**: `sudo tail -50 /var/log/nginx/error.log`
- **nginx-access**: `sudo tail -50 /var/log/nginx/access.log`
- **Any container name**: `sudo podman logs --tail 50 $ARGUMENTS`
Show the last 50 lines. If the user needs live streaming, use `-f` flag instead of `--tail`/`-n`.
+24
View File
@@ -0,0 +1,24 @@
---
name: sync-configs
description: Sync system configs from live server to repo for ISO builds
disable-model-invocation: true
allowed-tools: Bash, Read
---
Sync system configuration files from the live server back to the repo for ISO builds.
## Steps
1. **Capture systemd service**:
```bash
sshpass -p 'EwPDR8q45l0Upx@' ssh -o StrictHostKeyChecking=no archipelago@192.168.1.228 'sudo cat /etc/systemd/system/archipelago.service' > image-recipe/configs/archipelago.service
```
2. **Capture nginx config**:
```bash
sshpass -p 'EwPDR8q45l0Upx@' ssh -o StrictHostKeyChecking=no archipelago@192.168.1.228 'sudo cat /etc/nginx/sites-available/archipelago' > image-recipe/configs/nginx-archipelago.conf
```
3. **Capture any custom scripts** in `/opt/archipelago/scripts/` if they've changed.
4. After syncing, read the captured files and verify they look correct. These configs are used by the ISO build to create new installations.
+59
View File
@@ -0,0 +1,59 @@
---
name: test
description: Run tests or create test coverage for Archipelago
disable-model-invocation: true
allowed-tools: Read, Edit, Write, Glob, Grep, Bash
argument-hint: "[area: backend|frontend|all] or [specific-file]"
---
Run or create tests for $ARGUMENTS.
## Backend Testing (Rust)
### Run existing tests
```bash
# On dev server (never build Rust on macOS)
sshpass -p 'EwPDR8q45l0Upx@' ssh -o StrictHostKeyChecking=no archipelago@192.168.1.228 \
'source ~/.cargo/env && cd ~/archy/core && cargo test --all-features 2>&1'
```
### Creating new tests
- Place unit tests in the same file with `#[cfg(test)]` module
- Place integration tests in `core/{crate}/tests/`
- Use `#[tokio::test]` for async tests
- Mock external dependencies (filesystem, network, Podman)
- Test error cases, not just happy paths
- Aim for >80% coverage on core logic
### Priority areas needing tests
1. RPC endpoint handlers (core/archipelago/src/api/)
2. Manifest parsing (core/container/src/manifest.rs)
3. Dependency resolver (core/container/src/dependency_resolver.rs)
4. Auth flows (core/archipelago/src/auth.rs)
5. Secrets manager (core/security/src/secrets_manager.rs)
6. Port allocation (core/container/src/port_manager.rs)
## Frontend Testing (Vue/TypeScript)
### Setup (if not already configured)
Ensure vitest is configured in `neode-ui/`:
```bash
cd neode-ui && npm run test 2>&1 || echo "No test script configured"
```
### Creating new tests
- Use Vitest + @vue/test-utils
- Place tests in `neode-ui/src/__tests__/` or co-located `*.test.ts`
- Test stores (Pinia) with `createTestingPinia()`
- Test API clients with mocked fetch
- Test component rendering and interactions
- Test routing guards
### Priority areas needing tests
1. Pinia stores (app.ts, container.ts, appLauncher.ts)
2. RPC client (api/rpc-client.ts) — error handling, retry logic
3. WebSocket client (api/websocket.ts) — reconnection
4. Router guards — auth flow, session timeout
5. Key components — ContainerStatus, SpotlightSearch
Report test results and any new tests created.
+90
View File
@@ -0,0 +1,90 @@
---
name: ux-review
description: Review UI components against Archipelago glassmorphism design standards and UX conventions
disable-model-invocation: true
allowed-tools: Read, Glob, Grep, Edit, Write
argument-hint: "[component-or-view-name]"
---
Review the UI of $ARGUMENTS against Archipelago's glassmorphism design system and UX standards.
## Design System Compliance
### Glass Classes (must use global classes from style.css)
- [ ] Section containers use `.path-option-card cursor-default px-6 py-6` (Settings-style sections)
- [ ] Content containers/modals use `.glass-card`
- [ ] Interactive selectable cards use `.path-option-card` (with hover)
- [ ] Status displays use `.info-card` (no hover effects)
- [ ] ALL buttons use `.glass-button` — NEVER `.gradient-button` (BANNED)
- [ ] Large primary actions use `.path-action-button`
- [ ] Info sub-cards use `bg-black/20 rounded-xl border border-white/10`
- [ ] Info rows use `bg-white/5 rounded-lg` pattern
- [ ] Action buttons in info sections use `.info-card-button`
### BANNED — Flag These as Violations
- [ ] No `.gradient-button` anywhere (replace with `.glass-button`)
- [ ] No `.gradient-card` / `.gradient-card-dark` (replace with `.glass-card` or `.path-option-card`)
### NO Inline Tailwind
- [ ] Check for long `class="..."` strings with layout/color utilities
- [ ] Extract to semantic classes in `neode-ui/src/style.css`
- [ ] Name classes semantically: `.app-card`, `.status-badge`, `.nav-item`
### Color Compliance
- [ ] Primary text: `text-white/90` (not `text-white` or arbitrary opacity)
- [ ] Muted text: `text-white/60` to `text-white/70`
- [ ] Backgrounds: `rgba(0,0,0,0.60)` with `backdrop-filter: blur(24px)`
- [ ] Borders: `rgba(255,255,255,0.18)` standard
- [ ] Status colors: green=#4ade80, red=#ef4444, yellow=#facc15, blue=#3b82f6, orange=#fb923c
### Typography
- [ ] Font: Avenir Next (body), Montserrat (headings via `font-archipelago`)
- [ ] H1: text-3xl font-bold, H2: text-2xl font-semibold, H3: text-xl font-semibold
- [ ] Body: text-base, Small: text-sm, Labels: text-xs
### Interaction States
- [ ] Hover: `translateY(-2px)` lift + background brighten + enhanced shadow
- [ ] Active: `translateY(1px)` press
- [ ] Selected: brighter background + glow shadow + enhanced gradient border
- [ ] Disabled: reduced opacity (~50%), no pointer events
- [ ] Loading: spinner SVG + descriptive text, button disabled
- [ ] Focus-visible: soft blue glow `rgba(120, 180, 255, 0.2)`
### Transitions
- [ ] Standard: `all 0.3s ease`
- [ ] All interactive elements have transitions (no jarring state changes)
- [ ] Respect `prefers-reduced-motion`
### Spacing
- [ ] 4px grid system (p-1=4px, p-2=8px, p-3=12px, p-4=16px)
- [ ] 16px default padding on cards
- [ ] Consistent gap values between grid items
### Responsive
- [ ] Mobile: single column, reduced padding, touch targets >= 44x44px
- [ ] Tablet (md:): two columns
- [ ] Desktop (lg:): three columns, full effects
### Accessibility
- [ ] Semantic HTML (`<button>`, `<nav>`, `<main>`, not div soup)
- [ ] ARIA labels on icon-only buttons
- [ ] Keyboard navigable (Tab order, Enter to activate, Esc to close)
- [ ] Color contrast WCAG AA (4.5:1 normal text, 3:1 large)
- [ ] Images have alt text (decorative: `alt=""`)
### Icons
- [ ] Stroke-based SVGs, stroke-width 2.5 default
- [ ] Color: `text-white/85` default, `text-white` on hover
- [ ] Drop-shadow filter applied on interactive icons
- [ ] Size: w-5 h-5 standard, w-4 h-4 small
## Service UI Review (if reviewing docker/*-ui/)
- [ ] Uses `.glass-card` for main sections
- [ ] Uses `.info-card` for status (no hover)
- [ ] Uses `.info-card-button` for actions (with hover)
- [ ] Uses `bg-white/5` for info rows
- [ ] Header: logo + title + description + status
- [ ] Background image loads correctly
- [ ] Mobile responsive
Report violations with file paths and specific fixes.