@sleep2agi/commhub-server 0.8.1-preview.0 → 0.8.1-preview.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/package.json +1 -1
- package/src/rename.ts +35 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sleep2agi/commhub-server",
|
|
3
|
-
"version": "0.8.1-preview.
|
|
3
|
+
"version": "0.8.1-preview.2",
|
|
4
4
|
"description": "CommHub Server — AI Agent communication hub with MCP protocol, multi-network isolation, user auth, and 17 MCP tools.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
package/src/rename.ts
CHANGED
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
import { randomUUID } from "crypto";
|
|
16
16
|
import { db } from "./db";
|
|
17
|
-
import { getUserNetworkRole } from "./auth";
|
|
17
|
+
import { getUserNetworkRole, getNetworkMembers } from "./auth";
|
|
18
|
+
import { pushEvent } from "./push";
|
|
18
19
|
|
|
19
20
|
export interface RenameResult {
|
|
20
21
|
ok: boolean;
|
|
@@ -88,6 +89,39 @@ export function commitRename(userId: string, txnId: string): RenameResult {
|
|
|
88
89
|
db.run(
|
|
89
90
|
"UPDATE rename_txn SET status = 'committed', committed_at = datetime('now') WHERE txn_id = ?1",
|
|
90
91
|
[txnId]);
|
|
92
|
+
|
|
93
|
+
// RFC-010 §4.2.1 C4 — broadcast node.renamed SSE. (#84 实施补漏: the Server
|
|
94
|
+
// surface originally missed C4; N站马's dashboard slice needs this event.)
|
|
95
|
+
// Envelope per RFC §3.4: alias = NEW (the post-event truth); data carries
|
|
96
|
+
// old/new + surfaces + history_policy. `type` is also set for consumers that
|
|
97
|
+
// switch on .type (the existing SSE convention). Pushed to both the old- and
|
|
98
|
+
// new-alias streams since the SSE layer is per-session-name (no network-wide
|
|
99
|
+
// broadcast primitive) — whoever watched either name gets the rename.
|
|
100
|
+
const renamedEvent: Record<string, unknown> = {
|
|
101
|
+
type: "node.renamed",
|
|
102
|
+
event: "node.renamed",
|
|
103
|
+
txn_id: txnId,
|
|
104
|
+
alias: txn.new_alias,
|
|
105
|
+
network_id: txn.network_id,
|
|
106
|
+
data: {
|
|
107
|
+
old_alias: txn.old_alias,
|
|
108
|
+
new_alias: txn.new_alias,
|
|
109
|
+
surfaces_updated: ["config", "tmux", "commhub", "dashboard", "batch_prefix", "session_resume"],
|
|
110
|
+
history_policy: "preserve",
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
pushEvent(txn.old_alias, renamedEvent, txn.network_id);
|
|
114
|
+
pushEvent(txn.new_alias, renamedEvent, txn.network_id);
|
|
115
|
+
|
|
116
|
+
// Also push to every network member's user channel. The dashboard subscribes
|
|
117
|
+
// to /events/<username> (a user channel), NOT the per-node-alias streams — so
|
|
118
|
+
// without this it would never receive node.renamed (#84 SSE channel fix:
|
|
119
|
+
// N站马 confirmed the dashboard listens on the user channel). All members get
|
|
120
|
+
// it, not just the owner, since any member's dashboard should reflect the rename.
|
|
121
|
+
for (const member of getNetworkMembers(txn.network_id)) {
|
|
122
|
+
if (member.username) pushEvent(member.username, renamedEvent, txn.network_id);
|
|
123
|
+
}
|
|
124
|
+
|
|
91
125
|
return { ok: true, txn_id: txnId };
|
|
92
126
|
}
|
|
93
127
|
|