@epoch-agent/server 0.17.0 → 0.18.0
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/dist/index.d.ts
CHANGED
|
@@ -1996,6 +1996,16 @@ declare class SessionHub {
|
|
|
1996
1996
|
* 而那一行**本来就在列表里**(列表的另一半来自 DB)。列表没变,不该发。
|
|
1997
1997
|
*/
|
|
1998
1998
|
notifySessionsChanged(sessionId: string): void;
|
|
1999
|
+
/**
|
|
2000
|
+
* 广播「插件那张表变了」(2026-09-24)。语义和「为什么不带 `sessionId`」全在
|
|
2001
|
+
* protocol 的 `plugins-changed` 上。
|
|
2002
|
+
*
|
|
2003
|
+
* 唯一的调用方是 `index.ts` 里那条对 `runtime.plugins.onChange` 的订阅 ——
|
|
2004
|
+
* 同 {@link notifyTasksChanged},Hub 不认识插件表,它在这条链上只负责发帧。
|
|
2005
|
+
*
|
|
2006
|
+
* ⚠️ **它不发给旁听者**(`observe()` 那一路),判据在 {@link publish} 上。
|
|
2007
|
+
*/
|
|
2008
|
+
notifyPluginsChanged(): void;
|
|
1999
2009
|
/**
|
|
2000
2010
|
* 收摊:撤掉倒计时、放弃所有挂起的审批、中止所有在跑的回合。
|
|
2001
2011
|
*
|
|
@@ -2929,6 +2939,9 @@ interface PluginEntryView {
|
|
|
2929
2939
|
marketplace?: string;
|
|
2930
2940
|
active: boolean;
|
|
2931
2941
|
counts?: CountsView;
|
|
2942
|
+
/** 宿主给不给这两枚(2026-09-24)。**runtime 算好的**,这一层原样投影 */
|
|
2943
|
+
updateAllowed: boolean;
|
|
2944
|
+
uninstallAllowed: boolean;
|
|
2932
2945
|
}
|
|
2933
2946
|
/** `PluginSearchHit`(runtime)的镜像 */
|
|
2934
2947
|
interface PluginHitView {
|
|
@@ -2972,6 +2985,14 @@ interface PluginHitView {
|
|
|
2972
2985
|
};
|
|
2973
2986
|
sourceType?: WirePluginSourceType;
|
|
2974
2987
|
installable: boolean;
|
|
2988
|
+
/** 宿主给不给「安装」(2026-09-24)。和 `installable` 是两格,判据在 wire 那一格上 */
|
|
2989
|
+
installAllowed: boolean;
|
|
2990
|
+
/** 卡片菜单(2026-09-24)。runtime 已经收过一遍,`danger` 可缺省 → 这一层补成布尔 */
|
|
2991
|
+
menu: readonly {
|
|
2992
|
+
id: string;
|
|
2993
|
+
label: string;
|
|
2994
|
+
danger?: boolean;
|
|
2995
|
+
}[];
|
|
2975
2996
|
}
|
|
2976
2997
|
/** `InstallPreview`(core,经 runtime 原样透出)的镜像 —— 「将安装什么」那一屏的内容 */
|
|
2977
2998
|
interface PluginPreviewView {
|
|
@@ -3212,6 +3233,16 @@ interface PluginControlView {
|
|
|
3212
3233
|
* 口径逐字同 {@link uploadEnabled}。
|
|
3213
3234
|
*/
|
|
3214
3235
|
readonly refreshEnabled: boolean;
|
|
3236
|
+
/**
|
|
3237
|
+
* 「添加」那一枚画不画(2026-09-24)。**runtime 算好的结论**,口径同 {@link uploadEnabled}
|
|
3238
|
+
*/
|
|
3239
|
+
readonly localInstallEnabled: boolean;
|
|
3240
|
+
/**
|
|
3241
|
+
* 插件那张表变了就叫一声(2026-09-24)。**这个文件不调它** —— 订阅在 `index.ts`,
|
|
3242
|
+
* 转成一帧 `plugins-changed`(判据在 protocol 那一帧上)。镜像上有它是因为
|
|
3243
|
+
* `ApiContext.runtime.plugins` 就是这份镜像,而那条订阅要从它上面拿。
|
|
3244
|
+
*/
|
|
3245
|
+
onChange(listener: () => void): () => void;
|
|
3215
3246
|
/**
|
|
3216
3247
|
* 一个压缩包 → 一条已经验过的插件目录路径(2026-09-11,落区那一条)。
|
|
3217
3248
|
*
|
package/dist/index.js
CHANGED
|
@@ -597,6 +597,10 @@ var SessionHub = class {
|
|
|
597
597
|
if (this.closed) return;
|
|
598
598
|
this.publish(sessionId, { type: "sessions-changed" });
|
|
599
599
|
}
|
|
600
|
+
notifyPluginsChanged() {
|
|
601
|
+
if (this.closed) return;
|
|
602
|
+
this.publish(void 0, { type: "plugins-changed" });
|
|
603
|
+
}
|
|
600
604
|
shutdown() {
|
|
601
605
|
if (this.closed) return;
|
|
602
606
|
this.closed = true;
|
|
@@ -607,10 +611,15 @@ var SessionHub = class {
|
|
|
607
611
|
this.counted.clear();
|
|
608
612
|
}
|
|
609
613
|
publish(sessionId, event) {
|
|
610
|
-
const frame = {
|
|
614
|
+
const frame = {
|
|
615
|
+
seq: ++this.seq,
|
|
616
|
+
...sessionId === void 0 ? {} : { sessionId },
|
|
617
|
+
ts: this.clock(),
|
|
618
|
+
event
|
|
619
|
+
};
|
|
611
620
|
this.ring.push(frame);
|
|
612
621
|
for (const sink of this.sinks) sink(frame);
|
|
613
|
-
for (const sink of this.observers) sink(frame);
|
|
622
|
+
if (sessionId !== void 0) for (const sink of this.observers) sink(frame);
|
|
614
623
|
return frame;
|
|
615
624
|
}
|
|
616
625
|
connectionFrame(event) {
|
|
@@ -2745,7 +2754,9 @@ function toWirePluginEntry(entry, displayNames) {
|
|
|
2745
2754
|
installedAt: entry.installedAt,
|
|
2746
2755
|
marketplace: entry.marketplace ?? null,
|
|
2747
2756
|
active: entry.active,
|
|
2748
|
-
counts: entry.counts ? toWireCounts(entry.counts) : null
|
|
2757
|
+
counts: entry.counts ? toWireCounts(entry.counts) : null,
|
|
2758
|
+
updateAllowed: entry.updateAllowed,
|
|
2759
|
+
uninstallAllowed: entry.uninstallAllowed
|
|
2749
2760
|
};
|
|
2750
2761
|
}
|
|
2751
2762
|
function toWirePluginHit(hit, installed) {
|
|
@@ -2771,7 +2782,14 @@ function toWirePluginHit(hit, installed) {
|
|
|
2771
2782
|
homepage: hit.entry.homepage ?? null,
|
|
2772
2783
|
visibility: hit.entry.visibility ?? null,
|
|
2773
2784
|
status: hit.entry.status ?? null,
|
|
2774
|
-
updateAvailable: mine !== void 0 && !mine.linked && hit.entry.version !== void 0 && hit.entry.version !== mine.version
|
|
2785
|
+
updateAvailable: mine !== void 0 && !mine.linked && hit.entry.version !== void 0 && hit.entry.version !== mine.version,
|
|
2786
|
+
installAllowed: hit.installAllowed,
|
|
2787
|
+
updateAllowed: mine?.updateAllowed ?? false,
|
|
2788
|
+
menu: hit.menu.map((item) => ({
|
|
2789
|
+
id: item.id,
|
|
2790
|
+
label: item.label,
|
|
2791
|
+
danger: item.danger === true
|
|
2792
|
+
}))
|
|
2775
2793
|
};
|
|
2776
2794
|
}
|
|
2777
2795
|
function toWireMarketplace(market) {
|
|
@@ -2856,7 +2874,10 @@ function listPlugins(ctx, res, lang) {
|
|
|
2856
2874
|
function pluginsPayload(control) {
|
|
2857
2875
|
const installed = control.list();
|
|
2858
2876
|
const installedMap = new Map(
|
|
2859
|
-
installed.map((p) => [
|
|
2877
|
+
installed.map((p) => [
|
|
2878
|
+
p.name,
|
|
2879
|
+
{ version: p.version, linked: p.linked, updateAllowed: p.updateAllowed }
|
|
2880
|
+
])
|
|
2860
2881
|
);
|
|
2861
2882
|
const shown = displayNamesOf(control);
|
|
2862
2883
|
return {
|
|
@@ -2866,7 +2887,8 @@ function pluginsPayload(control) {
|
|
|
2866
2887
|
pendingRestart: control.pendingRestart,
|
|
2867
2888
|
uploadEnabled: control.uploadEnabled,
|
|
2868
2889
|
uploadOptions: control.uploadOptions,
|
|
2869
|
-
refreshEnabled: control.refreshEnabled
|
|
2890
|
+
refreshEnabled: control.refreshEnabled,
|
|
2891
|
+
localInstallEnabled: control.localInstallEnabled
|
|
2870
2892
|
};
|
|
2871
2893
|
}
|
|
2872
2894
|
function sendPreview(res, outcome) {
|
|
@@ -5270,6 +5292,7 @@ async function createWebServer(opts) {
|
|
|
5270
5292
|
const unsubscribeTasks = observeBackgroundTasks((sessionId) => {
|
|
5271
5293
|
hub.notifyTasksChanged(sessionId);
|
|
5272
5294
|
});
|
|
5295
|
+
const unsubscribePlugins = opts.runtime.plugins?.onChange(() => hub.notifyPluginsChanged()) ?? (() => void 0);
|
|
5273
5296
|
let handle = null;
|
|
5274
5297
|
const server = createServer((req, res) => {
|
|
5275
5298
|
if (handle) return handle(req, res);
|
|
@@ -5280,6 +5303,7 @@ async function createWebServer(opts) {
|
|
|
5280
5303
|
const listened = await listen(server, binding.host, binding.port);
|
|
5281
5304
|
if (!listened.ok) {
|
|
5282
5305
|
unsubscribeTasks();
|
|
5306
|
+
unsubscribePlugins();
|
|
5283
5307
|
return listened;
|
|
5284
5308
|
}
|
|
5285
5309
|
handle = buildHandler(opts, hub, binding, listened.port, webRoot);
|
|
@@ -5293,7 +5317,7 @@ async function createWebServer(opts) {
|
|
|
5293
5317
|
...webRoot === void 0 ? {} : { webRoot },
|
|
5294
5318
|
observe: (sink, opts2) => hub.observe(sink, opts2 ?? {}),
|
|
5295
5319
|
snapshot: () => hub.listSessions(),
|
|
5296
|
-
close: makeCloser(server, hub, opts.runtime, unsubscribeTasks)
|
|
5320
|
+
close: makeCloser(server, hub, opts.runtime, unsubscribeTasks, unsubscribePlugins)
|
|
5297
5321
|
}
|
|
5298
5322
|
};
|
|
5299
5323
|
}
|
|
@@ -5345,11 +5369,12 @@ function describeListenError(err, host, port) {
|
|
|
5345
5369
|
}
|
|
5346
5370
|
return t("web.listen_failed", { host, port, reason: err.message }, void 0);
|
|
5347
5371
|
}
|
|
5348
|
-
function makeCloser(server, hub, runtime, unsubscribeTasks) {
|
|
5372
|
+
function makeCloser(server, hub, runtime, unsubscribeTasks, unsubscribePlugins) {
|
|
5349
5373
|
let closing = null;
|
|
5350
5374
|
return () => {
|
|
5351
5375
|
closing ??= (async () => {
|
|
5352
5376
|
unsubscribeTasks();
|
|
5377
|
+
unsubscribePlugins();
|
|
5353
5378
|
hub.shutdown();
|
|
5354
5379
|
server.closeAllConnections();
|
|
5355
5380
|
await new Promise((resolve4) => server.close(() => resolve4()));
|