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,164 @@
|
|
|
1
|
+
import { formatForOffice, formatForTelegram, formatForWebSocket } from './agent-messenger.js';
|
|
2
|
+
import { openThread, postToThread, resolveThread, getOpenThreads } from './discussion-threads.js';
|
|
3
|
+
|
|
4
|
+
const MAX_HISTORY = 100;
|
|
5
|
+
const _history = [];
|
|
6
|
+
const _ceoHandlers = [];
|
|
7
|
+
let _bus = null;
|
|
8
|
+
let _ceoPendingResolvers = []; // resolvers for askCEO promises
|
|
9
|
+
|
|
10
|
+
export function initRoom(bus) {
|
|
11
|
+
_bus = bus;
|
|
12
|
+
|
|
13
|
+
// Translate pipeline-event events into room messages for display
|
|
14
|
+
bus.on('pipeline-event', ({ event, data }) => {
|
|
15
|
+
// Map pipeline events to room messages for display
|
|
16
|
+
const stageMessages = {
|
|
17
|
+
stage_start: (d) => postAction(d.role || 'system', `Started ${d.stage || 'stage'}`, d),
|
|
18
|
+
stage_complete: (d) => postAction(d.role || 'system', `Completed ${d.stage || 'stage'}`, d),
|
|
19
|
+
stage_error: (d) => postMessage('system', `Error in ${d.stage || 'stage'}: ${d.error || 'unknown'}`, { type: 'error' }),
|
|
20
|
+
};
|
|
21
|
+
const handler = stageMessages[event];
|
|
22
|
+
if (handler) {
|
|
23
|
+
try { handler(data); } catch { /* non-fatal */ }
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Thread event handlers
|
|
28
|
+
bus.on('pipeline-event', ({ event, data }) => {
|
|
29
|
+
if (event === 'room:thread_opened' && data) {
|
|
30
|
+
postMessage('system', `New discussion: "${data.title}" (opened by ${data.openedBy})`, { type: 'thread' });
|
|
31
|
+
}
|
|
32
|
+
if (event === 'room:thread_escalated' && data) {
|
|
33
|
+
postMessage('pm', `Thread needs your attention: "${data.thread?.title}"\nReason: ${data.reason}`, { type: 'question' });
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
postMessage,
|
|
39
|
+
postAction,
|
|
40
|
+
askCEO,
|
|
41
|
+
onCEOMessage,
|
|
42
|
+
getRoomHistory,
|
|
43
|
+
openThread,
|
|
44
|
+
postToThread,
|
|
45
|
+
resolveThread,
|
|
46
|
+
getOpenThreads,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function postMessage(role, message, options = {}) {
|
|
51
|
+
const entry = {
|
|
52
|
+
role,
|
|
53
|
+
message,
|
|
54
|
+
type: options.type || 'text',
|
|
55
|
+
targetRole: options.targetRole || null,
|
|
56
|
+
replyTo: options.replyTo || null,
|
|
57
|
+
buttons: options.buttons || null,
|
|
58
|
+
timestamp: new Date().toISOString(),
|
|
59
|
+
};
|
|
60
|
+
_history.push(entry);
|
|
61
|
+
if (_history.length > MAX_HISTORY) _history.shift();
|
|
62
|
+
|
|
63
|
+
if (_bus) {
|
|
64
|
+
_bus.emitEvent('room:message', entry);
|
|
65
|
+
}
|
|
66
|
+
return entry;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function postAction(role, action, details = {}) {
|
|
70
|
+
const entry = {
|
|
71
|
+
role,
|
|
72
|
+
action,
|
|
73
|
+
details,
|
|
74
|
+
type: 'action',
|
|
75
|
+
timestamp: new Date().toISOString(),
|
|
76
|
+
};
|
|
77
|
+
_history.push(entry);
|
|
78
|
+
if (_history.length > MAX_HISTORY) _history.shift();
|
|
79
|
+
|
|
80
|
+
if (_bus) {
|
|
81
|
+
_bus.emitEvent('room:action', entry);
|
|
82
|
+
}
|
|
83
|
+
return entry;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function askCEO(question, options = {}) {
|
|
87
|
+
const timeout = options.timeout || 300000; // 5 min default
|
|
88
|
+
|
|
89
|
+
return new Promise((resolve) => {
|
|
90
|
+
const entry = {
|
|
91
|
+
role: 'pm',
|
|
92
|
+
message: question,
|
|
93
|
+
type: 'question',
|
|
94
|
+
buttons: options.buttons || null,
|
|
95
|
+
timestamp: new Date().toISOString(),
|
|
96
|
+
};
|
|
97
|
+
_history.push(entry);
|
|
98
|
+
if (_history.length > MAX_HISTORY) _history.shift();
|
|
99
|
+
|
|
100
|
+
if (_bus) {
|
|
101
|
+
_bus.emitEvent('room:ask_ceo', { ...entry, options });
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Register resolver
|
|
105
|
+
const resolver = { resolve, timeout: null };
|
|
106
|
+
_ceoPendingResolvers.push(resolver);
|
|
107
|
+
|
|
108
|
+
// Auto-resolve on timeout
|
|
109
|
+
resolver.timeout = setTimeout(() => {
|
|
110
|
+
const idx = _ceoPendingResolvers.indexOf(resolver);
|
|
111
|
+
if (idx !== -1) {
|
|
112
|
+
_ceoPendingResolvers.splice(idx, 1);
|
|
113
|
+
resolve(null); // null = timeout, PM decides autonomously
|
|
114
|
+
}
|
|
115
|
+
}, timeout);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function resolveCEOResponse(response) {
|
|
120
|
+
if (_bus) {
|
|
121
|
+
_bus.emitEvent('room:ceo_response', { response, timestamp: new Date().toISOString() });
|
|
122
|
+
}
|
|
123
|
+
const resolvers = _ceoPendingResolvers.splice(0);
|
|
124
|
+
for (const r of resolvers) {
|
|
125
|
+
clearTimeout(r.timeout);
|
|
126
|
+
r.resolve(response);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function onCEOMessage(handler) {
|
|
131
|
+
_ceoHandlers.push(handler);
|
|
132
|
+
return () => {
|
|
133
|
+
const idx = _ceoHandlers.indexOf(handler);
|
|
134
|
+
if (idx !== -1) _ceoHandlers.splice(idx, 1);
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function dispatchCEOMessage(message, ctx = null) {
|
|
139
|
+
// Record CEO message in room history so AI has conversation context
|
|
140
|
+
const entry = {
|
|
141
|
+
role: 'ceo',
|
|
142
|
+
message,
|
|
143
|
+
type: 'text',
|
|
144
|
+
timestamp: new Date().toISOString(),
|
|
145
|
+
};
|
|
146
|
+
_history.push(entry);
|
|
147
|
+
if (_history.length > MAX_HISTORY) _history.shift();
|
|
148
|
+
|
|
149
|
+
if (_bus) {
|
|
150
|
+
_bus.emitEvent('room:ceo_response', { response: message, timestamp: new Date().toISOString() });
|
|
151
|
+
}
|
|
152
|
+
for (const handler of _ceoHandlers) {
|
|
153
|
+
try { handler(message, ctx); } catch { /* non-fatal */ }
|
|
154
|
+
}
|
|
155
|
+
// Also resolve any pending askCEO promises
|
|
156
|
+
resolveCEOResponse(message);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function getRoomHistory(limit = 50) {
|
|
160
|
+
return _history.slice(-limit);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Re-export thread functions for convenience
|
|
164
|
+
export { openThread, postToThread, resolveThread, getOpenThreads };
|