genesis-ai-cli 13.7.0 → 13.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/.env.example +26 -0
  2. package/dist/src/bus/event-bus.d.ts +146 -0
  3. package/dist/src/bus/event-bus.js +296 -0
  4. package/dist/src/bus/events.d.ts +468 -0
  5. package/dist/src/bus/events.js +13 -0
  6. package/dist/src/bus/index.d.ts +77 -0
  7. package/dist/src/bus/index.js +146 -0
  8. package/dist/src/causal/index.d.ts +6 -0
  9. package/dist/src/causal/index.js +30 -6
  10. package/dist/src/consciousness/central-awareness.d.ts +190 -0
  11. package/dist/src/consciousness/central-awareness.js +527 -0
  12. package/dist/src/consciousness/index.d.ts +1 -0
  13. package/dist/src/consciousness/index.js +7 -1
  14. package/dist/src/economy/autonomous.js +62 -0
  15. package/dist/src/economy/cli/boot.d.ts +10 -0
  16. package/dist/src/economy/cli/boot.js +83 -0
  17. package/dist/src/economy/cli/status.d.ts +10 -0
  18. package/dist/src/economy/cli/status.js +60 -0
  19. package/dist/src/economy/generators/bounty-hunter.d.ts +6 -0
  20. package/dist/src/economy/generators/bounty-hunter.js +126 -81
  21. package/dist/src/economy/generators/keeper.d.ts +1 -0
  22. package/dist/src/economy/generators/keeper.js +181 -53
  23. package/dist/src/economy/live/alerts.d.ts +81 -0
  24. package/dist/src/economy/live/alerts.js +343 -0
  25. package/dist/src/economy/live/balance-monitor.d.ts +76 -0
  26. package/dist/src/economy/live/balance-monitor.js +198 -0
  27. package/dist/src/economy/live/boot.js +71 -3
  28. package/dist/src/economy/live/defi-executor.d.ts +96 -0
  29. package/dist/src/economy/live/defi-executor.js +519 -0
  30. package/dist/src/economy/live/emergency.d.ts +101 -0
  31. package/dist/src/economy/live/emergency.js +340 -0
  32. package/dist/src/economy/live/gas-manager.d.ts +99 -0
  33. package/dist/src/economy/live/gas-manager.js +259 -0
  34. package/dist/src/economy/live/health.d.ts +72 -0
  35. package/dist/src/economy/live/health.js +423 -0
  36. package/dist/src/economy/live/index.d.ts +23 -1
  37. package/dist/src/economy/live/index.js +75 -2
  38. package/dist/src/economy/live/payment-verifier.d.ts +57 -0
  39. package/dist/src/economy/live/payment-verifier.js +185 -0
  40. package/dist/src/economy/live/position-tracker.d.ts +131 -0
  41. package/dist/src/economy/live/position-tracker.js +296 -0
  42. package/dist/src/economy/live/price-feeds.d.ts +81 -0
  43. package/dist/src/economy/live/price-feeds.js +293 -0
  44. package/dist/src/economy/live/retry.d.ts +129 -0
  45. package/dist/src/economy/live/retry.js +331 -0
  46. package/dist/src/economy/live/revenue-tracker.d.ts +92 -0
  47. package/dist/src/economy/live/revenue-tracker.js +233 -0
  48. package/dist/src/economy/live/wallet.d.ts +30 -0
  49. package/dist/src/economy/live/wallet.js +72 -0
  50. package/dist/src/finance/bus-wiring.d.ts +95 -0
  51. package/dist/src/finance/bus-wiring.js +416 -0
  52. package/dist/src/finance/example.d.ts +8 -0
  53. package/dist/src/finance/example.js +147 -0
  54. package/dist/src/finance/index.d.ts +73 -0
  55. package/dist/src/finance/index.js +243 -0
  56. package/dist/src/finance/integration-test.d.ts +7 -0
  57. package/dist/src/finance/integration-test.js +191 -0
  58. package/dist/src/finance/market-data.d.ts +128 -0
  59. package/dist/src/finance/market-data.js +444 -0
  60. package/dist/src/finance/polymarket/bus-wiring.d.ts +90 -0
  61. package/dist/src/finance/polymarket/bus-wiring.js +270 -0
  62. package/dist/src/finance/polymarket/client.d.ts +65 -0
  63. package/dist/src/finance/polymarket/client.js +339 -0
  64. package/dist/src/finance/polymarket/executor.d.ts +113 -0
  65. package/dist/src/finance/polymarket/executor.js +305 -0
  66. package/dist/src/finance/polymarket/index.d.ts +132 -0
  67. package/dist/src/finance/polymarket/index.js +300 -0
  68. package/dist/src/finance/polymarket/markets.d.ts +98 -0
  69. package/dist/src/finance/polymarket/markets.js +256 -0
  70. package/dist/src/finance/polymarket/strategy.d.ts +104 -0
  71. package/dist/src/finance/polymarket/strategy.js +319 -0
  72. package/dist/src/finance/polymarket/test.d.ts +13 -0
  73. package/dist/src/finance/polymarket/test.js +182 -0
  74. package/dist/src/finance/polymarket/types.d.ts +167 -0
  75. package/dist/src/finance/polymarket/types.js +14 -0
  76. package/dist/src/finance/portfolio.d.ts +121 -0
  77. package/dist/src/finance/portfolio.js +508 -0
  78. package/dist/src/finance/regime-detector.d.ts +71 -0
  79. package/dist/src/finance/regime-detector.js +336 -0
  80. package/dist/src/finance/risk-engine.d.ts +76 -0
  81. package/dist/src/finance/risk-engine.js +375 -0
  82. package/dist/src/finance/signals.d.ts +96 -0
  83. package/dist/src/finance/signals.js +479 -0
  84. package/dist/src/finance/types.d.ts +299 -0
  85. package/dist/src/finance/types.js +30 -0
  86. package/dist/src/genesis.d.ts +127 -0
  87. package/dist/src/genesis.js +472 -30
  88. package/dist/src/governance/self-modification.js +18 -3
  89. package/dist/src/integration/index.d.ts +7 -1
  90. package/dist/src/integration/index.js +11 -2
  91. package/dist/src/integration/module-wiring.d.ts +69 -0
  92. package/dist/src/integration/module-wiring.js +261 -0
  93. package/dist/src/kernel/free-energy-kernel.d.ts +13 -0
  94. package/dist/src/kernel/free-energy-kernel.js +48 -4
  95. package/dist/src/llm/index.d.ts +6 -1
  96. package/dist/src/llm/index.js +96 -32
  97. package/dist/src/mcp-finance/index.d.ts +97 -0
  98. package/dist/src/mcp-finance/index.js +269 -0
  99. package/dist/src/memory/index.d.ts +29 -1
  100. package/dist/src/memory/index.js +99 -1
  101. package/dist/src/memory/persistence.js +5 -1
  102. package/dist/src/neuromodulation/index.d.ts +15 -1
  103. package/dist/src/neuromodulation/index.js +74 -1
  104. package/dist/src/payments/x402/client.d.ts +98 -0
  105. package/dist/src/payments/x402/client.js +361 -0
  106. package/dist/src/payments/x402/example.d.ts +12 -0
  107. package/dist/src/payments/x402/example.js +268 -0
  108. package/dist/src/payments/x402/index.d.ts +102 -0
  109. package/dist/src/payments/x402/index.js +178 -0
  110. package/dist/src/payments/x402/pricing.d.ts +106 -0
  111. package/dist/src/payments/x402/pricing.js +312 -0
  112. package/dist/src/payments/x402/server.d.ts +101 -0
  113. package/dist/src/payments/x402/server.js +385 -0
  114. package/dist/src/payments/x402/types.d.ts +318 -0
  115. package/dist/src/payments/x402/types.js +31 -0
  116. package/dist/src/payments/x402/verification.d.ts +94 -0
  117. package/dist/src/payments/x402/verification.js +338 -0
  118. package/dist/src/perception/multi-modal.d.ts +10 -0
  119. package/dist/src/perception/multi-modal.js +29 -2
  120. package/dist/src/reasoning/metacognitive-controller.d.ts +15 -0
  121. package/dist/src/reasoning/metacognitive-controller.js +25 -2
  122. package/dist/src/revenue/bus-wiring.d.ts +79 -0
  123. package/dist/src/revenue/bus-wiring.js +260 -0
  124. package/dist/src/revenue/example.d.ts +7 -0
  125. package/dist/src/revenue/example.js +191 -0
  126. package/dist/src/revenue/index.d.ts +127 -0
  127. package/dist/src/revenue/index.js +283 -0
  128. package/dist/src/revenue/stream-manager.d.ts +97 -0
  129. package/dist/src/revenue/stream-manager.js +392 -0
  130. package/dist/src/revenue/streams/bounty-hunter.d.ts +66 -0
  131. package/dist/src/revenue/streams/bounty-hunter.js +336 -0
  132. package/dist/src/revenue/streams/content.d.ts +68 -0
  133. package/dist/src/revenue/streams/content.js +405 -0
  134. package/dist/src/revenue/streams/keeper.d.ts +62 -0
  135. package/dist/src/revenue/streams/keeper.js +351 -0
  136. package/dist/src/revenue/streams/mcp-services.d.ts +73 -0
  137. package/dist/src/revenue/streams/mcp-services.js +405 -0
  138. package/dist/src/revenue/streams/yield.d.ts +73 -0
  139. package/dist/src/revenue/streams/yield.js +469 -0
  140. package/dist/src/revenue/types.d.ts +177 -0
  141. package/dist/src/revenue/types.js +9 -0
  142. package/dist/src/streaming/mcp-bridge.d.ts +2 -0
  143. package/dist/src/streaming/mcp-bridge.js +5 -1
  144. package/dist/src/ui/components/agent-network.d.ts +99 -0
  145. package/dist/src/ui/components/agent-network.js +495 -0
  146. package/dist/src/ui/components/economy-card.d.ts +110 -0
  147. package/dist/src/ui/components/economy-card.js +341 -0
  148. package/dist/src/ui/components/neuromod-display.d.ts +84 -0
  149. package/dist/src/ui/components/neuromod-display.js +331 -0
  150. package/dist/src/ui/components/phi-orb.d.ts +72 -0
  151. package/dist/src/ui/components/phi-orb.js +250 -0
  152. package/dist/src/ui/example.d.ts +14 -0
  153. package/dist/src/ui/example.js +187 -0
  154. package/dist/src/ui/generative/index.d.ts +97 -0
  155. package/dist/src/ui/generative/index.js +344 -0
  156. package/dist/src/ui/index.d.ts +131 -0
  157. package/dist/src/ui/index.js +298 -0
  158. package/dist/src/ui/sse-client.d.ts +95 -0
  159. package/dist/src/ui/sse-client.js +297 -0
  160. package/dist/src/ui/state-mapper.d.ts +94 -0
  161. package/dist/src/ui/state-mapper.js +525 -0
  162. package/dist/src/ui/test.d.ts +7 -0
  163. package/dist/src/ui/test.js +275 -0
  164. package/dist/src/ui/types.d.ts +129 -0
  165. package/dist/src/ui/types.js +17 -0
  166. package/dist/test/active-inference.test.d.ts +10 -0
  167. package/dist/test/active-inference.test.js +401 -0
  168. package/dist/test/economy.test.d.ts +10 -0
  169. package/dist/test/economy.test.js +421 -0
  170. package/dist/test/llm.test.d.ts +13 -0
  171. package/dist/test/llm.test.js +454 -0
  172. package/dist/test/mcp.test.d.ts +9 -0
  173. package/dist/test/mcp.test.js +578 -0
  174. package/dist/test/memory.test.d.ts +9 -0
  175. package/dist/test/memory.test.js +631 -0
  176. package/package.json +1 -1
package/.env.example CHANGED
@@ -144,3 +144,29 @@ GENESIS_MAX_DRAWDOWN=0.20
144
144
 
145
145
  # Safety: daily spending limit USD (default: 100)
146
146
  GENESIS_DAILY_LIMIT=100
147
+
148
+ # ============================================================================
149
+ # v19.0 - MONITORING & ALERTS
150
+ # ============================================================================
151
+
152
+ # Enable/disable alerts (default: true)
153
+ GENESIS_ALERTS_ENABLED=true
154
+
155
+ # Minimum alert level: info, success, warning, error (default: info)
156
+ GENESIS_ALERTS_LEVEL=info
157
+
158
+ # Telegram alerts
159
+ # Create bot via @BotFather, get chat ID via @userinfobot
160
+ GENESIS_TELEGRAM_BOT_TOKEN=
161
+ GENESIS_TELEGRAM_CHAT_ID=
162
+
163
+ # Discord webhook
164
+ # Create in Server Settings → Integrations → Webhooks
165
+ GENESIS_DISCORD_WEBHOOK=
166
+
167
+ # Slack webhook
168
+ # Create in Slack App → Incoming Webhooks
169
+ GENESIS_SLACK_WEBHOOK=
170
+
171
+ # Custom webhook (receives JSON POST)
172
+ GENESIS_ALERT_WEBHOOK=
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Genesis Event Bus - Core Implementation
3
+ *
4
+ * A typed, precision-weighted event bus implementing Global Workspace Theory
5
+ * for inter-module communication in the Genesis cognitive architecture.
6
+ *
7
+ * Features:
8
+ * - Type-safe publish/subscribe with GenesisEventMap
9
+ * - Priority-ordered dispatch (critical handlers first)
10
+ * - Async handler support (non-blocking)
11
+ * - Ring-buffer history for late-joining subscribers
12
+ * - Prefix-based subscriptions for domain monitoring
13
+ * - Memory-safe unsubscription
14
+ * - Correlation IDs for causal tracing
15
+ *
16
+ * Scientific grounding:
17
+ * - Acts as Markov Blanket boundary between modules
18
+ * - Precision field enables reliability-weighted processing
19
+ * - History buffer supports temporal integration
20
+ */
21
+ import type { GenesisEventMap, GenesisEventTopic, BusEvent } from './events.js';
22
+ /** Handler function type */
23
+ type EventHandler<T extends BusEvent> = (event: T) => void | Promise<void>;
24
+ /** Subscription handle with unsubscribe capability */
25
+ export interface Subscription {
26
+ /** Unique subscription ID */
27
+ id: string;
28
+ /** Topic subscribed to */
29
+ topic: GenesisEventTopic | string;
30
+ /** Remove this subscription */
31
+ unsubscribe: () => void;
32
+ }
33
+ /** Subscribe options */
34
+ export interface SubscribeOptions {
35
+ /** Higher priority = called first. Default 0. */
36
+ priority?: number;
37
+ /** Custom subscription ID */
38
+ id?: string;
39
+ }
40
+ /** History entry */
41
+ interface HistoryEntry {
42
+ topic: string;
43
+ event: BusEvent;
44
+ }
45
+ /** Bus statistics */
46
+ export interface BusStats {
47
+ topics: number;
48
+ totalSubscriptions: number;
49
+ eventsPublished: number;
50
+ historySize: number;
51
+ }
52
+ export declare class GenesisEventBus {
53
+ private seq;
54
+ private subscribers;
55
+ private history;
56
+ private readonly maxHistory;
57
+ private correlationStack;
58
+ constructor(options?: {
59
+ maxHistory?: number;
60
+ });
61
+ /**
62
+ * Publish an event to all subscribers.
63
+ * Synchronous handlers execute in priority order.
64
+ * Async handlers are dispatched but not awaited (fire-and-forget with error logging).
65
+ *
66
+ * @param topic - The event topic
67
+ * @param payload - Event data (seq and timestamp added automatically)
68
+ * @returns The complete event with sequence number
69
+ */
70
+ publish<K extends GenesisEventTopic>(topic: K, payload: Omit<GenesisEventMap[K], 'seq' | 'timestamp'>): GenesisEventMap[K];
71
+ /**
72
+ * Publish with a specific correlation ID for causal tracing.
73
+ */
74
+ publishWithCorrelation<K extends GenesisEventTopic>(topic: K, payload: Omit<GenesisEventMap[K], 'seq' | 'timestamp' | 'correlationId'>, correlationId: string): GenesisEventMap[K];
75
+ /**
76
+ * Execute a function within a correlation context.
77
+ * All events published within the callback share the correlation ID.
78
+ */
79
+ withCorrelation<T>(correlationId: string, fn: () => T): T;
80
+ private currentCorrelation;
81
+ private recordHistory;
82
+ private dispatch;
83
+ /**
84
+ * Subscribe to a specific topic.
85
+ *
86
+ * @param topic - The event topic to subscribe to
87
+ * @param handler - Function called when event is published
88
+ * @param options - Priority and custom ID
89
+ * @returns Subscription with unsubscribe method
90
+ */
91
+ subscribe<K extends GenesisEventTopic>(topic: K, handler: EventHandler<GenesisEventMap[K]>, options?: SubscribeOptions): Subscription;
92
+ /**
93
+ * Subscribe to multiple topics matching a prefix.
94
+ * E.g., subscribePrefix('kernel.') matches all kernel events.
95
+ *
96
+ * @param prefix - Topic prefix to match
97
+ * @param handler - Function called for matching events
98
+ * @param options - Priority settings
99
+ * @returns Subscription covering all matching topics
100
+ */
101
+ subscribePrefix(prefix: string, handler: EventHandler<BusEvent>, options?: SubscribeOptions): Subscription;
102
+ /**
103
+ * Subscribe to all events (useful for logging/monitoring).
104
+ */
105
+ subscribeAll(handler: EventHandler<BusEvent>, options?: SubscribeOptions): Subscription;
106
+ /**
107
+ * One-time subscription that auto-unsubscribes after first event.
108
+ */
109
+ once<K extends GenesisEventTopic>(topic: K, handler: EventHandler<GenesisEventMap[K]>, options?: SubscribeOptions): Subscription;
110
+ /**
111
+ * Get recent event history (useful for late-joining subscribers).
112
+ *
113
+ * @param topic - Optional topic filter
114
+ * @param limit - Maximum entries to return
115
+ */
116
+ getHistory(topic?: GenesisEventTopic, limit?: number): HistoryEntry[];
117
+ /**
118
+ * Get events matching a correlation ID.
119
+ */
120
+ getCorrelatedEvents(correlationId: string): HistoryEntry[];
121
+ /**
122
+ * Wait for a specific event (promise-based).
123
+ */
124
+ waitFor<K extends GenesisEventTopic>(topic: K, predicate?: (event: GenesisEventMap[K]) => boolean, timeoutMs?: number): Promise<GenesisEventMap[K]>;
125
+ /**
126
+ * List all active topic subscriptions.
127
+ */
128
+ listTopics(): string[];
129
+ /**
130
+ * Get statistics for monitoring.
131
+ */
132
+ stats(): BusStats;
133
+ /**
134
+ * Check if a topic has any subscribers.
135
+ */
136
+ hasSubscribers(topic: GenesisEventTopic): boolean;
137
+ /**
138
+ * Clear all subscriptions (useful for testing).
139
+ */
140
+ clear(): void;
141
+ /**
142
+ * Clear history only.
143
+ */
144
+ clearHistory(): void;
145
+ }
146
+ export {};
@@ -0,0 +1,296 @@
1
+ "use strict";
2
+ /**
3
+ * Genesis Event Bus - Core Implementation
4
+ *
5
+ * A typed, precision-weighted event bus implementing Global Workspace Theory
6
+ * for inter-module communication in the Genesis cognitive architecture.
7
+ *
8
+ * Features:
9
+ * - Type-safe publish/subscribe with GenesisEventMap
10
+ * - Priority-ordered dispatch (critical handlers first)
11
+ * - Async handler support (non-blocking)
12
+ * - Ring-buffer history for late-joining subscribers
13
+ * - Prefix-based subscriptions for domain monitoring
14
+ * - Memory-safe unsubscription
15
+ * - Correlation IDs for causal tracing
16
+ *
17
+ * Scientific grounding:
18
+ * - Acts as Markov Blanket boundary between modules
19
+ * - Precision field enables reliability-weighted processing
20
+ * - History buffer supports temporal integration
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.GenesisEventBus = void 0;
24
+ // ============================================================================
25
+ // Event Bus Implementation
26
+ // ============================================================================
27
+ class GenesisEventBus {
28
+ seq = 0;
29
+ subscribers = new Map();
30
+ history = [];
31
+ maxHistory;
32
+ correlationStack = [];
33
+ constructor(options) {
34
+ this.maxHistory = options?.maxHistory ?? 500;
35
+ }
36
+ // --------------------------------------------------------------------------
37
+ // Publishing
38
+ // --------------------------------------------------------------------------
39
+ /**
40
+ * Publish an event to all subscribers.
41
+ * Synchronous handlers execute in priority order.
42
+ * Async handlers are dispatched but not awaited (fire-and-forget with error logging).
43
+ *
44
+ * @param topic - The event topic
45
+ * @param payload - Event data (seq and timestamp added automatically)
46
+ * @returns The complete event with sequence number
47
+ */
48
+ publish(topic, payload) {
49
+ const event = {
50
+ ...payload,
51
+ seq: ++this.seq,
52
+ timestamp: new Date().toISOString(),
53
+ correlationId: payload.correlationId ?? this.currentCorrelation(),
54
+ };
55
+ this.recordHistory(topic, event);
56
+ this.dispatch(topic, event);
57
+ return event;
58
+ }
59
+ /**
60
+ * Publish with a specific correlation ID for causal tracing.
61
+ */
62
+ publishWithCorrelation(topic, payload, correlationId) {
63
+ return this.publish(topic, { ...payload, correlationId });
64
+ }
65
+ /**
66
+ * Execute a function within a correlation context.
67
+ * All events published within the callback share the correlation ID.
68
+ */
69
+ withCorrelation(correlationId, fn) {
70
+ this.correlationStack.push(correlationId);
71
+ try {
72
+ return fn();
73
+ }
74
+ finally {
75
+ this.correlationStack.pop();
76
+ }
77
+ }
78
+ currentCorrelation() {
79
+ return this.correlationStack.length > 0
80
+ ? this.correlationStack[this.correlationStack.length - 1]
81
+ : undefined;
82
+ }
83
+ recordHistory(topic, event) {
84
+ this.history.push({ topic, event });
85
+ if (this.history.length > this.maxHistory) {
86
+ this.history.shift();
87
+ }
88
+ }
89
+ dispatch(topic, event) {
90
+ const subs = this.subscribers.get(topic);
91
+ if (!subs || subs.size === 0)
92
+ return;
93
+ // Sort by priority (descending)
94
+ const sorted = [...subs.values()].sort((a, b) => b.priority - a.priority);
95
+ for (const sub of sorted) {
96
+ try {
97
+ const result = sub.handler(event);
98
+ if (result instanceof Promise) {
99
+ result.catch((err) => {
100
+ console.error(`[EventBus] Async handler error on ${topic}:`, err);
101
+ });
102
+ }
103
+ }
104
+ catch (err) {
105
+ console.error(`[EventBus] Sync handler error on ${topic}:`, err);
106
+ }
107
+ }
108
+ }
109
+ // --------------------------------------------------------------------------
110
+ // Subscribing
111
+ // --------------------------------------------------------------------------
112
+ /**
113
+ * Subscribe to a specific topic.
114
+ *
115
+ * @param topic - The event topic to subscribe to
116
+ * @param handler - Function called when event is published
117
+ * @param options - Priority and custom ID
118
+ * @returns Subscription with unsubscribe method
119
+ */
120
+ subscribe(topic, handler, options) {
121
+ const id = options?.id ?? `sub-${++this.seq}`;
122
+ const priority = options?.priority ?? 0;
123
+ if (!this.subscribers.has(topic)) {
124
+ this.subscribers.set(topic, new Map());
125
+ }
126
+ this.subscribers.get(topic).set(id, {
127
+ handler,
128
+ priority,
129
+ async: true,
130
+ });
131
+ return {
132
+ id,
133
+ topic,
134
+ unsubscribe: () => {
135
+ this.subscribers.get(topic)?.delete(id);
136
+ },
137
+ };
138
+ }
139
+ /**
140
+ * Subscribe to multiple topics matching a prefix.
141
+ * E.g., subscribePrefix('kernel.') matches all kernel events.
142
+ *
143
+ * @param prefix - Topic prefix to match
144
+ * @param handler - Function called for matching events
145
+ * @param options - Priority settings
146
+ * @returns Subscription covering all matching topics
147
+ */
148
+ subscribePrefix(prefix, handler, options) {
149
+ const id = options?.id ?? `prefix-${++this.seq}`;
150
+ const priority = options?.priority ?? 0;
151
+ // Store as a special prefix subscription
152
+ const prefixKey = `__prefix__${prefix}`;
153
+ if (!this.subscribers.has(prefixKey)) {
154
+ this.subscribers.set(prefixKey, new Map());
155
+ }
156
+ this.subscribers.get(prefixKey).set(id, {
157
+ handler,
158
+ priority,
159
+ async: true,
160
+ });
161
+ // Override dispatch to check prefixes
162
+ const originalDispatch = this.dispatch.bind(this);
163
+ this.dispatch = (topic, event) => {
164
+ originalDispatch(topic, event);
165
+ // Check prefix subscriptions
166
+ for (const [key, subs] of this.subscribers) {
167
+ if (key.startsWith('__prefix__')) {
168
+ const p = key.slice('__prefix__'.length);
169
+ if (topic.startsWith(p)) {
170
+ for (const sub of subs.values()) {
171
+ try {
172
+ const result = sub.handler(event);
173
+ if (result instanceof Promise) {
174
+ result.catch((err) => {
175
+ console.error(`[EventBus] Prefix handler error:`, err);
176
+ });
177
+ }
178
+ }
179
+ catch (err) {
180
+ console.error(`[EventBus] Prefix handler error:`, err);
181
+ }
182
+ }
183
+ }
184
+ }
185
+ }
186
+ };
187
+ return {
188
+ id,
189
+ topic: prefix,
190
+ unsubscribe: () => {
191
+ this.subscribers.get(prefixKey)?.delete(id);
192
+ },
193
+ };
194
+ }
195
+ /**
196
+ * Subscribe to all events (useful for logging/monitoring).
197
+ */
198
+ subscribeAll(handler, options) {
199
+ return this.subscribePrefix('', handler, options);
200
+ }
201
+ /**
202
+ * One-time subscription that auto-unsubscribes after first event.
203
+ */
204
+ once(topic, handler, options) {
205
+ const sub = this.subscribe(topic, (event) => {
206
+ sub.unsubscribe();
207
+ return handler(event);
208
+ }, options);
209
+ return sub;
210
+ }
211
+ // --------------------------------------------------------------------------
212
+ // History & Introspection
213
+ // --------------------------------------------------------------------------
214
+ /**
215
+ * Get recent event history (useful for late-joining subscribers).
216
+ *
217
+ * @param topic - Optional topic filter
218
+ * @param limit - Maximum entries to return
219
+ */
220
+ getHistory(topic, limit = 50) {
221
+ const filtered = topic
222
+ ? this.history.filter((h) => h.topic === topic)
223
+ : this.history;
224
+ return filtered.slice(-limit);
225
+ }
226
+ /**
227
+ * Get events matching a correlation ID.
228
+ */
229
+ getCorrelatedEvents(correlationId) {
230
+ return this.history.filter((h) => h.event.correlationId === correlationId);
231
+ }
232
+ /**
233
+ * Wait for a specific event (promise-based).
234
+ */
235
+ waitFor(topic, predicate, timeoutMs = 30000) {
236
+ return new Promise((resolve, reject) => {
237
+ const timeout = setTimeout(() => {
238
+ sub.unsubscribe();
239
+ reject(new Error(`Timeout waiting for ${topic}`));
240
+ }, timeoutMs);
241
+ const sub = this.subscribe(topic, (event) => {
242
+ if (!predicate || predicate(event)) {
243
+ clearTimeout(timeout);
244
+ sub.unsubscribe();
245
+ resolve(event);
246
+ }
247
+ });
248
+ });
249
+ }
250
+ /**
251
+ * List all active topic subscriptions.
252
+ */
253
+ listTopics() {
254
+ return [...this.subscribers.keys()].filter((k) => !k.startsWith('__prefix__'));
255
+ }
256
+ /**
257
+ * Get statistics for monitoring.
258
+ */
259
+ stats() {
260
+ let totalSubs = 0;
261
+ for (const subs of this.subscribers.values()) {
262
+ totalSubs += subs.size;
263
+ }
264
+ return {
265
+ topics: this.listTopics().length,
266
+ totalSubscriptions: totalSubs,
267
+ eventsPublished: this.seq,
268
+ historySize: this.history.length,
269
+ };
270
+ }
271
+ /**
272
+ * Check if a topic has any subscribers.
273
+ */
274
+ hasSubscribers(topic) {
275
+ const subs = this.subscribers.get(topic);
276
+ return subs !== undefined && subs.size > 0;
277
+ }
278
+ // --------------------------------------------------------------------------
279
+ // Lifecycle
280
+ // --------------------------------------------------------------------------
281
+ /**
282
+ * Clear all subscriptions (useful for testing).
283
+ */
284
+ clear() {
285
+ this.subscribers.clear();
286
+ this.history = [];
287
+ this.correlationStack = [];
288
+ }
289
+ /**
290
+ * Clear history only.
291
+ */
292
+ clearHistory() {
293
+ this.history = [];
294
+ }
295
+ }
296
+ exports.GenesisEventBus = GenesisEventBus;