Skip to content

Commit 20d733e

Browse files
hyperpolymathclaude
andcommitted
feat: add .claude/CLAUDE.md, reconcile desktop entry and install script
- Create .claude/CLAUDE.md with build commands, architecture, conventions, file locations, and current project state - Fix game-server-admin.desktop: - Exec now references game-server-admin-launcher (not gsa-launcher) - Add System category - Add stop desktop action - Add gossamer/verisimdb keywords - Rewrite scripts/install-desktop.sh: - APP_NAME now matches desktop filename (game-server-admin) - Port corrected to 8090 (VeriSimDB, not 8080) - Launcher uses Gossamer webview + libgsa.so (not deno task dev) - Launcher checks VeriSimDB health, builds FFI if needed - Proper LD_LIBRARY_PATH for libgsa.so - Stop action uses systemctl/podman Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 6813413 commit 20d733e

3 files changed

Lines changed: 190 additions & 48 deletions

File tree

.claude/CLAUDE.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# CLAUDE.md — Game Server Admin (GSA)
2+
3+
## Quick Context
4+
5+
Universal game server probe, config management, and administration tool.
6+
Gossamer GUI + Zig FFI + Idris2 ABI + VeriSimDB backing store.
7+
8+
## Build & Test
9+
10+
```bash
11+
# All commands run from src/interface/ffi/
12+
cd src/interface/ffi
13+
14+
# Build shared + static library
15+
zig build
16+
17+
# Run unit tests (fast, no I/O)
18+
zig build test
19+
20+
# Run integration tests (36 tests, no live services)
21+
zig build test-integration
22+
23+
# Run e2e smoke tests (full pipeline, no live services)
24+
zig build test-smoke
25+
26+
# Build with optional Gossamer linking
27+
zig build -Dgossamer-lib-path=/path/to/gossamer/src/interface/ffi/zig-out/lib
28+
29+
# Pre-commit check
30+
panic-attack assail .
31+
```
32+
33+
## Architecture
34+
35+
```
36+
Gossamer GUI (Ephapax .eph) -- src/core/, src/gui/panels/
37+
| IPC (gossamer:// protocol)
38+
Zig FFI (libgsa.so) -- src/interface/ffi/src/ (8 modules)
39+
| C ABI (13 result codes)
40+
Idris2 ABI (Types/Foreign/Layout) -- src/interface/abi/
41+
| REST (port 8090)
42+
VeriSimDB (8-modality octads) -- container/verisimdb/
43+
```
44+
45+
### FFI Modules (src/interface/ffi/src/)
46+
47+
| Module | Purpose |
48+
|--------|---------|
49+
| `main.zig` | Lifecycle, GsaHandle, error buffer, result codes |
50+
| `probe.zig` | Protocol fingerprinting (8 protocols, 20+ known ports) |
51+
| `config_extract.zig` | Config parsing (8 formats: XML/INI/JSON/ENV/YAML/TOML/Lua/KV) |
52+
| `a2ml_emit.zig` | A2ML serialisation + parsing + config diff |
53+
| `verisimdb_client.zig` | VeriSimDB HTTP client (Zig 0.15 fetch API) |
54+
| `server_actions.zig` | Start/stop/restart/logs via Podman/Docker/systemd |
55+
| `game_profiles.zig` | A2ML profile registry + parser |
56+
| `groove_client.zig` | .well-known Groove voice alerting |
57+
58+
## Key Conventions
59+
60+
- **All exported FFI functions** are prefixed `gossamer_gsa_` and use `pub export fn ... callconv(.c)`
61+
- **Result codes** are contractual — must match `src/interface/abi/Types.idr`
62+
- **Secrets** must be redacted as `[REDACTED]` in A2ML output and octad JSON
63+
- **Machine-readable metadata** lives in `.machine_readable/` ONLY (never root)
64+
- **Game profiles** are A2ML files in `profiles/` — support quoted AND unquoted attribute values
65+
- **VeriSimDB instance** is dedicated (port 8090) — never store GSA data in the VeriSimDB source repo
66+
- **Container images** use Chainguard Wolfi base, Podman, `Containerfile` (never Docker/Dockerfile)
67+
68+
## Current State (2026-03-29)
69+
70+
- **Completion**: 82% (Phases 1-12 complete, 13-15 in progress)
71+
- **Zig version**: 0.15.2 (see `.tool-versions`)
72+
- **Tests**: All 3 suites pass (unit, integration, smoke)
73+
- **Remaining**: Live e2e test with real game server, container deployment, Bitbucket mirror
74+
75+
## Lint / Quality
76+
77+
- `panic-attack assail .` before every commit
78+
- `just check` for full quality sweep
79+
- No dangerous patterns: `believe_me`, `assert_total`, `unsafeCoerce`, etc.
80+
- All actions SHA-pinned in CI workflows
81+
82+
## File Locations
83+
84+
| What | Where |
85+
|------|-------|
86+
| AI manifest | `0-AI-MANIFEST.a2ml` (read FIRST) |
87+
| State checkpoint | `.machine_readable/6a2/STATE.a2ml` |
88+
| Game profiles | `profiles/*.a2ml` (17 games) |
89+
| GUI panels | `src/gui/panels/` (7 panels) |
90+
| Panel clades | `panel-clades/` (9 base + game children) |
91+
| Ephapax core | `src/core/` (Shell, Bridge, Types, Capabilities) |
92+
| VeriSimDB container | `container/verisimdb/` |
93+
| VeriSimDB quadlet | `container/verisimdb/gsa-verisimdb.container` |
94+
| Desktop entry | `game-server-admin.desktop` |

game-server-admin.desktop

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,24 @@
22
Type=Application
33
Name=Game Server Admin
44
GenericName=Game Server Administration
5-
Comment=Manage game servers with health monitoring and live configuration
6-
Exec=gsa-launcher %u
5+
Comment=Manage game servers with health monitoring and live configuration via Gossamer GUI
6+
Exec=game-server-admin-launcher %u
77
Icon=game-server-admin
8-
Categories=Game;Utility;Network;
8+
Categories=Game;Utility;Network;System;
99
Terminal=false
1010
StartupWMClass=game-server-admin
11-
Keywords=gameserver;admin;monitoring;dedicated;multiplayer;
11+
Keywords=gameserver;admin;monitoring;dedicated;multiplayer;gossamer;verisimdb;
1212
MimeType=x-scheme-handler/gsa;
13-
Actions=gossamer;web;
13+
Actions=gossamer;web;stop;
1414

1515
[Desktop Action gossamer]
1616
Name=Launch Desktop App (Gossamer)
17-
Exec=gsa-launcher --gossamer
17+
Exec=game-server-admin-launcher --gossamer
1818

1919
[Desktop Action web]
2020
Name=Launch in Browser
21-
Exec=gsa-launcher --web
21+
Exec=game-server-admin-launcher --web
22+
23+
[Desktop Action stop]
24+
Name=Stop Server
25+
Exec=game-server-admin-launcher --stop

scripts/install-desktop.sh

Lines changed: 85 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env bash
22
# SPDX-License-Identifier: PMPL-1.0-or-later
33
#
4-
# install-desktop.sh — Install Stapeln desktop entry, icon, and launcher on Linux.
4+
# install-desktop.sh — Install GSA desktop entry, icon, and launcher on Linux.
55
#
66
# Usage:
77
# ./scripts/install-desktop.sh # Install
@@ -11,10 +11,10 @@
1111

1212
set -euo pipefail
1313

14-
APP_NAME="gsa"
14+
APP_NAME="game-server-admin"
1515
APP_DISPLAY="Game Server Admin"
16-
APP_PORT="8080"
17-
APP_DESC="Game Server Administration"
16+
APP_PORT="8090"
17+
APP_DESC="Universal game server probe, config management, and administration"
1818

1919
REPO_DIR="$(cd "$(dirname "$0")/.." && pwd)"
2020
DESKTOP_FILE="$REPO_DIR/${APP_NAME}.desktop"
@@ -43,8 +43,13 @@ echo "Installing ${APP_DISPLAY}..."
4343
mkdir -p "$APPS_DIR" "$ICON_DIR" "$BIN_DIR"
4444

4545
# Copy desktop file
46-
cp "$DESKTOP_FILE" "$APPS_DIR/${APP_NAME}.desktop"
47-
echo " + Desktop entry -> $APPS_DIR/${APP_NAME}.desktop"
46+
if [[ -f "$DESKTOP_FILE" ]]; then
47+
cp "$DESKTOP_FILE" "$APPS_DIR/${APP_NAME}.desktop"
48+
echo " + Desktop entry -> $APPS_DIR/${APP_NAME}.desktop"
49+
else
50+
echo " ! Desktop file not found at $DESKTOP_FILE"
51+
exit 1
52+
fi
4853

4954
# Copy icon if available
5055
if [[ -f "$REPO_DIR/assets/icon-256.png" ]]; then
@@ -61,61 +66,94 @@ fi
6166
cat > "$LAUNCHER" << LAUNCHER_EOF
6267
#!/usr/bin/env bash
6368
# SPDX-License-Identifier: PMPL-1.0-or-later
64-
# ${APP_DISPLAY} Launcher
69+
# ${APP_DISPLAY} Launcher — Gossamer GUI for game server administration
6570
set -euo pipefail
6671
6772
REPO_DIR="$REPO_DIR"
73+
FFI_DIR="\$REPO_DIR/src/interface/ffi"
74+
VERISIMDB_URL="\${GSA_VERISIMDB_URL:-http://[::1]:${APP_PORT}}"
75+
PROFILES_DIR="\${GSA_PROFILES_DIR:-\$REPO_DIR/profiles}"
6876
MODE="\${1:---auto}"
6977
70-
start_server() {
71-
if ! curl -s http://localhost:${APP_PORT} >/dev/null 2>&1; then
72-
echo "Starting ${APP_DISPLAY} server..."
73-
cd "\$REPO_DIR"
74-
nohup deno task dev > /tmp/${APP_NAME}-server.log 2>&1 &
75-
echo \$! > /tmp/${APP_NAME}-server.pid
76-
for i in {1..30}; do
77-
curl -s http://localhost:${APP_PORT} >/dev/null 2>&1 && break
78-
sleep 0.5
79-
done
78+
# Check VeriSimDB is running
79+
check_verisimdb() {
80+
if curl -sf "\$VERISIMDB_URL/health" >/dev/null 2>&1; then
81+
return 0
82+
else
83+
echo "VeriSimDB not reachable at \$VERISIMDB_URL"
84+
echo "Start it with: systemctl --user start gsa-verisimdb"
85+
echo "Or: podman start gsa-verisimdb"
86+
return 1
8087
fi
8188
}
8289
83-
open_client() {
84-
xdg-open "http://localhost:${APP_PORT}" 2>/dev/null || \
85-
echo "Open http://localhost:${APP_PORT} in your browser"
90+
# Build libgsa.so if not already built
91+
build_ffi() {
92+
if [[ ! -f "\$FFI_DIR/zig-out/lib/libgsa.so" ]]; then
93+
echo "Building libgsa.so..."
94+
cd "\$FFI_DIR"
95+
zig build
96+
echo "Built: \$FFI_DIR/zig-out/lib/libgsa.so"
97+
fi
8698
}
8799
88-
stop_server() {
89-
if [[ -f /tmp/${APP_NAME}-server.pid ]]; then
90-
kill "\$(cat /tmp/${APP_NAME}-server.pid)" 2>/dev/null || true
91-
rm -f /tmp/${APP_NAME}-server.pid
92-
echo "${APP_DISPLAY} server stopped."
100+
# Launch via Gossamer webview (native desktop)
101+
launch_gossamer() {
102+
build_ffi
103+
export LD_LIBRARY_PATH="\$FFI_DIR/zig-out/lib:\${LD_LIBRARY_PATH:-}"
104+
export GSA_VERISIMDB_URL="\$VERISIMDB_URL"
105+
export GSA_PROFILES_DIR="\$PROFILES_DIR"
106+
107+
if command -v gossamer &>/dev/null; then
108+
exec gossamer \\
109+
--load "\$FFI_DIR/zig-out/lib/libgsa.so" \\
110+
--html "\$REPO_DIR/src/gui/host.html" \\
111+
--title "${APP_DISPLAY}" \\
112+
--width 1400 --height 900
113+
else
114+
echo "gossamer binary not found in PATH"
115+
echo "Falling back to browser mode..."
116+
launch_web
93117
fi
94118
}
95119
120+
# Launch web interface (opens browser to panel host)
121+
launch_web() {
122+
echo "Opening ${APP_DISPLAY} in browser..."
123+
local host_html="\$REPO_DIR/src/gui/host.html"
124+
if [[ -f "\$host_html" ]]; then
125+
xdg-open "file://\$host_html" 2>/dev/null || \\
126+
echo "Open file://\$host_html in your browser"
127+
else
128+
echo "Panel host HTML not found at \$host_html"
129+
exit 1
130+
fi
131+
}
132+
133+
# Stop VeriSimDB
134+
stop_services() {
135+
echo "Stopping ${APP_DISPLAY} services..."
136+
systemctl --user stop gsa-verisimdb 2>/dev/null || \\
137+
podman stop gsa-verisimdb 2>/dev/null || \\
138+
echo "No running services found."
139+
echo "Done."
140+
}
141+
96142
case "\$MODE" in
97143
--gossamer)
98-
start_server
99-
if command -v gossamer &>/dev/null; then
100-
exec gossamer --url "http://localhost:${APP_PORT}" --title "${APP_DISPLAY}"
101-
else
102-
open_client
103-
fi
144+
check_verisimdb || true
145+
launch_gossamer
104146
;;
105147
--web)
106-
start_server
107-
open_client
148+
check_verisimdb || true
149+
launch_web
108150
;;
109151
--stop)
110-
stop_server
152+
stop_services
111153
;;
112154
--auto|*)
113-
start_server
114-
if command -v gossamer &>/dev/null; then
115-
exec gossamer --url "http://localhost:${APP_PORT}" --title "${APP_DISPLAY}"
116-
else
117-
open_client
118-
fi
155+
check_verisimdb || true
156+
launch_gossamer
119157
;;
120158
esac
121159
LAUNCHER_EOF
@@ -131,6 +169,7 @@ cat > "$CONFIG_FILE" << CONF_EOF
131169
install_dir=$REPO_DIR
132170
install_type=user
133171
os=linux
172+
verisimdb_port=${APP_PORT}
134173
installed_at=$(date -Iseconds)
135174
CONF_EOF
136175
echo " + Config -> $CONFIG_FILE"
@@ -142,10 +181,15 @@ gtk-update-icon-cache "$HOME/.local/share/icons/hicolor/" 2>/dev/null || true
142181
echo ""
143182
echo "Done! ${APP_DISPLAY} is now available in your application menu."
144183
echo ""
184+
echo "Prerequisites:"
185+
echo " 1. Build Zig FFI: cd src/interface/ffi && zig build"
186+
echo " 2. Start VeriSimDB: systemctl --user start gsa-verisimdb"
187+
echo " 3. Install Gossamer for native desktop mode (optional)"
188+
echo ""
145189
echo "Commands:"
146190
echo " ${APP_NAME}-launcher # Start (auto-detect Gossamer/browser)"
147191
echo " ${APP_NAME}-launcher --web # Force browser mode"
148192
echo " ${APP_NAME}-launcher --gossamer # Force Gossamer mode"
149-
echo " ${APP_NAME}-launcher --stop # Stop server"
193+
echo " ${APP_NAME}-launcher --stop # Stop services"
150194
echo ""
151195
echo "To remove: $0 --remove"

0 commit comments

Comments
 (0)