feat: agor-launcher MCP server + .mcp.json + updated Rule 56

This commit is contained in:
Hibryda 2026-03-25 20:37:16 +01:00
parent 58ac5e8c84
commit e9d7356064
4 changed files with 282 additions and 49 deletions

View file

@ -0,0 +1,99 @@
#!/usr/bin/env node
/**
* agor-launcher MCP manages Electrobun app lifecycle.
* Tools: start, stop, restart, clean, rebuild, status, kill-stale, build-native, logs
*/
import { execSync, spawn } from "child_process";
import { createInterface } from "readline";
const SCRIPT = "/home/hibryda/code/ai/agent-orchestrator/scripts/launch.sh";
function run(cmd, timeout = 30000) {
try {
return execSync(`bash ${SCRIPT} ${cmd}`, {
timeout,
encoding: "utf-8",
stdio: ["pipe", "pipe", "pipe"],
}).trim();
} catch (e) {
return `Error: ${e.stderr || e.message}`;
}
}
const TOOLS = {
"agor-start": {
description: "Start Electrobun app (kills old instances first). Pass clean=true to remove build cache.",
schema: { type: "object", properties: { clean: { type: "boolean", default: false } } },
handler: ({ clean }) => run(clean ? "start --clean" : "start", 60000),
},
"agor-stop": {
description: "Stop all running Electrobun/PTY/Vite instances.",
schema: { type: "object", properties: {} },
handler: () => run("stop"),
},
"agor-restart": {
description: "Restart Electrobun app. Pass clean=true for clean restart.",
schema: { type: "object", properties: { clean: { type: "boolean", default: false } } },
handler: ({ clean }) => run(clean ? "restart --clean" : "restart", 60000),
},
"agor-clean": {
description: "Remove build artifacts, caches, and temp files.",
schema: { type: "object", properties: {} },
handler: () => run("clean"),
},
"agor-rebuild": {
description: "Full rebuild: clean + npm install + vite build + native C library + PTY daemon.",
schema: { type: "object", properties: {} },
handler: () => run("rebuild", 120000),
},
"agor-status": {
description: "Show running processes, ports, and window status.",
schema: { type: "object", properties: {} },
handler: () => run("status"),
},
"agor-kill-stale": {
description: "Kill ALL stale agor-ptyd instances that accumulated over sessions.",
schema: { type: "object", properties: {} },
handler: () => run("kill-stale"),
},
"agor-build-native": {
description: "Rebuild libagor-resize.so (GTK resize) and agor-ptyd (PTY daemon).",
schema: { type: "object", properties: {} },
handler: () => run("build-native", 120000),
},
};
// Minimal MCP stdio server
const rl = createInterface({ input: process.stdin });
function send(msg) { process.stdout.write(JSON.stringify(msg) + "\n"); }
rl.on("line", (line) => {
let msg;
try { msg = JSON.parse(line); } catch { return; }
if (msg.method === "initialize") {
send({ jsonrpc: "2.0", id: msg.id, result: {
protocolVersion: "2024-11-05",
capabilities: { tools: {} },
serverInfo: { name: "agor-launcher", version: "1.0.0" },
}});
} else if (msg.method === "notifications/initialized") {
// no-op
} else if (msg.method === "tools/list") {
send({ jsonrpc: "2.0", id: msg.id, result: {
tools: Object.entries(TOOLS).map(([name, t]) => ({
name, description: t.description, inputSchema: t.schema,
})),
}});
} else if (msg.method === "tools/call") {
const tool = TOOLS[msg.params.name];
if (!tool) {
send({ jsonrpc: "2.0", id: msg.id, error: { code: -32601, message: `Unknown tool: ${msg.params.name}` }});
return;
}
const result = tool.handler(msg.params.arguments || {});
send({ jsonrpc: "2.0", id: msg.id, result: {
content: [{ type: "text", text: result }],
}});
}
});

View file

@ -1,43 +1,41 @@
# Electrobun Launch Sequence (MANDATORY)
Before launching the Electrobun app, ALWAYS start dependencies in this exact order:
**Use the `agor-launcher` MCP tools** for ALL app lifecycle operations. Do NOT use raw bash commands for launch/stop/rebuild.
## Steps
## MCP Tools (preferred)
1. **Start Rust PTY daemon** (if not already running):
```bash
/home/hibryda/code/ai/agent-orchestrator/agor-pty/target/release/agor-ptyd &>/dev/null &
```
| Tool | Use When |
| --------------------------------------- | ------------------------------------------------------------------ |
| `mcp__agor-launcher__agor-start` | Launch the app (`clean: true` to rebuild from scratch) |
| `mcp__agor-launcher__agor-stop` | Stop all running instances |
| `mcp__agor-launcher__agor-restart` | Stop + start (`clean: true` for clean restart) |
| `mcp__agor-launcher__agor-clean` | Remove build caches without launching |
| `mcp__agor-launcher__agor-rebuild` | Full rebuild: npm install + vite build + native C lib + PTY daemon |
| `mcp__agor-launcher__agor-status` | Check running processes, ports, window |
| `mcp__agor-launcher__agor-kill-stale` | Kill accumulated stale agor-ptyd processes |
| `mcp__agor-launcher__agor-build-native` | Rebuild libagor-resize.so + agor-ptyd |
2. **Start Vite dev server** on port 9760:
```bash
cd /home/hibryda/code/ai/agent-orchestrator/ui-electrobun && npx vite dev --port 9760 --host localhost &>/dev/null &
```
## Fallback (if MCP unavailable)
3. **Wait 3-4 seconds** for Vite to be ready.
4. **Launch Electrobun**:
```bash
cd /home/hibryda/code/ai/agent-orchestrator/ui-electrobun && npx electrobun dev
```
```bash
./scripts/launch.sh start # normal launch
./scripts/launch.sh start --clean # clean build + launch
./scripts/launch.sh stop # stop all
./scripts/launch.sh rebuild # full rebuild
./scripts/launch.sh status # check state
./scripts/launch.sh kill-stale # clean up stale ptyd
```
## What Happens If You Skip Steps
- **No PTY daemon**: App crashes with `Connection timeout (5s). Is agor-ptyd running?` — Bun process dies silently.
- **No Vite**: WebView loads a blank page (no frontend bundle served).
- **No wait**: Electrobun opens before Vite is ready — blank page or partial load.
## Kill Sequence (Rule 55)
Always kill previous instances before launching new ones:
```bash
pkill -f "electrobun|vite.*9760|agor-ptyd|WebKit|AgentOrch|launcher" 2>/dev/null
fuser -k 9760/tcp 2>/dev/null
```
- **No PTY daemon**: App crashes with `Connection timeout (5s). Is agor-ptyd running?`
- **No Vite**: WebView loads blank page (no frontend bundle)
- **No kill first**: Duplicate windows, port conflicts
## Rules
- NEVER launch Electrobun without the PTY daemon running.
- NEVER launch Electrobun without Vite running on port 9760.
- ALWAYS kill previous instances first (Rule 55).
- Check `pgrep -f agor-ptyd` before launching to verify daemon is alive.
- ALWAYS use `agor-stop` before `agor-start` when relaunching
- Use `clean: true` when `src/bun/` files changed (Electrobun caches bundles)
- Use `agor-rebuild` after dependency changes or native code changes
- Use `agor-kill-stale` periodically (ptyd accumulates across sessions)
- NEVER launch manually with raw bash — always use MCP or scripts/launch.sh