feat: initial public release (MAESTRO v0.1.0)

Open-source release of MAESTRO, an agent orchestration platform that runs
LLM-driven tasks through sandboxed tools, with a web UI. Apache-2.0.
See README.md and docs/ (getting-started, configuration, architecture).
This commit is contained in:
clade
2026-06-03 04:01:14 +00:00
committed by swallow
commit 7049a874f3
825 changed files with 184390 additions and 0 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

+17
View File
@@ -0,0 +1,17 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- Background: rounded square in blue-600 -->
<rect width="32" height="32" rx="7" fill="#2563eb"/>
<!-- Connection lines: hub to agents -->
<line x1="16" y1="16" x2="16" y2="7" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-opacity="0.55"/>
<line x1="16" y1="16" x2="8.5" y2="23" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-opacity="0.55"/>
<line x1="16" y1="16" x2="23.5" y2="23" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-opacity="0.55"/>
<!-- Agent nodes (outer) -->
<circle cx="16" cy="7" r="2.5" fill="white" fill-opacity="0.8"/>
<circle cx="8.5" cy="23" r="2.5" fill="white" fill-opacity="0.8"/>
<circle cx="23.5" cy="23" r="2.5" fill="white" fill-opacity="0.8"/>
<!-- Orchestrator hub (center, larger) -->
<circle cx="16" cy="16" r="3.5" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 923 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

+32
View File
@@ -0,0 +1,32 @@
{
"name": "Agent Orchestrator",
"short_name": "Orchestrator",
"description": "AI agent orchestration dashboard",
"start_url": "/ui/",
"scope": "/ui/",
"display": "standalone",
"orientation": "any",
"theme_color": "#2563eb",
"background_color": "#f3f6fb",
"lang": "ja",
"icons": [
{
"src": "/ui/icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "/ui/icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
},
{
"src": "/ui/icon-maskable-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}
+137
View File
@@ -0,0 +1,137 @@
// Service Worker for MAESTRO. Two roles:
// 1. PWA install eligibility (a fetch handler must be registered).
// 2. V2 Web Push delivery — receives push events from the server and
// either suppresses them when a visible tab already handled the
// notification (ACK protocol) or shows an OS notification.
//
// Spec: docs/superpowers/specs/2026-05-28-browser-notifications-v2-webpush.md.
const VERSION = 'v2';
const ACK_TIMEOUT_MS = 200;
self.addEventListener('install', (event) => {
self.skipWaiting();
});
self.addEventListener('activate', (event) => {
event.waitUntil(self.clients.claim());
});
self.addEventListener('fetch', (event) => {
const req = event.request;
if (req.method !== 'GET') return;
const url = new URL(req.url);
// Only handle same-origin /ui/ requests; let the network handle everything else.
if (url.origin !== self.location.origin) return;
if (!url.pathname.startsWith('/ui/')) return;
// Network-first, fall back to cache only when offline. Never serve stale
// HTML/JS by default — users always get the latest deploy when online.
event.respondWith(
fetch(req)
.then((res) => {
// Opportunistically cache successful responses for offline fallback.
if (res.ok) {
const clone = res.clone();
caches.open(VERSION).then((cache) => cache.put(req, clone)).catch(() => {});
}
return res;
})
.catch(() => caches.match(req).then((hit) => hit || Response.error()))
);
});
// ── Push notification handler ───────────────────────────────────────────
// Strategy: when one or more open tabs exist, broadcast a "notify-request"
// and wait up to ACK_TIMEOUT_MS for any visible tab to ACK. ACK means the
// page is showing the user state changes in-app, so we suppress the OS
// notification. No ACK → tab is hidden or closed (race conditions included)
// → we show the OS notification. This is more robust than visibilityState
// polling because the page decides whether IT will handle the user-facing
// surfacing.
self.addEventListener('push', (event) => {
if (!event.data) return;
let payload;
try {
payload = event.data.json();
} catch {
payload = { title: 'MAESTRO', body: event.data.text(), tag: 'maestro' };
}
const showOptions = {
body: payload.body ?? '',
tag: payload.tag,
icon: payload.icon ?? '/ui/icon-192.png',
badge: '/ui/icon-192.png',
data: payload.data ?? {},
};
event.waitUntil((async () => {
const clients = await self.clients.matchAll({
type: 'window',
includeUncontrolled: true,
});
if (clients.length === 0) {
await self.registration.showNotification(payload.title ?? 'MAESTRO', showOptions);
return;
}
const handled = await waitForAck(clients, payload);
if (!handled) {
await self.registration.showNotification(payload.title ?? 'MAESTRO', showOptions);
}
})());
});
function waitForAck(clients, payload) {
return new Promise((resolve) => {
let settled = false;
const handler = (e) => {
if (settled) return;
if (e.data && e.data.type === 'notification-handled' && e.data.tag === payload.tag) {
settled = true;
self.removeEventListener('message', handler);
resolve(true);
}
};
self.addEventListener('message', handler);
setTimeout(() => {
if (settled) return;
settled = true;
self.removeEventListener('message', handler);
resolve(false);
}, ACK_TIMEOUT_MS);
for (const client of clients) {
client.postMessage({ type: 'notify-request', tag: payload.tag, payload });
}
});
}
// ── Notification click handler ──────────────────────────────────────────
// Focus an existing /ui/ tab if present (and tell it which task to open),
// otherwise open a new one at /ui/?task=N.
self.addEventListener('notificationclick', (event) => {
event.notification.close();
const taskId = event.notification.data && event.notification.data.taskId;
const targetUrl = taskId ? `/ui/?task=${taskId}` : '/ui/';
event.waitUntil((async () => {
const clients = await self.clients.matchAll({
type: 'window',
includeUncontrolled: true,
});
for (const client of clients) {
if (client.url.includes('/ui/')) {
try {
await client.focus();
} catch {
// some browsers throw if focus is not allowed — fall through
}
client.postMessage({ type: 'open-task', taskId });
return;
}
}
await self.clients.openWindow(targetUrl);
})());
});