- Restructure: pcexec/ and safe-restart/ → plugin/{tools,core,commands}
- New pcguard Go binary: validates AGENT_VERIFY, AGENT_ID, AGENT_WORKSPACE
- pcexec now injects AGENT_VERIFY env + appends openclaw bin to PATH
- plugin/index.ts: unified TypeScript entry point with resolveOpenclawPath()
- install.mjs: support --openclaw-profile-path, install pcguard, new paths
- README: updated structure docs + security limitations note
- Removed old root index.js and openclaw.plugin.json
101 lines
2.3 KiB
TypeScript
101 lines
2.3 KiB
TypeScript
import express from 'express';
|
|
import { StatusManager } from './status-manager';
|
|
|
|
export interface ApiOptions {
|
|
port?: number;
|
|
statusManager: StatusManager;
|
|
}
|
|
|
|
/**
|
|
* Creates and starts the REST API server for query-restart
|
|
*/
|
|
export function createApiServer(options: ApiOptions): express.Application {
|
|
const { port = 8765, statusManager } = options;
|
|
const app = express();
|
|
|
|
app.use(express.json());
|
|
|
|
// POST /query-restart
|
|
app.post('/query-restart', (req, res) => {
|
|
const { requesterAgentId, requesterSessionKey } = req.body;
|
|
|
|
if (!requesterAgentId || !requesterSessionKey) {
|
|
return res.status(400).json({
|
|
error: 'Missing required fields: requesterAgentId, requesterSessionKey',
|
|
});
|
|
}
|
|
|
|
const result = statusManager.queryRestart(requesterAgentId, requesterSessionKey);
|
|
|
|
res.json({
|
|
status: result,
|
|
timestamp: Date.now(),
|
|
});
|
|
});
|
|
|
|
// POST /restart-result
|
|
app.post('/restart-result', (req, res) => {
|
|
const { status, log } = req.body;
|
|
|
|
if (!status || !['ok', 'failed'].includes(status)) {
|
|
return res.status(400).json({
|
|
error: 'Invalid status. Must be "ok" or "failed"',
|
|
});
|
|
}
|
|
|
|
statusManager.completeRestart(status === 'ok', log);
|
|
|
|
res.json({
|
|
success: true,
|
|
timestamp: Date.now(),
|
|
});
|
|
});
|
|
|
|
// GET /status
|
|
app.get('/status', (req, res) => {
|
|
const agents = statusManager.getAllAgents();
|
|
const global = statusManager.getGlobalStatus();
|
|
|
|
res.json({
|
|
agents,
|
|
global,
|
|
timestamp: Date.now(),
|
|
});
|
|
});
|
|
|
|
// GET /agent/:agentId
|
|
app.get('/agent/:agentId', (req, res) => {
|
|
const { agentId } = req.params;
|
|
const agent = statusManager.getAgent(agentId);
|
|
|
|
if (!agent) {
|
|
return res.status(404).json({
|
|
error: `Agent ${agentId} not found`,
|
|
});
|
|
}
|
|
|
|
res.json({
|
|
agent,
|
|
timestamp: Date.now(),
|
|
});
|
|
});
|
|
|
|
return app;
|
|
}
|
|
|
|
export function startApiServer(options: ApiOptions): Promise<void> {
|
|
const { port = 8765 } = options;
|
|
const app = createApiServer(options);
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const server = app.listen(port, () => {
|
|
console.log(`Safe-restart API server listening on port ${port}`);
|
|
resolve();
|
|
});
|
|
|
|
server.on('error', (err) => {
|
|
reject(err);
|
|
});
|
|
});
|
|
}
|