@lobu/core 2.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 (137) hide show
  1. package/dist/__tests__/encryption.test.d.ts +2 -0
  2. package/dist/__tests__/encryption.test.d.ts.map +1 -0
  3. package/dist/__tests__/encryption.test.js +88 -0
  4. package/dist/__tests__/encryption.test.js.map +1 -0
  5. package/dist/__tests__/fixtures/factories.d.ts +30 -0
  6. package/dist/__tests__/fixtures/factories.d.ts.map +1 -0
  7. package/dist/__tests__/fixtures/factories.js +53 -0
  8. package/dist/__tests__/fixtures/factories.js.map +1 -0
  9. package/dist/__tests__/fixtures/index.d.ts +5 -0
  10. package/dist/__tests__/fixtures/index.d.ts.map +1 -0
  11. package/dist/__tests__/fixtures/index.js +14 -0
  12. package/dist/__tests__/fixtures/index.js.map +1 -0
  13. package/dist/__tests__/fixtures/mock-fetch.d.ts +13 -0
  14. package/dist/__tests__/fixtures/mock-fetch.d.ts.map +1 -0
  15. package/dist/__tests__/fixtures/mock-fetch.js +29 -0
  16. package/dist/__tests__/fixtures/mock-fetch.js.map +1 -0
  17. package/dist/__tests__/fixtures/mock-queue.d.ts +19 -0
  18. package/dist/__tests__/fixtures/mock-queue.d.ts.map +1 -0
  19. package/dist/__tests__/fixtures/mock-queue.js +45 -0
  20. package/dist/__tests__/fixtures/mock-queue.js.map +1 -0
  21. package/dist/__tests__/fixtures/mock-redis.d.ts +54 -0
  22. package/dist/__tests__/fixtures/mock-redis.d.ts.map +1 -0
  23. package/dist/__tests__/fixtures/mock-redis.js +267 -0
  24. package/dist/__tests__/fixtures/mock-redis.js.map +1 -0
  25. package/dist/__tests__/retry.test.d.ts +2 -0
  26. package/dist/__tests__/retry.test.d.ts.map +1 -0
  27. package/dist/__tests__/retry.test.js +114 -0
  28. package/dist/__tests__/retry.test.js.map +1 -0
  29. package/dist/__tests__/sanitize.test.d.ts +2 -0
  30. package/dist/__tests__/sanitize.test.d.ts.map +1 -0
  31. package/dist/__tests__/sanitize.test.js +129 -0
  32. package/dist/__tests__/sanitize.test.js.map +1 -0
  33. package/dist/agent-policy.d.ts +21 -0
  34. package/dist/agent-policy.d.ts.map +1 -0
  35. package/dist/agent-policy.js +181 -0
  36. package/dist/agent-policy.js.map +1 -0
  37. package/dist/agent-store.d.ts +140 -0
  38. package/dist/agent-store.d.ts.map +1 -0
  39. package/dist/agent-store.js +27 -0
  40. package/dist/agent-store.js.map +1 -0
  41. package/dist/api-types.d.ts +213 -0
  42. package/dist/api-types.d.ts.map +1 -0
  43. package/dist/api-types.js +7 -0
  44. package/dist/api-types.js.map +1 -0
  45. package/dist/command-registry.d.ts +41 -0
  46. package/dist/command-registry.d.ts.map +1 -0
  47. package/dist/command-registry.js +43 -0
  48. package/dist/command-registry.js.map +1 -0
  49. package/dist/constants.d.ts +54 -0
  50. package/dist/constants.d.ts.map +1 -0
  51. package/dist/constants.js +60 -0
  52. package/dist/constants.js.map +1 -0
  53. package/dist/errors.d.ts +97 -0
  54. package/dist/errors.d.ts.map +1 -0
  55. package/dist/errors.js +182 -0
  56. package/dist/errors.js.map +1 -0
  57. package/dist/index.d.ts +31 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +64 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/integration-types.d.ts +22 -0
  62. package/dist/integration-types.d.ts.map +1 -0
  63. package/dist/integration-types.js +9 -0
  64. package/dist/integration-types.js.map +1 -0
  65. package/dist/logger.d.ts +15 -0
  66. package/dist/logger.d.ts.map +1 -0
  67. package/dist/logger.js +223 -0
  68. package/dist/logger.js.map +1 -0
  69. package/dist/modules.d.ts +96 -0
  70. package/dist/modules.d.ts.map +1 -0
  71. package/dist/modules.js +140 -0
  72. package/dist/modules.js.map +1 -0
  73. package/dist/otel.d.ts +107 -0
  74. package/dist/otel.d.ts.map +1 -0
  75. package/dist/otel.js +251 -0
  76. package/dist/otel.js.map +1 -0
  77. package/dist/plugin-types.d.ts +42 -0
  78. package/dist/plugin-types.d.ts.map +1 -0
  79. package/dist/plugin-types.js +8 -0
  80. package/dist/plugin-types.js.map +1 -0
  81. package/dist/provider-config-types.d.ts +53 -0
  82. package/dist/provider-config-types.d.ts.map +1 -0
  83. package/dist/provider-config-types.js +7 -0
  84. package/dist/provider-config-types.js.map +1 -0
  85. package/dist/redis/base-store.d.ts +73 -0
  86. package/dist/redis/base-store.d.ts.map +1 -0
  87. package/dist/redis/base-store.js +174 -0
  88. package/dist/redis/base-store.js.map +1 -0
  89. package/dist/sentry.d.ts +12 -0
  90. package/dist/sentry.d.ts.map +1 -0
  91. package/dist/sentry.js +82 -0
  92. package/dist/sentry.js.map +1 -0
  93. package/dist/trace.d.ts +25 -0
  94. package/dist/trace.d.ts.map +1 -0
  95. package/dist/trace.js +32 -0
  96. package/dist/trace.js.map +1 -0
  97. package/dist/types.d.ts +373 -0
  98. package/dist/types.d.ts.map +1 -0
  99. package/dist/types.js +6 -0
  100. package/dist/types.js.map +1 -0
  101. package/dist/utils/encryption.d.ts +9 -0
  102. package/dist/utils/encryption.d.ts.map +1 -0
  103. package/dist/utils/encryption.js +107 -0
  104. package/dist/utils/encryption.js.map +1 -0
  105. package/dist/utils/env.d.ts +20 -0
  106. package/dist/utils/env.d.ts.map +1 -0
  107. package/dist/utils/env.js +50 -0
  108. package/dist/utils/env.js.map +1 -0
  109. package/dist/utils/json.d.ts +11 -0
  110. package/dist/utils/json.d.ts.map +1 -0
  111. package/dist/utils/json.js +38 -0
  112. package/dist/utils/json.js.map +1 -0
  113. package/dist/utils/lock.d.ts +34 -0
  114. package/dist/utils/lock.d.ts.map +1 -0
  115. package/dist/utils/lock.js +66 -0
  116. package/dist/utils/lock.js.map +1 -0
  117. package/dist/utils/mcp-tool-instructions.d.ts +6 -0
  118. package/dist/utils/mcp-tool-instructions.d.ts.map +1 -0
  119. package/dist/utils/mcp-tool-instructions.js +3 -0
  120. package/dist/utils/mcp-tool-instructions.js.map +1 -0
  121. package/dist/utils/retry.d.ts +40 -0
  122. package/dist/utils/retry.d.ts.map +1 -0
  123. package/dist/utils/retry.js +67 -0
  124. package/dist/utils/retry.js.map +1 -0
  125. package/dist/utils/sanitize.d.ts +55 -0
  126. package/dist/utils/sanitize.d.ts.map +1 -0
  127. package/dist/utils/sanitize.js +111 -0
  128. package/dist/utils/sanitize.js.map +1 -0
  129. package/dist/worker/auth.d.ts +34 -0
  130. package/dist/worker/auth.d.ts.map +1 -0
  131. package/dist/worker/auth.js +63 -0
  132. package/dist/worker/auth.js.map +1 -0
  133. package/dist/worker/transport.d.ts +86 -0
  134. package/dist/worker/transport.d.ts.map +1 -0
  135. package/dist/worker/transport.js +13 -0
  136. package/dist/worker/transport.js.map +1 -0
  137. package/package.json +40 -0
package/dist/logger.js ADDED
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.logger = void 0;
7
+ exports.createLogger = createLogger;
8
+ // Use simple console.log-based logger by default (unbuffered, 12-factor compliant)
9
+ // Set USE_WINSTON_LOGGER=true only if you need Winston features (file rotation, multiple transports)
10
+ const USE_WINSTON_LOGGER = process.env.USE_WINSTON_LOGGER === "true";
11
+ // Use JSON format for structured logging (better for Loki parsing in production)
12
+ const USE_JSON_FORMAT = process.env.LOG_FORMAT === "json";
13
+ const winston_1 = __importDefault(require("winston"));
14
+ const sentry_1 = require("./sentry");
15
+ // Simple console logger fallback for environments where Winston doesn't work (Bun + Alpine)
16
+ // Supports both formats: logger.info("message", data) AND pino-style logger.info({ data }, "message")
17
+ function createConsoleLogger(serviceName) {
18
+ const level = process.env.LOG_LEVEL || "info";
19
+ const levels = {
20
+ error: 0,
21
+ warn: 1,
22
+ info: 2,
23
+ debug: 3,
24
+ };
25
+ const currentLevel = levels[level] ?? 2;
26
+ const formatMessage = (lvl, message, ...args) => {
27
+ const timestamp = new Date().toISOString().replace("T", " ").slice(0, 19);
28
+ let msgStr;
29
+ let meta = null;
30
+ // Handle pino-style format: logger.info({ key: value }, "message")
31
+ if (typeof message === "object" &&
32
+ message !== null &&
33
+ !Array.isArray(message) &&
34
+ !(message instanceof Error)) {
35
+ if (args.length > 0 && typeof args[0] === "string") {
36
+ // First arg is metadata object, second arg is the actual message
37
+ msgStr = args[0];
38
+ meta = message;
39
+ args = args.slice(1);
40
+ }
41
+ else {
42
+ // Just an object, stringify it
43
+ try {
44
+ msgStr = JSON.stringify(message);
45
+ }
46
+ catch {
47
+ msgStr = "[object]";
48
+ }
49
+ }
50
+ }
51
+ else {
52
+ msgStr = String(message);
53
+ }
54
+ // Append remaining args
55
+ if (args.length > 0) {
56
+ try {
57
+ msgStr += ` ${JSON.stringify(args.length === 1 ? args[0] : args)}`;
58
+ }
59
+ catch {
60
+ msgStr += " [unserializable]";
61
+ }
62
+ }
63
+ // Append metadata object
64
+ if (meta) {
65
+ try {
66
+ msgStr += ` ${JSON.stringify(meta)}`;
67
+ }
68
+ catch {
69
+ msgStr += " [meta unserializable]";
70
+ }
71
+ }
72
+ return `[${timestamp}] [${lvl}] [${serviceName}] ${msgStr}`;
73
+ };
74
+ return {
75
+ error: (message, ...args) => {
76
+ if (currentLevel >= 0)
77
+ console.error(formatMessage("error", message, ...args));
78
+ },
79
+ warn: (message, ...args) => {
80
+ if (currentLevel >= 1)
81
+ console.warn(formatMessage("warn", message, ...args));
82
+ },
83
+ info: (message, ...args) => {
84
+ if (currentLevel >= 2)
85
+ console.log(formatMessage("info", message, ...args));
86
+ },
87
+ debug: (message, ...args) => {
88
+ if (currentLevel >= 3)
89
+ console.log(formatMessage("debug", message, ...args));
90
+ },
91
+ };
92
+ }
93
+ /**
94
+ * Custom Winston transport that sends errors to Sentry
95
+ */
96
+ class SentryTransport extends winston_1.default.transports.Stream {
97
+ constructor() {
98
+ super({ stream: process.stdout });
99
+ }
100
+ log(info, callback) {
101
+ setImmediate(() => {
102
+ this.emit("logged", info);
103
+ });
104
+ // Only send errors and warnings to Sentry
105
+ if (info.level === "error" || info.level === "warn") {
106
+ const Sentry = (0, sentry_1.getSentry)();
107
+ if (Sentry) {
108
+ try {
109
+ // Extract error object if present
110
+ const errorObj = info.error || (info.message instanceof Error ? info.message : null);
111
+ if (errorObj instanceof Error) {
112
+ Sentry.captureException(errorObj, {
113
+ level: info.level === "error" ? "error" : "warning",
114
+ tags: {
115
+ service: info.service,
116
+ },
117
+ extra: {
118
+ ...info,
119
+ message: info.message,
120
+ },
121
+ });
122
+ }
123
+ else {
124
+ // Send as message if no Error object
125
+ Sentry.captureMessage(String(info.message), {
126
+ level: info.level === "error" ? "error" : "warning",
127
+ tags: {
128
+ service: info.service,
129
+ },
130
+ extra: info,
131
+ });
132
+ }
133
+ }
134
+ catch (_err) {
135
+ // Ignore Sentry errors to avoid breaking logging
136
+ }
137
+ }
138
+ }
139
+ callback();
140
+ }
141
+ }
142
+ /**
143
+ * Creates a logger instance for a specific service
144
+ * Provides consistent logging format across all packages with level and timestamp
145
+ * @param serviceName The name of the service using the logger
146
+ * @returns A console logger by default, or Winston logger if USE_WINSTON_LOGGER=true
147
+ */
148
+ function createLogger(serviceName) {
149
+ // Use simple console.log logger by default (unbuffered, 12-factor compliant)
150
+ // Set USE_WINSTON_LOGGER=true for Winston features (file rotation, multiple transports)
151
+ if (!USE_WINSTON_LOGGER) {
152
+ return createConsoleLogger(serviceName);
153
+ }
154
+ const isProduction = process.env.NODE_ENV === "production";
155
+ const level = process.env.LOG_LEVEL || "info";
156
+ // JSON format for structured logging (better for Loki/Grafana parsing)
157
+ const jsonFormat = winston_1.default.format.combine(winston_1.default.format.timestamp({ format: "YYYY-MM-DDTHH:mm:ss.SSSZ" }), winston_1.default.format.json());
158
+ // Human-readable format for development
159
+ const humanFormat = winston_1.default.format.combine(...(isProduction ? [] : [winston_1.default.format.colorize()]), winston_1.default.format.printf(({ timestamp, level, message, service, ...meta }) => {
160
+ let metaStr = "";
161
+ if (Object.keys(meta).length) {
162
+ try {
163
+ metaStr = ` ${JSON.stringify(meta, null, 0)}`;
164
+ }
165
+ catch (_err) {
166
+ // Handle circular structures with a safer approach
167
+ try {
168
+ const seen = new WeakSet();
169
+ metaStr = ` ${JSON.stringify(meta, (_key, value) => {
170
+ if (typeof value === "object" && value !== null) {
171
+ if (seen.has(value)) {
172
+ return "[Circular Reference]";
173
+ }
174
+ seen.add(value);
175
+ if (value instanceof Error) {
176
+ return {
177
+ name: value.name,
178
+ message: value.message,
179
+ stack: value.stack?.split("\n")[0], // Only first line of stack
180
+ };
181
+ }
182
+ }
183
+ return value;
184
+ })}`;
185
+ }
186
+ catch (_err2) {
187
+ // Final fallback if even the circular handler fails
188
+ metaStr = " [Object too complex to serialize]";
189
+ }
190
+ }
191
+ }
192
+ return `[${timestamp}] [${level}] [${service}] ${message}${metaStr}`;
193
+ }));
194
+ const transports = [
195
+ new winston_1.default.transports.Console({
196
+ format: USE_JSON_FORMAT ? jsonFormat : humanFormat,
197
+ }),
198
+ ];
199
+ const logger = winston_1.default.createLogger({
200
+ level,
201
+ format: winston_1.default.format.combine(winston_1.default.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }), winston_1.default.format.errors({ stack: true }), winston_1.default.format.splat()),
202
+ defaultMeta: { service: serviceName },
203
+ transports,
204
+ });
205
+ // Add Sentry transport in production or if SENTRY_DSN is set
206
+ // Deferred to avoid circular dependency with sentry.ts
207
+ // The check is inside setImmediate to ensure SentryTransport class is fully initialized
208
+ setImmediate(() => {
209
+ if (isProduction || process.env.SENTRY_DSN) {
210
+ try {
211
+ const transport = new SentryTransport();
212
+ logger.add(transport);
213
+ }
214
+ catch {
215
+ // Ignore errors during Sentry transport setup
216
+ }
217
+ }
218
+ });
219
+ return logger;
220
+ }
221
+ // Default logger instance for backward compatibility
222
+ exports.logger = createLogger("shared");
223
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ export interface ModuleInterface<_TModuleData = unknown> {
2
+ /** Module identifier */
3
+ name: string;
4
+ /** Check if module should be enabled based on environment */
5
+ isEnabled(): boolean;
6
+ /** Initialize module - called once at startup */
7
+ init(): Promise<void>;
8
+ /** Register HTTP endpoints with Express app */
9
+ registerEndpoints(app: any): void;
10
+ }
11
+ export interface WorkerContext {
12
+ workspaceDir: string;
13
+ userId: string;
14
+ conversationId: string;
15
+ }
16
+ export interface WorkerModule<TModuleData = unknown> extends ModuleInterface<TModuleData> {
17
+ /** Initialize workspace - called when worker starts session */
18
+ initWorkspace(config: any): Promise<void>;
19
+ /** Called at session start - can modify system prompt */
20
+ onSessionStart(context: ModuleSessionContext): Promise<ModuleSessionContext>;
21
+ /** Called at session end - can add action buttons */
22
+ onSessionEnd(context: ModuleSessionContext): Promise<ActionButton[]>;
23
+ /** Collect module-specific data before sending response. Return null if no data. */
24
+ onBeforeResponse(context: WorkerContext): Promise<TModuleData | null>;
25
+ }
26
+ export interface ModuleSessionContext {
27
+ userId: string;
28
+ conversationId: string;
29
+ systemPrompt: string;
30
+ workspace?: any;
31
+ }
32
+ export interface ActionButton {
33
+ text: string;
34
+ action_id: string;
35
+ style?: "primary" | "danger";
36
+ value?: string;
37
+ url?: string;
38
+ }
39
+ export interface IModuleRegistry {
40
+ register(module: ModuleInterface): void;
41
+ getWorkerModules(): WorkerModule[];
42
+ registerAvailableModules(modulePackages?: string[]): Promise<void>;
43
+ initAll(): Promise<void>;
44
+ registerEndpoints(app: any): void;
45
+ /** Return all registered modules as base ModuleInterface array. */
46
+ getModules(): ModuleInterface[];
47
+ }
48
+ /**
49
+ * Module registry for managing plugin modules across the application.
50
+ *
51
+ * Modules must be explicitly registered by calling `register()` before use.
52
+ * This allows each package (dispatcher, worker) to load only the modules it needs.
53
+ *
54
+ * For production: use the global `moduleRegistry` instance
55
+ * For testing: create a new instance to avoid shared state
56
+ *
57
+ * @example
58
+ * // In gateway/worker
59
+ * import { MyModule } from './my-module';
60
+ * moduleRegistry.register(new MyModule());
61
+ * await moduleRegistry.initAll();
62
+ *
63
+ * @example
64
+ * // In tests
65
+ * const testRegistry = new ModuleRegistry();
66
+ * testRegistry.register(mockModule);
67
+ */
68
+ export declare class ModuleRegistry implements IModuleRegistry {
69
+ private modules;
70
+ register(module: ModuleInterface): void;
71
+ /**
72
+ * Automatically discover and register available modules.
73
+ * Tries to import module packages and registers them if available.
74
+ *
75
+ * @param modulePackages - List of module package names to try loading.
76
+ * Users can provide custom modules to register.
77
+ *
78
+ * @example
79
+ * // Register custom modules
80
+ * await moduleRegistry.registerAvailableModules([
81
+ * '@mycompany/slack-module',
82
+ * '@mycompany/jira-module'
83
+ * ]);
84
+ */
85
+ registerAvailableModules(modulePackages?: string[]): Promise<void>;
86
+ initAll(): Promise<void>;
87
+ registerEndpoints(app: any): void;
88
+ getWorkerModules(): WorkerModule[];
89
+ getModules(): ModuleInterface[];
90
+ }
91
+ /**
92
+ * Global registry instance for production use.
93
+ * For testing, create separate instances: `new ModuleRegistry()`
94
+ */
95
+ export declare const moduleRegistry: ModuleRegistry;
96
+ //# sourceMappingURL=modules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modules.d.ts","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,eAAe,CAAC,YAAY,GAAG,OAAO;IACrD,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IAEb,6DAA6D;IAC7D,SAAS,IAAI,OAAO,CAAC;IAErB,iDAAiD;IACjD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB,+CAA+C;IAC/C,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY,CAAC,WAAW,GAAG,OAAO,CACjD,SAAQ,eAAe,CAAC,WAAW,CAAC;IACpC,+DAA+D;IAC/D,aAAa,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1C,yDAAyD;IACzD,cAAc,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAE7E,qDAAqD;IACrD,YAAY,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAErE,oFAAoF;IACpF,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,GAAG,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAMD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IACxC,gBAAgB,IAAI,YAAY,EAAE,CAAC;IACnC,wBAAwB,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC;IAClC,mEAAmE;IACnE,UAAU,IAAI,eAAe,EAAE,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,cAAe,YAAW,eAAe;IACpD,OAAO,CAAC,OAAO,CAA2C;IAE1D,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI;IAMvC;;;;;;;;;;;;;OAaG;IACG,wBAAwB,CAAC,cAAc,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BtE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAU9B,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAejC,gBAAgB,IAAI,YAAY,EAAE;IAMlC,UAAU,IAAI,eAAe,EAAE;CAGhC;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,gBAAuB,CAAC"}
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.moduleRegistry = exports.ModuleRegistry = void 0;
37
+ const logger_1 = require("./logger");
38
+ const logger = (0, logger_1.createLogger)("modules");
39
+ /**
40
+ * Module registry for managing plugin modules across the application.
41
+ *
42
+ * Modules must be explicitly registered by calling `register()` before use.
43
+ * This allows each package (dispatcher, worker) to load only the modules it needs.
44
+ *
45
+ * For production: use the global `moduleRegistry` instance
46
+ * For testing: create a new instance to avoid shared state
47
+ *
48
+ * @example
49
+ * // In gateway/worker
50
+ * import { MyModule } from './my-module';
51
+ * moduleRegistry.register(new MyModule());
52
+ * await moduleRegistry.initAll();
53
+ *
54
+ * @example
55
+ * // In tests
56
+ * const testRegistry = new ModuleRegistry();
57
+ * testRegistry.register(mockModule);
58
+ */
59
+ class ModuleRegistry {
60
+ constructor() {
61
+ this.modules = new Map();
62
+ }
63
+ register(module) {
64
+ if (module.isEnabled()) {
65
+ this.modules.set(module.name, module);
66
+ }
67
+ }
68
+ /**
69
+ * Automatically discover and register available modules.
70
+ * Tries to import module packages and registers them if available.
71
+ *
72
+ * @param modulePackages - List of module package names to try loading.
73
+ * Users can provide custom modules to register.
74
+ *
75
+ * @example
76
+ * // Register custom modules
77
+ * await moduleRegistry.registerAvailableModules([
78
+ * '@mycompany/slack-module',
79
+ * '@mycompany/jira-module'
80
+ * ]);
81
+ */
82
+ async registerAvailableModules(modulePackages = []) {
83
+ for (const packageName of modulePackages) {
84
+ try {
85
+ // Dynamic import to avoid build-time dependencies
86
+ const moduleExports = await Promise.resolve(`${packageName}`).then(s => __importStar(require(s)));
87
+ // Try common export patterns
88
+ const ModuleClass = moduleExports.default ||
89
+ Object.values(moduleExports).find((exp) => typeof exp === "function" && exp.name.endsWith("Module"));
90
+ if (ModuleClass && typeof ModuleClass === "function") {
91
+ const moduleInstance = new ModuleClass();
92
+ if (!this.modules.has(moduleInstance.name)) {
93
+ this.register(moduleInstance);
94
+ logger.debug(`${packageName} registered`);
95
+ }
96
+ }
97
+ else {
98
+ logger.debug(`${packageName}: No module class found in exports`);
99
+ }
100
+ }
101
+ catch {
102
+ logger.debug(`${packageName} not available`);
103
+ }
104
+ }
105
+ }
106
+ async initAll() {
107
+ for (const module of this.modules.values()) {
108
+ if (module.init) {
109
+ logger.debug(`Initializing module: ${module.name}`);
110
+ await module.init();
111
+ logger.debug(`Module ${module.name} initialized`);
112
+ }
113
+ }
114
+ }
115
+ registerEndpoints(app) {
116
+ for (const module of this.modules.values()) {
117
+ if (module.registerEndpoints) {
118
+ try {
119
+ module.registerEndpoints(app);
120
+ }
121
+ catch (error) {
122
+ logger.error(`Failed to register endpoints for module ${module.name}:`, error);
123
+ }
124
+ }
125
+ }
126
+ }
127
+ getWorkerModules() {
128
+ return Array.from(this.modules.values()).filter((m) => "onBeforeResponse" in m);
129
+ }
130
+ getModules() {
131
+ return Array.from(this.modules.values());
132
+ }
133
+ }
134
+ exports.ModuleRegistry = ModuleRegistry;
135
+ /**
136
+ * Global registry instance for production use.
137
+ * For testing, create separate instances: `new ModuleRegistry()`
138
+ */
139
+ exports.moduleRegistry = new ModuleRegistry();
140
+ //# sourceMappingURL=modules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modules.js","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"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"}
package/dist/otel.d.ts ADDED
@@ -0,0 +1,107 @@
1
+ /**
2
+ * OpenTelemetry tracing setup for distributed tracing with Grafana Tempo.
3
+ * Provides Chrome DevTools-style waterfall visualization in Grafana.
4
+ */
5
+ import type { Span, Tracer } from "@opentelemetry/api";
6
+ import { SpanKind, SpanStatusCode } from "@opentelemetry/api";
7
+ export interface OtelConfig {
8
+ serviceName: string;
9
+ serviceVersion?: string;
10
+ tempoEndpoint?: string;
11
+ enabled?: boolean;
12
+ }
13
+ /**
14
+ * Initialize OpenTelemetry tracing.
15
+ * Call this once at application startup.
16
+ *
17
+ * @example
18
+ * initTracing({
19
+ * serviceName: "lobu-gateway",
20
+ * tempoEndpoint: "http://lobu-tempo:4318/v1/traces",
21
+ * });
22
+ */
23
+ export declare function initTracing(config: OtelConfig): void;
24
+ /**
25
+ * Get the configured tracer. Returns null if not initialized.
26
+ */
27
+ export declare function getTracer(): Tracer | null;
28
+ /**
29
+ * Shutdown tracing gracefully.
30
+ */
31
+ export declare function shutdownTracing(): Promise<void>;
32
+ /**
33
+ * Force flush all pending spans to the exporter.
34
+ * Call this after processing a message to ensure spans are exported promptly.
35
+ */
36
+ export declare function flushTracing(): Promise<void>;
37
+ /**
38
+ * Create a new span for tracing.
39
+ * If tracing is not initialized, returns a no-op span.
40
+ *
41
+ * @param name Span name (e.g., "queue_processing", "agent_execution")
42
+ * @param attributes Optional attributes to add to the span
43
+ * @param parentContext Optional parent context for trace correlation
44
+ */
45
+ export declare function createSpan(name: string, attributes?: Record<string, string | number | boolean>, kind?: SpanKind): Span | null;
46
+ /**
47
+ * Execute a function within a span context.
48
+ * Automatically handles span lifecycle (start, end, error recording).
49
+ *
50
+ * @example
51
+ * const result = await withSpan("process_message", async (span) => {
52
+ * span?.setAttribute("messageId", messageId);
53
+ * return await processMessage();
54
+ * });
55
+ */
56
+ export declare function withSpan<T>(name: string, fn: (span: Span | null) => Promise<T>, attributes?: Record<string, string | number | boolean>): Promise<T>;
57
+ /**
58
+ * Get current active span from context.
59
+ */
60
+ export declare function getCurrentSpan(): Span | undefined;
61
+ /**
62
+ * Run a function within a span context, propagating the span.
63
+ */
64
+ export declare function runInSpanContext<T>(span: Span, fn: () => T): T;
65
+ /**
66
+ * Create a root span and return traceparent header for propagation.
67
+ * Use this at the entry point (message ingestion) to start a trace.
68
+ *
69
+ * @example
70
+ * const { span, traceparent } = createRootSpan("message_received", { messageId });
71
+ * // Store traceparent in message metadata for downstream propagation
72
+ * await queueProducer.enqueueMessage({ ...data, platformMetadata: { traceparent } });
73
+ * span.end();
74
+ */
75
+ export declare function createRootSpan(name: string, attributes?: Record<string, string | number | boolean>): {
76
+ span: Span | null;
77
+ traceparent: string | null;
78
+ };
79
+ /**
80
+ * Create a child span from a traceparent header.
81
+ * Use this to continue a trace in downstream services (queue consumer, worker).
82
+ *
83
+ * @example
84
+ * const traceparent = data.platformMetadata?.traceparent;
85
+ * const span = createChildSpan("queue_processing", traceparent, { jobId });
86
+ * // ... do work ...
87
+ * span?.end();
88
+ */
89
+ export declare function createChildSpan(name: string, traceparent: string | null | undefined, attributes?: Record<string, string | number | boolean>): Span | null;
90
+ /**
91
+ * Run a function within a child span context.
92
+ * Automatically handles span lifecycle and error recording.
93
+ *
94
+ * @example
95
+ * const result = await withChildSpan("process_job", traceparent, async (span) => {
96
+ * span?.setAttribute("jobId", jobId);
97
+ * return await processJob();
98
+ * });
99
+ */
100
+ export declare function withChildSpan<T>(name: string, traceparent: string | null | undefined, fn: (span: Span | null) => Promise<T>, attributes?: Record<string, string | number | boolean>): Promise<T>;
101
+ /**
102
+ * Extract traceparent from span for propagation to downstream services.
103
+ */
104
+ export declare function getTraceparent(span: Span | null): string | null;
105
+ export { SpanKind, SpanStatusCode };
106
+ export type { Span, Tracer };
107
+ //# sourceMappingURL=otel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otel.d.ts","sourceRoot":"","sources":["../src/otel.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAW,QAAQ,EAAE,cAAc,EAAS,MAAM,oBAAoB,CAAC;AAkB9E,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAiCpD;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,MAAM,GAAG,IAAI,CAEzC;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAMrD;AAED;;;GAGG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAIlD;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EACtD,IAAI,GAAE,QAA4B,GACjC,IAAI,GAAG,IAAI,CAWb;AAED;;;;;;;;;GASG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EACrC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GACrD,OAAO,CAAC,CAAC,CAAC,CAmBZ;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,GAAG,SAAS,CAEjD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAG9D;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GACrD;IAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAenD;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACtC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GACrD,IAAI,GAAG,IAAI,CAiCb;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACtC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EACrC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GACrD,OAAO,CAAC,CAAC,CAAC,CAmBZ;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAI/D;AAGD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;AACpC,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC"}