@affectively/aeon 1.3.0 → 5.0.1
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/LICENSE +5 -11
- package/README.md +90 -10
- package/dist/compression/index.cjs +20 -3
- package/dist/compression/index.cjs.map +1 -1
- package/dist/compression/index.js +20 -3
- package/dist/compression/index.js.map +1 -1
- package/dist/crypto/index.cjs +30 -0
- package/dist/crypto/index.cjs.map +1 -1
- package/dist/crypto/index.js +29 -1
- package/dist/crypto/index.js.map +1 -1
- package/dist/distributed/index.cjs +15 -8
- package/dist/distributed/index.cjs.map +1 -1
- package/dist/distributed/index.js +15 -8
- package/dist/distributed/index.js.map +1 -1
- package/dist/index.cjs +2923 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2879 -47
- package/dist/index.js.map +1 -1
- package/dist/optimization/index.cjs +6 -3
- package/dist/optimization/index.cjs.map +1 -1
- package/dist/optimization/index.js +6 -3
- package/dist/optimization/index.js.map +1 -1
- package/dist/persistence/index.cjs +91 -29
- package/dist/persistence/index.cjs.map +1 -1
- package/dist/persistence/index.js +91 -29
- package/dist/persistence/index.js.map +1 -1
- package/dist/presence/index.cjs.map +1 -1
- package/dist/presence/index.js.map +1 -1
- package/dist/versioning/index.cjs +4 -3
- package/dist/versioning/index.cjs.map +1 -1
- package/dist/versioning/index.js +4 -3
- package/dist/versioning/index.js.map +1 -1
- package/package.json +7 -8
- package/dist/compression/index.d.cts +0 -189
- package/dist/compression/index.d.ts +0 -189
- package/dist/core/index.d.cts +0 -216
- package/dist/core/index.d.ts +0 -216
- package/dist/crypto/index.d.cts +0 -446
- package/dist/crypto/index.d.ts +0 -446
- package/dist/distributed/index.d.cts +0 -1016
- package/dist/distributed/index.d.ts +0 -1016
- package/dist/index.d.cts +0 -12
- package/dist/index.d.ts +0 -12
- package/dist/offline/index.d.cts +0 -154
- package/dist/offline/index.d.ts +0 -154
- package/dist/optimization/index.d.cts +0 -347
- package/dist/optimization/index.d.ts +0 -347
- package/dist/persistence/index.d.cts +0 -63
- package/dist/persistence/index.d.ts +0 -63
- package/dist/presence/index.d.cts +0 -283
- package/dist/presence/index.d.ts +0 -283
- package/dist/types-B7gCpNX9.d.cts +0 -33
- package/dist/types-B7gCpNX9.d.ts +0 -33
- package/dist/utils/index.d.cts +0 -38
- package/dist/utils/index.d.ts +0 -38
- package/dist/versioning/index.d.cts +0 -537
- package/dist/versioning/index.d.ts +0 -537
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
// src/persistence/DashStorageAdapter.ts
|
|
2
|
+
var DEFAULT_RULE = {
|
|
3
|
+
urgency: "deferred",
|
|
4
|
+
debounce: 50,
|
|
5
|
+
maxBufferSize: 5e3,
|
|
6
|
+
readThrough: true
|
|
7
|
+
};
|
|
2
8
|
var DashStorageAdapter = class {
|
|
3
9
|
backend;
|
|
4
10
|
syncClient;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
onSyncError;
|
|
11
|
+
rules;
|
|
12
|
+
hooks;
|
|
8
13
|
pendingChanges = /* @__PURE__ */ new Map();
|
|
9
14
|
syncTimer = null;
|
|
10
15
|
syncInFlight = false;
|
|
@@ -12,11 +17,33 @@ var DashStorageAdapter = class {
|
|
|
12
17
|
constructor(backend, options = {}) {
|
|
13
18
|
this.backend = backend;
|
|
14
19
|
this.syncClient = options.syncClient ?? null;
|
|
15
|
-
this.
|
|
16
|
-
|
|
17
|
-
|
|
20
|
+
this.hooks = options.hooks ?? {};
|
|
21
|
+
const defaultRule = {
|
|
22
|
+
...DEFAULT_RULE,
|
|
23
|
+
...options.rules?.default ?? {}
|
|
24
|
+
};
|
|
25
|
+
if (options.syncDebounceMs !== void 0)
|
|
26
|
+
defaultRule.debounce = options.syncDebounceMs;
|
|
27
|
+
if (options.maxPendingChanges !== void 0)
|
|
28
|
+
defaultRule.maxBufferSize = options.maxPendingChanges;
|
|
29
|
+
if (options.onSyncError && !this.hooks.onSyncError)
|
|
30
|
+
this.hooks.onSyncError = options.onSyncError;
|
|
31
|
+
this.rules = {
|
|
32
|
+
default: defaultRule,
|
|
33
|
+
prefixes: options.rules?.prefixes ?? {}
|
|
34
|
+
};
|
|
18
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Get an item, checking the write pool (pending changes) first for consistency.
|
|
38
|
+
*/
|
|
19
39
|
async getItem(key) {
|
|
40
|
+
const rule = this.getRuleForKey(key);
|
|
41
|
+
if (rule.readThrough !== false) {
|
|
42
|
+
const pending = this.pendingChanges.get(key);
|
|
43
|
+
if (pending) {
|
|
44
|
+
return pending.operation === "delete" ? null : pending.value ?? null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
20
47
|
return await this.backend.get(key);
|
|
21
48
|
}
|
|
22
49
|
async setItem(key, value) {
|
|
@@ -51,34 +78,45 @@ var DashStorageAdapter = class {
|
|
|
51
78
|
}
|
|
52
79
|
trackChange(change) {
|
|
53
80
|
this.pendingChanges.set(change.key, change);
|
|
54
|
-
this.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
enforcePendingLimit() {
|
|
58
|
-
if (this.pendingChanges.size <= this.maxPendingChanges) {
|
|
81
|
+
const rule = this.getRuleForKey(change.key);
|
|
82
|
+
if (rule.urgency === "realtime") {
|
|
83
|
+
void this.performSync();
|
|
59
84
|
return;
|
|
60
85
|
}
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
86
|
+
const maxSize = rule.maxBufferSize ?? 5e3;
|
|
87
|
+
if (this.pendingChanges.size >= maxSize) {
|
|
88
|
+
this.hooks.onBufferOverflow?.(
|
|
89
|
+
this.getPrefixMatch(change.key) || "default",
|
|
90
|
+
this.pendingChanges.size,
|
|
91
|
+
maxSize
|
|
92
|
+
);
|
|
93
|
+
void this.performSync();
|
|
94
|
+
return;
|
|
70
95
|
}
|
|
96
|
+
this.scheduleSync(rule);
|
|
71
97
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
98
|
+
getRuleForKey(key) {
|
|
99
|
+
const prefix = this.getPrefixMatch(key);
|
|
100
|
+
return (prefix ? this.rules.prefixes?.[prefix] : this.rules.default) ?? this.rules.default;
|
|
101
|
+
}
|
|
102
|
+
getPrefixMatch(key) {
|
|
103
|
+
if (!this.rules.prefixes) {
|
|
104
|
+
return null;
|
|
75
105
|
}
|
|
76
|
-
|
|
77
|
-
|
|
106
|
+
const prefixes = Object.keys(this.rules.prefixes).sort(
|
|
107
|
+
(a, b) => b.length - a.length
|
|
108
|
+
);
|
|
109
|
+
return prefixes.find((p) => key.startsWith(p)) ?? null;
|
|
110
|
+
}
|
|
111
|
+
scheduleSync(rule) {
|
|
112
|
+
if (!this.syncClient || this.syncTimer) {
|
|
113
|
+
return;
|
|
78
114
|
}
|
|
115
|
+
const debounceMs = typeof rule.debounce === "string" ? this.parseInterval(rule.debounce) : rule.debounce ?? 50;
|
|
79
116
|
this.syncTimer = setTimeout(() => {
|
|
117
|
+
this.syncTimer = null;
|
|
80
118
|
void this.performSync();
|
|
81
|
-
},
|
|
119
|
+
}, debounceMs);
|
|
82
120
|
}
|
|
83
121
|
async performSync() {
|
|
84
122
|
if (!this.syncClient) {
|
|
@@ -98,6 +136,8 @@ var DashStorageAdapter = class {
|
|
|
98
136
|
this.syncInFlight = true;
|
|
99
137
|
try {
|
|
100
138
|
await this.syncClient.syncChanges(changes);
|
|
139
|
+
this.hooks.onSync?.(changes);
|
|
140
|
+
this.hooks.onFlush?.(changes.length);
|
|
101
141
|
} catch (error) {
|
|
102
142
|
for (const change of changes) {
|
|
103
143
|
const current = this.pendingChanges.get(change.key);
|
|
@@ -105,19 +145,39 @@ var DashStorageAdapter = class {
|
|
|
105
145
|
this.pendingChanges.set(change.key, change);
|
|
106
146
|
}
|
|
107
147
|
}
|
|
108
|
-
if (this.onSyncError) {
|
|
148
|
+
if (this.hooks.onSyncError) {
|
|
109
149
|
const normalizedError = error instanceof Error ? error : new Error(String(error));
|
|
110
|
-
this.onSyncError(normalizedError, changes);
|
|
150
|
+
this.hooks.onSyncError(normalizedError, changes);
|
|
111
151
|
}
|
|
112
152
|
} finally {
|
|
113
153
|
this.syncInFlight = false;
|
|
114
154
|
const rerun = this.syncPending || this.pendingChanges.size > 0;
|
|
115
155
|
this.syncPending = false;
|
|
116
156
|
if (rerun) {
|
|
117
|
-
this.scheduleSync();
|
|
157
|
+
this.scheduleSync(this.rules.default);
|
|
118
158
|
}
|
|
119
159
|
}
|
|
120
160
|
}
|
|
161
|
+
parseInterval(input) {
|
|
162
|
+
const match = input.match(/^(\d+)(ms|s|m|h|d)$/);
|
|
163
|
+
if (!match) return 50;
|
|
164
|
+
const value = parseInt(match[1], 10);
|
|
165
|
+
const unit = match[2];
|
|
166
|
+
switch (unit) {
|
|
167
|
+
case "ms":
|
|
168
|
+
return value;
|
|
169
|
+
case "s":
|
|
170
|
+
return value * 1e3;
|
|
171
|
+
case "m":
|
|
172
|
+
return value * 60 * 1e3;
|
|
173
|
+
case "h":
|
|
174
|
+
return value * 60 * 60 * 1e3;
|
|
175
|
+
case "d":
|
|
176
|
+
return value * 24 * 60 * 60 * 1e3;
|
|
177
|
+
default:
|
|
178
|
+
return 50;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
121
181
|
};
|
|
122
182
|
|
|
123
183
|
// src/persistence/InMemoryStorageAdapter.ts
|
|
@@ -132,6 +192,8 @@ var InMemoryStorageAdapter = class {
|
|
|
132
192
|
removeItem(key) {
|
|
133
193
|
this.store.delete(key);
|
|
134
194
|
}
|
|
195
|
+
async flushSync() {
|
|
196
|
+
}
|
|
135
197
|
clear() {
|
|
136
198
|
this.store.clear();
|
|
137
199
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/persistence/DashStorageAdapter.ts","../../src/persistence/InMemoryStorageAdapter.ts"],"names":[],"mappings":";AAgCO,IAAM,qBAAN,MAAmD;AAAA,EACvC,OAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAA;AAAA,EACA,iBAAA;AAAA,EACA,WAAA;AAAA,EAGA,cAAA,uBAAqB,GAAA,EAA+B;AAAA,EAC7D,SAAA,GAAkD,IAAA;AAAA,EAClD,YAAA,GAAe,KAAA;AAAA,EACf,WAAA,GAAc,KAAA;AAAA,EAEtB,WAAA,CACE,OAAA,EACA,OAAA,GAAqC,EAAC,EACtC;AACA,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AACf,IAAA,IAAA,CAAK,UAAA,GAAa,QAAQ,UAAA,IAAc,IAAA;AACxC,IAAA,IAAA,CAAK,cAAA,GAAiB,QAAQ,cAAA,IAAkB,EAAA;AAChD,IAAA,IAAA,CAAK,iBAAA,GAAoB,QAAQ,iBAAA,IAAqB,GAAA;AACtD,IAAA,IAAA,CAAK,WAAA,GAAc,QAAQ,WAAA,IAAe,IAAA;AAAA,EAC5C;AAAA,EAEA,MAAM,QAAQ,GAAA,EAAqC;AACjD,IAAA,OAAO,MAAM,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AAAA,EACnC;AAAA,EAEA,MAAM,OAAA,CAAQ,GAAA,EAAa,KAAA,EAA8B;AACvD,IAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,GAAA,EAAK,KAAK,CAAA;AACjC,IAAA,IAAA,CAAK,WAAA,CAAY;AAAA,MACf,GAAA;AAAA,MACA,SAAA,EAAW,KAAA;AAAA,MACX,KAAA;AAAA,MACA,SAAA,EAAW,KAAK,GAAA;AAAI,KACrB,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,WAAW,GAAA,EAA4B;AAC3C,IAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,GAAG,CAAA;AAC7B,IAAA,IAAA,CAAK,WAAA,CAAY;AAAA,MACf,GAAA;AAAA,MACA,SAAA,EAAW,QAAA;AAAA,MACX,SAAA,EAAW,KAAK,GAAA;AAAI,KACrB,CAAA;AAAA,EACH;AAAA,EAEA,mBAAA,GAA8B;AAC5B,IAAA,OAAO,KAAK,cAAA,CAAe,IAAA;AAAA,EAC7B;AAAA,EAEA,MAAM,SAAA,GAA2B;AAC/B,IAAA,IAAI,CAAC,IAAA,CAAK,UAAA,IAAc,IAAA,CAAK,cAAA,CAAe,SAAS,CAAA,EAAG;AACtD,MAAA;AAAA,IACF;AACA,IAAA,IAAI,KAAK,SAAA,EAAW;AAClB,MAAA,YAAA,CAAa,KAAK,SAAS,CAAA;AAC3B,MAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,IACnB;AACA,IAAA,MAAM,KAAK,WAAA,EAAY;AAAA,EACzB;AAAA,EAEQ,YAAY,MAAA,EAAiC;AACnD,IAAA,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,MAAA,CAAO,GAAA,EAAK,MAAM,CAAA;AAC1C,IAAA,IAAA,CAAK,mBAAA,EAAoB;AACzB,IAAA,IAAA,CAAK,YAAA,EAAa;AAAA,EACpB;AAAA,EAEQ,mBAAA,GAA4B;AAClC,IAAA,IAAI,IAAA,CAAK,cAAA,CAAe,IAAA,IAAQ,IAAA,CAAK,iBAAA,EAAmB;AACtD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,SAAS,KAAA,CAAM,IAAA,CAAK,KAAK,cAAA,CAAe,MAAA,EAAQ,CAAA,CAAE,IAAA;AAAA,MACtD,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,YAAY,CAAA,CAAE;AAAA,KAC5B;AACA,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,cAAA,CAAe,IAAA,GAAO,IAAA,CAAK,iBAAA;AACjD,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,EAAU,CAAA,EAAA,EAAK;AACjC,MAAA,MAAM,MAAA,GAAS,OAAO,CAAC,CAAA;AACvB,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,IAAA,CAAK,cAAA,CAAe,MAAA,CAAO,MAAA,CAAO,GAAG,CAAA;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,YAAA,GAAqB;AAC3B,IAAA,IAAI,CAAC,KAAK,UAAA,EAAY;AACpB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,KAAK,SAAA,EAAW;AAClB,MAAA,YAAA,CAAa,KAAK,SAAS,CAAA;AAAA,IAC7B;AAEA,IAAA,IAAA,CAAK,SAAA,GAAY,WAAW,MAAM;AAChC,MAAA,KAAK,KAAK,WAAA,EAAY;AAAA,IACxB,CAAA,EAAG,KAAK,cAAc,CAAA;AAAA,EACxB;AAAA,EAEA,MAAc,WAAA,GAA6B;AACzC,IAAA,IAAI,CAAC,KAAK,UAAA,EAAY;AACpB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,KAAK,YAAA,EAAc;AACrB,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AACnB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,UAAU,KAAA,CAAM,IAAA,CAAK,KAAK,cAAA,CAAe,MAAA,EAAQ,CAAA,CAAE,IAAA;AAAA,MACvD,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,YAAY,CAAA,CAAE;AAAA,KAC5B;AACA,IAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,eAAe,KAAA,EAAM;AAC1B,IAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AACpB,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,UAAA,CAAW,WAAA,CAAY,OAAO,CAAA;AAAA,IAC3C,SAAS,KAAA,EAAO;AACd,MAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,QAAA,MAAM,OAAA,GAAU,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,OAAO,GAAG,CAAA;AAClD,QAAA,IAAI,CAAC,OAAA,IAAW,MAAA,CAAO,SAAA,GAAY,QAAQ,SAAA,EAAW;AACpD,UAAA,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,MAAA,CAAO,GAAA,EAAK,MAAM,CAAA;AAAA,QAC5C;AAAA,MACF;AAEA,MAAA,IAAI,KAAK,WAAA,EAAa;AACpB,QAAA,MAAM,eAAA,GACJ,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AAC1D,QAAA,IAAA,CAAK,WAAA,CAAY,iBAAiB,OAAO,CAAA;AAAA,MAC3C;AAAA,IACF,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,YAAA,GAAe,KAAA;AACpB,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,WAAA,IAAe,IAAA,CAAK,eAAe,IAAA,GAAO,CAAA;AAC7D,MAAA,IAAA,CAAK,WAAA,GAAc,KAAA;AACnB,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,IAAA,CAAK,YAAA,EAAa;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AACF;;;ACzKO,IAAM,yBAAN,MAAuD;AAAA,EAC3C,KAAA,uBAAY,GAAA,EAAoB;AAAA,EAEjD,QAAQ,GAAA,EAA4B;AAClC,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA,IAAK,IAAA;AAAA,EAChC;AAAA,EAEA,OAAA,CAAQ,KAAa,KAAA,EAAqB;AACxC,IAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,GAAA,EAAK,KAAK,CAAA;AAAA,EAC3B;AAAA,EAEA,WAAW,GAAA,EAAmB;AAC5B,IAAA,IAAA,CAAK,KAAA,CAAM,OAAO,GAAG,CAAA;AAAA,EACvB;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,MAAM,KAAA,EAAM;AAAA,EACnB;AACF","file":"index.js","sourcesContent":["import type { StorageAdapter } from './types';\n\nexport interface DashStorageBackend {\n get(key: string): Promise<string | null> | string | null;\n set(key: string, value: string): Promise<void> | void;\n delete(key: string): Promise<void> | void;\n}\n\nexport interface DashStorageChange {\n key: string;\n operation: 'set' | 'delete';\n value?: string;\n timestamp: number;\n}\n\nexport interface DashSyncClient {\n syncChanges(changes: DashStorageChange[]): Promise<void>;\n}\n\nexport interface DashStorageAdapterOptions {\n syncClient?: DashSyncClient;\n syncDebounceMs?: number;\n maxPendingChanges?: number;\n onSyncError?: (error: Error, changes: DashStorageChange[]) => void;\n}\n\n/**\n * Storage adapter boundary for dash-backed persistence.\n *\n * Writes are local-first through the provided backend and optionally synced\n * to D1/R2 via a sync client using debounced change batches.\n */\nexport class DashStorageAdapter implements StorageAdapter {\n private readonly backend: DashStorageBackend;\n private readonly syncClient: DashSyncClient | null;\n private readonly syncDebounceMs: number;\n private readonly maxPendingChanges: number;\n private readonly onSyncError:\n | ((error: Error, changes: DashStorageChange[]) => void)\n | null;\n private readonly pendingChanges = new Map<string, DashStorageChange>();\n private syncTimer: ReturnType<typeof setTimeout> | null = null;\n private syncInFlight = false;\n private syncPending = false;\n\n constructor(\n backend: DashStorageBackend,\n options: DashStorageAdapterOptions = {}\n ) {\n this.backend = backend;\n this.syncClient = options.syncClient ?? null;\n this.syncDebounceMs = options.syncDebounceMs ?? 50;\n this.maxPendingChanges = options.maxPendingChanges ?? 5000;\n this.onSyncError = options.onSyncError ?? null;\n }\n\n async getItem(key: string): Promise<string | null> {\n return await this.backend.get(key);\n }\n\n async setItem(key: string, value: string): Promise<void> {\n await this.backend.set(key, value);\n this.trackChange({\n key,\n operation: 'set',\n value,\n timestamp: Date.now(),\n });\n }\n\n async removeItem(key: string): Promise<void> {\n await this.backend.delete(key);\n this.trackChange({\n key,\n operation: 'delete',\n timestamp: Date.now(),\n });\n }\n\n getPendingSyncCount(): number {\n return this.pendingChanges.size;\n }\n\n async flushSync(): Promise<void> {\n if (!this.syncClient || this.pendingChanges.size === 0) {\n return;\n }\n if (this.syncTimer) {\n clearTimeout(this.syncTimer);\n this.syncTimer = null;\n }\n await this.performSync();\n }\n\n private trackChange(change: DashStorageChange): void {\n this.pendingChanges.set(change.key, change);\n this.enforcePendingLimit();\n this.scheduleSync();\n }\n\n private enforcePendingLimit(): void {\n if (this.pendingChanges.size <= this.maxPendingChanges) {\n return;\n }\n\n const sorted = Array.from(this.pendingChanges.values()).sort(\n (a, b) => a.timestamp - b.timestamp\n );\n const overflow = this.pendingChanges.size - this.maxPendingChanges;\n for (let i = 0; i < overflow; i++) {\n const toDrop = sorted[i];\n if (toDrop) {\n this.pendingChanges.delete(toDrop.key);\n }\n }\n }\n\n private scheduleSync(): void {\n if (!this.syncClient) {\n return;\n }\n\n if (this.syncTimer) {\n clearTimeout(this.syncTimer);\n }\n\n this.syncTimer = setTimeout(() => {\n void this.performSync();\n }, this.syncDebounceMs);\n }\n\n private async performSync(): Promise<void> {\n if (!this.syncClient) {\n return;\n }\n\n if (this.syncInFlight) {\n this.syncPending = true;\n return;\n }\n\n const changes = Array.from(this.pendingChanges.values()).sort(\n (a, b) => a.timestamp - b.timestamp\n );\n if (changes.length === 0) {\n return;\n }\n\n this.pendingChanges.clear();\n this.syncInFlight = true;\n try {\n await this.syncClient.syncChanges(changes);\n } catch (error) {\n for (const change of changes) {\n const current = this.pendingChanges.get(change.key);\n if (!current || change.timestamp > current.timestamp) {\n this.pendingChanges.set(change.key, change);\n }\n }\n\n if (this.onSyncError) {\n const normalizedError =\n error instanceof Error ? error : new Error(String(error));\n this.onSyncError(normalizedError, changes);\n }\n } finally {\n this.syncInFlight = false;\n const rerun = this.syncPending || this.pendingChanges.size > 0;\n this.syncPending = false;\n if (rerun) {\n this.scheduleSync();\n }\n }\n }\n}\n","import type { StorageAdapter } from './types';\n\n/**\n * In-memory adapter for tests and ephemeral runtimes.\n */\nexport class InMemoryStorageAdapter implements StorageAdapter {\n private readonly store = new Map<string, string>();\n\n getItem(key: string): string | null {\n return this.store.get(key) ?? null;\n }\n\n setItem(key: string, value: string): void {\n this.store.set(key, value);\n }\n\n removeItem(key: string): void {\n this.store.delete(key);\n }\n\n clear(): void {\n this.store.clear();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/persistence/DashStorageAdapter.ts","../../src/persistence/InMemoryStorageAdapter.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { StorageAdapter } from './types';\n\nexport interface DashStorageBackend {\n get(key: string): Promise<string | null> | string | null;\n set(key: string, value: string): Promise<void> | void;\n delete(key: string): Promise<void> | void;\n}\n\nexport interface DashStorageChange {\n key: string;\n operation: 'set' | 'delete';\n value?: string;\n timestamp: number;\n}\n\nexport interface DashSyncClient {\n syncChanges(changes: DashStorageChange[]): Promise<void>;\n}\n\nexport type DashSyncUrgency = 'realtime' | 'deferred' | 'lazy';\n\nexport interface DashSyncRule {\n /** How quickly to sync changes for keys matching this rule/prefix */\n urgency: DashSyncUrgency;\n /** Debounce/Interval for deferred/lazy sync (e.g. '1s', '1m', '1h') */\n debounce?: string | number;\n /** Maximum number of pending changes before forcing a sync */\n maxBufferSize?: number;\n /** Whether to return pending values from memory (default: true) */\n readThrough?: boolean;\n}\n\nexport interface DashSyncRules {\n default?: DashSyncRule;\n /** Key prefix mapping to sync rules */\n prefixes?: Record<string, DashSyncRule>;\n}\n\nexport interface DashStorageAdapterHooks {\n onSync?: (changes: DashStorageChange[]) => void;\n onSyncError?: (error: Error, changes: DashStorageChange[]) => void;\n onBufferOverflow?: (prefix: string, size: number, max: number) => void;\n onFlush?: (count: number) => void;\n}\n\nexport interface DashStorageAdapterOptions {\n syncClient?: DashSyncClient;\n rules?: DashSyncRules;\n hooks?: DashStorageAdapterHooks;\n /** @deprecated Use rules.default.debounce */\n syncDebounceMs?: number;\n /** @deprecated Use rules.default.maxBufferSize */\n maxPendingChanges?: number;\n /** @deprecated Use hooks.onSyncError */\n onSyncError?: (error: Error, changes: DashStorageChange[]) => void;\n}\n\nconst DEFAULT_RULE: DashSyncRule = {\n urgency: 'deferred',\n debounce: 50,\n maxBufferSize: 5000,\n readThrough: true,\n};\n\n/**\n * Storage adapter boundary for dash-backed persistence.\n *\n * Provides a \"Write Pool\" layer that buffers local-first writes and flushes\n * them to D1/R2 via a sync client based on declarative rules.\n */\nexport class DashStorageAdapter implements StorageAdapter {\n private readonly backend: DashStorageBackend;\n private readonly syncClient: DashSyncClient | null;\n private readonly rules: DashSyncRules;\n private readonly hooks: DashStorageAdapterHooks;\n private readonly pendingChanges = new Map<string, DashStorageChange>();\n private syncTimer: ReturnType<typeof setTimeout> | null = null;\n private syncInFlight = false;\n private syncPending = false;\n\n constructor(\n backend: DashStorageBackend,\n options: DashStorageAdapterOptions = {}\n ) {\n this.backend = backend;\n this.syncClient = options.syncClient ?? null;\n this.hooks = options.hooks ?? {};\n\n // Migration/Fallback for deprecated options\n const defaultRule: DashSyncRule = {\n ...DEFAULT_RULE,\n ...(options.rules?.default ?? {}),\n };\n if (options.syncDebounceMs !== undefined)\n defaultRule.debounce = options.syncDebounceMs;\n if (options.maxPendingChanges !== undefined)\n defaultRule.maxBufferSize = options.maxPendingChanges;\n if (options.onSyncError && !this.hooks.onSyncError)\n this.hooks.onSyncError = options.onSyncError;\n\n this.rules = {\n default: defaultRule,\n prefixes: options.rules?.prefixes ?? {},\n };\n }\n\n /**\n * Get an item, checking the write pool (pending changes) first for consistency.\n */\n async getItem(key: string): Promise<string | null> {\n const rule = this.getRuleForKey(key);\n\n // Read-through: check memory first if enabled\n if (rule.readThrough !== false) {\n const pending = this.pendingChanges.get(key);\n if (pending) {\n return pending.operation === 'delete' ? null : pending.value ?? null;\n }\n }\n\n return await this.backend.get(key);\n }\n\n async setItem(key: string, value: string): Promise<void> {\n await this.backend.set(key, value);\n this.trackChange({\n key,\n operation: 'set',\n value,\n timestamp: Date.now(),\n });\n }\n\n async removeItem(key: string): Promise<void> {\n await this.backend.delete(key);\n this.trackChange({\n key,\n operation: 'delete',\n timestamp: Date.now(),\n });\n }\n\n getPendingSyncCount(): number {\n return this.pendingChanges.size;\n }\n\n async flushSync(): Promise<void> {\n if (!this.syncClient || this.pendingChanges.size === 0) {\n return;\n }\n if (this.syncTimer) {\n clearTimeout(this.syncTimer);\n this.syncTimer = null;\n }\n await this.performSync();\n }\n\n private trackChange(change: DashStorageChange): void {\n this.pendingChanges.set(change.key, change);\n\n const rule = this.getRuleForKey(change.key);\n\n // Immediate flush for realtime\n if (rule.urgency === 'realtime') {\n void this.performSync();\n return;\n }\n\n // Check for buffer overflow\n const maxSize = rule.maxBufferSize ?? 5000;\n if (this.pendingChanges.size >= maxSize) {\n this.hooks.onBufferOverflow?.(\n this.getPrefixMatch(change.key) || 'default',\n this.pendingChanges.size,\n maxSize\n );\n void this.performSync();\n return;\n }\n\n this.scheduleSync(rule);\n }\n\n private getRuleForKey(key: string): DashSyncRule {\n const prefix = this.getPrefixMatch(key);\n return (\n (prefix ? this.rules.prefixes?.[prefix] : this.rules.default) ??\n this.rules.default!\n );\n }\n\n private getPrefixMatch(key: string): string | null {\n if (!this.rules.prefixes) {\n return null;\n }\n // Match longest prefix first\n const prefixes = Object.keys(this.rules.prefixes).sort(\n (a, b) => b.length - a.length\n );\n return prefixes.find((p) => key.startsWith(p)) ?? null;\n }\n\n private scheduleSync(rule: DashSyncRule): void {\n if (!this.syncClient || this.syncTimer) {\n return;\n }\n\n const debounceMs =\n typeof rule.debounce === 'string'\n ? this.parseInterval(rule.debounce)\n : rule.debounce ?? 50;\n\n this.syncTimer = setTimeout(() => {\n this.syncTimer = null;\n void this.performSync();\n }, debounceMs);\n }\n\n private async performSync(): Promise<void> {\n if (!this.syncClient) {\n return;\n }\n\n if (this.syncInFlight) {\n this.syncPending = true;\n return;\n }\n\n const changes = Array.from(this.pendingChanges.values()).sort(\n (a, b) => a.timestamp - b.timestamp\n );\n if (changes.length === 0) {\n return;\n }\n\n this.pendingChanges.clear();\n this.syncInFlight = true;\n try {\n await this.syncClient.syncChanges(changes);\n this.hooks.onSync?.(changes);\n this.hooks.onFlush?.(changes.length);\n } catch (error) {\n // Re-queue changes if they haven't been overwritten by newer local writes\n for (const change of changes) {\n const current = this.pendingChanges.get(change.key);\n if (!current || change.timestamp > current.timestamp) {\n this.pendingChanges.set(change.key, change);\n }\n }\n\n if (this.hooks.onSyncError) {\n const normalizedError =\n error instanceof Error ? error : new Error(String(error));\n this.hooks.onSyncError(normalizedError, changes);\n }\n } finally {\n this.syncInFlight = false;\n const rerun = this.syncPending || this.pendingChanges.size > 0;\n this.syncPending = false;\n if (rerun) {\n // Use default rule for re-run or wait for next trackChange\n this.scheduleSync(this.rules.default!);\n }\n }\n }\n\n private parseInterval(input: string): number {\n const match = input.match(/^(\\d+)(ms|s|m|h|d)$/);\n if (!match) return 50;\n const value = parseInt(match[1], 10);\n const unit = match[2];\n switch (unit) {\n case 'ms':\n return value;\n case 's':\n return value * 1000;\n case 'm':\n return value * 60 * 1000;\n case 'h':\n return value * 60 * 60 * 1000;\n case 'd':\n return value * 24 * 60 * 60 * 1000;\n default:\n return 50;\n }\n }\n}\n","import type { StorageAdapter } from './types';\n\n/**\n * In-memory adapter for tests and ephemeral runtimes.\n */\nexport class InMemoryStorageAdapter implements StorageAdapter {\n private readonly store = new Map<string, string>();\n\n getItem(key: string): string | null {\n return this.store.get(key) ?? null;\n }\n\n setItem(key: string, value: string): void {\n this.store.set(key, value);\n }\n\n removeItem(key: string): void {\n this.store.delete(key);\n }\n\n async flushSync(): Promise<void> {\n /* noop */\n }\n\n clear(): void {\n this.store.clear();\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/logger.ts","../../src/presence/AgentPresenceManager.ts"],"names":["EventEmitter"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Aeon Logger Interface\n *\n * Provides a pluggable logging interface that can be configured\n * by consumers to integrate with their preferred logging solution.\n */\n\n/**\n * Logger interface that consumers can implement\n */\nexport interface Logger {\n debug: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n}\n\n/**\n * Default console logger implementation\n */\nconst consoleLogger: Logger = {\n debug: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.debug('[AEON:DEBUG]', ...args);\n },\n info: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.info('[AEON:INFO]', ...args);\n },\n warn: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.warn('[AEON:WARN]', ...args);\n },\n error: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.error('[AEON:ERROR]', ...args);\n },\n};\n\n/**\n * No-op logger for production or when logging is disabled\n */\nconst noopLogger: Logger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n};\n\n/**\n * Current logger instance\n */\nlet currentLogger: Logger = consoleLogger;\n\n/**\n * Get the current logger instance\n */\nexport function getLogger(): Logger {\n return currentLogger;\n}\n\n/**\n * Set a custom logger implementation\n */\nexport function setLogger(logger: Logger): void {\n currentLogger = logger;\n}\n\n/**\n * Reset to the default console logger\n */\nexport function resetLogger(): void {\n currentLogger = consoleLogger;\n}\n\n/**\n * Disable all logging\n */\nexport function disableLogging(): void {\n currentLogger = noopLogger;\n}\n\n/**\n * Create a namespaced logger\n */\nexport function createNamespacedLogger(namespace: string): Logger {\n const logger = getLogger();\n return {\n debug: (...args: unknown[]) => logger.debug(`[${namespace}]`, ...args),\n info: (...args: unknown[]) => logger.info(`[${namespace}]`, ...args),\n warn: (...args: unknown[]) => logger.warn(`[${namespace}]`, ...args),\n error: (...args: unknown[]) => logger.error(`[${namespace}]`, ...args),\n };\n}\n\n// Export default logger for convenience\nexport const logger: Logger = {\n debug: (...args: unknown[]) => getLogger().debug(...args),\n info: (...args: unknown[]) => getLogger().info(...args),\n warn: (...args: unknown[]) => getLogger().warn(...args),\n error: (...args: unknown[]) => getLogger().error(...args),\n};\n","/**\n * Agent Presence Manager (Phase 14)\n *\n * Tracks real-time presence of all agents in a session.\n * Provides status updates, cursor tracking, and activity monitoring.\n */\n\nimport { EventEmitter } from 'eventemitter3';\nimport { getLogger } from '../utils/logger';\n\nconst logger = getLogger();\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface AgentPresence {\n agentId: string;\n name: string;\n role: 'user' | 'assistant' | 'monitor' | 'admin';\n status: 'online' | 'away' | 'offline' | 'reconnecting';\n joinedAt: string;\n lastSeen: string;\n cursorPosition?: { x: number; y: number; path: string };\n activeSection?: string;\n focusNode?: string;\n selectionRange?: AgentSelectionRange;\n typingState?: AgentTypingState;\n scrollState?: AgentScrollState;\n viewport?: AgentViewportState;\n inputState?: AgentInputState;\n emotionState?: AgentEmotionState;\n metadata?: Record<string, unknown>;\n}\n\nexport interface AgentSelectionRange {\n start: number;\n end: number;\n direction?: 'forward' | 'backward' | 'none';\n path?: string;\n}\n\nexport interface AgentTypingState {\n isTyping: boolean;\n field?: string;\n isComposing?: boolean;\n startedAt?: string;\n stoppedAt?: string;\n}\n\nexport interface AgentScrollState {\n depth: number;\n y?: number;\n viewportHeight?: number;\n documentHeight?: number;\n path?: string;\n}\n\nexport interface AgentViewportState {\n width: number;\n height: number;\n}\n\nexport interface AgentInputState {\n field: string;\n hasFocus: boolean;\n valueLength?: number;\n selectionStart?: number;\n selectionEnd?: number;\n isComposing?: boolean;\n inputMode?: string;\n}\n\nexport interface AgentEmotionState {\n primary?: string;\n secondary?: string;\n confidence?: number;\n intensity?: number;\n valence?: number;\n arousal?: number;\n dominance?: number;\n source?: 'self-report' | 'inferred' | 'sensor' | 'hybrid';\n updatedAt?: string;\n}\n\nexport interface PresenceUpdate {\n agentId: string;\n changes: Partial<AgentPresence>;\n timestamp: string;\n}\n\nexport interface PresenceEvents {\n presence_updated: (data: {\n agentId: string;\n presence: AgentPresence;\n }) => void;\n agent_joined: (data: { agentId: string; presence: AgentPresence }) => void;\n agent_left: (data: { agentId: string; presence: AgentPresence }) => void;\n cursor_updated: (data: {\n agentId: string;\n cursorPosition: { x: number; y: number; path: string };\n }) => void;\n section_updated: (data: { agentId: string; activeSection: string }) => void;\n focus_updated: (data: { agentId: string; focusNode: string }) => void;\n selection_updated: (data: {\n agentId: string;\n selectionRange: AgentSelectionRange;\n }) => void;\n typing_updated: (data: {\n agentId: string;\n typingState: AgentTypingState;\n }) => void;\n scroll_updated: (data: {\n agentId: string;\n scrollState: AgentScrollState;\n }) => void;\n viewport_updated: (data: {\n agentId: string;\n viewport: AgentViewportState;\n }) => void;\n input_state_updated: (data: {\n agentId: string;\n inputState?: AgentInputState;\n }) => void;\n emotion_updated: (data: {\n agentId: string;\n emotionState?: AgentEmotionState;\n }) => void;\n status_updated: (data: {\n agentId: string;\n status: AgentPresence['status'];\n }) => void;\n}\n\n// ============================================================================\n// Agent Presence Manager\n// ============================================================================\n\nexport class AgentPresenceManager extends EventEmitter<PresenceEvents> {\n private presences: Map<string, AgentPresence> = new Map();\n private sessionId: string;\n private heartbeatInterval: ReturnType<typeof setInterval> | null = null;\n private heartbeatTimeout = 30000;\n private inactivityThreshold = 60000;\n\n constructor(sessionId: string) {\n super();\n this.sessionId = sessionId;\n this.startHeartbeatCheck();\n logger.debug('[AgentPresenceManager] Initialized', { sessionId });\n }\n\n /**\n * Add or update agent presence\n */\n updatePresence(\n agentId: string,\n presence: Omit<AgentPresence, 'joinedAt' | 'lastSeen'>\n ): void {\n const existing = this.presences.get(agentId);\n const now = new Date().toISOString();\n\n const updated: AgentPresence = {\n ...existing,\n ...presence,\n agentId,\n joinedAt: existing?.joinedAt ?? now,\n lastSeen: now,\n };\n\n this.presences.set(agentId, updated);\n\n this.emit('presence_updated', {\n agentId,\n presence: updated,\n });\n }\n\n /**\n * Agent joined\n */\n agentJoined(\n agentId: string,\n name: string,\n role: AgentPresence['role'] = 'user',\n metadata?: Record<string, unknown>\n ): void {\n const now = new Date().toISOString();\n\n const presence: AgentPresence = {\n agentId,\n name,\n role,\n status: 'online',\n joinedAt: now,\n lastSeen: now,\n metadata,\n };\n\n this.presences.set(agentId, presence);\n this.emit('agent_joined', { agentId, presence });\n\n logger.debug('[AgentPresenceManager] Agent joined', {\n agentId,\n name,\n role,\n });\n }\n\n /**\n * Agent left\n */\n agentLeft(agentId: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.status = 'offline';\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('agent_left', { agentId, presence });\n\n logger.debug('[AgentPresenceManager] Agent left', { agentId });\n }\n }\n\n /**\n * Update cursor position\n */\n updateCursor(agentId: string, x: number, y: number, path: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.cursorPosition = { x, y, path };\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('cursor_updated', {\n agentId,\n cursorPosition: presence.cursorPosition,\n });\n }\n }\n\n /**\n * Update active section\n */\n updateActiveSection(agentId: string, section: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.activeSection = section;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('section_updated', {\n agentId,\n activeSection: section,\n });\n }\n }\n\n /**\n * Update focused node path\n */\n updateFocusNode(agentId: string, nodePath: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.focusNode = nodePath;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('focus_updated', {\n agentId,\n focusNode: nodePath,\n });\n }\n }\n\n /**\n * Update text selection range\n */\n updateSelection(agentId: string, selectionRange: AgentSelectionRange): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.selectionRange = selectionRange;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('selection_updated', {\n agentId,\n selectionRange,\n });\n }\n }\n\n /**\n * Update typing state\n */\n updateTyping(\n agentId: string,\n isTyping: boolean,\n field?: string,\n isComposing = false\n ): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n const now = new Date().toISOString();\n const previous = presence.typingState;\n const typingState: AgentTypingState = {\n isTyping,\n field,\n isComposing,\n startedAt:\n isTyping && !previous?.isTyping\n ? now\n : isTyping\n ? previous?.startedAt\n : undefined,\n stoppedAt: isTyping ? undefined : now,\n };\n\n presence.typingState = typingState;\n presence.lastSeen = now;\n\n this.presences.set(agentId, presence);\n this.emit('typing_updated', {\n agentId,\n typingState,\n });\n }\n }\n\n /**\n * Update scroll state\n */\n updateScroll(agentId: string, scrollState: AgentScrollState): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.scrollState = {\n ...scrollState,\n depth: Math.max(0, Math.min(1, scrollState.depth)),\n };\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('scroll_updated', {\n agentId,\n scrollState: presence.scrollState,\n });\n }\n }\n\n /**\n * Update viewport size\n */\n updateViewport(agentId: string, width: number, height: number): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.viewport = { width, height };\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('viewport_updated', {\n agentId,\n viewport: presence.viewport,\n });\n }\n }\n\n /**\n * Update input state\n */\n updateInputState(agentId: string, inputState: AgentInputState): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.inputState = inputState;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('input_state_updated', {\n agentId,\n inputState,\n });\n }\n }\n\n /**\n * Clear input state\n */\n clearInputState(agentId: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.inputState = undefined;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('input_state_updated', {\n agentId,\n inputState: undefined,\n });\n }\n }\n\n /**\n * Update emotional state\n */\n updateEmotionState(\n agentId: string,\n emotionState: Omit<AgentEmotionState, 'updatedAt'>\n ): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n const enrichedState: AgentEmotionState = {\n ...emotionState,\n updatedAt: new Date().toISOString(),\n };\n presence.emotionState = enrichedState;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('emotion_updated', {\n agentId,\n emotionState: enrichedState,\n });\n }\n }\n\n /**\n * Clear emotional state\n */\n clearEmotionState(agentId: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.emotionState = undefined;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('emotion_updated', {\n agentId,\n emotionState: undefined,\n });\n }\n }\n\n /**\n * Update status\n */\n updateStatus(agentId: string, status: AgentPresence['status']): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.status = status;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('status_updated', { agentId, status });\n }\n }\n\n /**\n * Heartbeat from agent (keeps them online)\n */\n heartbeat(agentId: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n if (presence.status === 'reconnecting') {\n presence.status = 'online';\n this.emit('status_updated', { agentId, status: 'online' });\n }\n\n presence.lastSeen = new Date().toISOString();\n this.presences.set(agentId, presence);\n }\n }\n\n /**\n * Get presence for agent\n */\n getPresence(agentId: string): AgentPresence | undefined {\n return this.presences.get(agentId);\n }\n\n /**\n * Get all online agents\n */\n getOnlineAgents(): AgentPresence[] {\n return Array.from(this.presences.values()).filter(\n (p) => p.status === 'online'\n );\n }\n\n /**\n * Get all agents\n */\n getAllAgents(): AgentPresence[] {\n return Array.from(this.presences.values());\n }\n\n /**\n * Get all presences\n */\n getAllPresences(): AgentPresence[] {\n return Array.from(this.presences.values());\n }\n\n /**\n * Get agent count\n */\n getAgentCount(): Record<AgentPresence['status'], number> {\n const counts = {\n online: 0,\n away: 0,\n offline: 0,\n reconnecting: 0,\n };\n\n this.presences.forEach((p) => {\n counts[p.status]++;\n });\n\n return counts;\n }\n\n /**\n * Get statistics\n */\n getStats() {\n return {\n totalAgents: this.presences.size,\n onlineAgents: Array.from(this.presences.values()).filter(\n (p) => p.status === 'online'\n ).length,\n offlineAgents: Array.from(this.presences.values()).filter(\n (p) => p.status === 'offline'\n ).length,\n awayAgents: Array.from(this.presences.values()).filter(\n (p) => p.status === 'away'\n ).length,\n reconnectingAgents: Array.from(this.presences.values()).filter(\n (p) => p.status === 'reconnecting'\n ).length,\n };\n }\n\n /**\n * Clear expired presences\n */\n clearExpiredPresences(maxAgeMs: number): void {\n const now = Date.now();\n const toRemove: string[] = [];\n\n this.presences.forEach((presence, agentId) => {\n const lastSeenTime = new Date(presence.lastSeen).getTime();\n const ageMs = now - lastSeenTime;\n\n if (ageMs > maxAgeMs && presence.status === 'offline') {\n toRemove.push(agentId);\n }\n });\n\n toRemove.forEach((agentId) => {\n this.presences.delete(agentId);\n });\n\n if (toRemove.length > 0) {\n logger.debug('[AgentPresenceManager] Cleared expired presences', {\n count: toRemove.length,\n });\n }\n }\n\n /**\n * Get agents by role\n */\n getByRole(role: AgentPresence['role']): AgentPresence[] {\n return Array.from(this.presences.values()).filter((p) => p.role === role);\n }\n\n /**\n * Get agents in active section\n */\n getInSection(section: string): AgentPresence[] {\n return Array.from(this.presences.values()).filter(\n (p) => p.activeSection === section && p.status === 'online'\n );\n }\n\n /**\n * Get presence timeline\n */\n getPresenceStats() {\n const stats = {\n total: this.presences.size,\n online: 0,\n away: 0,\n offline: 0,\n reconnecting: 0,\n byRole: {} as Record<string, number>,\n };\n\n this.presences.forEach((p) => {\n stats[p.status]++;\n stats.byRole[p.role] = (stats.byRole[p.role] ?? 0) + 1;\n });\n\n return stats;\n }\n\n /**\n * Start heartbeat check (mark inactive agents as away)\n */\n private startHeartbeatCheck(): void {\n this.heartbeatInterval = setInterval(() => {\n const now = Date.now();\n\n this.presences.forEach((presence) => {\n const lastSeenTime = new Date(presence.lastSeen).getTime();\n const timeSinceLastSeen = now - lastSeenTime;\n\n if (\n timeSinceLastSeen > this.inactivityThreshold &&\n presence.status === 'online'\n ) {\n presence.status = 'away';\n this.emit('status_updated', {\n agentId: presence.agentId,\n status: 'away',\n });\n }\n\n if (\n timeSinceLastSeen > this.heartbeatTimeout &&\n presence.status !== 'offline'\n ) {\n presence.status = 'reconnecting';\n this.emit('status_updated', {\n agentId: presence.agentId,\n status: 'reconnecting',\n });\n }\n });\n }, 10000);\n }\n\n /**\n * Stop heartbeat monitoring\n */\n stopHeartbeatMonitoring(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n }\n }\n\n /**\n * Clear all presences\n */\n clear(): void {\n this.presences.clear();\n }\n\n /**\n * Destroy the manager\n */\n destroy(): void {\n this.stopHeartbeatMonitoring();\n this.presences.clear();\n this.removeAllListeners();\n logger.debug('[AgentPresenceManager] Destroyed', {\n sessionId: this.sessionId,\n });\n }\n}\n\n// ============================================================================\n// Singleton Instance Map\n// ============================================================================\n\nconst instances = new Map<string, AgentPresenceManager>();\n\nexport function getAgentPresenceManager(\n sessionId: string\n): AgentPresenceManager {\n if (!instances.has(sessionId)) {\n instances.set(sessionId, new AgentPresenceManager(sessionId));\n }\n return instances.get(sessionId)!;\n}\n\nexport function clearAgentPresenceManager(sessionId: string): void {\n const instance = instances.get(sessionId);\n if (instance) {\n instance.destroy();\n instances.delete(sessionId);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/logger.ts","../../src/presence/AgentPresenceManager.ts"],"names":["EventEmitter"],"mappings":";;;;;;;AAoBA,IAAM,aAAA,GAAwB;AAAA,EAC5B,KAAA,EAAO,IAAI,IAAA,KAAoB;AAE7B,IAAA,OAAA,CAAQ,KAAA,CAAM,cAAA,EAAgB,GAAG,IAAI,CAAA;AAAA,EACvC,CAAA;AAAA,EACA,IAAA,EAAM,IAAI,IAAA,KAAoB;AAE5B,IAAA,OAAA,CAAQ,IAAA,CAAK,aAAA,EAAe,GAAG,IAAI,CAAA;AAAA,EACrC,CAAA;AAAA,EACA,IAAA,EAAM,IAAI,IAAA,KAAoB;AAE5B,IAAA,OAAA,CAAQ,IAAA,CAAK,aAAA,EAAe,GAAG,IAAI,CAAA;AAAA,EACrC,CAAA;AAAA,EACA,KAAA,EAAO,IAAI,IAAA,KAAoB;AAE7B,IAAA,OAAA,CAAQ,KAAA,CAAM,cAAA,EAAgB,GAAG,IAAI,CAAA;AAAA,EACvC;AACF,CAAA;AAeA,IAAI,aAAA,GAAwB,aAAA;AAKrB,SAAS,SAAA,GAAoB;AAClC,EAAA,OAAO,aAAA;AACT;;;ACjDA,IAAM,SAAS,SAAA,EAAU;AAgIlB,IAAM,oBAAA,GAAN,cAAmCA,0BAAA,CAA6B;AAAA,EAC7D,SAAA,uBAA4C,GAAA,EAAI;AAAA,EAChD,SAAA;AAAA,EACA,iBAAA,GAA2D,IAAA;AAAA,EAC3D,gBAAA,GAAmB,GAAA;AAAA,EACnB,mBAAA,GAAsB,GAAA;AAAA,EAE9B,YAAY,SAAA,EAAmB;AAC7B,IAAA,KAAA,EAAM;AACN,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,IAAA,CAAK,mBAAA,EAAoB;AACzB,IAAA,MAAA,CAAO,KAAA,CAAM,oCAAA,EAAsC,EAAE,SAAA,EAAW,CAAA;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA,EAKA,cAAA,CACE,SACA,QAAA,EACM;AACN,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAC3C,IAAA,MAAM,GAAA,GAAA,iBAAM,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAEnC,IAAA,MAAM,OAAA,GAAyB;AAAA,MAC7B,GAAG,QAAA;AAAA,MACH,GAAG,QAAA;AAAA,MACH,OAAA;AAAA,MACA,QAAA,EAAU,UAAU,QAAA,IAAY,GAAA;AAAA,MAChC,QAAA,EAAU;AAAA,KACZ;AAEA,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,OAAO,CAAA;AAEnC,IAAA,IAAA,CAAK,KAAK,kBAAA,EAAoB;AAAA,MAC5B,OAAA;AAAA,MACA,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,WAAA,CACE,OAAA,EACA,IAAA,EACA,IAAA,GAA8B,QAC9B,QAAA,EACM;AACN,IAAA,MAAM,GAAA,GAAA,iBAAM,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAEnC,IAAA,MAAM,QAAA,GAA0B;AAAA,MAC9B,OAAA;AAAA,MACA,IAAA;AAAA,MACA,IAAA;AAAA,MACA,MAAA,EAAQ,QAAA;AAAA,MACR,QAAA,EAAU,GAAA;AAAA,MACV,QAAA,EAAU,GAAA;AAAA,MACV;AAAA,KACF;AAEA,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,IAAA,IAAA,CAAK,IAAA,CAAK,cAAA,EAAgB,EAAE,OAAA,EAAS,UAAU,CAAA;AAE/C,IAAA,MAAA,CAAO,MAAM,qCAAA,EAAuC;AAAA,MAClD,OAAA;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,OAAA,EAAuB;AAC/B,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,MAAA,GAAS,SAAA;AAClB,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,IAAA,CAAK,YAAA,EAAc,EAAE,OAAA,EAAS,UAAU,CAAA;AAE7C,MAAA,MAAA,CAAO,KAAA,CAAM,mCAAA,EAAqC,EAAE,OAAA,EAAS,CAAA;AAAA,IAC/D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAA,CAAa,OAAA,EAAiB,CAAA,EAAW,CAAA,EAAW,IAAA,EAAqB;AACvE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,cAAA,GAAiB,EAAE,CAAA,EAAG,CAAA,EAAG,IAAA,EAAK;AACvC,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,gBAAA,EAAkB;AAAA,QAC1B,OAAA;AAAA,QACA,gBAAgB,QAAA,CAAS;AAAA,OAC1B,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAA,CAAoB,SAAiB,OAAA,EAAuB;AAC1D,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,aAAA,GAAgB,OAAA;AACzB,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,iBAAA,EAAmB;AAAA,QAC3B,OAAA;AAAA,QACA,aAAA,EAAe;AAAA,OAChB,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,CAAgB,SAAiB,QAAA,EAAwB;AACvD,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,SAAA,GAAY,QAAA;AACrB,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,eAAA,EAAiB;AAAA,QACzB,OAAA;AAAA,QACA,SAAA,EAAW;AAAA,OACZ,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,CAAgB,SAAiB,cAAA,EAA2C;AAC1E,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,cAAA,GAAiB,cAAA;AAC1B,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,mBAAA,EAAqB;AAAA,QAC7B,OAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAA,CACE,OAAA,EACA,QAAA,EACA,KAAA,EACA,cAAc,KAAA,EACR;AACN,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,MAAM,GAAA,GAAA,iBAAM,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACnC,MAAA,MAAM,WAAW,QAAA,CAAS,WAAA;AAC1B,MAAA,MAAM,WAAA,GAAgC;AAAA,QACpC,QAAA;AAAA,QACA,KAAA;AAAA,QACA,WAAA;AAAA,QACA,SAAA,EACE,YAAY,CAAC,QAAA,EAAU,WACnB,GAAA,GACA,QAAA,GACA,UAAU,SAAA,GACV,MAAA;AAAA,QACN,SAAA,EAAW,WAAW,MAAA,GAAY;AAAA,OACpC;AAEA,MAAA,QAAA,CAAS,WAAA,GAAc,WAAA;AACvB,MAAA,QAAA,CAAS,QAAA,GAAW,GAAA;AAEpB,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,gBAAA,EAAkB;AAAA,QAC1B,OAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAA,CAAa,SAAiB,WAAA,EAAqC;AACjE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,WAAA,GAAc;AAAA,QACrB,GAAG,WAAA;AAAA,QACH,KAAA,EAAO,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,WAAA,CAAY,KAAK,CAAC;AAAA,OACnD;AACA,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,gBAAA,EAAkB;AAAA,QAC1B,OAAA;AAAA,QACA,aAAa,QAAA,CAAS;AAAA,OACvB,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,cAAA,CAAe,OAAA,EAAiB,KAAA,EAAe,MAAA,EAAsB;AACnE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,QAAA,GAAW,EAAE,KAAA,EAAO,MAAA,EAAO;AACpC,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,kBAAA,EAAoB;AAAA,QAC5B,OAAA;AAAA,QACA,UAAU,QAAA,CAAS;AAAA,OACpB,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAA,CAAiB,SAAiB,UAAA,EAAmC;AACnE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,UAAA,GAAa,UAAA;AACtB,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,qBAAA,EAAuB;AAAA,QAC/B,OAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,OAAA,EAAuB;AACrC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,UAAA,GAAa,MAAA;AACtB,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,qBAAA,EAAuB;AAAA,QAC/B,OAAA;AAAA,QACA,UAAA,EAAY;AAAA,OACb,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAA,CACE,SACA,YAAA,EACM;AACN,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,MAAM,aAAA,GAAmC;AAAA,QACvC,GAAG,YAAA;AAAA,QACH,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,OACpC;AACA,MAAA,QAAA,CAAS,YAAA,GAAe,aAAA;AACxB,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,iBAAA,EAAmB;AAAA,QAC3B,OAAA;AAAA,QACA,YAAA,EAAc;AAAA,OACf,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB,OAAA,EAAuB;AACvC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,YAAA,GAAe,MAAA;AACxB,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,iBAAA,EAAmB;AAAA,QAC3B,OAAA;AAAA,QACA,YAAA,EAAc;AAAA,OACf,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAA,CAAa,SAAiB,MAAA,EAAuC;AACnE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,MAAA,GAAS,MAAA;AAClB,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,IAAA,CAAK,gBAAA,EAAkB,EAAE,OAAA,EAAS,QAAQ,CAAA;AAAA,IACjD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,OAAA,EAAuB;AAC/B,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,IAAI,QAAA,CAAS,WAAW,cAAA,EAAgB;AACtC,QAAA,QAAA,CAAS,MAAA,GAAS,QAAA;AAClB,QAAA,IAAA,CAAK,KAAK,gBAAA,EAAkB,EAAE,OAAA,EAAS,MAAA,EAAQ,UAAU,CAAA;AAAA,MAC3D;AAEA,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAC3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AAAA,IACtC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,OAAA,EAA4C;AACtD,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,GAAmC;AACjC,IAAA,OAAO,MAAM,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,CAAA,CAAE,MAAA;AAAA,MACzC,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW;AAAA,KACtB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAA,GAAgC;AAC9B,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,GAAmC;AACjC,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,aAAA,GAAyD;AACvD,IAAA,MAAM,MAAA,GAAS;AAAA,MACb,MAAA,EAAQ,CAAA;AAAA,MACR,IAAA,EAAM,CAAA;AAAA,MACN,OAAA,EAAS,CAAA;AAAA,MACT,YAAA,EAAc;AAAA,KAChB;AAEA,IAAA,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAA,KAAM;AAC5B,MAAA,MAAA,CAAO,EAAE,MAAM,CAAA,EAAA;AAAA,IACjB,CAAC,CAAA;AAED,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAAW;AACT,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,KAAK,SAAA,CAAU,IAAA;AAAA,MAC5B,cAAc,KAAA,CAAM,IAAA,CAAK,KAAK,SAAA,CAAU,MAAA,EAAQ,CAAA,CAAE,MAAA;AAAA,QAChD,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW;AAAA,OACtB,CAAE,MAAA;AAAA,MACF,eAAe,KAAA,CAAM,IAAA,CAAK,KAAK,SAAA,CAAU,MAAA,EAAQ,CAAA,CAAE,MAAA;AAAA,QACjD,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW;AAAA,OACtB,CAAE,MAAA;AAAA,MACF,YAAY,KAAA,CAAM,IAAA,CAAK,KAAK,SAAA,CAAU,MAAA,EAAQ,CAAA,CAAE,MAAA;AAAA,QAC9C,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW;AAAA,OACtB,CAAE,MAAA;AAAA,MACF,oBAAoB,KAAA,CAAM,IAAA,CAAK,KAAK,SAAA,CAAU,MAAA,EAAQ,CAAA,CAAE,MAAA;AAAA,QACtD,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW;AAAA,OACtB,CAAE;AAAA,KACJ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB,QAAA,EAAwB;AAC5C,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,MAAM,WAAqB,EAAC;AAE5B,IAAA,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,CAAC,QAAA,EAAU,OAAA,KAAY;AAC5C,MAAA,MAAM,eAAe,IAAI,IAAA,CAAK,QAAA,CAAS,QAAQ,EAAE,OAAA,EAAQ;AACzD,MAAA,MAAM,QAAQ,GAAA,GAAM,YAAA;AAEpB,MAAA,IAAI,KAAA,GAAQ,QAAA,IAAY,QAAA,CAAS,MAAA,KAAW,SAAA,EAAW;AACrD,QAAA,QAAA,CAAS,KAAK,OAAO,CAAA;AAAA,MACvB;AAAA,IACF,CAAC,CAAA;AAED,IAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC5B,MAAA,IAAA,CAAK,SAAA,CAAU,OAAO,OAAO,CAAA;AAAA,IAC/B,CAAC,CAAA;AAED,IAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AACvB,MAAA,MAAA,CAAO,MAAM,kDAAA,EAAoD;AAAA,QAC/D,OAAO,QAAA,CAAS;AAAA,OACjB,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,IAAA,EAA8C;AACtD,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,IAAI,CAAA;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,OAAA,EAAkC;AAC7C,IAAA,OAAO,MAAM,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,CAAA,CAAE,MAAA;AAAA,MACzC,CAAC,CAAA,KAAM,CAAA,CAAE,aAAA,KAAkB,OAAA,IAAW,EAAE,MAAA,KAAW;AAAA,KACrD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAA,GAAmB;AACjB,IAAA,MAAM,KAAA,GAAQ;AAAA,MACZ,KAAA,EAAO,KAAK,SAAA,CAAU,IAAA;AAAA,MACtB,MAAA,EAAQ,CAAA;AAAA,MACR,IAAA,EAAM,CAAA;AAAA,MACN,OAAA,EAAS,CAAA;AAAA,MACT,YAAA,EAAc,CAAA;AAAA,MACd,QAAQ;AAAC,KACX;AAEA,IAAA,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAA,KAAM;AAC5B,MAAA,KAAA,CAAM,EAAE,MAAM,CAAA,EAAA;AACd,MAAA,KAAA,CAAM,MAAA,CAAO,EAAE,IAAI,CAAA,GAAA,CAAK,MAAM,MAAA,CAAO,CAAA,CAAE,IAAI,CAAA,IAAK,CAAA,IAAK,CAAA;AAAA,IACvD,CAAC,CAAA;AAED,IAAA,OAAO,KAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAA,GAA4B;AAClC,IAAA,IAAA,CAAK,iBAAA,GAAoB,YAAY,MAAM;AACzC,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAErB,MAAA,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,CAAC,QAAA,KAAa;AACnC,QAAA,MAAM,eAAe,IAAI,IAAA,CAAK,QAAA,CAAS,QAAQ,EAAE,OAAA,EAAQ;AACzD,QAAA,MAAM,oBAAoB,GAAA,GAAM,YAAA;AAEhC,QAAA,IACE,iBAAA,GAAoB,IAAA,CAAK,mBAAA,IACzB,QAAA,CAAS,WAAW,QAAA,EACpB;AACA,UAAA,QAAA,CAAS,MAAA,GAAS,MAAA;AAClB,UAAA,IAAA,CAAK,KAAK,gBAAA,EAAkB;AAAA,YAC1B,SAAS,QAAA,CAAS,OAAA;AAAA,YAClB,MAAA,EAAQ;AAAA,WACT,CAAA;AAAA,QACH;AAEA,QAAA,IACE,iBAAA,GAAoB,IAAA,CAAK,gBAAA,IACzB,QAAA,CAAS,WAAW,SAAA,EACpB;AACA,UAAA,QAAA,CAAS,MAAA,GAAS,cAAA;AAClB,UAAA,IAAA,CAAK,KAAK,gBAAA,EAAkB;AAAA,YAC1B,SAAS,QAAA,CAAS,OAAA;AAAA,YAClB,MAAA,EAAQ;AAAA,WACT,CAAA;AAAA,QACH;AAAA,MACF,CAAC,CAAA;AAAA,IACH,GAAG,GAAK,CAAA;AAAA,EACV;AAAA;AAAA;AAAA;AAAA,EAKA,uBAAA,GAAgC;AAC9B,IAAA,IAAI,KAAK,iBAAA,EAAmB;AAC1B,MAAA,aAAA,CAAc,KAAK,iBAAiB,CAAA;AACpC,MAAA,IAAA,CAAK,iBAAA,GAAoB,IAAA;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,uBAAA,EAAwB;AAC7B,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AACrB,IAAA,IAAA,CAAK,kBAAA,EAAmB;AACxB,IAAA,MAAA,CAAO,MAAM,kCAAA,EAAoC;AAAA,MAC/C,WAAW,IAAA,CAAK;AAAA,KACjB,CAAA;AAAA,EACH;AACF;AAMA,IAAM,SAAA,uBAAgB,GAAA,EAAkC;AAEjD,SAAS,wBACd,SAAA,EACsB;AACtB,EAAA,IAAI,CAAC,SAAA,CAAU,GAAA,CAAI,SAAS,CAAA,EAAG;AAC7B,IAAA,SAAA,CAAU,GAAA,CAAI,SAAA,EAAW,IAAI,oBAAA,CAAqB,SAAS,CAAC,CAAA;AAAA,EAC9D;AACA,EAAA,OAAO,SAAA,CAAU,IAAI,SAAS,CAAA;AAChC;AAEO,SAAS,0BAA0B,SAAA,EAAyB;AACjE,EAAA,MAAM,QAAA,GAAW,SAAA,CAAU,GAAA,CAAI,SAAS,CAAA;AACxC,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,QAAA,CAAS,OAAA,EAAQ;AACjB,IAAA,SAAA,CAAU,OAAO,SAAS,CAAA;AAAA,EAC5B;AACF","file":"index.cjs","sourcesContent":["/**\n * Aeon Logger Interface\n *\n * Provides a pluggable logging interface that can be configured\n * by consumers to integrate with their preferred logging solution.\n */\n\n/**\n * Logger interface that consumers can implement\n */\nexport interface Logger {\n debug: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n}\n\n/**\n * Default console logger implementation\n */\nconst consoleLogger: Logger = {\n debug: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.debug('[AEON:DEBUG]', ...args);\n },\n info: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.info('[AEON:INFO]', ...args);\n },\n warn: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.warn('[AEON:WARN]', ...args);\n },\n error: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.error('[AEON:ERROR]', ...args);\n },\n};\n\n/**\n * No-op logger for production or when logging is disabled\n */\nconst noopLogger: Logger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n};\n\n/**\n * Current logger instance\n */\nlet currentLogger: Logger = consoleLogger;\n\n/**\n * Get the current logger instance\n */\nexport function getLogger(): Logger {\n return currentLogger;\n}\n\n/**\n * Set a custom logger implementation\n */\nexport function setLogger(logger: Logger): void {\n currentLogger = logger;\n}\n\n/**\n * Reset to the default console logger\n */\nexport function resetLogger(): void {\n currentLogger = consoleLogger;\n}\n\n/**\n * Disable all logging\n */\nexport function disableLogging(): void {\n currentLogger = noopLogger;\n}\n\n/**\n * Create a namespaced logger\n */\nexport function createNamespacedLogger(namespace: string): Logger {\n const logger = getLogger();\n return {\n debug: (...args: unknown[]) => logger.debug(`[${namespace}]`, ...args),\n info: (...args: unknown[]) => logger.info(`[${namespace}]`, ...args),\n warn: (...args: unknown[]) => logger.warn(`[${namespace}]`, ...args),\n error: (...args: unknown[]) => logger.error(`[${namespace}]`, ...args),\n };\n}\n\n// Export default logger for convenience\nexport const logger: Logger = {\n debug: (...args: unknown[]) => getLogger().debug(...args),\n info: (...args: unknown[]) => getLogger().info(...args),\n warn: (...args: unknown[]) => getLogger().warn(...args),\n error: (...args: unknown[]) => getLogger().error(...args),\n};\n","/**\n * Agent Presence Manager (Phase 14)\n *\n * Tracks real-time presence of all agents in a session.\n * Provides status updates, cursor tracking, and activity monitoring.\n */\n\nimport { EventEmitter } from 'eventemitter3';\nimport { getLogger } from '../utils/logger';\n\nconst logger = getLogger();\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface AgentPresence {\n agentId: string;\n name: string;\n role: 'user' | 'assistant' | 'monitor' | 'admin';\n status: 'online' | 'away' | 'offline' | 'reconnecting';\n joinedAt: string;\n lastSeen: string;\n cursorPosition?: { x: number; y: number; path?: string };\n activeSection?: string;\n focusNode?: string;\n selectionRange?: AgentSelectionRange;\n typingState?: AgentTypingState;\n scrollState?: AgentScrollState;\n viewport?: AgentViewportState;\n inputState?: AgentInputState;\n emotionState?: AgentEmotionState;\n metadata?: Record<string, unknown>;\n}\n\nexport interface AgentSelectionRange {\n start: number;\n end: number;\n direction?: 'forward' | 'backward' | 'none';\n path?: string;\n}\n\nexport interface AgentTypingState {\n isTyping: boolean;\n field?: string;\n isComposing?: boolean;\n startedAt?: string;\n stoppedAt?: string;\n}\n\nexport interface AgentScrollState {\n depth: number;\n y?: number;\n viewportHeight?: number;\n documentHeight?: number;\n path?: string;\n}\n\nexport interface AgentViewportState {\n width: number;\n height: number;\n}\n\nexport interface AgentInputState {\n field: string;\n hasFocus: boolean;\n valueLength?: number;\n selectionStart?: number;\n selectionEnd?: number;\n isComposing?: boolean;\n inputMode?: string;\n}\n\nexport interface AgentEmotionState {\n primary?: string;\n secondary?: string;\n confidence?: number;\n intensity?: number;\n valence?: number;\n arousal?: number;\n dominance?: number;\n source?: 'self-report' | 'inferred' | 'sensor' | 'hybrid';\n updatedAt?: string;\n}\n\nexport interface PresenceUpdate {\n agentId: string;\n changes: Partial<AgentPresence>;\n timestamp: string;\n}\n\nexport interface PresenceEvents {\n presence_updated: (data: {\n agentId: string;\n presence: AgentPresence;\n }) => void;\n agent_joined: (data: { agentId: string; presence: AgentPresence }) => void;\n agent_left: (data: { agentId: string; presence: AgentPresence }) => void;\n cursor_updated: (data: {\n agentId: string;\n cursorPosition: { x: number; y: number; path?: string };\n }) => void;\n section_updated: (data: { agentId: string; activeSection: string }) => void;\n focus_updated: (data: { agentId: string; focusNode: string }) => void;\n selection_updated: (data: {\n agentId: string;\n selectionRange: AgentSelectionRange;\n }) => void;\n typing_updated: (data: {\n agentId: string;\n typingState: AgentTypingState;\n }) => void;\n scroll_updated: (data: {\n agentId: string;\n scrollState: AgentScrollState;\n }) => void;\n viewport_updated: (data: {\n agentId: string;\n viewport: AgentViewportState;\n }) => void;\n input_state_updated: (data: {\n agentId: string;\n inputState?: AgentInputState;\n }) => void;\n emotion_updated: (data: {\n agentId: string;\n emotionState?: AgentEmotionState;\n }) => void;\n status_updated: (data: {\n agentId: string;\n status: AgentPresence['status'];\n }) => void;\n}\n\n// ============================================================================\n// Agent Presence Manager\n// ============================================================================\n\nexport class AgentPresenceManager extends EventEmitter<PresenceEvents> {\n private presences: Map<string, AgentPresence> = new Map();\n private sessionId: string;\n private heartbeatInterval: ReturnType<typeof setInterval> | null = null;\n private heartbeatTimeout = 30000;\n private inactivityThreshold = 60000;\n\n constructor(sessionId: string) {\n super();\n this.sessionId = sessionId;\n this.startHeartbeatCheck();\n logger.debug('[AgentPresenceManager] Initialized', { sessionId });\n }\n\n /**\n * Add or update agent presence\n */\n updatePresence(\n agentId: string,\n presence: Omit<AgentPresence, 'joinedAt' | 'lastSeen'>\n ): void {\n const existing = this.presences.get(agentId);\n const now = new Date().toISOString();\n\n const updated: AgentPresence = {\n ...existing,\n ...presence,\n agentId,\n joinedAt: existing?.joinedAt ?? now,\n lastSeen: now,\n };\n\n this.presences.set(agentId, updated);\n\n this.emit('presence_updated', {\n agentId,\n presence: updated,\n });\n }\n\n /**\n * Agent joined\n */\n agentJoined(\n agentId: string,\n name: string,\n role: AgentPresence['role'] = 'user',\n metadata?: Record<string, unknown>\n ): void {\n const now = new Date().toISOString();\n\n const presence: AgentPresence = {\n agentId,\n name,\n role,\n status: 'online',\n joinedAt: now,\n lastSeen: now,\n metadata,\n };\n\n this.presences.set(agentId, presence);\n this.emit('agent_joined', { agentId, presence });\n\n logger.debug('[AgentPresenceManager] Agent joined', {\n agentId,\n name,\n role,\n });\n }\n\n /**\n * Agent left\n */\n agentLeft(agentId: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.status = 'offline';\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('agent_left', { agentId, presence });\n\n logger.debug('[AgentPresenceManager] Agent left', { agentId });\n }\n }\n\n /**\n * Update cursor position\n */\n updateCursor(agentId: string, x: number, y: number, path?: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.cursorPosition = { x, y, path };\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('cursor_updated', {\n agentId,\n cursorPosition: presence.cursorPosition,\n });\n }\n }\n\n /**\n * Update active section\n */\n updateActiveSection(agentId: string, section: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.activeSection = section;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('section_updated', {\n agentId,\n activeSection: section,\n });\n }\n }\n\n /**\n * Update focused node path\n */\n updateFocusNode(agentId: string, nodePath: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.focusNode = nodePath;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('focus_updated', {\n agentId,\n focusNode: nodePath,\n });\n }\n }\n\n /**\n * Update text selection range\n */\n updateSelection(agentId: string, selectionRange: AgentSelectionRange): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.selectionRange = selectionRange;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('selection_updated', {\n agentId,\n selectionRange,\n });\n }\n }\n\n /**\n * Update typing state\n */\n updateTyping(\n agentId: string,\n isTyping: boolean,\n field?: string,\n isComposing = false\n ): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n const now = new Date().toISOString();\n const previous = presence.typingState;\n const typingState: AgentTypingState = {\n isTyping,\n field,\n isComposing,\n startedAt:\n isTyping && !previous?.isTyping\n ? now\n : isTyping\n ? previous?.startedAt\n : undefined,\n stoppedAt: isTyping ? undefined : now,\n };\n\n presence.typingState = typingState;\n presence.lastSeen = now;\n\n this.presences.set(agentId, presence);\n this.emit('typing_updated', {\n agentId,\n typingState,\n });\n }\n }\n\n /**\n * Update scroll state\n */\n updateScroll(agentId: string, scrollState: AgentScrollState): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.scrollState = {\n ...scrollState,\n depth: Math.max(0, Math.min(1, scrollState.depth)),\n };\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('scroll_updated', {\n agentId,\n scrollState: presence.scrollState,\n });\n }\n }\n\n /**\n * Update viewport size\n */\n updateViewport(agentId: string, width: number, height: number): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.viewport = { width, height };\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('viewport_updated', {\n agentId,\n viewport: presence.viewport,\n });\n }\n }\n\n /**\n * Update input state\n */\n updateInputState(agentId: string, inputState: AgentInputState): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.inputState = inputState;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('input_state_updated', {\n agentId,\n inputState,\n });\n }\n }\n\n /**\n * Clear input state\n */\n clearInputState(agentId: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.inputState = undefined;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('input_state_updated', {\n agentId,\n inputState: undefined,\n });\n }\n }\n\n /**\n * Update emotional state\n */\n updateEmotionState(\n agentId: string,\n emotionState: Omit<AgentEmotionState, 'updatedAt'>\n ): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n const enrichedState: AgentEmotionState = {\n ...emotionState,\n updatedAt: new Date().toISOString(),\n };\n presence.emotionState = enrichedState;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('emotion_updated', {\n agentId,\n emotionState: enrichedState,\n });\n }\n }\n\n /**\n * Clear emotional state\n */\n clearEmotionState(agentId: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.emotionState = undefined;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('emotion_updated', {\n agentId,\n emotionState: undefined,\n });\n }\n }\n\n /**\n * Update status\n */\n updateStatus(agentId: string, status: AgentPresence['status']): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.status = status;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('status_updated', { agentId, status });\n }\n }\n\n /**\n * Heartbeat from agent (keeps them online)\n */\n heartbeat(agentId: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n if (presence.status === 'reconnecting') {\n presence.status = 'online';\n this.emit('status_updated', { agentId, status: 'online' });\n }\n\n presence.lastSeen = new Date().toISOString();\n this.presences.set(agentId, presence);\n }\n }\n\n /**\n * Get presence for agent\n */\n getPresence(agentId: string): AgentPresence | undefined {\n return this.presences.get(agentId);\n }\n\n /**\n * Get all online agents\n */\n getOnlineAgents(): AgentPresence[] {\n return Array.from(this.presences.values()).filter(\n (p) => p.status === 'online'\n );\n }\n\n /**\n * Get all agents\n */\n getAllAgents(): AgentPresence[] {\n return Array.from(this.presences.values());\n }\n\n /**\n * Get all presences\n */\n getAllPresences(): AgentPresence[] {\n return Array.from(this.presences.values());\n }\n\n /**\n * Get agent count\n */\n getAgentCount(): Record<AgentPresence['status'], number> {\n const counts = {\n online: 0,\n away: 0,\n offline: 0,\n reconnecting: 0,\n };\n\n this.presences.forEach((p) => {\n counts[p.status]++;\n });\n\n return counts;\n }\n\n /**\n * Get statistics\n */\n getStats() {\n return {\n totalAgents: this.presences.size,\n onlineAgents: Array.from(this.presences.values()).filter(\n (p) => p.status === 'online'\n ).length,\n offlineAgents: Array.from(this.presences.values()).filter(\n (p) => p.status === 'offline'\n ).length,\n awayAgents: Array.from(this.presences.values()).filter(\n (p) => p.status === 'away'\n ).length,\n reconnectingAgents: Array.from(this.presences.values()).filter(\n (p) => p.status === 'reconnecting'\n ).length,\n };\n }\n\n /**\n * Clear expired presences\n */\n clearExpiredPresences(maxAgeMs: number): void {\n const now = Date.now();\n const toRemove: string[] = [];\n\n this.presences.forEach((presence, agentId) => {\n const lastSeenTime = new Date(presence.lastSeen).getTime();\n const ageMs = now - lastSeenTime;\n\n if (ageMs > maxAgeMs && presence.status === 'offline') {\n toRemove.push(agentId);\n }\n });\n\n toRemove.forEach((agentId) => {\n this.presences.delete(agentId);\n });\n\n if (toRemove.length > 0) {\n logger.debug('[AgentPresenceManager] Cleared expired presences', {\n count: toRemove.length,\n });\n }\n }\n\n /**\n * Get agents by role\n */\n getByRole(role: AgentPresence['role']): AgentPresence[] {\n return Array.from(this.presences.values()).filter((p) => p.role === role);\n }\n\n /**\n * Get agents in active section\n */\n getInSection(section: string): AgentPresence[] {\n return Array.from(this.presences.values()).filter(\n (p) => p.activeSection === section && p.status === 'online'\n );\n }\n\n /**\n * Get presence timeline\n */\n getPresenceStats() {\n const stats = {\n total: this.presences.size,\n online: 0,\n away: 0,\n offline: 0,\n reconnecting: 0,\n byRole: {} as Record<string, number>,\n };\n\n this.presences.forEach((p) => {\n stats[p.status]++;\n stats.byRole[p.role] = (stats.byRole[p.role] ?? 0) + 1;\n });\n\n return stats;\n }\n\n /**\n * Start heartbeat check (mark inactive agents as away)\n */\n private startHeartbeatCheck(): void {\n this.heartbeatInterval = setInterval(() => {\n const now = Date.now();\n\n this.presences.forEach((presence) => {\n const lastSeenTime = new Date(presence.lastSeen).getTime();\n const timeSinceLastSeen = now - lastSeenTime;\n\n if (\n timeSinceLastSeen > this.inactivityThreshold &&\n presence.status === 'online'\n ) {\n presence.status = 'away';\n this.emit('status_updated', {\n agentId: presence.agentId,\n status: 'away',\n });\n }\n\n if (\n timeSinceLastSeen > this.heartbeatTimeout &&\n presence.status !== 'offline'\n ) {\n presence.status = 'reconnecting';\n this.emit('status_updated', {\n agentId: presence.agentId,\n status: 'reconnecting',\n });\n }\n });\n }, 10000);\n }\n\n /**\n * Stop heartbeat monitoring\n */\n stopHeartbeatMonitoring(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n }\n }\n\n /**\n * Clear all presences\n */\n clear(): void {\n this.presences.clear();\n }\n\n /**\n * Destroy the manager\n */\n destroy(): void {\n this.stopHeartbeatMonitoring();\n this.presences.clear();\n this.removeAllListeners();\n logger.debug('[AgentPresenceManager] Destroyed', {\n sessionId: this.sessionId,\n });\n }\n}\n\n// ============================================================================\n// Singleton Instance Map\n// ============================================================================\n\nconst instances = new Map<string, AgentPresenceManager>();\n\nexport function getAgentPresenceManager(\n sessionId: string\n): AgentPresenceManager {\n if (!instances.has(sessionId)) {\n instances.set(sessionId, new AgentPresenceManager(sessionId));\n }\n return instances.get(sessionId)!;\n}\n\nexport function clearAgentPresenceManager(sessionId: string): void {\n const instance = instances.get(sessionId);\n if (instance) {\n instance.destroy();\n instances.delete(sessionId);\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/logger.ts","../../src/presence/AgentPresenceManager.ts"],"names":[],"mappings":";;;;;AAoBA,IAAM,aAAA,GAAwB;AAAA,EAC5B,KAAA,EAAO,IAAI,IAAA,KAAoB;AAE7B,IAAA,OAAA,CAAQ,KAAA,CAAM,cAAA,EAAgB,GAAG,IAAI,CAAA;AAAA,EACvC,CAAA;AAAA,EACA,IAAA,EAAM,IAAI,IAAA,KAAoB;AAE5B,IAAA,OAAA,CAAQ,IAAA,CAAK,aAAA,EAAe,GAAG,IAAI,CAAA;AAAA,EACrC,CAAA;AAAA,EACA,IAAA,EAAM,IAAI,IAAA,KAAoB;AAE5B,IAAA,OAAA,CAAQ,IAAA,CAAK,aAAA,EAAe,GAAG,IAAI,CAAA;AAAA,EACrC,CAAA;AAAA,EACA,KAAA,EAAO,IAAI,IAAA,KAAoB;AAE7B,IAAA,OAAA,CAAQ,KAAA,CAAM,cAAA,EAAgB,GAAG,IAAI,CAAA;AAAA,EACvC;AACF,CAAA;AAeA,IAAI,aAAA,GAAwB,aAAA;AAKrB,SAAS,SAAA,GAAoB;AAClC,EAAA,OAAO,aAAA;AACT;;;ACjDA,IAAM,SAAS,SAAA,EAAU;AAgIlB,IAAM,oBAAA,GAAN,cAAmC,YAAA,CAA6B;AAAA,EAC7D,SAAA,uBAA4C,GAAA,EAAI;AAAA,EAChD,SAAA;AAAA,EACA,iBAAA,GAA2D,IAAA;AAAA,EAC3D,gBAAA,GAAmB,GAAA;AAAA,EACnB,mBAAA,GAAsB,GAAA;AAAA,EAE9B,YAAY,SAAA,EAAmB;AAC7B,IAAA,KAAA,EAAM;AACN,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,IAAA,CAAK,mBAAA,EAAoB;AACzB,IAAA,MAAA,CAAO,KAAA,CAAM,oCAAA,EAAsC,EAAE,SAAA,EAAW,CAAA;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA,EAKA,cAAA,CACE,SACA,QAAA,EACM;AACN,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAC3C,IAAA,MAAM,GAAA,GAAA,iBAAM,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAEnC,IAAA,MAAM,OAAA,GAAyB;AAAA,MAC7B,GAAG,QAAA;AAAA,MACH,GAAG,QAAA;AAAA,MACH,OAAA;AAAA,MACA,QAAA,EAAU,UAAU,QAAA,IAAY,GAAA;AAAA,MAChC,QAAA,EAAU;AAAA,KACZ;AAEA,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,OAAO,CAAA;AAEnC,IAAA,IAAA,CAAK,KAAK,kBAAA,EAAoB;AAAA,MAC5B,OAAA;AAAA,MACA,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,WAAA,CACE,OAAA,EACA,IAAA,EACA,IAAA,GAA8B,QAC9B,QAAA,EACM;AACN,IAAA,MAAM,GAAA,GAAA,iBAAM,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAEnC,IAAA,MAAM,QAAA,GAA0B;AAAA,MAC9B,OAAA;AAAA,MACA,IAAA;AAAA,MACA,IAAA;AAAA,MACA,MAAA,EAAQ,QAAA;AAAA,MACR,QAAA,EAAU,GAAA;AAAA,MACV,QAAA,EAAU,GAAA;AAAA,MACV;AAAA,KACF;AAEA,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,IAAA,IAAA,CAAK,IAAA,CAAK,cAAA,EAAgB,EAAE,OAAA,EAAS,UAAU,CAAA;AAE/C,IAAA,MAAA,CAAO,MAAM,qCAAA,EAAuC;AAAA,MAClD,OAAA;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,OAAA,EAAuB;AAC/B,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,MAAA,GAAS,SAAA;AAClB,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,IAAA,CAAK,YAAA,EAAc,EAAE,OAAA,EAAS,UAAU,CAAA;AAE7C,MAAA,MAAA,CAAO,KAAA,CAAM,mCAAA,EAAqC,EAAE,OAAA,EAAS,CAAA;AAAA,IAC/D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAA,CAAa,OAAA,EAAiB,CAAA,EAAW,CAAA,EAAW,IAAA,EAAoB;AACtE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,cAAA,GAAiB,EAAE,CAAA,EAAG,CAAA,EAAG,IAAA,EAAK;AACvC,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,gBAAA,EAAkB;AAAA,QAC1B,OAAA;AAAA,QACA,gBAAgB,QAAA,CAAS;AAAA,OAC1B,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAA,CAAoB,SAAiB,OAAA,EAAuB;AAC1D,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,aAAA,GAAgB,OAAA;AACzB,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,iBAAA,EAAmB;AAAA,QAC3B,OAAA;AAAA,QACA,aAAA,EAAe;AAAA,OAChB,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,CAAgB,SAAiB,QAAA,EAAwB;AACvD,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,SAAA,GAAY,QAAA;AACrB,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,eAAA,EAAiB;AAAA,QACzB,OAAA;AAAA,QACA,SAAA,EAAW;AAAA,OACZ,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,CAAgB,SAAiB,cAAA,EAA2C;AAC1E,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,cAAA,GAAiB,cAAA;AAC1B,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,mBAAA,EAAqB;AAAA,QAC7B,OAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAA,CACE,OAAA,EACA,QAAA,EACA,KAAA,EACA,cAAc,KAAA,EACR;AACN,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,MAAM,GAAA,GAAA,iBAAM,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACnC,MAAA,MAAM,WAAW,QAAA,CAAS,WAAA;AAC1B,MAAA,MAAM,WAAA,GAAgC;AAAA,QACpC,QAAA;AAAA,QACA,KAAA;AAAA,QACA,WAAA;AAAA,QACA,SAAA,EACE,YAAY,CAAC,QAAA,EAAU,WACnB,GAAA,GACA,QAAA,GACA,UAAU,SAAA,GACV,MAAA;AAAA,QACN,SAAA,EAAW,WAAW,MAAA,GAAY;AAAA,OACpC;AAEA,MAAA,QAAA,CAAS,WAAA,GAAc,WAAA;AACvB,MAAA,QAAA,CAAS,QAAA,GAAW,GAAA;AAEpB,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,gBAAA,EAAkB;AAAA,QAC1B,OAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAA,CAAa,SAAiB,WAAA,EAAqC;AACjE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,WAAA,GAAc;AAAA,QACrB,GAAG,WAAA;AAAA,QACH,KAAA,EAAO,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,WAAA,CAAY,KAAK,CAAC;AAAA,OACnD;AACA,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,gBAAA,EAAkB;AAAA,QAC1B,OAAA;AAAA,QACA,aAAa,QAAA,CAAS;AAAA,OACvB,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,cAAA,CAAe,OAAA,EAAiB,KAAA,EAAe,MAAA,EAAsB;AACnE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,QAAA,GAAW,EAAE,KAAA,EAAO,MAAA,EAAO;AACpC,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,kBAAA,EAAoB;AAAA,QAC5B,OAAA;AAAA,QACA,UAAU,QAAA,CAAS;AAAA,OACpB,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAA,CAAiB,SAAiB,UAAA,EAAmC;AACnE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,UAAA,GAAa,UAAA;AACtB,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,qBAAA,EAAuB;AAAA,QAC/B,OAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,OAAA,EAAuB;AACrC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,UAAA,GAAa,MAAA;AACtB,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,qBAAA,EAAuB;AAAA,QAC/B,OAAA;AAAA,QACA,UAAA,EAAY;AAAA,OACb,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAA,CACE,SACA,YAAA,EACM;AACN,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,MAAM,aAAA,GAAmC;AAAA,QACvC,GAAG,YAAA;AAAA,QACH,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,OACpC;AACA,MAAA,QAAA,CAAS,YAAA,GAAe,aAAA;AACxB,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,iBAAA,EAAmB;AAAA,QAC3B,OAAA;AAAA,QACA,YAAA,EAAc;AAAA,OACf,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB,OAAA,EAAuB;AACvC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,YAAA,GAAe,MAAA;AACxB,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,KAAK,iBAAA,EAAmB;AAAA,QAC3B,OAAA;AAAA,QACA,YAAA,EAAc;AAAA,OACf,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAA,CAAa,SAAiB,MAAA,EAAuC;AACnE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,MAAA,GAAS,MAAA;AAClB,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAE3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AACpC,MAAA,IAAA,CAAK,IAAA,CAAK,gBAAA,EAAkB,EAAE,OAAA,EAAS,QAAQ,CAAA;AAAA,IACjD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,OAAA,EAAuB;AAC/B,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAE3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,IAAI,QAAA,CAAS,WAAW,cAAA,EAAgB;AACtC,QAAA,QAAA,CAAS,MAAA,GAAS,QAAA;AAClB,QAAA,IAAA,CAAK,KAAK,gBAAA,EAAkB,EAAE,OAAA,EAAS,MAAA,EAAQ,UAAU,CAAA;AAAA,MAC3D;AAEA,MAAA,QAAA,CAAS,QAAA,GAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAC3C,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,QAAQ,CAAA;AAAA,IACtC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,OAAA,EAA4C;AACtD,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,GAAmC;AACjC,IAAA,OAAO,MAAM,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,CAAA,CAAE,MAAA;AAAA,MACzC,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW;AAAA,KACtB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAA,GAAgC;AAC9B,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,GAAmC;AACjC,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,aAAA,GAAyD;AACvD,IAAA,MAAM,MAAA,GAAS;AAAA,MACb,MAAA,EAAQ,CAAA;AAAA,MACR,IAAA,EAAM,CAAA;AAAA,MACN,OAAA,EAAS,CAAA;AAAA,MACT,YAAA,EAAc;AAAA,KAChB;AAEA,IAAA,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAA,KAAM;AAC5B,MAAA,MAAA,CAAO,EAAE,MAAM,CAAA,EAAA;AAAA,IACjB,CAAC,CAAA;AAED,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAAW;AACT,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,KAAK,SAAA,CAAU,IAAA;AAAA,MAC5B,cAAc,KAAA,CAAM,IAAA,CAAK,KAAK,SAAA,CAAU,MAAA,EAAQ,CAAA,CAAE,MAAA;AAAA,QAChD,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW;AAAA,OACtB,CAAE,MAAA;AAAA,MACF,eAAe,KAAA,CAAM,IAAA,CAAK,KAAK,SAAA,CAAU,MAAA,EAAQ,CAAA,CAAE,MAAA;AAAA,QACjD,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW;AAAA,OACtB,CAAE,MAAA;AAAA,MACF,YAAY,KAAA,CAAM,IAAA,CAAK,KAAK,SAAA,CAAU,MAAA,EAAQ,CAAA,CAAE,MAAA;AAAA,QAC9C,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW;AAAA,OACtB,CAAE,MAAA;AAAA,MACF,oBAAoB,KAAA,CAAM,IAAA,CAAK,KAAK,SAAA,CAAU,MAAA,EAAQ,CAAA,CAAE,MAAA;AAAA,QACtD,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW;AAAA,OACtB,CAAE;AAAA,KACJ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB,QAAA,EAAwB;AAC5C,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,MAAM,WAAqB,EAAC;AAE5B,IAAA,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,CAAC,QAAA,EAAU,OAAA,KAAY;AAC5C,MAAA,MAAM,eAAe,IAAI,IAAA,CAAK,QAAA,CAAS,QAAQ,EAAE,OAAA,EAAQ;AACzD,MAAA,MAAM,QAAQ,GAAA,GAAM,YAAA;AAEpB,MAAA,IAAI,KAAA,GAAQ,QAAA,IAAY,QAAA,CAAS,MAAA,KAAW,SAAA,EAAW;AACrD,QAAA,QAAA,CAAS,KAAK,OAAO,CAAA;AAAA,MACvB;AAAA,IACF,CAAC,CAAA;AAED,IAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC5B,MAAA,IAAA,CAAK,SAAA,CAAU,OAAO,OAAO,CAAA;AAAA,IAC/B,CAAC,CAAA;AAED,IAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AACvB,MAAA,MAAA,CAAO,MAAM,kDAAA,EAAoD;AAAA,QAC/D,OAAO,QAAA,CAAS;AAAA,OACjB,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,IAAA,EAA8C;AACtD,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,IAAI,CAAA;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,OAAA,EAAkC;AAC7C,IAAA,OAAO,MAAM,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,CAAA,CAAE,MAAA;AAAA,MACzC,CAAC,CAAA,KAAM,CAAA,CAAE,aAAA,KAAkB,OAAA,IAAW,EAAE,MAAA,KAAW;AAAA,KACrD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAA,GAAmB;AACjB,IAAA,MAAM,KAAA,GAAQ;AAAA,MACZ,KAAA,EAAO,KAAK,SAAA,CAAU,IAAA;AAAA,MACtB,MAAA,EAAQ,CAAA;AAAA,MACR,IAAA,EAAM,CAAA;AAAA,MACN,OAAA,EAAS,CAAA;AAAA,MACT,YAAA,EAAc,CAAA;AAAA,MACd,QAAQ;AAAC,KACX;AAEA,IAAA,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAA,KAAM;AAC5B,MAAA,KAAA,CAAM,EAAE,MAAM,CAAA,EAAA;AACd,MAAA,KAAA,CAAM,MAAA,CAAO,EAAE,IAAI,CAAA,GAAA,CAAK,MAAM,MAAA,CAAO,CAAA,CAAE,IAAI,CAAA,IAAK,CAAA,IAAK,CAAA;AAAA,IACvD,CAAC,CAAA;AAED,IAAA,OAAO,KAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAA,GAA4B;AAClC,IAAA,IAAA,CAAK,iBAAA,GAAoB,YAAY,MAAM;AACzC,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAErB,MAAA,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,CAAC,QAAA,KAAa;AACnC,QAAA,MAAM,eAAe,IAAI,IAAA,CAAK,QAAA,CAAS,QAAQ,EAAE,OAAA,EAAQ;AACzD,QAAA,MAAM,oBAAoB,GAAA,GAAM,YAAA;AAEhC,QAAA,IACE,iBAAA,GAAoB,IAAA,CAAK,mBAAA,IACzB,QAAA,CAAS,WAAW,QAAA,EACpB;AACA,UAAA,QAAA,CAAS,MAAA,GAAS,MAAA;AAClB,UAAA,IAAA,CAAK,KAAK,gBAAA,EAAkB;AAAA,YAC1B,SAAS,QAAA,CAAS,OAAA;AAAA,YAClB,MAAA,EAAQ;AAAA,WACT,CAAA;AAAA,QACH;AAEA,QAAA,IACE,iBAAA,GAAoB,IAAA,CAAK,gBAAA,IACzB,QAAA,CAAS,WAAW,SAAA,EACpB;AACA,UAAA,QAAA,CAAS,MAAA,GAAS,cAAA;AAClB,UAAA,IAAA,CAAK,KAAK,gBAAA,EAAkB;AAAA,YAC1B,SAAS,QAAA,CAAS,OAAA;AAAA,YAClB,MAAA,EAAQ;AAAA,WACT,CAAA;AAAA,QACH;AAAA,MACF,CAAC,CAAA;AAAA,IACH,GAAG,GAAK,CAAA;AAAA,EACV;AAAA;AAAA;AAAA;AAAA,EAKA,uBAAA,GAAgC;AAC9B,IAAA,IAAI,KAAK,iBAAA,EAAmB;AAC1B,MAAA,aAAA,CAAc,KAAK,iBAAiB,CAAA;AACpC,MAAA,IAAA,CAAK,iBAAA,GAAoB,IAAA;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,uBAAA,EAAwB;AAC7B,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AACrB,IAAA,IAAA,CAAK,kBAAA,EAAmB;AACxB,IAAA,MAAA,CAAO,MAAM,kCAAA,EAAoC;AAAA,MAC/C,WAAW,IAAA,CAAK;AAAA,KACjB,CAAA;AAAA,EACH;AACF;AAMA,IAAM,SAAA,uBAAgB,GAAA,EAAkC;AAEjD,SAAS,wBACd,SAAA,EACsB;AACtB,EAAA,IAAI,CAAC,SAAA,CAAU,GAAA,CAAI,SAAS,CAAA,EAAG;AAC7B,IAAA,SAAA,CAAU,GAAA,CAAI,SAAA,EAAW,IAAI,oBAAA,CAAqB,SAAS,CAAC,CAAA;AAAA,EAC9D;AACA,EAAA,OAAO,SAAA,CAAU,IAAI,SAAS,CAAA;AAChC;AAEO,SAAS,0BAA0B,SAAA,EAAyB;AACjE,EAAA,MAAM,QAAA,GAAW,SAAA,CAAU,GAAA,CAAI,SAAS,CAAA;AACxC,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,QAAA,CAAS,OAAA,EAAQ;AACjB,IAAA,SAAA,CAAU,OAAO,SAAS,CAAA;AAAA,EAC5B;AACF","file":"index.js","sourcesContent":["/**\n * Aeon Logger Interface\n *\n * Provides a pluggable logging interface that can be configured\n * by consumers to integrate with their preferred logging solution.\n */\n\n/**\n * Logger interface that consumers can implement\n */\nexport interface Logger {\n debug: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n}\n\n/**\n * Default console logger implementation\n */\nconst consoleLogger: Logger = {\n debug: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.debug('[AEON:DEBUG]', ...args);\n },\n info: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.info('[AEON:INFO]', ...args);\n },\n warn: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.warn('[AEON:WARN]', ...args);\n },\n error: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.error('[AEON:ERROR]', ...args);\n },\n};\n\n/**\n * No-op logger for production or when logging is disabled\n */\nconst noopLogger: Logger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n};\n\n/**\n * Current logger instance\n */\nlet currentLogger: Logger = consoleLogger;\n\n/**\n * Get the current logger instance\n */\nexport function getLogger(): Logger {\n return currentLogger;\n}\n\n/**\n * Set a custom logger implementation\n */\nexport function setLogger(logger: Logger): void {\n currentLogger = logger;\n}\n\n/**\n * Reset to the default console logger\n */\nexport function resetLogger(): void {\n currentLogger = consoleLogger;\n}\n\n/**\n * Disable all logging\n */\nexport function disableLogging(): void {\n currentLogger = noopLogger;\n}\n\n/**\n * Create a namespaced logger\n */\nexport function createNamespacedLogger(namespace: string): Logger {\n const logger = getLogger();\n return {\n debug: (...args: unknown[]) => logger.debug(`[${namespace}]`, ...args),\n info: (...args: unknown[]) => logger.info(`[${namespace}]`, ...args),\n warn: (...args: unknown[]) => logger.warn(`[${namespace}]`, ...args),\n error: (...args: unknown[]) => logger.error(`[${namespace}]`, ...args),\n };\n}\n\n// Export default logger for convenience\nexport const logger: Logger = {\n debug: (...args: unknown[]) => getLogger().debug(...args),\n info: (...args: unknown[]) => getLogger().info(...args),\n warn: (...args: unknown[]) => getLogger().warn(...args),\n error: (...args: unknown[]) => getLogger().error(...args),\n};\n","/**\n * Agent Presence Manager (Phase 14)\n *\n * Tracks real-time presence of all agents in a session.\n * Provides status updates, cursor tracking, and activity monitoring.\n */\n\nimport { EventEmitter } from 'eventemitter3';\nimport { getLogger } from '../utils/logger';\n\nconst logger = getLogger();\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface AgentPresence {\n agentId: string;\n name: string;\n role: 'user' | 'assistant' | 'monitor' | 'admin';\n status: 'online' | 'away' | 'offline' | 'reconnecting';\n joinedAt: string;\n lastSeen: string;\n cursorPosition?: { x: number; y: number; path: string };\n activeSection?: string;\n focusNode?: string;\n selectionRange?: AgentSelectionRange;\n typingState?: AgentTypingState;\n scrollState?: AgentScrollState;\n viewport?: AgentViewportState;\n inputState?: AgentInputState;\n emotionState?: AgentEmotionState;\n metadata?: Record<string, unknown>;\n}\n\nexport interface AgentSelectionRange {\n start: number;\n end: number;\n direction?: 'forward' | 'backward' | 'none';\n path?: string;\n}\n\nexport interface AgentTypingState {\n isTyping: boolean;\n field?: string;\n isComposing?: boolean;\n startedAt?: string;\n stoppedAt?: string;\n}\n\nexport interface AgentScrollState {\n depth: number;\n y?: number;\n viewportHeight?: number;\n documentHeight?: number;\n path?: string;\n}\n\nexport interface AgentViewportState {\n width: number;\n height: number;\n}\n\nexport interface AgentInputState {\n field: string;\n hasFocus: boolean;\n valueLength?: number;\n selectionStart?: number;\n selectionEnd?: number;\n isComposing?: boolean;\n inputMode?: string;\n}\n\nexport interface AgentEmotionState {\n primary?: string;\n secondary?: string;\n confidence?: number;\n intensity?: number;\n valence?: number;\n arousal?: number;\n dominance?: number;\n source?: 'self-report' | 'inferred' | 'sensor' | 'hybrid';\n updatedAt?: string;\n}\n\nexport interface PresenceUpdate {\n agentId: string;\n changes: Partial<AgentPresence>;\n timestamp: string;\n}\n\nexport interface PresenceEvents {\n presence_updated: (data: {\n agentId: string;\n presence: AgentPresence;\n }) => void;\n agent_joined: (data: { agentId: string; presence: AgentPresence }) => void;\n agent_left: (data: { agentId: string; presence: AgentPresence }) => void;\n cursor_updated: (data: {\n agentId: string;\n cursorPosition: { x: number; y: number; path: string };\n }) => void;\n section_updated: (data: { agentId: string; activeSection: string }) => void;\n focus_updated: (data: { agentId: string; focusNode: string }) => void;\n selection_updated: (data: {\n agentId: string;\n selectionRange: AgentSelectionRange;\n }) => void;\n typing_updated: (data: {\n agentId: string;\n typingState: AgentTypingState;\n }) => void;\n scroll_updated: (data: {\n agentId: string;\n scrollState: AgentScrollState;\n }) => void;\n viewport_updated: (data: {\n agentId: string;\n viewport: AgentViewportState;\n }) => void;\n input_state_updated: (data: {\n agentId: string;\n inputState?: AgentInputState;\n }) => void;\n emotion_updated: (data: {\n agentId: string;\n emotionState?: AgentEmotionState;\n }) => void;\n status_updated: (data: {\n agentId: string;\n status: AgentPresence['status'];\n }) => void;\n}\n\n// ============================================================================\n// Agent Presence Manager\n// ============================================================================\n\nexport class AgentPresenceManager extends EventEmitter<PresenceEvents> {\n private presences: Map<string, AgentPresence> = new Map();\n private sessionId: string;\n private heartbeatInterval: ReturnType<typeof setInterval> | null = null;\n private heartbeatTimeout = 30000;\n private inactivityThreshold = 60000;\n\n constructor(sessionId: string) {\n super();\n this.sessionId = sessionId;\n this.startHeartbeatCheck();\n logger.debug('[AgentPresenceManager] Initialized', { sessionId });\n }\n\n /**\n * Add or update agent presence\n */\n updatePresence(\n agentId: string,\n presence: Omit<AgentPresence, 'joinedAt' | 'lastSeen'>\n ): void {\n const existing = this.presences.get(agentId);\n const now = new Date().toISOString();\n\n const updated: AgentPresence = {\n ...existing,\n ...presence,\n agentId,\n joinedAt: existing?.joinedAt ?? now,\n lastSeen: now,\n };\n\n this.presences.set(agentId, updated);\n\n this.emit('presence_updated', {\n agentId,\n presence: updated,\n });\n }\n\n /**\n * Agent joined\n */\n agentJoined(\n agentId: string,\n name: string,\n role: AgentPresence['role'] = 'user',\n metadata?: Record<string, unknown>\n ): void {\n const now = new Date().toISOString();\n\n const presence: AgentPresence = {\n agentId,\n name,\n role,\n status: 'online',\n joinedAt: now,\n lastSeen: now,\n metadata,\n };\n\n this.presences.set(agentId, presence);\n this.emit('agent_joined', { agentId, presence });\n\n logger.debug('[AgentPresenceManager] Agent joined', {\n agentId,\n name,\n role,\n });\n }\n\n /**\n * Agent left\n */\n agentLeft(agentId: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.status = 'offline';\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('agent_left', { agentId, presence });\n\n logger.debug('[AgentPresenceManager] Agent left', { agentId });\n }\n }\n\n /**\n * Update cursor position\n */\n updateCursor(agentId: string, x: number, y: number, path: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.cursorPosition = { x, y, path };\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('cursor_updated', {\n agentId,\n cursorPosition: presence.cursorPosition,\n });\n }\n }\n\n /**\n * Update active section\n */\n updateActiveSection(agentId: string, section: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.activeSection = section;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('section_updated', {\n agentId,\n activeSection: section,\n });\n }\n }\n\n /**\n * Update focused node path\n */\n updateFocusNode(agentId: string, nodePath: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.focusNode = nodePath;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('focus_updated', {\n agentId,\n focusNode: nodePath,\n });\n }\n }\n\n /**\n * Update text selection range\n */\n updateSelection(agentId: string, selectionRange: AgentSelectionRange): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.selectionRange = selectionRange;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('selection_updated', {\n agentId,\n selectionRange,\n });\n }\n }\n\n /**\n * Update typing state\n */\n updateTyping(\n agentId: string,\n isTyping: boolean,\n field?: string,\n isComposing = false\n ): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n const now = new Date().toISOString();\n const previous = presence.typingState;\n const typingState: AgentTypingState = {\n isTyping,\n field,\n isComposing,\n startedAt:\n isTyping && !previous?.isTyping\n ? now\n : isTyping\n ? previous?.startedAt\n : undefined,\n stoppedAt: isTyping ? undefined : now,\n };\n\n presence.typingState = typingState;\n presence.lastSeen = now;\n\n this.presences.set(agentId, presence);\n this.emit('typing_updated', {\n agentId,\n typingState,\n });\n }\n }\n\n /**\n * Update scroll state\n */\n updateScroll(agentId: string, scrollState: AgentScrollState): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.scrollState = {\n ...scrollState,\n depth: Math.max(0, Math.min(1, scrollState.depth)),\n };\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('scroll_updated', {\n agentId,\n scrollState: presence.scrollState,\n });\n }\n }\n\n /**\n * Update viewport size\n */\n updateViewport(agentId: string, width: number, height: number): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.viewport = { width, height };\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('viewport_updated', {\n agentId,\n viewport: presence.viewport,\n });\n }\n }\n\n /**\n * Update input state\n */\n updateInputState(agentId: string, inputState: AgentInputState): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.inputState = inputState;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('input_state_updated', {\n agentId,\n inputState,\n });\n }\n }\n\n /**\n * Clear input state\n */\n clearInputState(agentId: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.inputState = undefined;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('input_state_updated', {\n agentId,\n inputState: undefined,\n });\n }\n }\n\n /**\n * Update emotional state\n */\n updateEmotionState(\n agentId: string,\n emotionState: Omit<AgentEmotionState, 'updatedAt'>\n ): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n const enrichedState: AgentEmotionState = {\n ...emotionState,\n updatedAt: new Date().toISOString(),\n };\n presence.emotionState = enrichedState;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('emotion_updated', {\n agentId,\n emotionState: enrichedState,\n });\n }\n }\n\n /**\n * Clear emotional state\n */\n clearEmotionState(agentId: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.emotionState = undefined;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('emotion_updated', {\n agentId,\n emotionState: undefined,\n });\n }\n }\n\n /**\n * Update status\n */\n updateStatus(agentId: string, status: AgentPresence['status']): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.status = status;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('status_updated', { agentId, status });\n }\n }\n\n /**\n * Heartbeat from agent (keeps them online)\n */\n heartbeat(agentId: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n if (presence.status === 'reconnecting') {\n presence.status = 'online';\n this.emit('status_updated', { agentId, status: 'online' });\n }\n\n presence.lastSeen = new Date().toISOString();\n this.presences.set(agentId, presence);\n }\n }\n\n /**\n * Get presence for agent\n */\n getPresence(agentId: string): AgentPresence | undefined {\n return this.presences.get(agentId);\n }\n\n /**\n * Get all online agents\n */\n getOnlineAgents(): AgentPresence[] {\n return Array.from(this.presences.values()).filter(\n (p) => p.status === 'online'\n );\n }\n\n /**\n * Get all agents\n */\n getAllAgents(): AgentPresence[] {\n return Array.from(this.presences.values());\n }\n\n /**\n * Get all presences\n */\n getAllPresences(): AgentPresence[] {\n return Array.from(this.presences.values());\n }\n\n /**\n * Get agent count\n */\n getAgentCount(): Record<AgentPresence['status'], number> {\n const counts = {\n online: 0,\n away: 0,\n offline: 0,\n reconnecting: 0,\n };\n\n this.presences.forEach((p) => {\n counts[p.status]++;\n });\n\n return counts;\n }\n\n /**\n * Get statistics\n */\n getStats() {\n return {\n totalAgents: this.presences.size,\n onlineAgents: Array.from(this.presences.values()).filter(\n (p) => p.status === 'online'\n ).length,\n offlineAgents: Array.from(this.presences.values()).filter(\n (p) => p.status === 'offline'\n ).length,\n awayAgents: Array.from(this.presences.values()).filter(\n (p) => p.status === 'away'\n ).length,\n reconnectingAgents: Array.from(this.presences.values()).filter(\n (p) => p.status === 'reconnecting'\n ).length,\n };\n }\n\n /**\n * Clear expired presences\n */\n clearExpiredPresences(maxAgeMs: number): void {\n const now = Date.now();\n const toRemove: string[] = [];\n\n this.presences.forEach((presence, agentId) => {\n const lastSeenTime = new Date(presence.lastSeen).getTime();\n const ageMs = now - lastSeenTime;\n\n if (ageMs > maxAgeMs && presence.status === 'offline') {\n toRemove.push(agentId);\n }\n });\n\n toRemove.forEach((agentId) => {\n this.presences.delete(agentId);\n });\n\n if (toRemove.length > 0) {\n logger.debug('[AgentPresenceManager] Cleared expired presences', {\n count: toRemove.length,\n });\n }\n }\n\n /**\n * Get agents by role\n */\n getByRole(role: AgentPresence['role']): AgentPresence[] {\n return Array.from(this.presences.values()).filter((p) => p.role === role);\n }\n\n /**\n * Get agents in active section\n */\n getInSection(section: string): AgentPresence[] {\n return Array.from(this.presences.values()).filter(\n (p) => p.activeSection === section && p.status === 'online'\n );\n }\n\n /**\n * Get presence timeline\n */\n getPresenceStats() {\n const stats = {\n total: this.presences.size,\n online: 0,\n away: 0,\n offline: 0,\n reconnecting: 0,\n byRole: {} as Record<string, number>,\n };\n\n this.presences.forEach((p) => {\n stats[p.status]++;\n stats.byRole[p.role] = (stats.byRole[p.role] ?? 0) + 1;\n });\n\n return stats;\n }\n\n /**\n * Start heartbeat check (mark inactive agents as away)\n */\n private startHeartbeatCheck(): void {\n this.heartbeatInterval = setInterval(() => {\n const now = Date.now();\n\n this.presences.forEach((presence) => {\n const lastSeenTime = new Date(presence.lastSeen).getTime();\n const timeSinceLastSeen = now - lastSeenTime;\n\n if (\n timeSinceLastSeen > this.inactivityThreshold &&\n presence.status === 'online'\n ) {\n presence.status = 'away';\n this.emit('status_updated', {\n agentId: presence.agentId,\n status: 'away',\n });\n }\n\n if (\n timeSinceLastSeen > this.heartbeatTimeout &&\n presence.status !== 'offline'\n ) {\n presence.status = 'reconnecting';\n this.emit('status_updated', {\n agentId: presence.agentId,\n status: 'reconnecting',\n });\n }\n });\n }, 10000);\n }\n\n /**\n * Stop heartbeat monitoring\n */\n stopHeartbeatMonitoring(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n }\n }\n\n /**\n * Clear all presences\n */\n clear(): void {\n this.presences.clear();\n }\n\n /**\n * Destroy the manager\n */\n destroy(): void {\n this.stopHeartbeatMonitoring();\n this.presences.clear();\n this.removeAllListeners();\n logger.debug('[AgentPresenceManager] Destroyed', {\n sessionId: this.sessionId,\n });\n }\n}\n\n// ============================================================================\n// Singleton Instance Map\n// ============================================================================\n\nconst instances = new Map<string, AgentPresenceManager>();\n\nexport function getAgentPresenceManager(\n sessionId: string\n): AgentPresenceManager {\n if (!instances.has(sessionId)) {\n instances.set(sessionId, new AgentPresenceManager(sessionId));\n }\n return instances.get(sessionId)!;\n}\n\nexport function clearAgentPresenceManager(sessionId: string): void {\n const instance = instances.get(sessionId);\n if (instance) {\n instance.destroy();\n instances.delete(sessionId);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/logger.ts","../../src/presence/AgentPresenceManager.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Aeon Logger Interface\n *\n * Provides a pluggable logging interface that can be configured\n * by consumers to integrate with their preferred logging solution.\n */\n\n/**\n * Logger interface that consumers can implement\n */\nexport interface Logger {\n debug: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n}\n\n/**\n * Default console logger implementation\n */\nconst consoleLogger: Logger = {\n debug: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.debug('[AEON:DEBUG]', ...args);\n },\n info: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.info('[AEON:INFO]', ...args);\n },\n warn: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.warn('[AEON:WARN]', ...args);\n },\n error: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.error('[AEON:ERROR]', ...args);\n },\n};\n\n/**\n * No-op logger for production or when logging is disabled\n */\nconst noopLogger: Logger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n};\n\n/**\n * Current logger instance\n */\nlet currentLogger: Logger = consoleLogger;\n\n/**\n * Get the current logger instance\n */\nexport function getLogger(): Logger {\n return currentLogger;\n}\n\n/**\n * Set a custom logger implementation\n */\nexport function setLogger(logger: Logger): void {\n currentLogger = logger;\n}\n\n/**\n * Reset to the default console logger\n */\nexport function resetLogger(): void {\n currentLogger = consoleLogger;\n}\n\n/**\n * Disable all logging\n */\nexport function disableLogging(): void {\n currentLogger = noopLogger;\n}\n\n/**\n * Create a namespaced logger\n */\nexport function createNamespacedLogger(namespace: string): Logger {\n const logger = getLogger();\n return {\n debug: (...args: unknown[]) => logger.debug(`[${namespace}]`, ...args),\n info: (...args: unknown[]) => logger.info(`[${namespace}]`, ...args),\n warn: (...args: unknown[]) => logger.warn(`[${namespace}]`, ...args),\n error: (...args: unknown[]) => logger.error(`[${namespace}]`, ...args),\n };\n}\n\n// Export default logger for convenience\nexport const logger: Logger = {\n debug: (...args: unknown[]) => getLogger().debug(...args),\n info: (...args: unknown[]) => getLogger().info(...args),\n warn: (...args: unknown[]) => getLogger().warn(...args),\n error: (...args: unknown[]) => getLogger().error(...args),\n};\n","/**\n * Agent Presence Manager (Phase 14)\n *\n * Tracks real-time presence of all agents in a session.\n * Provides status updates, cursor tracking, and activity monitoring.\n */\n\nimport { EventEmitter } from 'eventemitter3';\nimport { getLogger } from '../utils/logger';\n\nconst logger = getLogger();\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface AgentPresence {\n agentId: string;\n name: string;\n role: 'user' | 'assistant' | 'monitor' | 'admin';\n status: 'online' | 'away' | 'offline' | 'reconnecting';\n joinedAt: string;\n lastSeen: string;\n cursorPosition?: { x: number; y: number; path?: string };\n activeSection?: string;\n focusNode?: string;\n selectionRange?: AgentSelectionRange;\n typingState?: AgentTypingState;\n scrollState?: AgentScrollState;\n viewport?: AgentViewportState;\n inputState?: AgentInputState;\n emotionState?: AgentEmotionState;\n metadata?: Record<string, unknown>;\n}\n\nexport interface AgentSelectionRange {\n start: number;\n end: number;\n direction?: 'forward' | 'backward' | 'none';\n path?: string;\n}\n\nexport interface AgentTypingState {\n isTyping: boolean;\n field?: string;\n isComposing?: boolean;\n startedAt?: string;\n stoppedAt?: string;\n}\n\nexport interface AgentScrollState {\n depth: number;\n y?: number;\n viewportHeight?: number;\n documentHeight?: number;\n path?: string;\n}\n\nexport interface AgentViewportState {\n width: number;\n height: number;\n}\n\nexport interface AgentInputState {\n field: string;\n hasFocus: boolean;\n valueLength?: number;\n selectionStart?: number;\n selectionEnd?: number;\n isComposing?: boolean;\n inputMode?: string;\n}\n\nexport interface AgentEmotionState {\n primary?: string;\n secondary?: string;\n confidence?: number;\n intensity?: number;\n valence?: number;\n arousal?: number;\n dominance?: number;\n source?: 'self-report' | 'inferred' | 'sensor' | 'hybrid';\n updatedAt?: string;\n}\n\nexport interface PresenceUpdate {\n agentId: string;\n changes: Partial<AgentPresence>;\n timestamp: string;\n}\n\nexport interface PresenceEvents {\n presence_updated: (data: {\n agentId: string;\n presence: AgentPresence;\n }) => void;\n agent_joined: (data: { agentId: string; presence: AgentPresence }) => void;\n agent_left: (data: { agentId: string; presence: AgentPresence }) => void;\n cursor_updated: (data: {\n agentId: string;\n cursorPosition: { x: number; y: number; path?: string };\n }) => void;\n section_updated: (data: { agentId: string; activeSection: string }) => void;\n focus_updated: (data: { agentId: string; focusNode: string }) => void;\n selection_updated: (data: {\n agentId: string;\n selectionRange: AgentSelectionRange;\n }) => void;\n typing_updated: (data: {\n agentId: string;\n typingState: AgentTypingState;\n }) => void;\n scroll_updated: (data: {\n agentId: string;\n scrollState: AgentScrollState;\n }) => void;\n viewport_updated: (data: {\n agentId: string;\n viewport: AgentViewportState;\n }) => void;\n input_state_updated: (data: {\n agentId: string;\n inputState?: AgentInputState;\n }) => void;\n emotion_updated: (data: {\n agentId: string;\n emotionState?: AgentEmotionState;\n }) => void;\n status_updated: (data: {\n agentId: string;\n status: AgentPresence['status'];\n }) => void;\n}\n\n// ============================================================================\n// Agent Presence Manager\n// ============================================================================\n\nexport class AgentPresenceManager extends EventEmitter<PresenceEvents> {\n private presences: Map<string, AgentPresence> = new Map();\n private sessionId: string;\n private heartbeatInterval: ReturnType<typeof setInterval> | null = null;\n private heartbeatTimeout = 30000;\n private inactivityThreshold = 60000;\n\n constructor(sessionId: string) {\n super();\n this.sessionId = sessionId;\n this.startHeartbeatCheck();\n logger.debug('[AgentPresenceManager] Initialized', { sessionId });\n }\n\n /**\n * Add or update agent presence\n */\n updatePresence(\n agentId: string,\n presence: Omit<AgentPresence, 'joinedAt' | 'lastSeen'>\n ): void {\n const existing = this.presences.get(agentId);\n const now = new Date().toISOString();\n\n const updated: AgentPresence = {\n ...existing,\n ...presence,\n agentId,\n joinedAt: existing?.joinedAt ?? now,\n lastSeen: now,\n };\n\n this.presences.set(agentId, updated);\n\n this.emit('presence_updated', {\n agentId,\n presence: updated,\n });\n }\n\n /**\n * Agent joined\n */\n agentJoined(\n agentId: string,\n name: string,\n role: AgentPresence['role'] = 'user',\n metadata?: Record<string, unknown>\n ): void {\n const now = new Date().toISOString();\n\n const presence: AgentPresence = {\n agentId,\n name,\n role,\n status: 'online',\n joinedAt: now,\n lastSeen: now,\n metadata,\n };\n\n this.presences.set(agentId, presence);\n this.emit('agent_joined', { agentId, presence });\n\n logger.debug('[AgentPresenceManager] Agent joined', {\n agentId,\n name,\n role,\n });\n }\n\n /**\n * Agent left\n */\n agentLeft(agentId: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.status = 'offline';\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('agent_left', { agentId, presence });\n\n logger.debug('[AgentPresenceManager] Agent left', { agentId });\n }\n }\n\n /**\n * Update cursor position\n */\n updateCursor(agentId: string, x: number, y: number, path?: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.cursorPosition = { x, y, path };\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('cursor_updated', {\n agentId,\n cursorPosition: presence.cursorPosition,\n });\n }\n }\n\n /**\n * Update active section\n */\n updateActiveSection(agentId: string, section: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.activeSection = section;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('section_updated', {\n agentId,\n activeSection: section,\n });\n }\n }\n\n /**\n * Update focused node path\n */\n updateFocusNode(agentId: string, nodePath: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.focusNode = nodePath;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('focus_updated', {\n agentId,\n focusNode: nodePath,\n });\n }\n }\n\n /**\n * Update text selection range\n */\n updateSelection(agentId: string, selectionRange: AgentSelectionRange): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.selectionRange = selectionRange;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('selection_updated', {\n agentId,\n selectionRange,\n });\n }\n }\n\n /**\n * Update typing state\n */\n updateTyping(\n agentId: string,\n isTyping: boolean,\n field?: string,\n isComposing = false\n ): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n const now = new Date().toISOString();\n const previous = presence.typingState;\n const typingState: AgentTypingState = {\n isTyping,\n field,\n isComposing,\n startedAt:\n isTyping && !previous?.isTyping\n ? now\n : isTyping\n ? previous?.startedAt\n : undefined,\n stoppedAt: isTyping ? undefined : now,\n };\n\n presence.typingState = typingState;\n presence.lastSeen = now;\n\n this.presences.set(agentId, presence);\n this.emit('typing_updated', {\n agentId,\n typingState,\n });\n }\n }\n\n /**\n * Update scroll state\n */\n updateScroll(agentId: string, scrollState: AgentScrollState): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.scrollState = {\n ...scrollState,\n depth: Math.max(0, Math.min(1, scrollState.depth)),\n };\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('scroll_updated', {\n agentId,\n scrollState: presence.scrollState,\n });\n }\n }\n\n /**\n * Update viewport size\n */\n updateViewport(agentId: string, width: number, height: number): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.viewport = { width, height };\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('viewport_updated', {\n agentId,\n viewport: presence.viewport,\n });\n }\n }\n\n /**\n * Update input state\n */\n updateInputState(agentId: string, inputState: AgentInputState): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.inputState = inputState;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('input_state_updated', {\n agentId,\n inputState,\n });\n }\n }\n\n /**\n * Clear input state\n */\n clearInputState(agentId: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.inputState = undefined;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('input_state_updated', {\n agentId,\n inputState: undefined,\n });\n }\n }\n\n /**\n * Update emotional state\n */\n updateEmotionState(\n agentId: string,\n emotionState: Omit<AgentEmotionState, 'updatedAt'>\n ): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n const enrichedState: AgentEmotionState = {\n ...emotionState,\n updatedAt: new Date().toISOString(),\n };\n presence.emotionState = enrichedState;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('emotion_updated', {\n agentId,\n emotionState: enrichedState,\n });\n }\n }\n\n /**\n * Clear emotional state\n */\n clearEmotionState(agentId: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.emotionState = undefined;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('emotion_updated', {\n agentId,\n emotionState: undefined,\n });\n }\n }\n\n /**\n * Update status\n */\n updateStatus(agentId: string, status: AgentPresence['status']): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n presence.status = status;\n presence.lastSeen = new Date().toISOString();\n\n this.presences.set(agentId, presence);\n this.emit('status_updated', { agentId, status });\n }\n }\n\n /**\n * Heartbeat from agent (keeps them online)\n */\n heartbeat(agentId: string): void {\n const presence = this.presences.get(agentId);\n\n if (presence) {\n if (presence.status === 'reconnecting') {\n presence.status = 'online';\n this.emit('status_updated', { agentId, status: 'online' });\n }\n\n presence.lastSeen = new Date().toISOString();\n this.presences.set(agentId, presence);\n }\n }\n\n /**\n * Get presence for agent\n */\n getPresence(agentId: string): AgentPresence | undefined {\n return this.presences.get(agentId);\n }\n\n /**\n * Get all online agents\n */\n getOnlineAgents(): AgentPresence[] {\n return Array.from(this.presences.values()).filter(\n (p) => p.status === 'online'\n );\n }\n\n /**\n * Get all agents\n */\n getAllAgents(): AgentPresence[] {\n return Array.from(this.presences.values());\n }\n\n /**\n * Get all presences\n */\n getAllPresences(): AgentPresence[] {\n return Array.from(this.presences.values());\n }\n\n /**\n * Get agent count\n */\n getAgentCount(): Record<AgentPresence['status'], number> {\n const counts = {\n online: 0,\n away: 0,\n offline: 0,\n reconnecting: 0,\n };\n\n this.presences.forEach((p) => {\n counts[p.status]++;\n });\n\n return counts;\n }\n\n /**\n * Get statistics\n */\n getStats() {\n return {\n totalAgents: this.presences.size,\n onlineAgents: Array.from(this.presences.values()).filter(\n (p) => p.status === 'online'\n ).length,\n offlineAgents: Array.from(this.presences.values()).filter(\n (p) => p.status === 'offline'\n ).length,\n awayAgents: Array.from(this.presences.values()).filter(\n (p) => p.status === 'away'\n ).length,\n reconnectingAgents: Array.from(this.presences.values()).filter(\n (p) => p.status === 'reconnecting'\n ).length,\n };\n }\n\n /**\n * Clear expired presences\n */\n clearExpiredPresences(maxAgeMs: number): void {\n const now = Date.now();\n const toRemove: string[] = [];\n\n this.presences.forEach((presence, agentId) => {\n const lastSeenTime = new Date(presence.lastSeen).getTime();\n const ageMs = now - lastSeenTime;\n\n if (ageMs > maxAgeMs && presence.status === 'offline') {\n toRemove.push(agentId);\n }\n });\n\n toRemove.forEach((agentId) => {\n this.presences.delete(agentId);\n });\n\n if (toRemove.length > 0) {\n logger.debug('[AgentPresenceManager] Cleared expired presences', {\n count: toRemove.length,\n });\n }\n }\n\n /**\n * Get agents by role\n */\n getByRole(role: AgentPresence['role']): AgentPresence[] {\n return Array.from(this.presences.values()).filter((p) => p.role === role);\n }\n\n /**\n * Get agents in active section\n */\n getInSection(section: string): AgentPresence[] {\n return Array.from(this.presences.values()).filter(\n (p) => p.activeSection === section && p.status === 'online'\n );\n }\n\n /**\n * Get presence timeline\n */\n getPresenceStats() {\n const stats = {\n total: this.presences.size,\n online: 0,\n away: 0,\n offline: 0,\n reconnecting: 0,\n byRole: {} as Record<string, number>,\n };\n\n this.presences.forEach((p) => {\n stats[p.status]++;\n stats.byRole[p.role] = (stats.byRole[p.role] ?? 0) + 1;\n });\n\n return stats;\n }\n\n /**\n * Start heartbeat check (mark inactive agents as away)\n */\n private startHeartbeatCheck(): void {\n this.heartbeatInterval = setInterval(() => {\n const now = Date.now();\n\n this.presences.forEach((presence) => {\n const lastSeenTime = new Date(presence.lastSeen).getTime();\n const timeSinceLastSeen = now - lastSeenTime;\n\n if (\n timeSinceLastSeen > this.inactivityThreshold &&\n presence.status === 'online'\n ) {\n presence.status = 'away';\n this.emit('status_updated', {\n agentId: presence.agentId,\n status: 'away',\n });\n }\n\n if (\n timeSinceLastSeen > this.heartbeatTimeout &&\n presence.status !== 'offline'\n ) {\n presence.status = 'reconnecting';\n this.emit('status_updated', {\n agentId: presence.agentId,\n status: 'reconnecting',\n });\n }\n });\n }, 10000);\n }\n\n /**\n * Stop heartbeat monitoring\n */\n stopHeartbeatMonitoring(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n }\n }\n\n /**\n * Clear all presences\n */\n clear(): void {\n this.presences.clear();\n }\n\n /**\n * Destroy the manager\n */\n destroy(): void {\n this.stopHeartbeatMonitoring();\n this.presences.clear();\n this.removeAllListeners();\n logger.debug('[AgentPresenceManager] Destroyed', {\n sessionId: this.sessionId,\n });\n }\n}\n\n// ============================================================================\n// Singleton Instance Map\n// ============================================================================\n\nconst instances = new Map<string, AgentPresenceManager>();\n\nexport function getAgentPresenceManager(\n sessionId: string\n): AgentPresenceManager {\n if (!instances.has(sessionId)) {\n instances.set(sessionId, new AgentPresenceManager(sessionId));\n }\n return instances.get(sessionId)!;\n}\n\nexport function clearAgentPresenceManager(sessionId: string): void {\n const instance = instances.get(sessionId);\n if (instance) {\n instance.destroy();\n instances.delete(sessionId);\n }\n}\n"]}
|
|
@@ -184,10 +184,11 @@ var SchemaVersionManager = class {
|
|
|
184
184
|
*/
|
|
185
185
|
parseVersion(versionString) {
|
|
186
186
|
const parts = versionString.split(".").map(Number);
|
|
187
|
+
const safeInt = (v) => v !== void 0 && Number.isFinite(v) ? v : 0;
|
|
187
188
|
return {
|
|
188
|
-
major: parts[0]
|
|
189
|
-
minor: parts[1]
|
|
190
|
-
patch: parts[2]
|
|
189
|
+
major: safeInt(parts[0]),
|
|
190
|
+
minor: safeInt(parts[1]),
|
|
191
|
+
patch: safeInt(parts[2]),
|
|
191
192
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
192
193
|
description: "",
|
|
193
194
|
breaking: false
|