galaxy-opc-plugin 0.2.9 → 0.3.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/index.ts +0 -2
- package/package.json +1 -1
- package/src/api/companies.ts +4 -8
- package/src/api/dashboard.ts +37 -16
- package/src/api/routes.ts +0 -2
- package/src/web/config-ui.ts +4 -8
- package/src/web/landing-page.ts +6 -15
package/index.ts
CHANGED
|
@@ -47,7 +47,6 @@ import { registerOrderTool } from "./src/tools/order-tool.js";
|
|
|
47
47
|
import { registerOpcCommand } from "./src/commands/opc-command.js";
|
|
48
48
|
import { triggerEventRules } from "./src/opc/event-triggers.js";
|
|
49
49
|
import { registerConfigUi } from "./src/web/config-ui.js";
|
|
50
|
-
import { registerLandingPage } from "./src/web/landing-page.js";
|
|
51
50
|
|
|
52
51
|
/** 解析数据库路径,支持 ~ 前缀 */
|
|
53
52
|
function resolveDbPath(configured?: string): string {
|
|
@@ -153,7 +152,6 @@ const plugin = {
|
|
|
153
152
|
|
|
154
153
|
// 注册 Web UI
|
|
155
154
|
registerConfigUi(api, db, gatewayToken);
|
|
156
|
-
registerLandingPage(api);
|
|
157
155
|
|
|
158
156
|
// ── 智能刷新器(共享函数,after_tool_call + subagent_ended 共用) ──
|
|
159
157
|
const refreshTimers = new Map<string, ReturnType<typeof setTimeout>>();
|
package/package.json
CHANGED
package/src/api/companies.ts
CHANGED
|
@@ -208,7 +208,7 @@ export function registerCompanyRoutes(api: OpenClawPluginApi, db: OpcDatabase, g
|
|
|
208
208
|
|
|
209
209
|
const apiAny = api as unknown as {
|
|
210
210
|
registerHttpHandler?: (h: (req: IncomingMessage, res: ServerResponse) => Promise<boolean> | boolean) => void;
|
|
211
|
-
registerHttpRoute?: (r: { path: string
|
|
211
|
+
registerHttpRoute?: (r: { path: string; handler: (req: IncomingMessage, res: ServerResponse) => Promise<boolean | void> | boolean | void; auth: string; match?: string }) => void;
|
|
212
212
|
};
|
|
213
213
|
|
|
214
214
|
if (typeof apiAny.registerHttpHandler === "function") {
|
|
@@ -216,13 +216,9 @@ export function registerCompanyRoutes(api: OpenClawPluginApi, db: OpcDatabase, g
|
|
|
216
216
|
} else if (typeof apiAny.registerHttpRoute === "function") {
|
|
217
217
|
apiAny.registerHttpRoute({
|
|
218
218
|
path: "/opc/api/companies",
|
|
219
|
-
handler
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
res.writeHead(404, { "Content-Type": "application/json; charset=utf-8" });
|
|
223
|
-
res.end(JSON.stringify({ error: "Not found" }));
|
|
224
|
-
}
|
|
225
|
-
},
|
|
219
|
+
handler,
|
|
220
|
+
auth: "plugin",
|
|
221
|
+
match: "prefix",
|
|
226
222
|
});
|
|
227
223
|
} else {
|
|
228
224
|
throw new Error("No compatible HTTP registration API found on OpenClaw plugin API");
|
package/src/api/dashboard.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* POST /opc/admin/api/alerts/:id/dismiss — 忽略预警
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
9
10
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
10
11
|
import type { OpcDatabase } from "../db/index.js";
|
|
11
12
|
import {
|
|
@@ -60,10 +61,14 @@ interface TodoRow {
|
|
|
60
61
|
* 注册 Dashboard API 路由
|
|
61
62
|
*/
|
|
62
63
|
export function registerDashboardApiRoutes(api: OpenClawPluginApi, db: OpcDatabase): void {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
const handler = async (req: IncomingMessage, res: ServerResponse): Promise<boolean> => {
|
|
65
|
+
const rawUrl = req.url ?? "";
|
|
66
|
+
const urlObj = new URL(rawUrl, "http://localhost");
|
|
67
|
+
const pathname = urlObj.pathname;
|
|
68
|
+
const method = req.method?.toUpperCase() ?? "GET";
|
|
69
|
+
|
|
70
|
+
// GET /opc/admin/api/dashboard
|
|
71
|
+
if (pathname === "/opc/admin/api/dashboard" && method === "GET") {
|
|
67
72
|
try {
|
|
68
73
|
const data = getDashboardData(db);
|
|
69
74
|
const html = generateDashboardHtml(data);
|
|
@@ -73,22 +78,19 @@ export function registerDashboardApiRoutes(api: OpenClawPluginApi, db: OpcDataba
|
|
|
73
78
|
res.writeHead(500, { "Content-Type": "application/json; charset=utf-8" });
|
|
74
79
|
res.end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }));
|
|
75
80
|
}
|
|
76
|
-
|
|
77
|
-
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
78
83
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
handler: async (req, res) => {
|
|
84
|
+
// POST /opc/admin/api/alerts/:id/dismiss
|
|
85
|
+
const alertMatch = pathname.match(/^\/opc\/admin\/api\/alerts\/([^/]+)\/dismiss$/);
|
|
86
|
+
if (alertMatch && method === "POST") {
|
|
83
87
|
try {
|
|
84
|
-
const
|
|
85
|
-
const pathParts = url.pathname.split("/");
|
|
86
|
-
const alertId = pathParts[pathParts.length - 2]; // .../alerts/{id}/dismiss
|
|
88
|
+
const alertId = alertMatch[1];
|
|
87
89
|
|
|
88
90
|
if (!alertId) {
|
|
89
91
|
res.writeHead(400, { "Content-Type": "application/json; charset=utf-8" });
|
|
90
92
|
res.end(JSON.stringify({ error: "Missing alert ID" }));
|
|
91
|
-
return;
|
|
93
|
+
return true;
|
|
92
94
|
}
|
|
93
95
|
|
|
94
96
|
const now = new Date().toISOString();
|
|
@@ -109,8 +111,27 @@ export function registerDashboardApiRoutes(api: OpenClawPluginApi, db: OpcDataba
|
|
|
109
111
|
res.writeHead(500, { "Content-Type": "application/json; charset=utf-8" });
|
|
110
112
|
res.end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }));
|
|
111
113
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return false;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const apiAny = api as unknown as {
|
|
121
|
+
registerHttpHandler?: (h: (req: IncomingMessage, res: ServerResponse) => Promise<boolean> | boolean) => void;
|
|
122
|
+
registerHttpRoute?: (r: { path: string; handler: (req: IncomingMessage, res: ServerResponse) => Promise<boolean | void> | boolean | void; auth: string; match?: string }) => void;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
if (typeof apiAny.registerHttpHandler === "function") {
|
|
126
|
+
apiAny.registerHttpHandler(handler);
|
|
127
|
+
} else if (typeof apiAny.registerHttpRoute === "function") {
|
|
128
|
+
apiAny.registerHttpRoute({
|
|
129
|
+
path: "/opc/admin/api",
|
|
130
|
+
handler,
|
|
131
|
+
auth: "plugin",
|
|
132
|
+
match: "prefix",
|
|
133
|
+
});
|
|
134
|
+
}
|
|
114
135
|
}
|
|
115
136
|
|
|
116
137
|
/**
|
package/src/api/routes.ts
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
6
6
|
import type { OpcDatabase } from "../db/index.js";
|
|
7
7
|
import { registerCompanyRoutes } from "./companies.js";
|
|
8
|
-
import { registerDashboardApiRoutes } from "./dashboard.js";
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* 从 OpenClaw 配置中读取 gateway auth token。
|
|
@@ -26,6 +25,5 @@ export function registerHttpRoutes(api: OpenClawPluginApi, db: OpcDatabase): voi
|
|
|
26
25
|
const gatewayToken = getGatewayToken(api);
|
|
27
26
|
|
|
28
27
|
registerCompanyRoutes(api, db, gatewayToken);
|
|
29
|
-
registerDashboardApiRoutes(api, db);
|
|
30
28
|
api.logger.info("opc: 已注册 HTTP API 路由");
|
|
31
29
|
}
|
package/src/web/config-ui.ts
CHANGED
|
@@ -4173,7 +4173,7 @@ export function registerConfigUi(api: OpenClawPluginApi, db: OpcDatabase, gatewa
|
|
|
4173
4173
|
|
|
4174
4174
|
const apiAny = api as unknown as {
|
|
4175
4175
|
registerHttpHandler?: (h: (req: IncomingMessage, res: ServerResponse) => Promise<boolean> | boolean) => void;
|
|
4176
|
-
registerHttpRoute?: (r: { path: string
|
|
4176
|
+
registerHttpRoute?: (r: { path: string; handler: (req: IncomingMessage, res: ServerResponse) => Promise<boolean | void> | boolean | void; auth: string; match?: string }) => void;
|
|
4177
4177
|
};
|
|
4178
4178
|
|
|
4179
4179
|
if (typeof apiAny.registerHttpHandler === "function") {
|
|
@@ -4181,13 +4181,9 @@ export function registerConfigUi(api: OpenClawPluginApi, db: OpcDatabase, gatewa
|
|
|
4181
4181
|
} else if (typeof apiAny.registerHttpRoute === "function") {
|
|
4182
4182
|
apiAny.registerHttpRoute({
|
|
4183
4183
|
path: "/opc/admin",
|
|
4184
|
-
handler
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
res.writeHead(404, { "Content-Type": "application/json; charset=utf-8" });
|
|
4188
|
-
res.end(JSON.stringify({ error: "Not found" }));
|
|
4189
|
-
}
|
|
4190
|
-
},
|
|
4184
|
+
handler,
|
|
4185
|
+
auth: "plugin",
|
|
4186
|
+
match: "prefix",
|
|
4191
4187
|
});
|
|
4192
4188
|
} else {
|
|
4193
4189
|
throw new Error("No compatible HTTP registration API found on OpenClaw plugin API");
|
package/src/web/landing-page.ts
CHANGED
|
@@ -317,25 +317,16 @@ export function registerLandingPage(api: OpenClawPluginApi): void {
|
|
|
317
317
|
|
|
318
318
|
const apiAny = api as unknown as {
|
|
319
319
|
registerHttpHandler?: (h: (req: IncomingMessage, res: ServerResponse) => Promise<boolean> | boolean) => void;
|
|
320
|
-
registerHttpRoute?: (r: { path: string
|
|
320
|
+
registerHttpRoute?: (r: { path: string; handler: (req: IncomingMessage, res: ServerResponse) => Promise<boolean | void> | boolean | void; auth: string; match?: string }) => void;
|
|
321
321
|
};
|
|
322
322
|
|
|
323
323
|
if (typeof apiAny.registerHttpHandler === "function") {
|
|
324
|
+
// 旧版 openclaw:通过 registerHttpHandler 注册,返回 false 时 openclaw 继续处理聊天 UI
|
|
324
325
|
apiAny.registerHttpHandler(handler);
|
|
325
|
-
|
|
326
|
-
apiAny.registerHttpRoute({
|
|
327
|
-
path: "/",
|
|
328
|
-
handler: async (req, res) => {
|
|
329
|
-
const handled = await handler(req, res);
|
|
330
|
-
if (!handled) {
|
|
331
|
-
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
|
|
332
|
-
res.end("Not found");
|
|
333
|
-
}
|
|
334
|
-
},
|
|
335
|
-
});
|
|
326
|
+
api.logger.info("opc: 已注册产品官网 (/)");
|
|
336
327
|
} else {
|
|
337
|
-
|
|
328
|
+
// 新版 openclaw (2026.3.2+):跳过官网注册,保留 openclaw 原生聊天 UI 在 /
|
|
329
|
+
// 用户通过 /opc/admin 直接访问管理后台
|
|
330
|
+
api.logger.info("opc: 跳过官网注册(新版 openclaw,聊天 UI 保留在 /)");
|
|
338
331
|
}
|
|
339
|
-
|
|
340
|
-
api.logger.info("opc: 已注册产品官网 (/)");
|
|
341
332
|
}
|