ai-control-center 1.15.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +584 -0
- package/bin/aicc.js +772 -0
- package/lib/actions/approve.js +71 -0
- package/lib/actions/assign-project.js +132 -0
- package/lib/actions/browser-test.js +64 -0
- package/lib/actions/cleanup.js +174 -0
- package/lib/actions/debug.js +298 -0
- package/lib/actions/deploy.js +1229 -0
- package/lib/actions/fix-bug.js +134 -0
- package/lib/actions/new-feature.js +255 -0
- package/lib/actions/reject.js +307 -0
- package/lib/actions/review.js +706 -0
- package/lib/actions/status.js +47 -0
- package/lib/agents/browser-qa-agent.js +611 -0
- package/lib/agents/payment-agent.js +116 -0
- package/lib/agents/suggestion-agent.js +88 -0
- package/lib/cli.js +303 -0
- package/lib/config.js +243 -0
- package/lib/hub/hub-server.js +440 -0
- package/lib/hub/project-poller.js +75 -0
- package/lib/hub/skill-registry.js +89 -0
- package/lib/hub/state-aggregator.js +204 -0
- package/lib/index.js +471 -0
- package/lib/init/doctor.js +523 -0
- package/lib/init/presets.js +222 -0
- package/lib/init/skill-fetcher.js +77 -0
- package/lib/init/wizard.js +973 -0
- package/lib/integrations/codex-runner.js +128 -0
- package/lib/integrations/github-actions.js +248 -0
- package/lib/integrations/github-reporter.js +229 -0
- package/lib/integrations/screenshot-store.js +102 -0
- package/lib/openclaw/bridge.js +650 -0
- package/lib/openclaw/generate-skill.js +235 -0
- package/lib/openclaw/openclaw.json +64 -0
- package/lib/orchestrator/autonomous-loop.js +429 -0
- package/lib/orchestrator/thread-triggers.js +63 -0
- package/lib/roleplay/agent-messenger.js +75 -0
- package/lib/roleplay/discussion-threads.js +303 -0
- package/lib/roleplay/health-monitor.js +121 -0
- package/lib/roleplay/pm-agent.js +513 -0
- package/lib/roleplay/roleplay-config.js +25 -0
- package/lib/roleplay/room.js +164 -0
- package/lib/shared/action-runner.js +2330 -0
- package/lib/shared/event-bus.js +185 -0
- package/lib/slack/bot.js +378 -0
- package/lib/telegram/bot.js +416 -0
- package/lib/telegram/commands.js +1267 -0
- package/lib/telegram/keyboards.js +113 -0
- package/lib/telegram/notifications.js +247 -0
- package/lib/twitch/bot.js +354 -0
- package/lib/twitch/commands.js +302 -0
- package/lib/twitch/notifications.js +63 -0
- package/lib/utils/achievements.js +191 -0
- package/lib/utils/activity-log.js +182 -0
- package/lib/utils/agent-leaderboard.js +119 -0
- package/lib/utils/audit-logger.js +232 -0
- package/lib/utils/codebase-context.js +288 -0
- package/lib/utils/codebase-indexer.js +381 -0
- package/lib/utils/config-schema.js +230 -0
- package/lib/utils/context-compressor.js +172 -0
- package/lib/utils/correlation.js +63 -0
- package/lib/utils/cost-tracker.js +423 -0
- package/lib/utils/cron-scheduler.js +53 -0
- package/lib/utils/db-adapter.js +293 -0
- package/lib/utils/display.js +272 -0
- package/lib/utils/errors.js +116 -0
- package/lib/utils/format.js +134 -0
- package/lib/utils/intent-engine.js +464 -0
- package/lib/utils/mcp-client.js +238 -0
- package/lib/utils/model-ab-test.js +164 -0
- package/lib/utils/notify.js +122 -0
- package/lib/utils/persona-loader.js +80 -0
- package/lib/utils/pipeline-lock.js +73 -0
- package/lib/utils/pipeline.js +214 -0
- package/lib/utils/plugin-runner.js +234 -0
- package/lib/utils/rate-limiter.js +84 -0
- package/lib/utils/rbac.js +74 -0
- package/lib/utils/runner.js +1809 -0
- package/lib/utils/security.js +191 -0
- package/lib/utils/self-healer.js +144 -0
- package/lib/utils/skill-loader.js +255 -0
- package/lib/utils/spinner.js +132 -0
- package/lib/utils/stage-queue.js +50 -0
- package/lib/utils/state-machine.js +89 -0
- package/lib/utils/status-bar.js +327 -0
- package/lib/utils/token-estimator.js +101 -0
- package/lib/utils/ux-analyzer.js +101 -0
- package/lib/utils/webhook-emitter.js +83 -0
- package/lib/web/public/css/styles.css +417 -0
- package/lib/web/public/dark-mode.js +44 -0
- package/lib/web/public/hub/kanban.html +206 -0
- package/lib/web/public/index.html +45 -0
- package/lib/web/public/js/app.js +71 -0
- package/lib/web/public/js/ask.js +110 -0
- package/lib/web/public/js/dashboard.js +165 -0
- package/lib/web/public/js/deploy.js +72 -0
- package/lib/web/public/js/feature.js +79 -0
- package/lib/web/public/js/health.js +65 -0
- package/lib/web/public/js/logs.js +93 -0
- package/lib/web/public/js/review.js +123 -0
- package/lib/web/public/js/ws-client.js +82 -0
- package/lib/web/public/office/css/office.css +678 -0
- package/lib/web/public/office/index.html +148 -0
- package/lib/web/public/office/js/achievements-ui.js +117 -0
- package/lib/web/public/office/js/character.js +1056 -0
- package/lib/web/public/office/js/chat-bubbles.js +177 -0
- package/lib/web/public/office/js/cost-overlay.js +123 -0
- package/lib/web/public/office/js/day-night.js +68 -0
- package/lib/web/public/office/js/effects.js +632 -0
- package/lib/web/public/office/js/engine.js +146 -0
- package/lib/web/public/office/js/feature-ticket.js +216 -0
- package/lib/web/public/office/js/hub-client.js +60 -0
- package/lib/web/public/office/js/main.js +1757 -0
- package/lib/web/public/office/js/office-layout.js +1524 -0
- package/lib/web/public/office/js/pathfinding.js +144 -0
- package/lib/web/public/office/js/pixel-sprites.js +1454 -0
- package/lib/web/public/office/js/progress-bars.js +117 -0
- package/lib/web/public/office/js/replay.js +191 -0
- package/lib/web/public/office/js/sound-effects.js +91 -0
- package/lib/web/public/office/js/sprite-renderer.js +211 -0
- package/lib/web/public/office/js/stamina-system.js +89 -0
- package/lib/web/public/office/js/ui.js +107 -0
- package/lib/web/public/onboarding/index.html +243 -0
- package/lib/web/public/timeline/index.html +195 -0
- package/lib/web/routes/api.js +499 -0
- package/lib/web/routes/logs.js +20 -0
- package/lib/web/routes/metrics.js +99 -0
- package/lib/web/server.js +183 -0
- package/lib/web/ws/handler.js +65 -0
- package/package.json +67 -0
- package/templates/agent-architect.md +69 -0
- package/templates/agent-gemini-pm.md +49 -0
- package/templates/agent-gemini-reviewer.md +52 -0
- package/templates/copilot-instructions.md +36 -0
- package/templates/pipelines/mobile.json +27 -0
- package/templates/pipelines/nodejs-api.json +27 -0
- package/templates/pipelines/python.json +27 -0
- package/templates/pipelines/react.json +27 -0
- package/templates/pipelines/salesforce.json +27 -0
- package/templates/role-gemini.md +97 -0
- package/templates/skill-architect.md +114 -0
- package/templates/skill-browser-qa.md +50 -0
- package/templates/skill-bug-from-qa.md +58 -0
- package/templates/skill-chatbot.md +93 -0
- package/templates/skill-implement.md +78 -0
- package/templates/skill-openclaw.md +174 -0
- package/templates/skill-payment.md +110 -0
- package/templates/skill-pm-spec.md +77 -0
- package/templates/skill-requirement-capture.md +97 -0
- package/templates/skill-review.md +108 -0
- package/templates/skill-reviewer-qa.md +44 -0
- package/templates/skill-suggestion.md +45 -0
- package/templates/skill-template.md +142 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Control Center Web Dashboard — Express + WebSocket server.
|
|
3
|
+
*
|
|
4
|
+
* Serves the dashboard SPA and provides REST API + real-time WebSocket updates.
|
|
5
|
+
* Runs alongside the terminal CLI — does NOT replace it.
|
|
6
|
+
*
|
|
7
|
+
* Usage: aicc web
|
|
8
|
+
*/
|
|
9
|
+
import { execSync } from 'child_process';
|
|
10
|
+
import express from 'express';
|
|
11
|
+
import { createServer } from 'http';
|
|
12
|
+
import { dirname, resolve } from 'path';
|
|
13
|
+
import { fileURLToPath } from 'url';
|
|
14
|
+
import { WebSocketServer } from 'ws';
|
|
15
|
+
import { env, getConfig, loadConfig } from '../config.js';
|
|
16
|
+
import { bus } from '../shared/event-bus.js';
|
|
17
|
+
import { apiRouter } from './routes/api.js';
|
|
18
|
+
import { logsRouter } from './routes/logs.js';
|
|
19
|
+
import { handleWsConnection } from './ws/handler.js';
|
|
20
|
+
import { initWebhooks } from '../utils/webhook-emitter.js';
|
|
21
|
+
|
|
22
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
|
|
24
|
+
let server, wss;
|
|
25
|
+
|
|
26
|
+
export async function startServer() {
|
|
27
|
+
// Ensure config + .env are loaded before reading port
|
|
28
|
+
await loadConfig().catch(() => {});
|
|
29
|
+
const DEFAULT_PORT = (() => { try { return getConfig().web?.port || 3847; } catch { return 3847; } })();
|
|
30
|
+
const PORT = parseInt(env('WEB_PORT') || DEFAULT_PORT, 10);
|
|
31
|
+
|
|
32
|
+
const app = express();
|
|
33
|
+
app.use(express.json());
|
|
34
|
+
|
|
35
|
+
// Serve static frontend
|
|
36
|
+
app.use(express.static(resolve(__dirname, 'public')));
|
|
37
|
+
|
|
38
|
+
// Serve office visualizer
|
|
39
|
+
app.use('/office', express.static(resolve(__dirname, 'public/office')));
|
|
40
|
+
|
|
41
|
+
// Serve hub views (kanban, etc.)
|
|
42
|
+
app.use('/hub', express.static(resolve(__dirname, 'public/hub')));
|
|
43
|
+
|
|
44
|
+
// Kanban shortcut
|
|
45
|
+
app.get('/kanban', (req, res) => {
|
|
46
|
+
res.redirect('/hub/kanban.html');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// API routes
|
|
50
|
+
app.use('/api', apiRouter);
|
|
51
|
+
app.use('/api/logs', logsRouter);
|
|
52
|
+
|
|
53
|
+
// SPA fallback — all non-API routes serve index.html
|
|
54
|
+
app.get('*', (req, res) => {
|
|
55
|
+
if (req.path.startsWith('/api')) {
|
|
56
|
+
res.status(404).json({ error: 'Not found' });
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
res.sendFile(resolve(__dirname, 'public/index.html'));
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
server = createServer(app);
|
|
63
|
+
|
|
64
|
+
// WebSocket for real-time updates
|
|
65
|
+
wss = new WebSocketServer({ server, path: '/ws' });
|
|
66
|
+
wss.on('connection', (ws) => handleWsConnection(ws, bus, wss));
|
|
67
|
+
|
|
68
|
+
// Start watching status.json for changes
|
|
69
|
+
bus.startWatching();
|
|
70
|
+
|
|
71
|
+
// Initialize roleplay room + PM agent (non-fatal if config not loaded)
|
|
72
|
+
try {
|
|
73
|
+
const { isRoleplayEnabled } = await import('../roleplay/roleplay-config.js');
|
|
74
|
+
if (isRoleplayEnabled()) {
|
|
75
|
+
const { initRoom } = await import('../roleplay/room.js');
|
|
76
|
+
const { startPMAgent } = await import('../roleplay/pm-agent.js');
|
|
77
|
+
const room = initRoom(bus);
|
|
78
|
+
startPMAgent(bus, room);
|
|
79
|
+
}
|
|
80
|
+
} catch { /* roleplay optional — non-fatal */ }
|
|
81
|
+
|
|
82
|
+
// Push pipeline events to hub in real-time (no poll delay)
|
|
83
|
+
const hubCfg = (() => { try { return getConfig().hub; } catch { return null; } })();
|
|
84
|
+
const projectName = (() => { try { return getConfig().name || 'unknown'; } catch { return 'unknown'; } })();
|
|
85
|
+
if (hubCfg?.port) {
|
|
86
|
+
const hubBase = `http://localhost:${hubCfg.port}`;
|
|
87
|
+
bus.on('pipeline-event', ({ event, data }) => {
|
|
88
|
+
fetch(`${hubBase}/api/projects/${encodeURIComponent(projectName)}/push-event`, {
|
|
89
|
+
method: 'POST',
|
|
90
|
+
headers: { 'Content-Type': 'application/json' },
|
|
91
|
+
body: JSON.stringify({ event, data }),
|
|
92
|
+
}).catch(() => { /* hub may not be running */ });
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Handle port-in-use before it becomes an uncaughtException loop
|
|
97
|
+
server.on('error', (err) => {
|
|
98
|
+
if (err.code === 'EADDRINUSE') {
|
|
99
|
+
console.error(`[Web] Port ${PORT} already in use — killing occupying process…`);
|
|
100
|
+
try {
|
|
101
|
+
// lsof-based kill works on macOS/Linux; safe no-op if nothing found
|
|
102
|
+
execSync(`lsof -ti tcp:${PORT} | xargs kill -9`, { stdio: 'ignore' });
|
|
103
|
+
} catch { /* nothing on that port */ }
|
|
104
|
+
console.log('[Web] Retrying in 2 s…');
|
|
105
|
+
setTimeout(() => {
|
|
106
|
+
server.close();
|
|
107
|
+
startServer().catch(console.error);
|
|
108
|
+
}, 2000);
|
|
109
|
+
} else {
|
|
110
|
+
console.error('[Web] Server error:', err.message);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
server.listen(PORT, () => {
|
|
115
|
+
const projectName = (() => { try { return getConfig().name; } catch { return 'AI Control Center'; } })();
|
|
116
|
+
console.log(`\n ${projectName} Web Dashboard`);
|
|
117
|
+
console.log(` http://localhost:${PORT}\n`);
|
|
118
|
+
|
|
119
|
+
// Initialize webhooks after server starts
|
|
120
|
+
try { initWebhooks(); } catch (e) { /* webhooks are optional */ }
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Register crash recovery + SIGINT handler (once per process)
|
|
124
|
+
_setupGlobalHandlers();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ── Crash recovery — registered once per process ──────────────────────────────
|
|
128
|
+
let _handlersSetup = false;
|
|
129
|
+
function _setupGlobalHandlers() {
|
|
130
|
+
if (_handlersSetup) return;
|
|
131
|
+
_handlersSetup = true;
|
|
132
|
+
|
|
133
|
+
// Clean shutdown on SIGINT
|
|
134
|
+
process.on('SIGINT', () => {
|
|
135
|
+
bus.stopWatching();
|
|
136
|
+
if (wss) wss.close();
|
|
137
|
+
if (server) server.close();
|
|
138
|
+
process.exit(0);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// Helper: send Telegram notification via raw HTTP (no bot instance needed here)
|
|
142
|
+
function notifyWebCrash(label, err) {
|
|
143
|
+
const chatId = (() => { try { return env('TELEGRAM_CHAT_ID'); } catch { return null; } })();
|
|
144
|
+
const token = (() => { try { return env('TELEGRAM_TOKEN'); } catch { return null; } })();
|
|
145
|
+
if (!chatId || !token) return;
|
|
146
|
+
fetch(`https://api.telegram.org/bot${token}/sendMessage`, {
|
|
147
|
+
method: 'POST',
|
|
148
|
+
headers: { 'Content-Type': 'application/json' },
|
|
149
|
+
body: JSON.stringify({
|
|
150
|
+
chat_id: chatId,
|
|
151
|
+
text: `🚨 Web dashboard ${label}: ${err?.message || String(err)}\nAuto-restarting in 15s...`,
|
|
152
|
+
}),
|
|
153
|
+
}).catch(() => {});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
process.on('uncaughtException', (err) => {
|
|
157
|
+
// EADDRINUSE is handled directly on the server 'error' event — skip here
|
|
158
|
+
if (err.code === 'EADDRINUSE') return;
|
|
159
|
+
console.error('[Web] Uncaught exception:', err.message);
|
|
160
|
+
notifyWebCrash('uncaught exception', err);
|
|
161
|
+
bus.stopWatching();
|
|
162
|
+
if (wss) wss.close();
|
|
163
|
+
if (server) server.close();
|
|
164
|
+
console.log('[Web] Auto-restarting in 15s...');
|
|
165
|
+
setTimeout(() => startServer().catch(console.error), 15000);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
process.on('unhandledRejection', (err) => {
|
|
169
|
+
console.error('[Web] Unhandled rejection:', err?.message || err);
|
|
170
|
+
notifyWebCrash('unhandled rejection', err);
|
|
171
|
+
if (wss) wss.close();
|
|
172
|
+
if (server) server.close();
|
|
173
|
+
console.log('[Web] Auto-restarting in 10s...');
|
|
174
|
+
setTimeout(() => startServer().catch(console.error), 10000);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Auto-start when run directly (node server.js), not when imported
|
|
179
|
+
if (process.argv[1]?.endsWith('server.js')) {
|
|
180
|
+
startServer();
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export { server, wss };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket connection handler.
|
|
3
|
+
*
|
|
4
|
+
* Each connected browser client receives real-time pipeline events:
|
|
5
|
+
* - status: pipeline stage changes (detected via fs.watchFile)
|
|
6
|
+
* - log: activity log lines
|
|
7
|
+
* - pipeline-event: review done, deploy result, feature created, etc.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export function handleWsConnection(ws, bus, wss) {
|
|
11
|
+
// Send current status on connect
|
|
12
|
+
const status = bus.getStatus();
|
|
13
|
+
safeSend(ws, { type: 'status', data: { status, timestamp: new Date().toISOString() } });
|
|
14
|
+
|
|
15
|
+
// Send connected client count
|
|
16
|
+
broadcastClientCount(wss);
|
|
17
|
+
|
|
18
|
+
// Forward bus events to this client
|
|
19
|
+
const onStatus = (data) => safeSend(ws, { type: 'status', data });
|
|
20
|
+
const onLog = (data) => safeSend(ws, { type: 'log', data });
|
|
21
|
+
const onEvent = (data) => {
|
|
22
|
+
safeSend(ws, { type: 'event', data });
|
|
23
|
+
// Room messages — forward agent chat to WebSocket clients
|
|
24
|
+
if (data && (data.event === 'room:message' || data.event === 'room:action' || data.event === 'room:ask_ceo')) {
|
|
25
|
+
safeSend(ws, { type: 'room_message', data: data.data });
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
bus.on('status', onStatus);
|
|
30
|
+
bus.on('log', onLog);
|
|
31
|
+
bus.on('pipeline-event', onEvent);
|
|
32
|
+
|
|
33
|
+
// Cleanup on disconnect
|
|
34
|
+
ws.on('close', () => {
|
|
35
|
+
bus.off('status', onStatus);
|
|
36
|
+
bus.off('log', onLog);
|
|
37
|
+
bus.off('pipeline-event', onEvent);
|
|
38
|
+
broadcastClientCount(wss);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Handle incoming messages from browser (ping/pong keep-alive)
|
|
42
|
+
ws.on('message', (raw) => {
|
|
43
|
+
try {
|
|
44
|
+
const msg = JSON.parse(raw.toString());
|
|
45
|
+
if (msg.type === 'ping') {
|
|
46
|
+
safeSend(ws, { type: 'pong' });
|
|
47
|
+
}
|
|
48
|
+
} catch { /* ignore non-JSON */ }
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function safeSend(ws, data) {
|
|
53
|
+
try {
|
|
54
|
+
if (ws.readyState === 1) { // WebSocket.OPEN
|
|
55
|
+
ws.send(JSON.stringify(data));
|
|
56
|
+
}
|
|
57
|
+
} catch { /* client disconnected */ }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function broadcastClientCount(wss) {
|
|
61
|
+
const count = [...wss.clients].filter(c => c.readyState === 1).length;
|
|
62
|
+
for (const client of wss.clients) {
|
|
63
|
+
safeSend(client, { type: 'clients', data: { count } });
|
|
64
|
+
}
|
|
65
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ai-control-center",
|
|
3
|
+
"version": "1.15.2",
|
|
4
|
+
"description": "Multi-AI orchestration control center — terminal, web dashboard, Telegram bot, and OpenClaw gateway for any project type.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"aicc": "bin/aicc.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./lib/config.js",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": "./lib/config.js",
|
|
12
|
+
"./config": "./lib/config.js",
|
|
13
|
+
"./actions": "./lib/shared/action-runner.js",
|
|
14
|
+
"./runner": "./lib/utils/runner.js",
|
|
15
|
+
"./pipeline": "./lib/utils/pipeline.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"bin/",
|
|
19
|
+
"lib/",
|
|
20
|
+
"templates/",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"start": "node bin/aicc.js",
|
|
25
|
+
"preversion": "vitest run",
|
|
26
|
+
"test": "vitest run",
|
|
27
|
+
"test:watch": "vitest",
|
|
28
|
+
"test:coverage": "vitest run --coverage",
|
|
29
|
+
"package": "node scripts/release.js",
|
|
30
|
+
"release": "node scripts/release.js",
|
|
31
|
+
"release:minor": "node scripts/release.js minor",
|
|
32
|
+
"release:major": "node scripts/release.js major"
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"ai",
|
|
36
|
+
"control-center",
|
|
37
|
+
"multi-ai",
|
|
38
|
+
"pipeline",
|
|
39
|
+
"gemini",
|
|
40
|
+
"claude",
|
|
41
|
+
"copilot",
|
|
42
|
+
"ollama",
|
|
43
|
+
"telegram",
|
|
44
|
+
"openclaw",
|
|
45
|
+
"devops"
|
|
46
|
+
],
|
|
47
|
+
"author": "Nguyen Phuc Hung <phuchung.nguyen78@gmail.com>",
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@octokit/rest": "^22.0.1",
|
|
51
|
+
"chalk": "^5.6.2",
|
|
52
|
+
"express": "^4.22.1",
|
|
53
|
+
"grammy": "^1.41.0",
|
|
54
|
+
"inquirer": "^9.3.8",
|
|
55
|
+
"node-cron": "^4.2.1",
|
|
56
|
+
"pixelmatch": "^7.1.0",
|
|
57
|
+
"playwright": "^1.58.2",
|
|
58
|
+
"pngjs": "^7.0.0",
|
|
59
|
+
"ws": "^8.19.0"
|
|
60
|
+
},
|
|
61
|
+
"engines": {
|
|
62
|
+
"node": ">=18.0.0"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"vitest": "^4.0.18"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: architect
|
|
3
|
+
description: Claude Code acting as system architect. Use this agent for architecture design, technical specs, implementation planning, and dependency analysis.
|
|
4
|
+
model: sonnet
|
|
5
|
+
color: magenta
|
|
6
|
+
tools: Read, Grep, Glob, Bash, WebFetch, WebSearch
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Role: System Architect (Claude Code)
|
|
10
|
+
|
|
11
|
+
You are the **System Architect** in a multi-AI workflow:
|
|
12
|
+
- **You (Claude)** → Architecture, Technical Design, Planning
|
|
13
|
+
- **Copilot** → Code implementation
|
|
14
|
+
- **Gemini** → PM (specs) + Code Review
|
|
15
|
+
|
|
16
|
+
## Your Responsibilities
|
|
17
|
+
|
|
18
|
+
1. **Read** the feature spec from `.ai-workflow/specs/`
|
|
19
|
+
2. **Explore** the codebase to understand existing patterns
|
|
20
|
+
3. **Design** the technical architecture
|
|
21
|
+
4. **Write** architecture docs to `.ai-workflow/architecture/ARCH-{id}.md`
|
|
22
|
+
5. **Create** implementation tasks in `.ai-workflow/tasks/TASKS-{id}.md`
|
|
23
|
+
|
|
24
|
+
## Architecture Document Format
|
|
25
|
+
|
|
26
|
+
```markdown
|
|
27
|
+
# Architecture: {Feature Name}
|
|
28
|
+
|
|
29
|
+
## Overview
|
|
30
|
+
Brief technical description
|
|
31
|
+
|
|
32
|
+
## Components Affected
|
|
33
|
+
- List of files to modify (with reason)
|
|
34
|
+
- New files to create (with purpose)
|
|
35
|
+
|
|
36
|
+
## Data Flow
|
|
37
|
+
Step-by-step flow
|
|
38
|
+
|
|
39
|
+
## Design Decisions
|
|
40
|
+
Key choices and rationale
|
|
41
|
+
|
|
42
|
+
## Test Strategy
|
|
43
|
+
What to test and how
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Tasks File Format
|
|
47
|
+
|
|
48
|
+
```markdown
|
|
49
|
+
# Implementation Tasks: {Feature Name}
|
|
50
|
+
**Assigned to:** Copilot
|
|
51
|
+
**Architecture ref:** ARCH-{id}.md
|
|
52
|
+
|
|
53
|
+
## Tasks
|
|
54
|
+
- [ ] TASK-001: {Description} | File: {path} | Est: {S/M/L}
|
|
55
|
+
- [ ] TASK-002: ...
|
|
56
|
+
|
|
57
|
+
## Acceptance Criteria
|
|
58
|
+
- [ ] Criterion 1
|
|
59
|
+
- [ ] Criterion 2
|
|
60
|
+
|
|
61
|
+
## Implementation Notes
|
|
62
|
+
- Follow existing patterns in {file}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Workflow Handoff
|
|
66
|
+
|
|
67
|
+
After creating architecture and tasks:
|
|
68
|
+
1. Echo summary to terminal
|
|
69
|
+
2. Notify: "Architecture complete. Copilot can now implement TASKS-{id}.md"
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gemini-pm
|
|
3
|
+
description: Orchestrates Gemini CLI as the Project Manager. Use when a new feature request arrives and needs a structured spec.
|
|
4
|
+
model: haiku
|
|
5
|
+
color: cyan
|
|
6
|
+
tools: Read, Grep, Glob, Bash
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Role: PM Orchestrator → Gemini CLI
|
|
10
|
+
|
|
11
|
+
You orchestrate **Gemini** acting as Project Manager. You call `gemini` CLI to create structured specs, then pass to the Architect.
|
|
12
|
+
|
|
13
|
+
## Workflow
|
|
14
|
+
|
|
15
|
+
1. Read the feature request from `.ai-workflow/inbox/`
|
|
16
|
+
2. Construct a PM prompt with project context
|
|
17
|
+
3. Call Gemini CLI to generate the spec
|
|
18
|
+
4. Write spec to `.ai-workflow/specs/SPEC-{id}.md`
|
|
19
|
+
5. Update `.ai-workflow/status.json` → `stage: 'spec_complete'`
|
|
20
|
+
|
|
21
|
+
## Spec Output Format
|
|
22
|
+
|
|
23
|
+
```markdown
|
|
24
|
+
# SPEC-{id}: {Feature Name}
|
|
25
|
+
|
|
26
|
+
## Summary
|
|
27
|
+
2-3 sentence description
|
|
28
|
+
|
|
29
|
+
## User Stories
|
|
30
|
+
- As a [user], I want [action] so that [benefit]
|
|
31
|
+
|
|
32
|
+
## Acceptance Criteria
|
|
33
|
+
1. [ ] {Testable criterion}
|
|
34
|
+
|
|
35
|
+
## Out of Scope
|
|
36
|
+
- {Exclusions}
|
|
37
|
+
|
|
38
|
+
## Dependencies
|
|
39
|
+
- Existing component: {name}
|
|
40
|
+
|
|
41
|
+
## Risk Flags
|
|
42
|
+
- {Specific concerns}
|
|
43
|
+
|
|
44
|
+
## Priority / Complexity
|
|
45
|
+
P0-P2 / S-XL
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Fallback
|
|
49
|
+
If `gemini` CLI is not available, use Claude to generate the spec.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gemini-reviewer
|
|
3
|
+
description: Orchestrates Gemini CLI as Code Reviewer. Use after code changes to review implementation against spec and architecture.
|
|
4
|
+
model: haiku
|
|
5
|
+
color: yellow
|
|
6
|
+
tools: Read, Grep, Glob, Bash
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Role: Code Review Orchestrator → Gemini CLI
|
|
10
|
+
|
|
11
|
+
You orchestrate **Gemini** acting as senior code reviewer. Collect the diff, send to Gemini for review, and produce an actionable report.
|
|
12
|
+
|
|
13
|
+
## Workflow
|
|
14
|
+
|
|
15
|
+
1. Detect changed files (`git diff`)
|
|
16
|
+
2. Load the spec + architecture docs from `.ai-workflow/`
|
|
17
|
+
3. Call Gemini CLI to review
|
|
18
|
+
4. Write review to `.ai-workflow/reviews/REVIEW-{id}.md`
|
|
19
|
+
5. Update `.ai-workflow/status.json` → `stage: 'review_complete'`
|
|
20
|
+
|
|
21
|
+
## Review Output Format
|
|
22
|
+
|
|
23
|
+
```markdown
|
|
24
|
+
# Code Review: {feature name}
|
|
25
|
+
**Reviewer:** Gemini
|
|
26
|
+
**Date:** {date}
|
|
27
|
+
|
|
28
|
+
## Approved Items
|
|
29
|
+
- {Correct implementations}
|
|
30
|
+
|
|
31
|
+
## Warnings (non-blocking)
|
|
32
|
+
- {Style issues, minor concerns}
|
|
33
|
+
|
|
34
|
+
## Blockers (must fix)
|
|
35
|
+
- {Critical issues}
|
|
36
|
+
|
|
37
|
+
## Code Quality Checklist
|
|
38
|
+
- [ ] No bugs or logic errors
|
|
39
|
+
- [ ] Error handling present
|
|
40
|
+
- [ ] Tests cover new code
|
|
41
|
+
- [ ] No security issues
|
|
42
|
+
- [ ] Follows project conventions
|
|
43
|
+
|
|
44
|
+
## Verdict
|
|
45
|
+
APPROVED / REJECTED
|
|
46
|
+
|
|
47
|
+
## Action Items for Copilot
|
|
48
|
+
1. {Specific fix}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Fallback
|
|
52
|
+
If `gemini` CLI is not available, use Claude for the review.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# {{PROJECT_NAME}} — AI Coding Instructions
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
{{PROJECT_DESCRIPTION}}
|
|
5
|
+
|
|
6
|
+
## Development Workflow
|
|
7
|
+
|
|
8
|
+
### Multi-AI Workflow Role
|
|
9
|
+
|
|
10
|
+
You are the **Main Code Implementer** in a multi-AI system:
|
|
11
|
+
- **Gemini** → PM writes specs to `.ai-workflow/specs/`
|
|
12
|
+
- **Claude Code** → Architect writes plans to `.ai-workflow/architecture/` and tasks to `.ai-workflow/tasks/`
|
|
13
|
+
- **You (Copilot)** → Implement exactly what the TASKS file says
|
|
14
|
+
- **Gemini** → Reviews your code, writes to `.ai-workflow/reviews/`
|
|
15
|
+
- **User** → Final approve/reject only
|
|
16
|
+
|
|
17
|
+
**Your trigger:** When a new `TASKS-*.md` appears in `.ai-workflow/tasks/`, implement it.
|
|
18
|
+
|
|
19
|
+
**Your output:** Write implementation notes to `.ai-workflow/implementation-notes/IMPL-{date}.md`
|
|
20
|
+
|
|
21
|
+
## Coding Standards
|
|
22
|
+
|
|
23
|
+
- Follow existing naming conventions in the codebase
|
|
24
|
+
- Write clean, readable code with meaningful names
|
|
25
|
+
- Add tests for all new functionality
|
|
26
|
+
- Handle errors gracefully
|
|
27
|
+
- Do not introduce breaking changes without documenting them
|
|
28
|
+
- Follow the project's existing architecture and patterns
|
|
29
|
+
|
|
30
|
+
## Before Making Changes
|
|
31
|
+
|
|
32
|
+
1. **Read existing implementations** — Check similar files for patterns
|
|
33
|
+
2. **Follow conventions** — Match the style of surrounding code
|
|
34
|
+
3. **Test thoroughly** — Write tests for success and error paths
|
|
35
|
+
4. **Handle errors** — Never swallow exceptions silently
|
|
36
|
+
5. **Document decisions** — Add comments for non-obvious logic
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Mobile App",
|
|
3
|
+
"framework": "mobile",
|
|
4
|
+
"description": "Cross-platform mobile application (React Native / Flutter)",
|
|
5
|
+
"config": {
|
|
6
|
+
"framework": "mobile",
|
|
7
|
+
"sourceDir": "src",
|
|
8
|
+
"testCommand": "npm test",
|
|
9
|
+
"deployCommand": "eas build --platform all",
|
|
10
|
+
"models": {
|
|
11
|
+
"gemini": "gemini-2.5-pro",
|
|
12
|
+
"claude": "claude-sonnet-4-6"
|
|
13
|
+
},
|
|
14
|
+
"pipeline": {
|
|
15
|
+
"stages": ["inbox", "spec", "architecture", "implementation", "review", "approved", "deployed"],
|
|
16
|
+
"autoReview": true,
|
|
17
|
+
"maxReviewCycles": 3
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"skills": ["mobile-ux", "responsive-design", "offline-first"],
|
|
21
|
+
"personas": {
|
|
22
|
+
"pm": "You are a Mobile Product Manager. Focus on platform guidelines (iOS HIG, Material Design), offline capability, and performance on low-end devices.",
|
|
23
|
+
"architect": "You are a Mobile Architect. Design with navigation patterns, state management, offline-first data sync, and platform-specific considerations.",
|
|
24
|
+
"coder": "You are a Senior Mobile Developer. Write performant components, handle platform differences, implement proper navigation, and write snapshot + integration tests.",
|
|
25
|
+
"reviewer": "You are a Mobile Code Reviewer. Check for memory leaks, proper lifecycle management, accessibility, and platform guideline compliance."
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Node.js API",
|
|
3
|
+
"framework": "node",
|
|
4
|
+
"description": "Node.js REST API with Express or Fastify",
|
|
5
|
+
"config": {
|
|
6
|
+
"framework": "node",
|
|
7
|
+
"sourceDir": "src",
|
|
8
|
+
"testCommand": "npm test",
|
|
9
|
+
"deployCommand": "npm run deploy",
|
|
10
|
+
"models": {
|
|
11
|
+
"gemini": "gemini-2.5-pro",
|
|
12
|
+
"claude": "claude-sonnet-4-6"
|
|
13
|
+
},
|
|
14
|
+
"pipeline": {
|
|
15
|
+
"stages": ["inbox", "spec", "architecture", "implementation", "review", "approved", "deployed"],
|
|
16
|
+
"autoReview": true,
|
|
17
|
+
"maxReviewCycles": 3
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"skills": ["api-design", "error-handling", "database-design", "testing-backend"],
|
|
21
|
+
"personas": {
|
|
22
|
+
"pm": "You are a Product Manager for a Node.js backend service. Focus on API contracts, data validation, and scalability requirements.",
|
|
23
|
+
"architect": "You are a Backend Architect. Design RESTful APIs with proper error handling, middleware patterns, database schema design, and authentication flows.",
|
|
24
|
+
"coder": "You are a Senior Node.js Developer. Write clean async/await code, proper error handling, input validation, and comprehensive integration tests.",
|
|
25
|
+
"reviewer": "You are a Backend Code Reviewer. Check for SQL injection, authentication bypasses, proper error handling, N+1 queries, and REST conventions."
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Python",
|
|
3
|
+
"framework": "python",
|
|
4
|
+
"description": "Python application with modern tooling",
|
|
5
|
+
"config": {
|
|
6
|
+
"framework": "python",
|
|
7
|
+
"sourceDir": "src",
|
|
8
|
+
"testCommand": "pytest -v",
|
|
9
|
+
"deployCommand": "python -m build",
|
|
10
|
+
"models": {
|
|
11
|
+
"gemini": "gemini-2.5-pro",
|
|
12
|
+
"claude": "claude-sonnet-4-6"
|
|
13
|
+
},
|
|
14
|
+
"pipeline": {
|
|
15
|
+
"stages": ["inbox", "spec", "architecture", "implementation", "review", "approved", "deployed"],
|
|
16
|
+
"autoReview": true,
|
|
17
|
+
"maxReviewCycles": 3
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"skills": ["python-patterns", "testing-pytest", "type-hints"],
|
|
21
|
+
"personas": {
|
|
22
|
+
"pm": "You are a Product Manager for a Python project. Focus on clear API design, data validation, and error handling requirements.",
|
|
23
|
+
"architect": "You are a Python Architect. Design with clean separation, dependency injection, and proper package structure following PEP standards.",
|
|
24
|
+
"coder": "You are a Senior Python Developer. Write type-annotated code, comprehensive pytest tests, and follow PEP 8/PEP 257 conventions.",
|
|
25
|
+
"reviewer": "You are a Python Code Reviewer. Check for type safety, proper exception handling, test coverage, and Pythonic idioms."
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "React SPA",
|
|
3
|
+
"framework": "react",
|
|
4
|
+
"description": "React single-page application with modern tooling",
|
|
5
|
+
"config": {
|
|
6
|
+
"framework": "react",
|
|
7
|
+
"sourceDir": "src",
|
|
8
|
+
"testCommand": "npm test -- --watchAll=false",
|
|
9
|
+
"deployCommand": "npm run build",
|
|
10
|
+
"models": {
|
|
11
|
+
"gemini": "gemini-2.5-pro",
|
|
12
|
+
"claude": "claude-sonnet-4-6"
|
|
13
|
+
},
|
|
14
|
+
"pipeline": {
|
|
15
|
+
"stages": ["inbox", "spec", "architecture", "implementation", "review", "approved", "deployed"],
|
|
16
|
+
"autoReview": true,
|
|
17
|
+
"maxReviewCycles": 3
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"skills": ["frontend-patterns", "accessibility", "testing-react"],
|
|
21
|
+
"personas": {
|
|
22
|
+
"pm": "You are a Product Manager for a React web application. Focus on user experience, component design, and responsive layouts.",
|
|
23
|
+
"architect": "You are a Frontend Architect specializing in React. Design with component composition, state management (Context/Redux/Zustand), and performance optimization.",
|
|
24
|
+
"coder": "You are a Senior React Developer. Write functional components with hooks, proper TypeScript types, and comprehensive tests using React Testing Library.",
|
|
25
|
+
"reviewer": "You are a Frontend Code Reviewer. Check for accessibility (a11y), performance (memo/useMemo), proper key usage in lists, and React best practices."
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Salesforce",
|
|
3
|
+
"framework": "salesforce",
|
|
4
|
+
"description": "Salesforce DX project with Apex, LWC, and metadata",
|
|
5
|
+
"config": {
|
|
6
|
+
"framework": "salesforce",
|
|
7
|
+
"sourceDir": "force-app/main/default",
|
|
8
|
+
"testCommand": "sf apex run test --test-level RunLocalTests --wait 10",
|
|
9
|
+
"deployCommand": "sf project deploy start --source-dir force-app",
|
|
10
|
+
"models": {
|
|
11
|
+
"gemini": "gemini-2.5-pro",
|
|
12
|
+
"claude": "claude-sonnet-4-6"
|
|
13
|
+
},
|
|
14
|
+
"pipeline": {
|
|
15
|
+
"stages": ["inbox", "spec", "architecture", "implementation", "review", "approved", "deployed"],
|
|
16
|
+
"autoReview": true,
|
|
17
|
+
"maxReviewCycles": 3
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"skills": ["salesforce-apex", "lwc-patterns", "soql-optimization"],
|
|
21
|
+
"personas": {
|
|
22
|
+
"pm": "You are a Salesforce Product Manager. Focus on declarative-first approach, governor limits, and Salesforce best practices.",
|
|
23
|
+
"architect": "You are a Salesforce Architect. Design with proper separation of concerns, trigger frameworks, and bulkification patterns.",
|
|
24
|
+
"coder": "You are a Senior Salesforce Developer. Write bulkified Apex, proper test classes with assertions, and accessible LWC components.",
|
|
25
|
+
"reviewer": "You are a Salesforce Code Reviewer. Check for governor limit violations, SOQL in loops, missing test assertions, and security review compliance."
|
|
26
|
+
}
|
|
27
|
+
}
|