mu-agent-bridge 1.0.4 → 1.0.5
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.
|
@@ -41,6 +41,9 @@
|
|
|
41
41
|
head.append(headRow);
|
|
42
42
|
const body = document.createElement("tbody");
|
|
43
43
|
for (const plugin of items) {
|
|
44
|
+
const installed = plugins.find((item) => item.id === plugin.name.replace(/^agent-bridge-/, ""));
|
|
45
|
+
const versionStatus = installed ? pluginVersions[installed.id] : undefined;
|
|
46
|
+
const isUpgrade = Boolean(installed && versionStatus?.packageName === plugin.name && newerVersion(plugin.version, installed.version));
|
|
44
47
|
const row = document.createElement("tr");
|
|
45
48
|
for (const value of [plugin.name, `v${plugin.version}`, typeNames[plugin.type] ?? plugin.type, plugin.description || "无描述"]) {
|
|
46
49
|
const cell = document.createElement("td");
|
|
@@ -48,21 +51,23 @@
|
|
|
48
51
|
row.append(cell);
|
|
49
52
|
}
|
|
50
53
|
const actionCell = document.createElement("td");
|
|
54
|
+
const action = isUpgrade ? "升级" : installed ? "已安装" : "安装";
|
|
51
55
|
const install = document.createElement("button");
|
|
52
56
|
install.type = "button";
|
|
53
57
|
install.className = "catalog-action";
|
|
54
|
-
install.title =
|
|
55
|
-
install.
|
|
56
|
-
install.
|
|
57
|
-
install.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
install.
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
install.title = `${action} ${plugin.name}`;
|
|
59
|
+
install.textContent = installingPackages.has(plugin.name) ? "处理中…" : action;
|
|
60
|
+
install.disabled = Boolean(installed && !isUpgrade) || installingPackages.has(plugin.name);
|
|
61
|
+
if (!install.disabled)
|
|
62
|
+
install.onclick = () => {
|
|
63
|
+
installingPackages.add(plugin.name);
|
|
64
|
+
install.disabled = true;
|
|
65
|
+
install.textContent = isUpgrade ? "升级中…" : "安装中…";
|
|
66
|
+
void (isUpgrade ? request(`/api/plugins/${encodeURIComponent(installed.id)}/update`, "POST", { packageName: plugin.name, version: plugin.version }) : request("/api/plugins/install", "POST", { packageName: plugin.name })).then(() => load()).catch((cause) => error(String(cause))).finally(() => { installingPackages.delete(plugin.name); if (install.isConnected) {
|
|
67
|
+
install.disabled = false;
|
|
68
|
+
install.textContent = action;
|
|
69
|
+
} });
|
|
70
|
+
};
|
|
66
71
|
actionCell.append(install);
|
|
67
72
|
row.append(actionCell);
|
|
68
73
|
body.append(row);
|
|
@@ -104,31 +109,41 @@
|
|
|
104
109
|
renderPlugins(installed);
|
|
105
110
|
const groups = identities.groups ?? { evolcore: aids, muAgentBridge: [] };
|
|
106
111
|
aidList.replaceChildren(...[["EvolCore", groups.evolcore], ["mu-agent-bridge", groups.muAgentBridge]].flatMap(([label, values]) => {
|
|
107
|
-
const title = document.createElement("strong");
|
|
108
|
-
title.textContent = String(label);
|
|
109
112
|
const items = values.map((aid) => {
|
|
110
|
-
const item = document.createElement("
|
|
113
|
+
const item = document.createElement("tr");
|
|
111
114
|
item.className = "aid-row";
|
|
112
|
-
const name = document.createElement("
|
|
115
|
+
const name = document.createElement("td");
|
|
113
116
|
name.textContent = aid;
|
|
117
|
+
const source = document.createElement("td");
|
|
118
|
+
source.textContent = String(label);
|
|
114
119
|
const linked = installed.filter((plugin) => pluginConfigs[plugin.id]?.aid === aid).map((plugin) => plugin.displayName || plugin.id);
|
|
115
|
-
const current = document.createElement("
|
|
120
|
+
const current = document.createElement("td");
|
|
116
121
|
current.className = "muted";
|
|
117
|
-
current.textContent = linked.length ?
|
|
122
|
+
current.textContent = linked.length ? linked.join("、") : "未关联插件";
|
|
123
|
+
const action = document.createElement("td");
|
|
118
124
|
const select = document.createElement("select");
|
|
119
125
|
select.setAttribute("aria-label", `${aid} 关联插件`);
|
|
120
126
|
select.append(new Option("关联插件", ""), ...installed.filter((plugin) => plugin.id !== "abweb").map((plugin) => new Option(plugin.displayName || plugin.id, plugin.id)));
|
|
121
127
|
select.onchange = () => { if (select.value)
|
|
122
128
|
void request(`/api/plugins/${encodeURIComponent(select.value)}/aid`, "PATCH", { aid }).then(() => load()).catch((cause) => error(String(cause))); };
|
|
123
|
-
|
|
129
|
+
action.append(select);
|
|
130
|
+
item.append(name, source, current, action);
|
|
124
131
|
return item;
|
|
125
132
|
});
|
|
126
|
-
return
|
|
133
|
+
return items;
|
|
127
134
|
}));
|
|
128
|
-
if (!aids.length)
|
|
129
|
-
|
|
135
|
+
if (!aids.length) {
|
|
136
|
+
const row = document.createElement("tr");
|
|
137
|
+
const cell = document.createElement("td");
|
|
138
|
+
cell.colSpan = 4;
|
|
139
|
+
cell.className = "muted";
|
|
140
|
+
cell.textContent = "当前没有已连接的 AID";
|
|
141
|
+
row.append(cell);
|
|
142
|
+
aidList.append(row);
|
|
143
|
+
}
|
|
130
144
|
node("#aid-count").textContent = `${aids.length} 个`;
|
|
131
145
|
renderMessages(messages.messages ?? []);
|
|
146
|
+
void loadCatalog().catch((cause) => error(String(cause)));
|
|
132
147
|
}
|
|
133
148
|
catch (cause) {
|
|
134
149
|
node("#access-panel").hidden = false;
|
|
@@ -267,5 +282,11 @@
|
|
|
267
282
|
}).catch((cause) => { result.textContent = ""; error(String(cause)); });
|
|
268
283
|
};
|
|
269
284
|
void load();
|
|
270
|
-
|
|
285
|
+
function newerVersion(remote, current) {
|
|
286
|
+
const parse = (value) => { const match = /^(\d+)\.(\d+)\.(\d+)/.exec(value); return match ? match.slice(1).map(Number) : undefined; };
|
|
287
|
+
const a = parse(remote), b = parse(current);
|
|
288
|
+
if (!a || !b)
|
|
289
|
+
return false;
|
|
290
|
+
return a.some((part, index) => part !== b[index] && part > b[index] && a.slice(0, index).every((item, i) => item === b[i]));
|
|
291
|
+
}
|
|
271
292
|
})();
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<div id="settings-panel" role="tabpanel" aria-labelledby="settings-tab">
|
|
15
15
|
<section><div class="section-heading"><h2>版本管理</h2><button id="check-versions" type="button">检查更新</button></div><div id="versions" class="muted"></div></section>
|
|
16
16
|
<section><div class="section-heading"><h2>插件</h2><select id="plugin-picker" aria-label="选择插件"></select></div><div id="plugins" class="plugins"></div><div class="plugin-catalog"><div class="section-heading"><h3>npm 插件目录</h3><button id="search-packages" type="button">刷新目录</button></div><input id="package-search" placeholder="搜索插件名称或功能" aria-label="搜索 npm 插件"><div id="catalog" class="catalog" aria-live="polite"></div></div><form id="install-local-form"><input id="plugin-path" required placeholder="Windows 上的插件目录路径" aria-label="本地插件目录"><button type="submit">安装本地插件</button></form></section>
|
|
17
|
-
<section><div class="section-heading"><h2>已连接 AID</h2><span id="aid-count" class="muted"></span></div><div
|
|
17
|
+
<section><div class="section-heading"><h2>已连接 AID</h2><span id="aid-count" class="muted"></span></div><div class="aid-list"><table class="aid-table"><thead><tr><th scope="col">AID</th><th scope="col">身份来源</th><th scope="col">已关联插件</th><th scope="col">操作</th></tr></thead><tbody id="aids" aria-live="polite"></tbody></table></div><form id="create-aid-form"><input id="new-aid" required placeholder="新 AID,例如 new.agentid.cn" aria-label="新 AID"><input id="owner-aid" required placeholder="owner AID" aria-label="owner AID"><button type="submit">创建 AID</button></form><p id="aid-result" class="muted" role="status"></p></section>
|
|
18
18
|
</div>
|
|
19
19
|
<div id="messages-panel" role="tabpanel" aria-labelledby="messages-tab" hidden><section><div class="section-heading"><h2>最近通信</h2></div><div class="table-scroll"><table><thead><tr><th scope="col">时间</th><th scope="col">插件</th><th scope="col">接收 AID</th><th scope="col">来源 Peer</th><th scope="col">方向</th><th scope="col">消息</th><th scope="col">错误</th></tr></thead><tbody id="messages"></tbody></table></div><p id="messages-empty" class="muted" hidden>暂无通信记录</p></section></div>
|
|
20
20
|
<p id="error" class="error" role="alert" hidden></p>
|
|
@@ -19,11 +19,12 @@ button { cursor: pointer; white-space: nowrap; }
|
|
|
19
19
|
button:hover { background: #e5f2ea; }
|
|
20
20
|
form { display: flex; gap: 8px; }
|
|
21
21
|
form { margin-top: 14px; flex-wrap: wrap; }
|
|
22
|
-
.aid-list {
|
|
23
|
-
.aid-
|
|
24
|
-
.aid-
|
|
25
|
-
.aid-
|
|
26
|
-
.aid-
|
|
22
|
+
.aid-list { overflow-x: auto; margin-top: 12px; }
|
|
23
|
+
.aid-table { width: 100%; min-width: 720px; border-collapse: collapse; table-layout: fixed; font-size: 13px; }
|
|
24
|
+
.aid-table th, .aid-table td { padding: 9px 8px; text-align: left; vertical-align: middle; border-bottom: 1px solid #dce3df; overflow-wrap: anywhere; }
|
|
25
|
+
.aid-table th { color: #566761; font-weight: 600; background: #edf1ef; }
|
|
26
|
+
.aid-table th:nth-child(1) { width: 230px; } .aid-table th:nth-child(2) { width: 145px; } .aid-table th:nth-child(4) { width: 180px; }
|
|
27
|
+
.aid-row select { max-width: 165px; }
|
|
27
28
|
.plugins, .messages { margin-top: 13px; }
|
|
28
29
|
.plugin-row { justify-content: space-between; border-bottom: 1px solid #e0e5e2; padding: 12px 0; flex-wrap: wrap; }
|
|
29
30
|
.plugin-main { flex-wrap: wrap; }
|
|
@@ -50,7 +50,15 @@ function createContext(config = {}) {
|
|
|
50
50
|
strict_1.default.match(String(response.body), /通信记录/);
|
|
51
51
|
strict_1.default.match(String(response.body), /<th scope="col">来源 Peer<\/th>/);
|
|
52
52
|
strict_1.default.match(String(response.body), /id="catalog" class="catalog" aria-live="polite"/);
|
|
53
|
+
strict_1.default.match(String(response.body), /<th scope="col">身份来源<\/th>/);
|
|
54
|
+
strict_1.default.match(String(response.body), /<tbody id="aids" aria-live="polite"><\/tbody>/);
|
|
53
55
|
strict_1.default.doesNotMatch(String(response.body), /id="package-name"/);
|
|
56
|
+
const scriptHandler = routes.get("/abweb/app.js");
|
|
57
|
+
strict_1.default.ok(scriptHandler);
|
|
58
|
+
const script = await scriptHandler({ method: "GET", path: "/abweb/app.js" });
|
|
59
|
+
strict_1.default.match(String(script.body), /"升级"/);
|
|
60
|
+
strict_1.default.match(String(script.body), /"已安装"/);
|
|
61
|
+
strict_1.default.match(String(script.body), /\/update/);
|
|
54
62
|
strict_1.default.equal(response.headers["content-type"], "text/html; charset=utf-8");
|
|
55
63
|
});
|
|
56
64
|
(0, node_test_1.default)("abweb returns 404 for unknown static assets", async () => {
|
package/package.json
CHANGED