@essentialai/cogent-server 3.0.4 → 3.1.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/dist/__tests__/helpers.js +1 -1
- package/dist/__tests__/helpers.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware/ws-auth.d.ts +6 -6
- package/dist/middleware/ws-auth.d.ts.map +1 -1
- package/dist/middleware/ws-auth.js +36 -12
- package/dist/middleware/ws-auth.js.map +1 -1
- package/dist/routes/messages.d.ts +3 -2
- package/dist/routes/messages.d.ts.map +1 -1
- package/dist/routes/messages.js +41 -3
- package/dist/routes/messages.js.map +1 -1
- package/dist/routes/peers.d.ts.map +1 -1
- package/dist/routes/peers.js +5 -0
- package/dist/routes/peers.js.map +1 -1
- package/dist/routes/ui.d.ts.map +1 -1
- package/dist/routes/ui.js +5 -0
- package/dist/routes/ui.js.map +1 -1
- package/dist/services/connection-manager.d.ts +1 -1
- package/dist/services/connection-manager.d.ts.map +1 -1
- package/dist/services/connection-manager.js +3 -0
- package/dist/services/connection-manager.js.map +1 -1
- package/dist/services/message-queue.d.ts +12 -0
- package/dist/services/message-queue.d.ts.map +1 -1
- package/dist/services/message-queue.js +36 -0
- package/dist/services/message-queue.js.map +1 -1
- package/dist/services/peer-cleanup.d.ts +3 -1
- package/dist/services/peer-cleanup.d.ts.map +1 -1
- package/dist/services/peer-cleanup.js +24 -11
- package/dist/services/peer-cleanup.js.map +1 -1
- package/dist/services/session-store.d.ts +12 -0
- package/dist/services/session-store.d.ts.map +1 -1
- package/dist/services/session-store.js +45 -2
- package/dist/services/session-store.js.map +1 -1
- package/dist/services/stats-service.d.ts.map +1 -1
- package/dist/services/stats-service.js +1 -6
- package/dist/services/stats-service.js.map +1 -1
- package/dist/ui/pages/HowToPage.d.ts.map +1 -1
- package/dist/ui/pages/HowToPage.js +127 -2
- package/dist/ui/pages/HowToPage.js.map +1 -1
- package/dist/ui/pages/LandingPage.d.ts.map +1 -1
- package/dist/ui/pages/LandingPage.js +1 -1
- package/dist/ui/pages/LandingPage.js.map +1 -1
- package/dist/ui/pages/UpdateGuidePage.d.ts +3 -0
- package/dist/ui/pages/UpdateGuidePage.d.ts.map +1 -0
- package/dist/ui/pages/UpdateGuidePage.js +167 -0
- package/dist/ui/pages/UpdateGuidePage.js.map +1 -0
- package/dist/ws/adapter-handler.d.ts.map +1 -1
- package/dist/ws/adapter-handler.js +14 -7
- package/dist/ws/adapter-handler.js.map +1 -1
- package/dist/ws/handler.d.ts.map +1 -1
- package/dist/ws/handler.js +3 -2
- package/dist/ws/handler.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { SessionStore } from "./session-store.js";
|
|
2
|
+
import type { ConnectionManager } from "./connection-manager.js";
|
|
2
3
|
/**
|
|
3
4
|
* Background service that periodically scans all sessions and removes
|
|
4
5
|
* stale peers -- peers whose lastSeenAt timestamp exceeds the configured
|
|
@@ -9,10 +10,11 @@ import type { SessionStore } from "./session-store.js";
|
|
|
9
10
|
* from exiting naturally during graceful shutdown.
|
|
10
11
|
*/
|
|
11
12
|
export declare class PeerCleanup {
|
|
13
|
+
private readonly connectionManager?;
|
|
12
14
|
private readonly sessionStore;
|
|
13
15
|
private readonly staleTimeoutMs;
|
|
14
16
|
private intervalHandle;
|
|
15
|
-
constructor(sessionStore: SessionStore, staleTimeoutMs: number);
|
|
17
|
+
constructor(sessionStore: SessionStore, staleTimeoutMs: number, connectionManager?: ConnectionManager | undefined);
|
|
16
18
|
/**
|
|
17
19
|
* Start the periodic cleanup timer.
|
|
18
20
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"peer-cleanup.d.ts","sourceRoot":"","sources":["../../src/services/peer-cleanup.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"peer-cleanup.d.ts","sourceRoot":"","sources":["../../src/services/peer-cleanup.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE;;;;;;;;GAQG;AACH,qBAAa,WAAW;IAQpB,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IAPrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,cAAc,CAA+C;gBAGnE,YAAY,EAAE,YAAY,EAC1B,cAAc,EAAE,MAAM,EACL,iBAAiB,CAAC,EAAE,iBAAiB,YAAA;IAMxD;;;;OAIG;IACH,KAAK,CAAC,UAAU,GAAE,MAAe,GAAG,IAAI;IAexC;;OAEG;IACH,IAAI,IAAI,IAAI;IAOZ;;;;;;;;;;OAUG;IACG,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;CA6DjC"}
|
|
@@ -8,10 +8,12 @@
|
|
|
8
8
|
* from exiting naturally during graceful shutdown.
|
|
9
9
|
*/
|
|
10
10
|
export class PeerCleanup {
|
|
11
|
+
connectionManager;
|
|
11
12
|
sessionStore;
|
|
12
13
|
staleTimeoutMs;
|
|
13
14
|
intervalHandle = null;
|
|
14
|
-
constructor(sessionStore, staleTimeoutMs) {
|
|
15
|
+
constructor(sessionStore, staleTimeoutMs, connectionManager) {
|
|
16
|
+
this.connectionManager = connectionManager;
|
|
15
17
|
this.sessionStore = sessionStore;
|
|
16
18
|
this.staleTimeoutMs = staleTimeoutMs;
|
|
17
19
|
}
|
|
@@ -53,6 +55,8 @@ export class PeerCleanup {
|
|
|
53
55
|
* @returns Total number of stale peers removed across all sessions.
|
|
54
56
|
*/
|
|
55
57
|
async cleanup() {
|
|
58
|
+
if (this.staleTimeoutMs <= 0)
|
|
59
|
+
return 0;
|
|
56
60
|
const sessionIds = await this.sessionStore.listSessions();
|
|
57
61
|
let totalRemoved = 0;
|
|
58
62
|
for (const sessionId of sessionIds) {
|
|
@@ -63,7 +67,7 @@ export class PeerCleanup {
|
|
|
63
67
|
const stalePeerIds = [];
|
|
64
68
|
for (const [peerId, peer] of Object.entries(session.peers)) {
|
|
65
69
|
const lastSeen = Date.parse(peer.lastSeenAt);
|
|
66
|
-
if (now - lastSeen > this.staleTimeoutMs) {
|
|
70
|
+
if (Number.isNaN(lastSeen) || now - lastSeen > this.staleTimeoutMs) {
|
|
67
71
|
stalePeerIds.push(peerId);
|
|
68
72
|
}
|
|
69
73
|
}
|
|
@@ -73,19 +77,28 @@ export class PeerCleanup {
|
|
|
73
77
|
const timestamp = new Date().toISOString();
|
|
74
78
|
for (const peerId of stalePeerIds) {
|
|
75
79
|
// Only remove if still present (could have been deregistered concurrently)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
const peer = state.peers[peerId];
|
|
81
|
+
if (!peer)
|
|
82
|
+
continue;
|
|
83
|
+
const lastSeen = Date.parse(peer.lastSeenAt);
|
|
84
|
+
const stillStale = Number.isNaN(lastSeen) || now - lastSeen > this.staleTimeoutMs;
|
|
85
|
+
if (!stillStale)
|
|
86
|
+
continue;
|
|
87
|
+
if (this.connectionManager?.isConnected(sessionId, peerId)) {
|
|
88
|
+
peer.lastSeenAt = timestamp;
|
|
89
|
+
continue;
|
|
84
90
|
}
|
|
91
|
+
delete state.peers[peerId];
|
|
92
|
+
const event = {
|
|
93
|
+
type: "peer_disconnected",
|
|
94
|
+
peerId,
|
|
95
|
+
timestamp,
|
|
96
|
+
};
|
|
97
|
+
state.peerEvents.push(event);
|
|
98
|
+
totalRemoved++;
|
|
85
99
|
}
|
|
86
100
|
return state;
|
|
87
101
|
});
|
|
88
|
-
totalRemoved += stalePeerIds.length;
|
|
89
102
|
}
|
|
90
103
|
if (totalRemoved > 0) {
|
|
91
104
|
console.error(`Peer cleanup: removed ${totalRemoved} stale peer(s)`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"peer-cleanup.js","sourceRoot":"","sources":["../../src/services/peer-cleanup.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"peer-cleanup.js","sourceRoot":"","sources":["../../src/services/peer-cleanup.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,MAAM,OAAO,WAAW;IAQH;IAPF,YAAY,CAAe;IAC3B,cAAc,CAAS;IAChC,cAAc,GAA0C,IAAI,CAAC;IAErE,YACE,YAA0B,EAC1B,cAAsB,EACL,iBAAqC;QAArC,sBAAiB,GAAjB,iBAAiB,CAAoB;QAEtD,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACvC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,aAAqB,MAAM;QAC/B,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;YACjC,OAAO,CAAC,kBAAkB;QAC5B,CAAC;QAED,IAAI,CAAC,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;YACrC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC3B,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC;YAC5C,CAAC,CAAC,CAAC;QACL,CAAC,EAAE,UAAU,CAAC,CAAC;QAEf,2DAA2D;QAC3D,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,IAAI;QACF,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;YACjC,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YACnC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;IACH,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;QAEvC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;QAC1D,IAAI,YAAY,GAAG,CAAC,CAAC;QAErB,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YAC9D,IAAI,CAAC,OAAO;gBAAE,SAAS;YAEvB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,YAAY,GAAa,EAAE,CAAC;YAElC,KAAK,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC7C,IAAI,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,GAAG,GAAG,QAAQ,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;oBACnE,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAC5B,CAAC;YACH,CAAC;YAED,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAExC,MAAM,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;gBACzD,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;gBAE3C,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;oBAClC,2EAA2E;oBAC3E,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;oBACjC,IAAI,CAAC,IAAI;wBAAE,SAAS;oBAEpB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBAC7C,MAAM,UAAU,GACd,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,GAAG,GAAG,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC;oBACjE,IAAI,CAAC,UAAU;wBAAE,SAAS;oBAE1B,IAAI,IAAI,CAAC,iBAAiB,EAAE,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC;wBAC3D,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;wBAC5B,SAAS;oBACX,CAAC;oBAED,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;oBAE3B,MAAM,KAAK,GAAc;wBACvB,IAAI,EAAE,mBAAmB;wBACzB,MAAM;wBACN,SAAS;qBACV,CAAC;oBACF,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBAC7B,YAAY,EAAE,CAAC;gBACjB,CAAC;gBAED,OAAO,KAAK,CAAC;YACf,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,KAAK,CAAC,yBAAyB,YAAY,gBAAgB,CAAC,CAAC;QACvE,CAAC;QAED,OAAO,YAAY,CAAC;IACtB,CAAC;CACF"}
|
|
@@ -99,5 +99,17 @@ export declare class SessionStore {
|
|
|
99
99
|
private _rebuildLabelIndex;
|
|
100
100
|
/** Compute the file path for a session ID. */
|
|
101
101
|
private _filePath;
|
|
102
|
+
private _globalStatsPath;
|
|
103
|
+
/**
|
|
104
|
+
* Read the global (monotonic) message counter.
|
|
105
|
+
* Returns 0 if the file doesn't exist yet.
|
|
106
|
+
*/
|
|
107
|
+
getGlobalMessageCount(): Promise<number>;
|
|
108
|
+
/**
|
|
109
|
+
* Atomically increment the global message counter by 1.
|
|
110
|
+
* Uses the per-session lock mechanism with a reserved key.
|
|
111
|
+
*/
|
|
112
|
+
incrementGlobalMessageCount(): Promise<void>;
|
|
113
|
+
private _writeGlobalStats;
|
|
102
114
|
}
|
|
103
115
|
//# sourceMappingURL=session-store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../../src/services/session-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEhE;;;;;;;GAOG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;IAE/C,uCAAuC;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoC;IAE1D,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6B;IAExD,8DAA8D;IAC9D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6B;gBAE5C,QAAQ,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM;IAK3D;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../../src/services/session-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEhE;;;;;;;GAOG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;IAE/C,uCAAuC;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoC;IAE1D,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6B;IAExD,8DAA8D;IAC9D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6B;gBAE5C,QAAQ,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM;IAK3D;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA4B3B;;;OAGG;IACG,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,UAAU,EACtB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,CAAC;IA8C5B;;OAEG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAcrE;;;OAGG;IACG,qBAAqB,CACzB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,gBAAgB,CAAA;KAAE,GAAG,IAAI,CAAC;IAcjE;;;;OAIG;IACG,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,gBAAgB,GACrD,OAAO,CAAC,gBAAgB,CAAC;IAe5B;;OAEG;IACG,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IASxE;;;;OAIG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2CrD;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAOvC;;OAEG;IACH,aAAa,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC;IAI5C;;;OAGG;IACH,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIjD;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAMpC;;;;OAIG;YACW,UAAU;IAgCxB;;;OAGG;YACW,WAAW;IAWzB;;;;OAIG;YACW,SAAS;IAmBvB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAM1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAM1B,8CAA8C;IAC9C,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,gBAAgB;IAIxB;;;OAGG;IACG,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;IAU9C;;;OAGG;IACG,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC;YAOpC,iBAAiB;CAMhC"}
|
|
@@ -29,13 +29,15 @@ export class SessionStore {
|
|
|
29
29
|
async init() {
|
|
30
30
|
await fs.mkdir(this.stateDir, { recursive: true });
|
|
31
31
|
const files = await fs.readdir(this.stateDir);
|
|
32
|
+
let seedMessageCount = 0;
|
|
32
33
|
for (const file of files) {
|
|
33
|
-
if (!file.endsWith(".json"))
|
|
34
|
+
if (!file.endsWith(".json") || file === "global-stats.json")
|
|
34
35
|
continue;
|
|
35
36
|
const filePath = path.join(this.stateDir, file);
|
|
36
37
|
try {
|
|
37
38
|
const raw = await fs.readFile(filePath, "utf-8");
|
|
38
39
|
const state = JSON.parse(raw);
|
|
40
|
+
seedMessageCount += state.messages.length;
|
|
39
41
|
this._rebuildTokenIndex(state);
|
|
40
42
|
this._rebuildLabelIndex(state);
|
|
41
43
|
}
|
|
@@ -43,6 +45,13 @@ export class SessionStore {
|
|
|
43
45
|
// Skip corrupt files during init -- they'll error on access
|
|
44
46
|
}
|
|
45
47
|
}
|
|
48
|
+
// Seed global message counter on first run (migration from sum-based counting)
|
|
49
|
+
try {
|
|
50
|
+
await fs.access(this._globalStatsPath());
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
await this._writeGlobalStats(seedMessageCount);
|
|
54
|
+
}
|
|
46
55
|
}
|
|
47
56
|
/**
|
|
48
57
|
* Create a new session with the given ID, label, secret hash, and initial token.
|
|
@@ -189,7 +198,7 @@ export class SessionStore {
|
|
|
189
198
|
async listSessions() {
|
|
190
199
|
const files = await fs.readdir(this.stateDir);
|
|
191
200
|
return files
|
|
192
|
-
.filter((f) => f.endsWith(".json"))
|
|
201
|
+
.filter((f) => f.endsWith(".json") && f !== "global-stats.json")
|
|
193
202
|
.map((f) => f.slice(0, -5));
|
|
194
203
|
}
|
|
195
204
|
/**
|
|
@@ -288,5 +297,39 @@ export class SessionStore {
|
|
|
288
297
|
_filePath(sessionId) {
|
|
289
298
|
return path.join(this.stateDir, `${sessionId}.json`);
|
|
290
299
|
}
|
|
300
|
+
// --- Global message counter ---
|
|
301
|
+
_globalStatsPath() {
|
|
302
|
+
return path.join(this.stateDir, "global-stats.json");
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Read the global (monotonic) message counter.
|
|
306
|
+
* Returns 0 if the file doesn't exist yet.
|
|
307
|
+
*/
|
|
308
|
+
async getGlobalMessageCount() {
|
|
309
|
+
try {
|
|
310
|
+
const raw = await fs.readFile(this._globalStatsPath(), "utf-8");
|
|
311
|
+
const data = JSON.parse(raw);
|
|
312
|
+
return data.totalMessages ?? 0;
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
return 0;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Atomically increment the global message counter by 1.
|
|
320
|
+
* Uses the per-session lock mechanism with a reserved key.
|
|
321
|
+
*/
|
|
322
|
+
async incrementGlobalMessageCount() {
|
|
323
|
+
await this._withLock("__global_stats__", async () => {
|
|
324
|
+
const count = await this.getGlobalMessageCount();
|
|
325
|
+
await this._writeGlobalStats(count + 1);
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
async _writeGlobalStats(totalMessages) {
|
|
329
|
+
const filePath = this._globalStatsPath();
|
|
330
|
+
const tmpPath = `${filePath}.${process.pid}.tmp`;
|
|
331
|
+
await fs.writeFile(tmpPath, JSON.stringify({ totalMessages }), "utf-8");
|
|
332
|
+
await fs.rename(tmpPath, filePath);
|
|
333
|
+
}
|
|
291
334
|
}
|
|
292
335
|
//# sourceMappingURL=session-store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-store.js","sourceRoot":"","sources":["../../src/services/session-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAG7D;;;;;;;GAOG;AACH,MAAM,OAAO,YAAY;IACN,QAAQ,CAAS;IACjB,qBAAqB,CAAS;IAE/C,uCAAuC;IACtB,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAE1D,0EAA0E;IACzD,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAExD,8DAA8D;IAC7C,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAExD,YAAY,QAAgB,EAAE,qBAA6B;QACzD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,qBAAqB,GAAG,qBAAqB,CAAC;IACrD,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEnD,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,SAAS;
|
|
1
|
+
{"version":3,"file":"session-store.js","sourceRoot":"","sources":["../../src/services/session-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAG7D;;;;;;;GAOG;AACH,MAAM,OAAO,YAAY;IACN,QAAQ,CAAS;IACjB,qBAAqB,CAAS;IAE/C,uCAAuC;IACtB,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAE1D,0EAA0E;IACzD,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAExD,8DAA8D;IAC7C,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAExD,YAAY,QAAgB,EAAE,qBAA6B;QACzD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,qBAAqB,GAAG,qBAAqB,CAAC;IACrD,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEnD,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,gBAAgB,GAAG,CAAC,CAAC;QACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,KAAK,mBAAmB;gBAAE,SAAS;YAEtE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YAChD,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACjD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAC;gBAClD,gBAAgB,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAC1C,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;gBAC/B,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;YACjC,CAAC;YAAC,MAAM,CAAC;gBACP,4DAA4D;YAC9D,CAAC;QACH,CAAC;QAED,+EAA+E;QAC/E,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;QAC3C,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,aAAa,CACjB,SAAiB,EACjB,KAAyB,EACzB,UAAkB,EAClB,UAAsB,EACtB,SAAkB;QAElB,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;YAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YAE3C,uCAAuC;YACvC,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC1B,MAAM,IAAI,WAAW,CACnB,SAAS,CAAC,aAAa,EACvB,WAAW,SAAS,iBAAiB,EACrC,yDAAyD,CAC1D,CAAC;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,+CAA+C;gBAC/C,IAAI,GAAG,YAAY,WAAW;oBAAE,MAAM,GAAG,CAAC;gBAC1C,2CAA2C;YAC7C,CAAC;YAED,2CAA2C;YAC3C,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpD,MAAM,IAAI,WAAW,CACnB,SAAS,CAAC,aAAa,EACvB,UAAU,KAAK,kBAAkB,EACjC,0BAA0B,CAC3B,CAAC;YACJ,CAAC;YAED,MAAM,KAAK,GAAqB;gBAC9B,SAAS;gBACT,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzC,UAAU;gBACV,MAAM,EAAE,CAAC,UAAU,CAAC;gBACpB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnC,KAAK,EAAE,EAAE;gBACT,QAAQ,EAAE,EAAE;gBACZ,UAAU,EAAE,EAAE;aACf,CAAC;YAEF,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YACzC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAC/B,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAC/B,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,SAAiB;QAChC,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IACE,GAAG,YAAY,WAAW;gBAC1B,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,iBAAiB,EACxC,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,qBAAqB,CACzB,SAAiB;QAEjB,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAE5B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,6CAA6C;YAC7C,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAClC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,aAAa,CACjB,SAAiB,EACjB,OAAsD;QAEtD,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;YAC1C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAE/B,sBAAsB;YACtB,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBACzD,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;YACzE,CAAC;YAED,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC3C,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,SAAiB,EAAE,UAAsB;QACtD,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;YACzC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YAC/C,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC9B,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YACzC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,aAAa,CAAC,SAAiB;QACnC,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;YACzC,6DAA6D;YAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YAC3C,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACjD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAC;gBAElD,kDAAkD;gBAClD,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;oBACjC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;gBAC1C,CAAC;gBAED,oCAAoC;gBACpC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;oBAChB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,mEAAmE;gBACnE,sDAAsD;YACxD,CAAC;YAED,yCAAyC;YACzC,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,yCAAyC;gBACzC,IACE,CAAC,CACC,GAAG,YAAY,KAAK;oBACpB,MAAM,IAAI,GAAG;oBACZ,GAA6B,CAAC,IAAI,KAAK,QAAQ,CACjD,EACD,CAAC;oBACD,MAAM,GAAG,CAAC;gBACZ,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,2CAA2C;QAC3C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY;QAChB,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9C,OAAO,KAAK;aACT,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,mBAAmB,CAAC;aAC/D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,aAAa;QACX,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,mBAAmB,CAAC,KAAa;QAC/B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,KAAa;QACxB,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,0BAA0B;IAE1B;;;;OAIG;IACK,KAAK,CAAC,UAAU,CAAC,SAAiB;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC3C,IAAI,GAAW,CAAC;QAEhB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IACE,GAAG,YAAY,KAAK;gBACpB,MAAM,IAAI,GAAG;gBACZ,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAChD,CAAC;gBACD,MAAM,IAAI,WAAW,CACnB,SAAS,CAAC,iBAAiB,EAC3B,WAAW,SAAS,YAAY,EAChC,8CAA8C,CAC/C,CAAC;YACJ,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;QAED,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,WAAW,CACnB,SAAS,CAAC,aAAa,EACvB,oBAAoB,SAAS,aAAa,EAC1C,mDAAmD,CACpD,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,WAAW,CACvB,SAAiB,EACjB,KAAuB;QAEvB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,GAAG,QAAQ,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC;QAEjD,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACrE,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,SAAS,CACrB,SAAiB,EACjB,EAAoB;QAEpB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAC5D,IAAI,OAAmB,CAAC;QACxB,MAAM,IAAI,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YACzC,OAAO,GAAG,OAAO,CAAC;QACpB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAEhC,MAAM,IAAI,CAAC;QACX,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;gBAAS,CAAC;YACT,OAAQ,EAAE,CAAC;QACb,CAAC;IACH,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,KAAuB;QAChD,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,KAAuB;QAChD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,8CAA8C;IACtC,SAAS,CAAC,SAAiB;QACjC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,SAAS,OAAO,CAAC,CAAC;IACvD,CAAC;IAED,iCAAiC;IAEzB,gBAAgB;QACtB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;IACvD,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,qBAAqB;QACzB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,OAAO,CAAC,CAAC;YAChE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC7B,OAAO,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,2BAA2B;QAC/B,MAAM,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;YAClD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;YACjD,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,aAAqB;QACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,GAAG,QAAQ,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC;QACjD,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;QACxE,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stats-service.d.ts","sourceRoot":"","sources":["../../src/services/stats-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoB;IACtD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,aAAa,CAA+C;gBAGlE,YAAY,EAAE,YAAY,EAC1B,iBAAiB,EAAE,iBAAiB,EACpC,SAAS,EAAE,MAAM;IAanB;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"stats-service.d.ts","sourceRoot":"","sources":["../../src/services/stats-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoB;IACtD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,aAAa,CAA+C;gBAGlE,YAAY,EAAE,YAAY,EAC1B,iBAAiB,EAAE,iBAAiB,EACpC,SAAS,EAAE,MAAM;IAanB;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAY9B;;;OAGG;IACH,QAAQ,IAAI,WAAW;IAOvB;;;;OAIG;IACH,KAAK,CAAC,UAAU,GAAE,MAAa,GAAG,IAAI;IAUtC;;OAEG;IACH,IAAI,IAAI,IAAI;CAMb"}
|
|
@@ -28,12 +28,7 @@ export class StatsService {
|
|
|
28
28
|
*/
|
|
29
29
|
async refresh() {
|
|
30
30
|
const sessionIds = await this.sessionStore.listSessions();
|
|
31
|
-
|
|
32
|
-
for (const id of sessionIds) {
|
|
33
|
-
const session = await this.sessionStore.getSession(id);
|
|
34
|
-
if (session)
|
|
35
|
-
totalMessages += session.messages.length;
|
|
36
|
-
}
|
|
31
|
+
const totalMessages = await this.sessionStore.getGlobalMessageCount();
|
|
37
32
|
this.cachedStats = {
|
|
38
33
|
activeSessions: sessionIds.length,
|
|
39
34
|
connectedAgents: this.connectionManager.getTotalConnectedPeers(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stats-service.js","sourceRoot":"","sources":["../../src/services/stats-service.ts"],"names":[],"mappings":"AAcA;;;;;;GAMG;AACH,MAAM,OAAO,YAAY;IACf,WAAW,CAAc;IAChB,YAAY,CAAe;IAC3B,iBAAiB,CAAoB;IACrC,SAAS,CAAS;IAC3B,aAAa,GAA0C,IAAI,CAAC;IAEpE,YACE,YAA0B,EAC1B,iBAAoC,EACpC,SAAiB;QAEjB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;QAC3C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,WAAW,GAAG;YACjB,cAAc,EAAE,CAAC;YACjB,eAAe,EAAE,CAAC;YAClB,oBAAoB,EAAE,CAAC;YACvB,MAAM,EAAE,CAAC;SACV,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,OAAO;QACX,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;QAC1D,
|
|
1
|
+
{"version":3,"file":"stats-service.js","sourceRoot":"","sources":["../../src/services/stats-service.ts"],"names":[],"mappings":"AAcA;;;;;;GAMG;AACH,MAAM,OAAO,YAAY;IACf,WAAW,CAAc;IAChB,YAAY,CAAe;IAC3B,iBAAiB,CAAoB;IACrC,SAAS,CAAS;IAC3B,aAAa,GAA0C,IAAI,CAAC;IAEpE,YACE,YAA0B,EAC1B,iBAAoC,EACpC,SAAiB;QAEjB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;QAC3C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,WAAW,GAAG;YACjB,cAAc,EAAE,CAAC;YACjB,eAAe,EAAE,CAAC;YAClB,oBAAoB,EAAE,CAAC;YACvB,MAAM,EAAE,CAAC;SACV,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,OAAO;QACX,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;QAC1D,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,qBAAqB,EAAE,CAAC;QAEtE,IAAI,CAAC,WAAW,GAAG;YACjB,cAAc,EAAE,UAAU,CAAC,MAAM;YACjC,eAAe,EAAE,IAAI,CAAC,iBAAiB,CAAC,sBAAsB,EAAE;YAChE,oBAAoB,EAAE,aAAa;YACnC,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI;SAC7C,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,QAAQ;QACN,OAAO;YACL,GAAG,IAAI,CAAC,WAAW;YACnB,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI;SAC7C,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,aAAqB,IAAI;QAC7B,+DAA+D;QAC/D,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAEpC,IAAI,CAAC,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE;YACpC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACtC,CAAC,EAAE,UAAU,CAAC,CAAC;QACf,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,IAAI;QACF,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAClC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC5B,CAAC;IACH,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HowToPage.d.ts","sourceRoot":"","sources":["../../../src/ui/pages/HowToPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"HowToPage.d.ts","sourceRoot":"","sources":["../../../src/ui/pages/HowToPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAyXnC;;;;GAIG;AACH,eAAO,MAAM,SAAS,EAAE,EAihCvB,CAAC"}
|
|
@@ -86,6 +86,7 @@ const sectionAnchor = css `
|
|
|
86
86
|
position: relative;
|
|
87
87
|
top: -1rem;
|
|
88
88
|
visibility: hidden;
|
|
89
|
+
scroll-margin-top: 2rem;
|
|
89
90
|
`;
|
|
90
91
|
const sectionTitle = css `
|
|
91
92
|
font-size: 1.2rem;
|
|
@@ -266,12 +267,78 @@ const footer = css `
|
|
|
266
267
|
border-top: 1px solid ${colors.border};
|
|
267
268
|
margin-top: 2rem;
|
|
268
269
|
`;
|
|
270
|
+
const floatingNav = css `
|
|
271
|
+
position: fixed;
|
|
272
|
+
bottom: 1.5rem;
|
|
273
|
+
right: 1.5rem;
|
|
274
|
+
z-index: 1000;
|
|
275
|
+
display: flex;
|
|
276
|
+
flex-direction: column;
|
|
277
|
+
align-items: flex-end;
|
|
278
|
+
gap: 0.5rem;
|
|
279
|
+
`;
|
|
280
|
+
const floatingBtn = css `
|
|
281
|
+
width: 48px;
|
|
282
|
+
height: 48px;
|
|
283
|
+
border-radius: 50%;
|
|
284
|
+
background: ${colors.bgCard};
|
|
285
|
+
border: 1px solid ${colors.border};
|
|
286
|
+
color: ${colors.green};
|
|
287
|
+
font-size: 1.2rem;
|
|
288
|
+
cursor: pointer;
|
|
289
|
+
display: flex;
|
|
290
|
+
align-items: center;
|
|
291
|
+
justify-content: center;
|
|
292
|
+
transition: border-color 0.2s, transform 0.2s;
|
|
293
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
|
|
294
|
+
&:hover {
|
|
295
|
+
border-color: ${colors.green};
|
|
296
|
+
transform: scale(1.1);
|
|
297
|
+
}
|
|
298
|
+
`;
|
|
299
|
+
const floatingMenu = css `
|
|
300
|
+
background: ${colors.bgCard};
|
|
301
|
+
border: 1px solid ${colors.border};
|
|
302
|
+
border-radius: 8px;
|
|
303
|
+
padding: 0.75rem 1rem;
|
|
304
|
+
box-shadow: 0 4px 16px rgba(0,0,0,0.4);
|
|
305
|
+
list-style: none;
|
|
306
|
+
margin: 0 0 0.5rem 0;
|
|
307
|
+
min-width: 220px;
|
|
308
|
+
max-height: 70vh;
|
|
309
|
+
overflow-y: auto;
|
|
310
|
+
& li {
|
|
311
|
+
margin: 0.25rem 0;
|
|
312
|
+
}
|
|
313
|
+
& a {
|
|
314
|
+
color: ${colors.cyan};
|
|
315
|
+
font-size: 0.8rem;
|
|
316
|
+
text-decoration: none;
|
|
317
|
+
display: block;
|
|
318
|
+
padding: 0.3rem 0.5rem;
|
|
319
|
+
border-radius: 4px;
|
|
320
|
+
transition: background 0.15s;
|
|
321
|
+
&:hover {
|
|
322
|
+
background: ${colors.bg};
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
& a.active {
|
|
326
|
+
color: ${colors.green};
|
|
327
|
+
font-weight: 700;
|
|
328
|
+
}
|
|
329
|
+
& .nav-num {
|
|
330
|
+
color: ${colors.amber};
|
|
331
|
+
margin-right: 0.4rem;
|
|
332
|
+
font-weight: 700;
|
|
333
|
+
font-size: 0.75rem;
|
|
334
|
+
}
|
|
335
|
+
`;
|
|
269
336
|
/**
|
|
270
337
|
* Comprehensive "How-To" guide page covering real-world use cases
|
|
271
338
|
* for Cogent Bridge from the perspective of business owners,
|
|
272
339
|
* product owners, and project managers.
|
|
273
340
|
*/
|
|
274
|
-
export const HowToPage = () => (
|
|
341
|
+
export const HowToPage = () => (_jsxs(Layout, { title: "How-To Guide", children: [_jsxs("div", { class: container, children: [_jsx("a", { href: "/", class: backLink, children: "\u2190 Back to Home" }), _jsxs("div", { class: heroSection, children: [_jsx("h1", { class: heroTitle, children: "How Teams Deliver Faster with Cogent" }), _jsx("p", { class: heroSubtitle, children: "When your developers connect their Claude Code agents through Cogent, every team member stays aligned in real time. No more integration surprises, no more \"I didn't know you changed that.\" Just continuous sync across codebases." }), _jsx("p", { class: heroSubtitle, children: "This guide walks through the most common use cases with exact commands your teams will use every day." })] }), _jsxs("div", { class: toc, children: [_jsx("div", { class: tocTitle, children: "In This Guide" }), _jsxs("ul", { class: tocList, children: [_jsxs("li", { class: tocItem, children: [_jsx("span", { class: tocNumber, children: "00" }), _jsx("a", { href: "#prerequisites", children: "Prerequisites & Setup" })] }), _jsxs("li", { class: tocItem, children: [_jsx("span", { class: tocNumber, children: "01" }), _jsx("a", { href: "#parallel-dev", children: "Parallel Feature Development" })] }), _jsxs("li", { class: tocItem, children: [_jsx("span", { class: tocNumber, children: "02" }), _jsx("a", { href: "#bug-relay", children: "Cross-Team Bug Investigation" })] }), _jsxs("li", { class: tocItem, children: [_jsx("span", { class: tocNumber, children: "03" }), _jsx("a", { href: "#api-contracts", children: "API Contract Negotiation" })] }), _jsxs("li", { class: tocItem, children: [_jsx("span", { class: tocNumber, children: "04" }), _jsx("a", { href: "#code-review", children: "Cross-Agent Code Review" })] }), _jsxs("li", { class: tocItem, children: [_jsx("span", { class: tocNumber, children: "05" }), _jsx("a", { href: "#multi-service", children: "Multi-Service Orchestration" })] }), _jsxs("li", { class: tocItem, children: [_jsx("span", { class: tocNumber, children: "06" }), _jsx("a", { href: "#sprint-sync", children: "Sprint Kick-off Alignment" })] }), _jsxs("li", { class: tocItem, children: [_jsx("span", { class: tocNumber, children: "07" }), _jsx("a", { href: "#integration-test", children: "Real-Time Integration Testing" })] }), _jsxs("li", { class: tocItem, children: [_jsx("span", { class: tocNumber, children: "08" }), _jsx("a", { href: "#command-ref", children: "Command Reference" })] }), _jsxs("li", { class: tocItem, children: [_jsx("span", { class: tocNumber, children: "09" }), _jsx("a", { href: "#best-practices", children: "Best Practices for Managers" })] }), _jsxs("li", { class: tocItem, children: [_jsx("span", { class: tocNumber, children: "10" }), _jsx("a", { href: "#slack-bridge", children: "Slack Integration (NEW)" })] })] })] }), _jsxs("div", { class: section, children: [_jsx("span", { id: "prerequisites", class: sectionAnchor }), _jsx("h2", { class: sectionTitle, children: "00 \u2014 Prerequisites & Setup" }), _jsx("p", { class: sectionSubtitle, children: "Get every team member connected in under 2 minutes" }), _jsxs("p", { class: paragraph, children: ["Before your agents can collaborate, each developer needs Cogent Bridge installed as an MCP server in their Claude Code environment. There are two approaches:", _jsx("span", { class: highlight, children: " cloud mode" }), " (recommended for teams) and", _jsx("span", { class: highlight, children: " local mode" }), " (for same-machine sessions)."] }), _jsxs(Terminal, { title: "Install Cogent Bridge (Every Team Member)", children: [_jsx("p", { class: noteText, children: "Install the plugin for slash commands and automatic session discovery:" }), _jsxs("div", { class: codeBlock, children: [_jsx("span", { class: promptChar, children: "$" }), _jsx("span", { class: stepCommand, children: "claude plugin marketplace add eaisdevelopment/cogent" })] }), _jsxs("div", { class: codeBlock, children: [_jsx("span", { class: promptChar, children: "$" }), _jsx("span", { class: stepCommand, children: "claude plugin install cogent@cogent" })] }), _jsxs("p", { class: noteText, children: ["Restart Claude Code. Use ", _jsx("span", { class: inlineCode, children: "/cogent:register" }), " to join the bridge."] })] }), _jsxs(Terminal, { title: "Claude Desktop", children: [_jsx("p", { class: noteText, children: "Add Cogent Bridge to your Claude Desktop config file:" }), _jsxs("p", { class: noteText, style: "font-size: 0.8rem;", children: [_jsx("strong", { children: "macOS:" }), " ", _jsx("span", { class: inlineCode, children: "~/Library/Application Support/Claude/claude_desktop_config.json" }), _jsx("br", {}), _jsx("strong", { children: "Windows:" }), " ", _jsx("span", { class: inlineCode, children: "%APPDATA%\\Claude\\claude_desktop_config.json" })] }), _jsx("div", { class: codeBlock, children: `{
|
|
275
342
|
"mcpServers": {
|
|
276
343
|
"cogent-bridge": {
|
|
277
344
|
"command": "npx",
|
|
@@ -308,5 +375,63 @@ You are the **[Team Name]** agent.
|
|
|
308
375
|
|
|
309
376
|
### Team Dependencies
|
|
310
377
|
- "frontend" — consumes our API, notify of any contract changes
|
|
311
|
-
- "devops" — manages deployment, notify of new env vars or infra needs` })] }), _jsxs("div", { class: tipBox, children: [_jsx("div", { class: tipLabel, children: "2. Name Your Peers Descriptively" }), _jsx("p", { class: noteText, children: "Use clear, role-based peer IDs that any team member can understand:" }), _jsxs("ul", { class: bulletList, children: [_jsxs("li", { children: [_jsx("span", { class: inlineCode, children: "backend" }), ", ", _jsx("span", { class: inlineCode, children: "frontend" }), ", ", _jsx("span", { class: inlineCode, children: "mobile" }), " \u2014 for team-based splits"] }), _jsxs("li", { children: [_jsx("span", { class: inlineCode, children: "auth-service" }), ", ", _jsx("span", { class: inlineCode, children: "payments" }), ", ", _jsx("span", { class: inlineCode, children: "gateway" }), " \u2014 for microservice architectures"] }), _jsxs("li", { children: [_jsx("span", { class: inlineCode, children: "reviewer" }), ", ", _jsx("span", { class: inlineCode, children: "qa" }), ", ", _jsx("span", { class: inlineCode, children: "security" }), " \u2014 for role-based workflows"] })] })] }), _jsxs("div", { class: tipBox, children: [_jsx("div", { class: tipLabel, children: "3. Establish Communication Standards" }), _jsx("p", { class: noteText, children: "Define message formats in your CLAUDE.md so agents communicate consistently:" }), _jsxs("ul", { class: bulletList, children: [_jsxs("li", { children: [_jsx("strong", { children: "Bug reports:" }), " endpoint, expected, actual, reproduction steps"] }), _jsxs("li", { children: [_jsx("strong", { children: "API changes:" }), " method, path, request body, response shape, breaking?"] }), _jsxs("li", { children: [_jsx("strong", { children: "Status updates:" }), " what's done, what's in progress, what's blocked"] }), _jsxs("li", { children: [_jsx("strong", { children: "Review requests:" }), " files changed, design decisions, areas of concern"] })] })] }), _jsxs("div", { class: tipBox, children: [_jsx("div", { class: tipLabel, children: "4. Use Sessions Strategically" }), _jsx("p", { class: noteText, children: "Create sessions that match your work patterns:" }), _jsxs("ul", { class: bulletList, children: [_jsxs("li", { children: [_jsx("strong", { children: "Per-sprint sessions:" }), " \"sprint-42\" \u2014 all agents join for the sprint duration"] }), _jsxs("li", { children: [_jsx("strong", { children: "Per-feature sessions:" }), " \"feature-payments\" \u2014 only relevant teams join"] }), _jsxs("li", { children: [_jsx("strong", { children: "Ad-hoc sessions:" }), " \"debug-login-issue\" \u2014 temporary session for incident response"] })] })] }), _jsxs("div", { class: tipBox, children: [_jsx("div", { class: tipLabel, children: "5. Review Message History Regularly" }), _jsxs("p", { class: noteText, children: ["Use ", _jsx("span", { class: inlineCode, children: "cogent_get_history" }), " as a management tool. The message history captures every technical decision, every API contract negotiation, every bug report and resolution. This is far richer than any standup summary or ticket description."] })] }), _jsxs("div", { class: tipBox, children: [_jsx("div", { class: tipLabel, children: "6. Start Small, Scale Up" }), _jsx("p", { class: noteText, children: "Begin with two agents on one feature. Once your team sees the speed improvement, expand to multi-agent workflows. Common progression:" }), _jsxs("ul", { class: bulletList, children: [_jsxs("li", { children: [_jsx("strong", { children: "Week 1:" }), " Frontend + Backend on a single feature"] }), _jsxs("li", { children: [_jsx("strong", { children: "Week 2:" }), " Add a QA/testing agent"] }), _jsxs("li", { children: [_jsx("strong", { children: "Week 3:" }), " Full sprint with all team agents connected"] }), _jsxs("li", { children: [_jsx("strong", { children: "Month 2:" }), " Cross-team orchestration for complex features"] })] })] })] }), _jsxs("div", { class: section, children: [_jsx("span", { id: "slack-bridge", class: sectionAnchor }), _jsx("h2", { class: sectionTitle, children: "10 \u2014 Slack Integration (NEW)" }), _jsx("p", { class: sectionSubtitle, children: "Bridge Slack channels to COGENT sessions so humans and AI agents share one conversation" }), _jsxs("div", { class: scenarioBox, children: [_jsx("div", { class: scenarioLabel, children: "Scenario" }), _jsx("p", { class: noteText, children: "Your team communicates in Slack but your Claude Code agents collaborate via COGENT. With the Cogent Bridge Slack app, you can map a Slack channel directly to a COGENT session. Messages flow bidirectionally \u2014 Slack users and CC agents share the same conversation thread without switching tools." })] }), _jsxs("p", { class: paragraph, children: ["The Slack integration turns any Slack channel into a COGENT peer. When a Slack user types a message, the CC agent receives it as a normal COGENT message. When the CC agent responds, the reply appears in the Slack channel. ", _jsx("span", { class: highlight, children: "@mention resolution works both ways" }), " \u2014 Slack usernames map to COGENT peer IDs and vice versa."] }), _jsxs(Terminal, { title: "Step 1: Create a COGENT Session", children: [_jsx("p", { class: noteText, children: "First, create a session from any Claude Code instance (or reuse an existing one):" }), _jsxs("div", { class: codeBlock, children: [_jsx("span", { class: promptChar, children: ">" }), _jsx("span", { class: stepCommand, children: ` Create a Cogent channel called "my-project" with secret "team-secret"` })] }), _jsxs("p", { class: noteText, children: ["Note the ", _jsx("span", { class: inlineCode, children: "sessionId" }), " and ", _jsx("span", { class: inlineCode, children: "secret" }), " \u2014 you'll need them in the next step."] })] }), _jsxs(Terminal, { title: "Step 2: Map a Slack Channel", children: [_jsx("p", { class: noteText, children: "In any Slack channel where the Cogent Bridge app is installed, run:" }), _jsxs("div", { class: codeBlock, children: [_jsx("span", { class: promptChar, children: "/" }), _jsx("span", { class: stepCommand, children: "cogent map <sessionId> <secret>" })] }), _jsx("p", { class: noteText, children: "This binds the Slack channel to the COGENT session. All messages in this channel will be relayed to connected CC agents, and agent responses will appear here." })] }), _jsxs(Terminal, { title: "Step 3: Configure the CC Agent", children: [_jsxs("p", { class: noteText, children: ["On the Claude Code side, ensure ", _jsx("span", { class: inlineCode, children: "COGENT_ENDPOINT" }), " is set and join the same session:"] }), _jsxs("div", { class: codeBlock, children: [_jsx("span", { class: promptChar, children: ">" }), _jsx("span", { class: stepCommand, children: ` Join Cogent channel "my-project" with secret "team-secret"` }), "\n", _jsx("span", { class: promptChar, children: ">" }), _jsx("span", { class: stepCommand, children: ` Register on Cogent as peerId="backend", label="Backend Agent"` })] }), _jsx("p", { class: noteText, children: "The CC agent is now a peer in the same session as the Slack channel. Messages sent from Slack arrive via the normal COGENT relay." })] }), _jsxs(Terminal, { title: "Slack Slash Commands", children: [_jsx("p", { class: noteText, children: "The Slack app provides several slash commands for interacting with the session:" }), _jsxs("div", { class: codeBlock, children: [_jsx("span", { class: promptChar, children: "/" }), _jsx("span", { class: stepCommand, children: "cogent peers" }), _jsx("span", { class: commentLine, children: ` # List all peers in the session` })] }), _jsxs("div", { class: codeBlock, children: [_jsx("span", { class: promptChar, children: "/" }), _jsx("span", { class: stepCommand, children: "cogent send @backend <message>" }), _jsx("span", { class: commentLine, children: ` # Send a targeted message to a specific peer` })] }), _jsxs("div", { class: codeBlock, children: [_jsx("span", { class: promptChar, children: "/" }), _jsx("span", { class: stepCommand, children: "cogent status" }), _jsx("span", { class: commentLine, children: ` # Check session health and connection status` })] })] }), _jsxs("div", { class: flowDiagram, children: [_jsx("span", { class: diagramLabel, children: "Slack Channel CC Agent (backend)" }), "\n", " | |", "\n", " |", _jsx("span", { class: diagramArrow, children: " ---- /cogent map <session> ------> " }), " |", "\n", " | |", "\n", " | [user types message] |", "\n", " |", _jsx("span", { class: diagramArrow, children: " ---- relayed via COGENT ---------> " }), " |", "\n", " | |", "\n", " | [agent processes & responds]", "\n", " | |", "\n", " |", _jsx("span", { class: diagramArrow, children: " <--- response appears in Slack -- " }), " |", "\n", " | |", "\n", " | [team sees response in channel] |", "\n"] }), _jsxs("div", { class: outcomeBox, children: [_jsx("div", { class: outcomeLabel, children: "Business Impact" }), _jsx("p", { class: noteText, children: "Product managers and non-technical stakeholders interact with AI agents directly from Slack \u2014 no need to open a terminal or learn Claude Code. Developers monitor agent activity in real time alongside normal team chat. The entire team shares one communication channel." })] })] }), _jsx("hr", { class: divider }), _jsxs("div", { class: footer, children: ["COGENT \u2014 Powered by ", _jsx("a", { href: "https://essentialai.uk", style: "color: inherit;", children: "Essential AI Solutions Ltd." }), " \u2014 ", _jsx("a", { href: "/", style: "color: inherit;", children: "cogent.tools" })] })] }) }));
|
|
378
|
+
- "devops" — manages deployment, notify of new env vars or infra needs` })] }), _jsxs("div", { class: tipBox, children: [_jsx("div", { class: tipLabel, children: "2. Name Your Peers Descriptively" }), _jsx("p", { class: noteText, children: "Use clear, role-based peer IDs that any team member can understand:" }), _jsxs("ul", { class: bulletList, children: [_jsxs("li", { children: [_jsx("span", { class: inlineCode, children: "backend" }), ", ", _jsx("span", { class: inlineCode, children: "frontend" }), ", ", _jsx("span", { class: inlineCode, children: "mobile" }), " \u2014 for team-based splits"] }), _jsxs("li", { children: [_jsx("span", { class: inlineCode, children: "auth-service" }), ", ", _jsx("span", { class: inlineCode, children: "payments" }), ", ", _jsx("span", { class: inlineCode, children: "gateway" }), " \u2014 for microservice architectures"] }), _jsxs("li", { children: [_jsx("span", { class: inlineCode, children: "reviewer" }), ", ", _jsx("span", { class: inlineCode, children: "qa" }), ", ", _jsx("span", { class: inlineCode, children: "security" }), " \u2014 for role-based workflows"] })] })] }), _jsxs("div", { class: tipBox, children: [_jsx("div", { class: tipLabel, children: "3. Establish Communication Standards" }), _jsx("p", { class: noteText, children: "Define message formats in your CLAUDE.md so agents communicate consistently:" }), _jsxs("ul", { class: bulletList, children: [_jsxs("li", { children: [_jsx("strong", { children: "Bug reports:" }), " endpoint, expected, actual, reproduction steps"] }), _jsxs("li", { children: [_jsx("strong", { children: "API changes:" }), " method, path, request body, response shape, breaking?"] }), _jsxs("li", { children: [_jsx("strong", { children: "Status updates:" }), " what's done, what's in progress, what's blocked"] }), _jsxs("li", { children: [_jsx("strong", { children: "Review requests:" }), " files changed, design decisions, areas of concern"] })] })] }), _jsxs("div", { class: tipBox, children: [_jsx("div", { class: tipLabel, children: "4. Use Sessions Strategically" }), _jsx("p", { class: noteText, children: "Create sessions that match your work patterns:" }), _jsxs("ul", { class: bulletList, children: [_jsxs("li", { children: [_jsx("strong", { children: "Per-sprint sessions:" }), " \"sprint-42\" \u2014 all agents join for the sprint duration"] }), _jsxs("li", { children: [_jsx("strong", { children: "Per-feature sessions:" }), " \"feature-payments\" \u2014 only relevant teams join"] }), _jsxs("li", { children: [_jsx("strong", { children: "Ad-hoc sessions:" }), " \"debug-login-issue\" \u2014 temporary session for incident response"] })] })] }), _jsxs("div", { class: tipBox, children: [_jsx("div", { class: tipLabel, children: "5. Review Message History Regularly" }), _jsxs("p", { class: noteText, children: ["Use ", _jsx("span", { class: inlineCode, children: "cogent_get_history" }), " as a management tool. The message history captures every technical decision, every API contract negotiation, every bug report and resolution. This is far richer than any standup summary or ticket description."] })] }), _jsxs("div", { class: tipBox, children: [_jsx("div", { class: tipLabel, children: "6. Start Small, Scale Up" }), _jsx("p", { class: noteText, children: "Begin with two agents on one feature. Once your team sees the speed improvement, expand to multi-agent workflows. Common progression:" }), _jsxs("ul", { class: bulletList, children: [_jsxs("li", { children: [_jsx("strong", { children: "Week 1:" }), " Frontend + Backend on a single feature"] }), _jsxs("li", { children: [_jsx("strong", { children: "Week 2:" }), " Add a QA/testing agent"] }), _jsxs("li", { children: [_jsx("strong", { children: "Week 3:" }), " Full sprint with all team agents connected"] }), _jsxs("li", { children: [_jsx("strong", { children: "Month 2:" }), " Cross-team orchestration for complex features"] })] })] })] }), _jsxs("div", { class: section, children: [_jsx("span", { id: "slack-bridge", class: sectionAnchor }), _jsx("h2", { class: sectionTitle, children: "10 \u2014 Slack Integration (NEW)" }), _jsx("p", { class: sectionSubtitle, children: "Bridge Slack channels to COGENT sessions so humans and AI agents share one conversation" }), _jsxs("div", { class: scenarioBox, children: [_jsx("div", { class: scenarioLabel, children: "Scenario" }), _jsx("p", { class: noteText, children: "Your team communicates in Slack but your Claude Code agents collaborate via COGENT. With the Cogent Bridge Slack app, you can map a Slack channel directly to a COGENT session. Messages flow bidirectionally \u2014 Slack users and CC agents share the same conversation thread without switching tools." })] }), _jsxs("p", { class: paragraph, children: ["The Slack integration turns any Slack channel into a COGENT peer. When a Slack user types a message, the CC agent receives it as a normal COGENT message. When the CC agent responds, the reply appears in the Slack channel. ", _jsx("span", { class: highlight, children: "@mention resolution works both ways" }), " \u2014 Slack usernames map to COGENT peer IDs and vice versa."] }), _jsxs(Terminal, { title: "Step 1: Create a COGENT Session", children: [_jsx("p", { class: noteText, children: "First, create a session from any Claude Code instance (or reuse an existing one):" }), _jsxs("div", { class: codeBlock, children: [_jsx("span", { class: promptChar, children: ">" }), _jsx("span", { class: stepCommand, children: ` Create a Cogent channel called "my-project" with secret "team-secret"` })] }), _jsxs("p", { class: noteText, children: ["Note the ", _jsx("span", { class: inlineCode, children: "sessionId" }), " and ", _jsx("span", { class: inlineCode, children: "secret" }), " \u2014 you'll need them in the next step."] })] }), _jsxs(Terminal, { title: "Step 2: Map a Slack Channel", children: [_jsx("p", { class: noteText, children: "In any Slack channel where the Cogent Bridge app is installed, run:" }), _jsxs("div", { class: codeBlock, children: [_jsx("span", { class: promptChar, children: "/" }), _jsx("span", { class: stepCommand, children: "cogent map <sessionId> <secret>" })] }), _jsx("p", { class: noteText, children: "This binds the Slack channel to the COGENT session. All messages in this channel will be relayed to connected CC agents, and agent responses will appear here." })] }), _jsxs(Terminal, { title: "Step 3: Configure the CC Agent", children: [_jsxs("p", { class: noteText, children: ["On the Claude Code side, ensure ", _jsx("span", { class: inlineCode, children: "COGENT_ENDPOINT" }), " is set and join the same session:"] }), _jsxs("div", { class: codeBlock, children: [_jsx("span", { class: promptChar, children: ">" }), _jsx("span", { class: stepCommand, children: ` Join Cogent channel "my-project" with secret "team-secret"` }), "\n", _jsx("span", { class: promptChar, children: ">" }), _jsx("span", { class: stepCommand, children: ` Register on Cogent as peerId="backend", label="Backend Agent"` })] }), _jsx("p", { class: noteText, children: "The CC agent is now a peer in the same session as the Slack channel. Messages sent from Slack arrive via the normal COGENT relay." })] }), _jsxs(Terminal, { title: "Slack Slash Commands", children: [_jsx("p", { class: noteText, children: "The Slack app provides several slash commands for interacting with the session:" }), _jsxs("div", { class: codeBlock, children: [_jsx("span", { class: promptChar, children: "/" }), _jsx("span", { class: stepCommand, children: "cogent peers" }), _jsx("span", { class: commentLine, children: ` # List all peers in the session` })] }), _jsxs("div", { class: codeBlock, children: [_jsx("span", { class: promptChar, children: "/" }), _jsx("span", { class: stepCommand, children: "cogent send @backend <message>" }), _jsx("span", { class: commentLine, children: ` # Send a targeted message to a specific peer` })] }), _jsxs("div", { class: codeBlock, children: [_jsx("span", { class: promptChar, children: "/" }), _jsx("span", { class: stepCommand, children: "cogent status" }), _jsx("span", { class: commentLine, children: ` # Check session health and connection status` })] })] }), _jsxs("div", { class: flowDiagram, children: [_jsx("span", { class: diagramLabel, children: "Slack Channel CC Agent (backend)" }), "\n", " | |", "\n", " |", _jsx("span", { class: diagramArrow, children: " ---- /cogent map <session> ------> " }), " |", "\n", " | |", "\n", " | [user types message] |", "\n", " |", _jsx("span", { class: diagramArrow, children: " ---- relayed via COGENT ---------> " }), " |", "\n", " | |", "\n", " | [agent processes & responds]", "\n", " | |", "\n", " |", _jsx("span", { class: diagramArrow, children: " <--- response appears in Slack -- " }), " |", "\n", " | |", "\n", " | [team sees response in channel] |", "\n"] }), _jsxs("div", { class: outcomeBox, children: [_jsx("div", { class: outcomeLabel, children: "Business Impact" }), _jsx("p", { class: noteText, children: "Product managers and non-technical stakeholders interact with AI agents directly from Slack \u2014 no need to open a terminal or learn Claude Code. Developers monitor agent activity in real time alongside normal team chat. The entire team shares one communication channel." })] })] }), _jsx("hr", { class: divider }), _jsxs("div", { class: footer, children: ["COGENT \u2014 Powered by ", _jsx("a", { href: "https://essentialai.uk", style: "color: inherit;", children: "Essential AI Solutions Ltd." }), " \u2014 ", _jsx("a", { href: "/", style: "color: inherit;", children: "cogent.tools" })] })] }), _jsxs("div", { id: "floating-nav", class: floatingNav, style: "opacity: 0; pointer-events: none; transition: opacity 0.3s;", children: [_jsxs("ul", { id: "floating-menu", class: floatingMenu, style: "display: none;", children: [_jsx("li", { children: _jsxs("a", { href: "#prerequisites", children: [_jsx("span", { class: "nav-num", children: "00" }), "Prerequisites & Setup"] }) }), _jsx("li", { children: _jsxs("a", { href: "#parallel-dev", children: [_jsx("span", { class: "nav-num", children: "01" }), "Parallel Feature Development"] }) }), _jsx("li", { children: _jsxs("a", { href: "#bug-relay", children: [_jsx("span", { class: "nav-num", children: "02" }), "Cross-Team Bug Investigation"] }) }), _jsx("li", { children: _jsxs("a", { href: "#api-contracts", children: [_jsx("span", { class: "nav-num", children: "03" }), "API Contract Negotiation"] }) }), _jsx("li", { children: _jsxs("a", { href: "#code-review", children: [_jsx("span", { class: "nav-num", children: "04" }), "Cross-Agent Code Review"] }) }), _jsx("li", { children: _jsxs("a", { href: "#multi-service", children: [_jsx("span", { class: "nav-num", children: "05" }), "Multi-Service Orchestration"] }) }), _jsx("li", { children: _jsxs("a", { href: "#sprint-sync", children: [_jsx("span", { class: "nav-num", children: "06" }), "Sprint Kick-off Alignment"] }) }), _jsx("li", { children: _jsxs("a", { href: "#integration-test", children: [_jsx("span", { class: "nav-num", children: "07" }), "Real-Time Integration Testing"] }) }), _jsx("li", { children: _jsxs("a", { href: "#command-ref", children: [_jsx("span", { class: "nav-num", children: "08" }), "Command Reference"] }) }), _jsx("li", { children: _jsxs("a", { href: "#best-practices", children: [_jsx("span", { class: "nav-num", children: "09" }), "Best Practices for Managers"] }) }), _jsx("li", { children: _jsxs("a", { href: "#slack-bridge", children: [_jsx("span", { class: "nav-num", children: "10" }), "Slack Integration"] }) })] }), _jsx("button", { id: "nav-toggle", class: floatingBtn, title: "Section Navigator", children: "\u2630" }), _jsx("button", { id: "back-to-top", class: floatingBtn, title: "Back to Top", children: "\u2191" })] }), _jsx("script", { dangerouslySetInnerHTML: { __html: `
|
|
379
|
+
(function() {
|
|
380
|
+
var nav = document.getElementById('floating-nav');
|
|
381
|
+
var menu = document.getElementById('floating-menu');
|
|
382
|
+
var toggle = document.getElementById('nav-toggle');
|
|
383
|
+
var topBtn = document.getElementById('back-to-top');
|
|
384
|
+
var tocEl = document.querySelector('[class*="toc"]');
|
|
385
|
+
var menuOpen = false;
|
|
386
|
+
|
|
387
|
+
// Show/hide floating nav based on scroll past TOC
|
|
388
|
+
function checkScroll() {
|
|
389
|
+
if (!tocEl) return;
|
|
390
|
+
var tocBottom = tocEl.getBoundingClientRect().bottom;
|
|
391
|
+
if (tocBottom < 0) {
|
|
392
|
+
nav.style.opacity = '1';
|
|
393
|
+
nav.style.pointerEvents = 'auto';
|
|
394
|
+
} else {
|
|
395
|
+
nav.style.opacity = '0';
|
|
396
|
+
nav.style.pointerEvents = 'none';
|
|
397
|
+
if (menuOpen) { menu.style.display = 'none'; menuOpen = false; }
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Highlight active section
|
|
402
|
+
var anchors = ['prerequisites','parallel-dev','bug-relay','api-contracts','code-review','multi-service','sprint-sync','integration-test','command-ref','best-practices','slack-bridge'];
|
|
403
|
+
function highlightActive() {
|
|
404
|
+
var current = '';
|
|
405
|
+
for (var i = 0; i < anchors.length; i++) {
|
|
406
|
+
var el = document.getElementById(anchors[i]);
|
|
407
|
+
if (el && el.getBoundingClientRect().top < 120) current = anchors[i];
|
|
408
|
+
}
|
|
409
|
+
var links = menu.querySelectorAll('a');
|
|
410
|
+
for (var j = 0; j < links.length; j++) {
|
|
411
|
+
links[j].classList.toggle('active', links[j].getAttribute('href') === '#' + current);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
window.addEventListener('scroll', function() { checkScroll(); highlightActive(); }, { passive: true });
|
|
416
|
+
|
|
417
|
+
toggle.addEventListener('click', function() {
|
|
418
|
+
menuOpen = !menuOpen;
|
|
419
|
+
menu.style.display = menuOpen ? 'block' : 'none';
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
// Close menu when clicking a link
|
|
423
|
+
menu.addEventListener('click', function(e) {
|
|
424
|
+
if (e.target.tagName === 'A' || e.target.closest('a')) {
|
|
425
|
+
menuOpen = false;
|
|
426
|
+
menu.style.display = 'none';
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
topBtn.addEventListener('click', function() {
|
|
431
|
+
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
checkScroll();
|
|
435
|
+
})();
|
|
436
|
+
` } })] }));
|
|
312
437
|
//# sourceMappingURL=HowToPage.js.map
|