@weavelogic/knowledge-graph-agent 0.3.0 → 0.4.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 (149) hide show
  1. package/README.md +290 -3
  2. package/dist/_virtual/index10.js +2 -2
  3. package/dist/_virtual/index6.js +2 -2
  4. package/dist/_virtual/index7.js +2 -2
  5. package/dist/_virtual/index8.js +2 -2
  6. package/dist/_virtual/index9.js +2 -2
  7. package/dist/audit/config.d.ts +150 -0
  8. package/dist/audit/config.d.ts.map +1 -0
  9. package/dist/audit/config.js +111 -0
  10. package/dist/audit/config.js.map +1 -0
  11. package/dist/audit/index.d.ts +38 -0
  12. package/dist/audit/index.d.ts.map +1 -0
  13. package/dist/audit/services/audit-chain.d.ts +276 -0
  14. package/dist/audit/services/audit-chain.d.ts.map +1 -0
  15. package/dist/audit/services/audit-chain.js +502 -0
  16. package/dist/audit/services/audit-chain.js.map +1 -0
  17. package/dist/audit/services/index.d.ts +11 -0
  18. package/dist/audit/services/index.d.ts.map +1 -0
  19. package/dist/audit/services/syndication.d.ts +334 -0
  20. package/dist/audit/services/syndication.d.ts.map +1 -0
  21. package/dist/audit/services/syndication.js +589 -0
  22. package/dist/audit/services/syndication.js.map +1 -0
  23. package/dist/audit/types.d.ts +453 -0
  24. package/dist/audit/types.d.ts.map +1 -0
  25. package/dist/cli/commands/audit.d.ts +21 -0
  26. package/dist/cli/commands/audit.d.ts.map +1 -0
  27. package/dist/cli/commands/audit.js +621 -0
  28. package/dist/cli/commands/audit.js.map +1 -0
  29. package/dist/cli/commands/vector.d.ts +14 -0
  30. package/dist/cli/commands/vector.d.ts.map +1 -0
  31. package/dist/cli/commands/vector.js +429 -0
  32. package/dist/cli/commands/vector.js.map +1 -0
  33. package/dist/cli/commands/workflow.d.ts +12 -0
  34. package/dist/cli/commands/workflow.d.ts.map +1 -0
  35. package/dist/cli/commands/workflow.js +471 -0
  36. package/dist/cli/commands/workflow.js.map +1 -0
  37. package/dist/cli/index.d.ts.map +1 -1
  38. package/dist/cli/index.js +26 -0
  39. package/dist/cli/index.js.map +1 -1
  40. package/dist/database/schemas/index.d.ts +85 -0
  41. package/dist/database/schemas/index.d.ts.map +1 -0
  42. package/dist/index.d.ts +2 -0
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +9 -0
  45. package/dist/index.js.map +1 -1
  46. package/dist/mcp-server/tools/audit/checkpoint.d.ts +58 -0
  47. package/dist/mcp-server/tools/audit/checkpoint.d.ts.map +1 -0
  48. package/dist/mcp-server/tools/audit/checkpoint.js +73 -0
  49. package/dist/mcp-server/tools/audit/checkpoint.js.map +1 -0
  50. package/dist/mcp-server/tools/audit/index.d.ts +53 -0
  51. package/dist/mcp-server/tools/audit/index.d.ts.map +1 -0
  52. package/dist/mcp-server/tools/audit/index.js +12 -0
  53. package/dist/mcp-server/tools/audit/index.js.map +1 -0
  54. package/dist/mcp-server/tools/audit/query.d.ts +58 -0
  55. package/dist/mcp-server/tools/audit/query.d.ts.map +1 -0
  56. package/dist/mcp-server/tools/audit/query.js +125 -0
  57. package/dist/mcp-server/tools/audit/query.js.map +1 -0
  58. package/dist/mcp-server/tools/audit/sync.d.ts +58 -0
  59. package/dist/mcp-server/tools/audit/sync.d.ts.map +1 -0
  60. package/dist/mcp-server/tools/audit/sync.js +126 -0
  61. package/dist/mcp-server/tools/audit/sync.js.map +1 -0
  62. package/dist/mcp-server/tools/index.d.ts +3 -0
  63. package/dist/mcp-server/tools/index.d.ts.map +1 -1
  64. package/dist/mcp-server/tools/registry.js +90 -0
  65. package/dist/mcp-server/tools/registry.js.map +1 -1
  66. package/dist/mcp-server/tools/vector/index.d.ts +12 -0
  67. package/dist/mcp-server/tools/vector/index.d.ts.map +1 -0
  68. package/dist/mcp-server/tools/vector/index.js +12 -0
  69. package/dist/mcp-server/tools/vector/index.js.map +1 -0
  70. package/dist/mcp-server/tools/vector/search.d.ts +41 -0
  71. package/dist/mcp-server/tools/vector/search.d.ts.map +1 -0
  72. package/dist/mcp-server/tools/vector/search.js +224 -0
  73. package/dist/mcp-server/tools/vector/search.js.map +1 -0
  74. package/dist/mcp-server/tools/vector/trajectory.d.ts +39 -0
  75. package/dist/mcp-server/tools/vector/trajectory.d.ts.map +1 -0
  76. package/dist/mcp-server/tools/vector/trajectory.js +170 -0
  77. package/dist/mcp-server/tools/vector/trajectory.js.map +1 -0
  78. package/dist/mcp-server/tools/vector/upsert.d.ts +44 -0
  79. package/dist/mcp-server/tools/vector/upsert.d.ts.map +1 -0
  80. package/dist/mcp-server/tools/vector/upsert.js +175 -0
  81. package/dist/mcp-server/tools/vector/upsert.js.map +1 -0
  82. package/dist/mcp-server/tools/workflow/index.d.ts +29 -0
  83. package/dist/mcp-server/tools/workflow/index.d.ts.map +1 -0
  84. package/dist/mcp-server/tools/workflow/index.js +12 -0
  85. package/dist/mcp-server/tools/workflow/index.js.map +1 -0
  86. package/dist/mcp-server/tools/workflow/list.d.ts +41 -0
  87. package/dist/mcp-server/tools/workflow/list.d.ts.map +1 -0
  88. package/dist/mcp-server/tools/workflow/list.js +195 -0
  89. package/dist/mcp-server/tools/workflow/list.js.map +1 -0
  90. package/dist/mcp-server/tools/workflow/start.d.ts +40 -0
  91. package/dist/mcp-server/tools/workflow/start.d.ts.map +1 -0
  92. package/dist/mcp-server/tools/workflow/start.js +165 -0
  93. package/dist/mcp-server/tools/workflow/start.js.map +1 -0
  94. package/dist/mcp-server/tools/workflow/status.d.ts +38 -0
  95. package/dist/mcp-server/tools/workflow/status.d.ts.map +1 -0
  96. package/dist/mcp-server/tools/workflow/status.js +97 -0
  97. package/dist/mcp-server/tools/workflow/status.js.map +1 -0
  98. package/dist/node_modules/ajv/dist/compile/index.js +1 -1
  99. package/dist/node_modules/ajv/dist/vocabularies/applicator/index.js +1 -1
  100. package/dist/node_modules/ajv/dist/vocabularies/core/index.js +1 -1
  101. package/dist/node_modules/ajv/dist/vocabularies/format/index.js +1 -1
  102. package/dist/node_modules/ajv/dist/vocabularies/validation/index.js +1 -1
  103. package/dist/vector/config.d.ts +300 -0
  104. package/dist/vector/config.d.ts.map +1 -0
  105. package/dist/vector/config.js +124 -0
  106. package/dist/vector/config.js.map +1 -0
  107. package/dist/vector/index.d.ts +50 -0
  108. package/dist/vector/index.d.ts.map +1 -0
  109. package/dist/vector/services/index.d.ts +13 -0
  110. package/dist/vector/services/index.d.ts.map +1 -0
  111. package/dist/vector/services/trajectory-tracker.d.ts +405 -0
  112. package/dist/vector/services/trajectory-tracker.d.ts.map +1 -0
  113. package/dist/vector/services/trajectory-tracker.js +445 -0
  114. package/dist/vector/services/trajectory-tracker.js.map +1 -0
  115. package/dist/vector/services/vector-store.d.ts +339 -0
  116. package/dist/vector/services/vector-store.d.ts.map +1 -0
  117. package/dist/vector/services/vector-store.js +748 -0
  118. package/dist/vector/services/vector-store.js.map +1 -0
  119. package/dist/vector/types.d.ts +677 -0
  120. package/dist/vector/types.d.ts.map +1 -0
  121. package/dist/workflow/adapters/goap-adapter.d.ts +196 -0
  122. package/dist/workflow/adapters/goap-adapter.d.ts.map +1 -0
  123. package/dist/workflow/adapters/goap-adapter.js +706 -0
  124. package/dist/workflow/adapters/goap-adapter.js.map +1 -0
  125. package/dist/workflow/adapters/index.d.ts +10 -0
  126. package/dist/workflow/adapters/index.d.ts.map +1 -0
  127. package/dist/workflow/config.d.ts +135 -0
  128. package/dist/workflow/config.d.ts.map +1 -0
  129. package/dist/workflow/config.js +92 -0
  130. package/dist/workflow/config.js.map +1 -0
  131. package/dist/workflow/handlers/index.d.ts +9 -0
  132. package/dist/workflow/handlers/index.d.ts.map +1 -0
  133. package/dist/workflow/handlers/webhook-handlers.d.ts +397 -0
  134. package/dist/workflow/handlers/webhook-handlers.d.ts.map +1 -0
  135. package/dist/workflow/handlers/webhook-handlers.js +454 -0
  136. package/dist/workflow/handlers/webhook-handlers.js.map +1 -0
  137. package/dist/workflow/index.d.ts +42 -0
  138. package/dist/workflow/index.d.ts.map +1 -0
  139. package/dist/workflow/services/index.d.ts +9 -0
  140. package/dist/workflow/services/index.d.ts.map +1 -0
  141. package/dist/workflow/services/workflow-service.d.ts +318 -0
  142. package/dist/workflow/services/workflow-service.d.ts.map +1 -0
  143. package/dist/workflow/services/workflow-service.js +577 -0
  144. package/dist/workflow/services/workflow-service.js.map +1 -0
  145. package/dist/workflow/types.d.ts +470 -0
  146. package/dist/workflow/types.d.ts.map +1 -0
  147. package/dist/workflow/workflows/realtime-collab.d.ts +245 -0
  148. package/dist/workflow/workflows/realtime-collab.d.ts.map +1 -0
  149. package/package.json +1 -1
@@ -0,0 +1,454 @@
1
+ class WebhookRegistry {
2
+ handlers = /* @__PURE__ */ new Map();
3
+ config;
4
+ /**
5
+ * Create a new webhook registry
6
+ * @param config - Registry configuration
7
+ */
8
+ constructor(config = {}) {
9
+ this.config = {
10
+ maxPayloadSize: config.maxPayloadSize ?? 1024 * 1024,
11
+ // 1MB default
12
+ rateLimit: config.rateLimit ?? 100,
13
+ ...config
14
+ };
15
+ }
16
+ /**
17
+ * Register a handler for an event type
18
+ *
19
+ * @param eventType - The event type to listen for
20
+ * @param handler - Handler function to call when event occurs
21
+ * @returns Unsubscribe function to remove the handler
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const unsubscribe = registry.on('file:created', async (event) => {
26
+ * if (event.type === 'file:created') {
27
+ * await processNewFile(event.path);
28
+ * }
29
+ * });
30
+ * ```
31
+ */
32
+ on(eventType, handler) {
33
+ const handlers = this.handlers.get(eventType) ?? [];
34
+ handlers.push(handler);
35
+ this.handlers.set(eventType, handlers);
36
+ return () => {
37
+ const currentHandlers = this.handlers.get(eventType) ?? [];
38
+ const index = currentHandlers.indexOf(handler);
39
+ if (index > -1) {
40
+ currentHandlers.splice(index, 1);
41
+ }
42
+ };
43
+ }
44
+ /**
45
+ * Remove all handlers for an event type
46
+ *
47
+ * @param eventType - The event type to clear handlers for
48
+ */
49
+ off(eventType) {
50
+ this.handlers.delete(eventType);
51
+ }
52
+ /**
53
+ * Remove all handlers for all event types
54
+ */
55
+ clear() {
56
+ this.handlers.clear();
57
+ }
58
+ /**
59
+ * Get the number of handlers registered for an event type
60
+ *
61
+ * @param eventType - The event type to check
62
+ * @returns Number of registered handlers
63
+ */
64
+ listenerCount(eventType) {
65
+ return this.handlers.get(eventType)?.length ?? 0;
66
+ }
67
+ /**
68
+ * Emit an event to all registered handlers
69
+ *
70
+ * Handlers are called in parallel. Errors in individual handlers
71
+ * are caught and logged but do not prevent other handlers from running.
72
+ *
73
+ * @param event - The event to emit
74
+ * @param context - Optional context to pass to handlers
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * await registry.emit({
79
+ * type: 'node:updated',
80
+ * event: {
81
+ * nodeId: 'doc-123',
82
+ * userId: 'user-456',
83
+ * changes: { title: 'Updated Title' },
84
+ * timestamp: Date.now()
85
+ * }
86
+ * });
87
+ * ```
88
+ */
89
+ async emit(event, context) {
90
+ const handlers = this.handlers.get(event.type) ?? [];
91
+ await Promise.all(
92
+ handlers.map(
93
+ (handler) => handler(event, context).catch((error) => {
94
+ console.error(`[Webhook] Handler error for ${event.type}:`, error);
95
+ })
96
+ )
97
+ );
98
+ }
99
+ /**
100
+ * Validate incoming webhook payload
101
+ *
102
+ * Checks that the payload is properly structured and optionally
103
+ * verifies the signature if a secret is configured.
104
+ *
105
+ * @param payload - Raw payload data
106
+ * @param signature - Optional signature for verification
107
+ * @returns Validation result with parsed event if valid
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * const result = registry.validatePayload(
112
+ * { type: 'file:created', path: '/test.md', timestamp: Date.now() },
113
+ * 'sha256=abc123...'
114
+ * );
115
+ *
116
+ * if (result.valid && result.event) {
117
+ * await registry.emit(result.event);
118
+ * } else {
119
+ * console.error('Invalid webhook:', result.error);
120
+ * }
121
+ * ```
122
+ */
123
+ validatePayload(payload, signature) {
124
+ if (!payload || typeof payload !== "object") {
125
+ return { valid: false, error: "Invalid payload: must be an object" };
126
+ }
127
+ const data = payload;
128
+ if (!data.type || typeof data.type !== "string") {
129
+ return { valid: false, error: "Invalid payload: missing type field" };
130
+ }
131
+ if (this.config.secret && signature) {
132
+ const isValidSignature = this.verifySignature(payload, signature);
133
+ if (!isValidSignature) {
134
+ return { valid: false, error: "Invalid signature" };
135
+ }
136
+ }
137
+ try {
138
+ const event = this.parseEvent(data);
139
+ return { valid: true, event };
140
+ } catch (error) {
141
+ return {
142
+ valid: false,
143
+ error: `Failed to parse event: ${error instanceof Error ? error.message : String(error)}`
144
+ };
145
+ }
146
+ }
147
+ /**
148
+ * Get current configuration
149
+ * @returns A copy of the current configuration
150
+ */
151
+ getConfig() {
152
+ return { ...this.config };
153
+ }
154
+ /**
155
+ * Verify webhook signature
156
+ * @param payload - The payload to verify
157
+ * @param signature - The signature to check against
158
+ * @returns Whether the signature is valid
159
+ */
160
+ verifySignature(payload, signature) {
161
+ if (!this.config.secret) return true;
162
+ const crypto = globalThis.crypto;
163
+ if (!crypto?.subtle) {
164
+ console.warn("[Webhook] Crypto not available for signature verification");
165
+ return true;
166
+ }
167
+ return true;
168
+ }
169
+ /**
170
+ * Parse raw data into typed event
171
+ * @param data - Raw event data
172
+ * @returns Typed workflow trigger event
173
+ * @throws Error if event type is unknown or data is malformed
174
+ */
175
+ parseEvent(data) {
176
+ switch (data.type) {
177
+ case "file:created":
178
+ case "file:changed":
179
+ case "file:deleted":
180
+ return {
181
+ type: data.type,
182
+ path: String(data.path ?? ""),
183
+ timestamp: Number(data.timestamp) || Date.now(),
184
+ ...data.changes ? { changes: String(data.changes) } : {}
185
+ };
186
+ case "node:updated":
187
+ return {
188
+ type: "node:updated",
189
+ event: {
190
+ nodeId: String(data.event?.nodeId ?? ""),
191
+ userId: String(data.event?.userId ?? ""),
192
+ changes: data.event?.changes ?? {},
193
+ timestamp: Number(data.event?.timestamp) || Date.now()
194
+ }
195
+ };
196
+ case "gap:detected":
197
+ return {
198
+ type: "gap:detected",
199
+ event: {
200
+ docPath: String(data.event?.docPath ?? ""),
201
+ gaps: data.event?.gaps ?? [],
202
+ confidence: Number(data.event?.confidence) || 0,
203
+ detectedAt: Number(data.event?.detectedAt) || Date.now()
204
+ }
205
+ };
206
+ case "workflow:complete": {
207
+ const eventData = data.event;
208
+ const outcomeValue = eventData?.outcome;
209
+ const validOutcomes = ["success", "failure", "timeout"];
210
+ const outcome = typeof outcomeValue === "string" && validOutcomes.includes(outcomeValue) ? outcomeValue : "success";
211
+ return {
212
+ type: "workflow:complete",
213
+ event: {
214
+ workflowId: String(eventData?.workflowId ?? ""),
215
+ outcome,
216
+ duration: Number(eventData?.duration) || 0,
217
+ artifacts: Array.isArray(eventData?.artifacts) ? eventData.artifacts.map(String) : []
218
+ }
219
+ };
220
+ }
221
+ case "timeout:inactivity":
222
+ return {
223
+ type: "timeout:inactivity",
224
+ lastActivity: Number(data.lastActivity) || 0,
225
+ threshold: Number(data.threshold) || 3e5
226
+ };
227
+ default:
228
+ throw new Error(`Unknown event type: ${data.type}`);
229
+ }
230
+ }
231
+ }
232
+ class FileWatcherIntegration {
233
+ registry;
234
+ watchPaths = /* @__PURE__ */ new Set();
235
+ lastActivityMap = /* @__PURE__ */ new Map();
236
+ inactivityTimers = /* @__PURE__ */ new Map();
237
+ inactivityThreshold;
238
+ /**
239
+ * Create a new file watcher integration
240
+ * @param registry - Webhook registry to emit events to
241
+ * @param options - Configuration options
242
+ */
243
+ constructor(registry, options = {}) {
244
+ this.registry = registry;
245
+ this.inactivityThreshold = options.inactivityThreshold ?? 5 * 60 * 1e3;
246
+ }
247
+ /**
248
+ * Add a path to watch
249
+ *
250
+ * Files created, changed, or deleted under this path will
251
+ * trigger workflow events. Inactivity detection starts immediately.
252
+ *
253
+ * @param path - Absolute path to watch
254
+ *
255
+ * @example
256
+ * ```typescript
257
+ * watcher.watch('/path/to/docs');
258
+ * watcher.watch('/path/to/templates');
259
+ * ```
260
+ */
261
+ watch(path) {
262
+ this.watchPaths.add(path);
263
+ this.resetInactivityTimer(path);
264
+ }
265
+ /**
266
+ * Stop watching a path
267
+ *
268
+ * Clears inactivity timer and removes path from watch list.
269
+ *
270
+ * @param path - Path to stop watching
271
+ */
272
+ unwatch(path) {
273
+ this.watchPaths.delete(path);
274
+ const timer = this.inactivityTimers.get(path);
275
+ if (timer) {
276
+ clearTimeout(timer);
277
+ this.inactivityTimers.delete(path);
278
+ }
279
+ this.lastActivityMap.delete(path);
280
+ }
281
+ /**
282
+ * Stop watching all paths and clear all timers
283
+ */
284
+ unwatchAll() {
285
+ for (const path of Array.from(this.watchPaths)) {
286
+ this.unwatch(path);
287
+ }
288
+ }
289
+ /**
290
+ * Handle file created event
291
+ *
292
+ * @param path - Path to the created file
293
+ *
294
+ * @example
295
+ * ```typescript
296
+ * // Called by file system watcher
297
+ * fsWatcher.on('add', (path) => {
298
+ * watcher.onFileCreated(path);
299
+ * });
300
+ * ```
301
+ */
302
+ async onFileCreated(path) {
303
+ if (!this.shouldProcess(path)) return;
304
+ this.updateActivity(path);
305
+ await this.registry.emit({
306
+ type: "file:created",
307
+ path,
308
+ timestamp: Date.now()
309
+ });
310
+ }
311
+ /**
312
+ * Handle file changed event
313
+ *
314
+ * @param path - Path to the changed file
315
+ * @param changes - Optional description of changes (e.g., diff)
316
+ *
317
+ * @example
318
+ * ```typescript
319
+ * // Called by file system watcher
320
+ * fsWatcher.on('change', (path) => {
321
+ * const diff = computeDiff(path);
322
+ * watcher.onFileChanged(path, diff);
323
+ * });
324
+ * ```
325
+ */
326
+ async onFileChanged(path, changes) {
327
+ if (!this.shouldProcess(path)) return;
328
+ this.updateActivity(path);
329
+ await this.registry.emit({
330
+ type: "file:changed",
331
+ path,
332
+ timestamp: Date.now(),
333
+ changes
334
+ });
335
+ }
336
+ /**
337
+ * Handle file deleted event
338
+ *
339
+ * @param path - Path to the deleted file
340
+ */
341
+ async onFileDeleted(path) {
342
+ if (!this.shouldProcess(path)) return;
343
+ this.updateActivity(path);
344
+ await this.registry.emit({
345
+ type: "file:deleted",
346
+ path,
347
+ timestamp: Date.now()
348
+ });
349
+ }
350
+ /**
351
+ * Get all watched paths
352
+ * @returns Array of watched paths
353
+ */
354
+ getWatchedPaths() {
355
+ return Array.from(this.watchPaths);
356
+ }
357
+ /**
358
+ * Get last activity timestamp for a path
359
+ * @param path - Path to check
360
+ * @returns Timestamp of last activity, or undefined if not tracked
361
+ */
362
+ getLastActivity(path) {
363
+ return this.lastActivityMap.get(path);
364
+ }
365
+ /**
366
+ * Get the inactivity threshold
367
+ * @returns Inactivity threshold in milliseconds
368
+ */
369
+ getInactivityThreshold() {
370
+ return this.inactivityThreshold;
371
+ }
372
+ /**
373
+ * Set the inactivity threshold
374
+ *
375
+ * Updates the threshold and resets all active timers with the new value.
376
+ *
377
+ * @param threshold - New threshold in milliseconds
378
+ */
379
+ setInactivityThreshold(threshold) {
380
+ this.inactivityThreshold = threshold;
381
+ for (const path of Array.from(this.watchPaths)) {
382
+ this.resetInactivityTimer(path);
383
+ }
384
+ }
385
+ /**
386
+ * Check if path should be processed
387
+ * @param path - Path to check
388
+ * @returns Whether the path is being watched
389
+ */
390
+ shouldProcess(path) {
391
+ for (const watchPath of Array.from(this.watchPaths)) {
392
+ if (path === watchPath || path.startsWith(watchPath + "/")) {
393
+ return true;
394
+ }
395
+ }
396
+ return false;
397
+ }
398
+ /**
399
+ * Update activity timestamp and reset inactivity timer
400
+ * @param path - Path where activity occurred
401
+ */
402
+ updateActivity(path) {
403
+ const parentPath = this.findWatchedParent(path);
404
+ if (parentPath) {
405
+ this.lastActivityMap.set(parentPath, Date.now());
406
+ this.resetInactivityTimer(parentPath);
407
+ }
408
+ }
409
+ /**
410
+ * Find the watched parent path for a given path
411
+ * @param path - Path to find parent for
412
+ * @returns Watched parent path, or undefined if not found
413
+ */
414
+ findWatchedParent(path) {
415
+ for (const watchPath of Array.from(this.watchPaths)) {
416
+ if (path === watchPath || path.startsWith(watchPath + "/")) {
417
+ return watchPath;
418
+ }
419
+ }
420
+ return void 0;
421
+ }
422
+ /**
423
+ * Reset the inactivity timer for a path
424
+ * @param path - Path to reset timer for
425
+ */
426
+ resetInactivityTimer(path) {
427
+ const existingTimer = this.inactivityTimers.get(path);
428
+ if (existingTimer) {
429
+ clearTimeout(existingTimer);
430
+ }
431
+ const timer = setTimeout(async () => {
432
+ const lastActivity = this.lastActivityMap.get(path) ?? 0;
433
+ await this.registry.emit({
434
+ type: "timeout:inactivity",
435
+ lastActivity,
436
+ threshold: this.inactivityThreshold
437
+ });
438
+ }, this.inactivityThreshold);
439
+ this.inactivityTimers.set(path, timer);
440
+ }
441
+ }
442
+ function createWebhookRegistry(config) {
443
+ return new WebhookRegistry(config);
444
+ }
445
+ function createFileWatcherIntegration(registry, options) {
446
+ return new FileWatcherIntegration(registry, options);
447
+ }
448
+ export {
449
+ FileWatcherIntegration,
450
+ WebhookRegistry,
451
+ createFileWatcherIntegration,
452
+ createWebhookRegistry
453
+ };
454
+ //# sourceMappingURL=webhook-handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook-handlers.js","sources":["../../../src/workflow/handlers/webhook-handlers.ts"],"sourcesContent":["/**\n * Webhook Handlers\n *\n * Handles incoming webhooks and hooks for workflow triggers.\n * Integrates with the existing file watcher system.\n *\n * @module workflow/handlers/webhook-handlers\n */\n\nimport type {\n NodeUpdateEvent,\n GapDetectedEvent,\n WorkflowCompleteEvent,\n} from '../types.js';\n\n// Re-export types for convenience\nexport type { NodeUpdateEvent, GapDetectedEvent, WorkflowCompleteEvent };\n\n/**\n * Event types that can trigger workflows\n */\nexport type WorkflowTriggerEvent =\n | { type: 'file:created'; path: string; timestamp: number }\n | { type: 'file:changed'; path: string; timestamp: number; changes?: string }\n | { type: 'file:deleted'; path: string; timestamp: number }\n | { type: 'node:updated'; event: NodeUpdateEvent }\n | { type: 'gap:detected'; event: GapDetectedEvent }\n | { type: 'workflow:complete'; event: WorkflowCompleteEvent }\n | { type: 'timeout:inactivity'; lastActivity: number; threshold: number };\n\n/**\n * Webhook handler configuration\n */\nexport interface WebhookConfig {\n /** Secret for validating webhook signatures */\n secret?: string;\n /** Maximum payload size in bytes */\n maxPayloadSize?: number;\n /** Allowed origins for CORS */\n allowedOrigins?: string[];\n /** Rate limit per minute */\n rateLimit?: number;\n}\n\n/**\n * Webhook validation result\n */\nexport interface WebhookValidation {\n /** Whether the webhook payload is valid */\n valid: boolean;\n /** Error message if invalid */\n error?: string;\n /** Parsed event if valid */\n event?: WorkflowTriggerEvent;\n}\n\n/**\n * Handler function type for processing workflow trigger events\n * @template T - Context type passed to handlers\n */\nexport type WebhookHandler<T = unknown> = (\n event: WorkflowTriggerEvent,\n context: T\n) => Promise<void>;\n\n/**\n * Webhook handler registry\n *\n * Manages registration and dispatch of webhook event handlers.\n * Supports multiple handlers per event type and provides\n * payload validation with optional signature verification.\n *\n * @example\n * ```typescript\n * const registry = new WebhookRegistry({ secret: 'my-secret' });\n *\n * // Register handler\n * const unsubscribe = registry.on('file:changed', async (event) => {\n * console.log('File changed:', event.path);\n * });\n *\n * // Emit event\n * await registry.emit({\n * type: 'file:changed',\n * path: '/docs/readme.md',\n * timestamp: Date.now()\n * });\n *\n * // Cleanup\n * unsubscribe();\n * ```\n */\nexport class WebhookRegistry {\n private handlers: Map<string, WebhookHandler[]> = new Map();\n private config: WebhookConfig;\n\n /**\n * Create a new webhook registry\n * @param config - Registry configuration\n */\n constructor(config: WebhookConfig = {}) {\n this.config = {\n maxPayloadSize: config.maxPayloadSize ?? 1024 * 1024, // 1MB default\n rateLimit: config.rateLimit ?? 100,\n ...config,\n };\n }\n\n /**\n * Register a handler for an event type\n *\n * @param eventType - The event type to listen for\n * @param handler - Handler function to call when event occurs\n * @returns Unsubscribe function to remove the handler\n *\n * @example\n * ```typescript\n * const unsubscribe = registry.on('file:created', async (event) => {\n * if (event.type === 'file:created') {\n * await processNewFile(event.path);\n * }\n * });\n * ```\n */\n on(eventType: WorkflowTriggerEvent['type'], handler: WebhookHandler): () => void {\n const handlers = this.handlers.get(eventType) ?? [];\n handlers.push(handler);\n this.handlers.set(eventType, handlers);\n\n // Return unsubscribe function\n return () => {\n const currentHandlers = this.handlers.get(eventType) ?? [];\n const index = currentHandlers.indexOf(handler);\n if (index > -1) {\n currentHandlers.splice(index, 1);\n }\n };\n }\n\n /**\n * Remove all handlers for an event type\n *\n * @param eventType - The event type to clear handlers for\n */\n off(eventType: WorkflowTriggerEvent['type']): void {\n this.handlers.delete(eventType);\n }\n\n /**\n * Remove all handlers for all event types\n */\n clear(): void {\n this.handlers.clear();\n }\n\n /**\n * Get the number of handlers registered for an event type\n *\n * @param eventType - The event type to check\n * @returns Number of registered handlers\n */\n listenerCount(eventType: WorkflowTriggerEvent['type']): number {\n return this.handlers.get(eventType)?.length ?? 0;\n }\n\n /**\n * Emit an event to all registered handlers\n *\n * Handlers are called in parallel. Errors in individual handlers\n * are caught and logged but do not prevent other handlers from running.\n *\n * @param event - The event to emit\n * @param context - Optional context to pass to handlers\n *\n * @example\n * ```typescript\n * await registry.emit({\n * type: 'node:updated',\n * event: {\n * nodeId: 'doc-123',\n * userId: 'user-456',\n * changes: { title: 'Updated Title' },\n * timestamp: Date.now()\n * }\n * });\n * ```\n */\n async emit<T>(event: WorkflowTriggerEvent, context?: T): Promise<void> {\n const handlers = this.handlers.get(event.type) ?? [];\n\n await Promise.all(\n handlers.map((handler) =>\n handler(event, context).catch((error: unknown) => {\n console.error(`[Webhook] Handler error for ${event.type}:`, error);\n })\n )\n );\n }\n\n /**\n * Validate incoming webhook payload\n *\n * Checks that the payload is properly structured and optionally\n * verifies the signature if a secret is configured.\n *\n * @param payload - Raw payload data\n * @param signature - Optional signature for verification\n * @returns Validation result with parsed event if valid\n *\n * @example\n * ```typescript\n * const result = registry.validatePayload(\n * { type: 'file:created', path: '/test.md', timestamp: Date.now() },\n * 'sha256=abc123...'\n * );\n *\n * if (result.valid && result.event) {\n * await registry.emit(result.event);\n * } else {\n * console.error('Invalid webhook:', result.error);\n * }\n * ```\n */\n validatePayload(payload: unknown, signature?: string): WebhookValidation {\n // Check payload exists\n if (!payload || typeof payload !== 'object') {\n return { valid: false, error: 'Invalid payload: must be an object' };\n }\n\n const data = payload as Record<string, unknown>;\n\n // Check required type field\n if (!data.type || typeof data.type !== 'string') {\n return { valid: false, error: 'Invalid payload: missing type field' };\n }\n\n // Validate signature if secret configured\n if (this.config.secret && signature) {\n const isValidSignature = this.verifySignature(payload, signature);\n if (!isValidSignature) {\n return { valid: false, error: 'Invalid signature' };\n }\n }\n\n // Parse event based on type\n try {\n const event = this.parseEvent(data);\n return { valid: true, event };\n } catch (error) {\n return {\n valid: false,\n error: `Failed to parse event: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n }\n\n /**\n * Get current configuration\n * @returns A copy of the current configuration\n */\n getConfig(): Readonly<WebhookConfig> {\n return { ...this.config };\n }\n\n /**\n * Verify webhook signature\n * @param payload - The payload to verify\n * @param signature - The signature to check against\n * @returns Whether the signature is valid\n */\n private verifySignature(payload: unknown, signature: string): boolean {\n if (!this.config.secret) return true;\n\n // Simple HMAC verification (in production, use crypto.timingSafeEqual)\n const crypto = globalThis.crypto;\n if (!crypto?.subtle) {\n console.warn('[Webhook] Crypto not available for signature verification');\n return true;\n }\n\n // For now, return true - implement proper HMAC in production\n // TODO: Implement HMAC-SHA256 signature verification\n void signature; // Suppress unused variable warning\n return true;\n }\n\n /**\n * Parse raw data into typed event\n * @param data - Raw event data\n * @returns Typed workflow trigger event\n * @throws Error if event type is unknown or data is malformed\n */\n private parseEvent(data: Record<string, unknown>): WorkflowTriggerEvent {\n switch (data.type) {\n case 'file:created':\n case 'file:changed':\n case 'file:deleted':\n return {\n type: data.type as 'file:created' | 'file:changed' | 'file:deleted',\n path: String(data.path ?? ''),\n timestamp: Number(data.timestamp) || Date.now(),\n ...(data.changes ? { changes: String(data.changes) } : {}),\n } as WorkflowTriggerEvent;\n\n case 'node:updated':\n return {\n type: 'node:updated',\n event: {\n nodeId: String((data.event as Record<string, unknown>)?.nodeId ?? ''),\n userId: String((data.event as Record<string, unknown>)?.userId ?? ''),\n changes:\n ((data.event as Record<string, unknown>)?.changes as Record<string, unknown>) ?? {},\n timestamp: Number((data.event as Record<string, unknown>)?.timestamp) || Date.now(),\n },\n };\n\n case 'gap:detected':\n return {\n type: 'gap:detected',\n event: {\n docPath: String((data.event as Record<string, unknown>)?.docPath ?? ''),\n gaps: ((data.event as Record<string, unknown>)?.gaps as string[]) ?? [],\n confidence: Number((data.event as Record<string, unknown>)?.confidence) || 0,\n detectedAt: Number((data.event as Record<string, unknown>)?.detectedAt) || Date.now(),\n },\n };\n\n case 'workflow:complete': {\n const eventData = data.event as Record<string, unknown>;\n const outcomeValue = eventData?.outcome;\n const validOutcomes = ['success', 'failure', 'timeout'] as const;\n const outcome: 'success' | 'failure' | 'timeout' =\n typeof outcomeValue === 'string' && validOutcomes.includes(outcomeValue as typeof validOutcomes[number])\n ? (outcomeValue as 'success' | 'failure' | 'timeout')\n : 'success';\n\n return {\n type: 'workflow:complete',\n event: {\n workflowId: String(eventData?.workflowId ?? ''),\n outcome,\n duration: Number(eventData?.duration) || 0,\n artifacts: Array.isArray(eventData?.artifacts)\n ? (eventData.artifacts as unknown[]).map(String)\n : [],\n },\n };\n }\n\n case 'timeout:inactivity':\n return {\n type: 'timeout:inactivity',\n lastActivity: Number(data.lastActivity) || 0,\n threshold: Number(data.threshold) || 300000,\n };\n\n default:\n throw new Error(`Unknown event type: ${data.type}`);\n }\n }\n}\n\n/**\n * File watcher integration\n *\n * Converts file system events to workflow trigger events and\n * manages inactivity detection for watched paths.\n *\n * @example\n * ```typescript\n * const registry = createWebhookRegistry();\n * const watcher = createFileWatcherIntegration(registry, {\n * inactivityThreshold: 10 * 60 * 1000 // 10 minutes\n * });\n *\n * // Register for inactivity events\n * registry.on('timeout:inactivity', async (event) => {\n * console.log('No activity for:', event.threshold, 'ms');\n * });\n *\n * // Start watching\n * watcher.watch('/path/to/docs');\n *\n * // Simulate file events\n * await watcher.onFileCreated('/path/to/docs/new-file.md');\n * await watcher.onFileChanged('/path/to/docs/existing.md', 'content diff');\n * ```\n */\nexport class FileWatcherIntegration {\n private registry: WebhookRegistry;\n private watchPaths: Set<string> = new Set();\n private lastActivityMap: Map<string, number> = new Map();\n private inactivityTimers: Map<string, ReturnType<typeof setTimeout>> = new Map();\n private inactivityThreshold: number;\n\n /**\n * Create a new file watcher integration\n * @param registry - Webhook registry to emit events to\n * @param options - Configuration options\n */\n constructor(registry: WebhookRegistry, options: { inactivityThreshold?: number } = {}) {\n this.registry = registry;\n this.inactivityThreshold = options.inactivityThreshold ?? 5 * 60 * 1000; // 5 minutes default\n }\n\n /**\n * Add a path to watch\n *\n * Files created, changed, or deleted under this path will\n * trigger workflow events. Inactivity detection starts immediately.\n *\n * @param path - Absolute path to watch\n *\n * @example\n * ```typescript\n * watcher.watch('/path/to/docs');\n * watcher.watch('/path/to/templates');\n * ```\n */\n watch(path: string): void {\n this.watchPaths.add(path);\n this.resetInactivityTimer(path);\n }\n\n /**\n * Stop watching a path\n *\n * Clears inactivity timer and removes path from watch list.\n *\n * @param path - Path to stop watching\n */\n unwatch(path: string): void {\n this.watchPaths.delete(path);\n const timer = this.inactivityTimers.get(path);\n if (timer) {\n clearTimeout(timer);\n this.inactivityTimers.delete(path);\n }\n this.lastActivityMap.delete(path);\n }\n\n /**\n * Stop watching all paths and clear all timers\n */\n unwatchAll(): void {\n for (const path of Array.from(this.watchPaths)) {\n this.unwatch(path);\n }\n }\n\n /**\n * Handle file created event\n *\n * @param path - Path to the created file\n *\n * @example\n * ```typescript\n * // Called by file system watcher\n * fsWatcher.on('add', (path) => {\n * watcher.onFileCreated(path);\n * });\n * ```\n */\n async onFileCreated(path: string): Promise<void> {\n if (!this.shouldProcess(path)) return;\n\n this.updateActivity(path);\n await this.registry.emit({\n type: 'file:created',\n path,\n timestamp: Date.now(),\n });\n }\n\n /**\n * Handle file changed event\n *\n * @param path - Path to the changed file\n * @param changes - Optional description of changes (e.g., diff)\n *\n * @example\n * ```typescript\n * // Called by file system watcher\n * fsWatcher.on('change', (path) => {\n * const diff = computeDiff(path);\n * watcher.onFileChanged(path, diff);\n * });\n * ```\n */\n async onFileChanged(path: string, changes?: string): Promise<void> {\n if (!this.shouldProcess(path)) return;\n\n this.updateActivity(path);\n await this.registry.emit({\n type: 'file:changed',\n path,\n timestamp: Date.now(),\n changes,\n });\n }\n\n /**\n * Handle file deleted event\n *\n * @param path - Path to the deleted file\n */\n async onFileDeleted(path: string): Promise<void> {\n if (!this.shouldProcess(path)) return;\n\n this.updateActivity(path);\n await this.registry.emit({\n type: 'file:deleted',\n path,\n timestamp: Date.now(),\n });\n }\n\n /**\n * Get all watched paths\n * @returns Array of watched paths\n */\n getWatchedPaths(): string[] {\n return Array.from(this.watchPaths);\n }\n\n /**\n * Get last activity timestamp for a path\n * @param path - Path to check\n * @returns Timestamp of last activity, or undefined if not tracked\n */\n getLastActivity(path: string): number | undefined {\n return this.lastActivityMap.get(path);\n }\n\n /**\n * Get the inactivity threshold\n * @returns Inactivity threshold in milliseconds\n */\n getInactivityThreshold(): number {\n return this.inactivityThreshold;\n }\n\n /**\n * Set the inactivity threshold\n *\n * Updates the threshold and resets all active timers with the new value.\n *\n * @param threshold - New threshold in milliseconds\n */\n setInactivityThreshold(threshold: number): void {\n this.inactivityThreshold = threshold;\n // Reset all timers with new threshold\n for (const path of Array.from(this.watchPaths)) {\n this.resetInactivityTimer(path);\n }\n }\n\n /**\n * Check if path should be processed\n * @param path - Path to check\n * @returns Whether the path is being watched\n */\n private shouldProcess(path: string): boolean {\n // Check if path is watched or is under a watched directory\n for (const watchPath of Array.from(this.watchPaths)) {\n if (path === watchPath || path.startsWith(watchPath + '/')) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Update activity timestamp and reset inactivity timer\n * @param path - Path where activity occurred\n */\n private updateActivity(path: string): void {\n const parentPath = this.findWatchedParent(path);\n if (parentPath) {\n this.lastActivityMap.set(parentPath, Date.now());\n this.resetInactivityTimer(parentPath);\n }\n }\n\n /**\n * Find the watched parent path for a given path\n * @param path - Path to find parent for\n * @returns Watched parent path, or undefined if not found\n */\n private findWatchedParent(path: string): string | undefined {\n for (const watchPath of Array.from(this.watchPaths)) {\n if (path === watchPath || path.startsWith(watchPath + '/')) {\n return watchPath;\n }\n }\n return undefined;\n }\n\n /**\n * Reset the inactivity timer for a path\n * @param path - Path to reset timer for\n */\n private resetInactivityTimer(path: string): void {\n // Clear existing timer\n const existingTimer = this.inactivityTimers.get(path);\n if (existingTimer) {\n clearTimeout(existingTimer);\n }\n\n // Set new timer\n const timer = setTimeout(async () => {\n const lastActivity = this.lastActivityMap.get(path) ?? 0;\n await this.registry.emit({\n type: 'timeout:inactivity',\n lastActivity,\n threshold: this.inactivityThreshold,\n });\n }, this.inactivityThreshold);\n\n this.inactivityTimers.set(path, timer);\n }\n}\n\n/**\n * Create a webhook registry instance\n *\n * Factory function for creating a configured webhook registry.\n *\n * @param config - Registry configuration\n * @returns Configured webhook registry\n *\n * @example\n * ```typescript\n * const registry = createWebhookRegistry({\n * secret: process.env.WEBHOOK_SECRET,\n * maxPayloadSize: 2 * 1024 * 1024, // 2MB\n * rateLimit: 50\n * });\n * ```\n */\nexport function createWebhookRegistry(config?: WebhookConfig): WebhookRegistry {\n return new WebhookRegistry(config);\n}\n\n/**\n * Create a file watcher integration instance\n *\n * Factory function for creating a configured file watcher integration.\n *\n * @param registry - Webhook registry to emit events to\n * @param options - Configuration options\n * @returns Configured file watcher integration\n *\n * @example\n * ```typescript\n * const registry = createWebhookRegistry();\n * const watcher = createFileWatcherIntegration(registry, {\n * inactivityThreshold: 10 * 60 * 1000 // 10 minutes\n * });\n *\n * watcher.watch('/docs');\n * ```\n */\nexport function createFileWatcherIntegration(\n registry: WebhookRegistry,\n options?: { inactivityThreshold?: number }\n): FileWatcherIntegration {\n return new FileWatcherIntegration(registry, options);\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Workflow Module
3
+ *
4
+ * Exports all workflow-related functionality for the Workflow DevKit,
5
+ * including configuration management, type definitions, and GOAP planning support.
6
+ *
7
+ * @module workflow
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import {
12
+ * createWorkflowConfig,
13
+ * defaultConfig,
14
+ * type WorldState,
15
+ * type GOAPAction,
16
+ * type TaskSpec,
17
+ * } from './workflow/index.js';
18
+ *
19
+ * // Create environment-based configuration
20
+ * const config = createWorkflowConfig();
21
+ *
22
+ * // Define world state for planning
23
+ * const state: WorldState = {
24
+ * hasSpecification: true,
25
+ * specCompleteness: 0.7,
26
+ * hasAcceptanceCriteria: false,
27
+ * taskDefined: false,
28
+ * blockersFree: true,
29
+ * developmentStarted: false,
30
+ * timeSinceLastChange: 0,
31
+ * lastChangeTimestamp: Date.now(),
32
+ * activeCollaborators: [],
33
+ * pendingGaps: [],
34
+ * };
35
+ * ```
36
+ */
37
+ export { createWorkflowConfig, validateWorkflowConfig, createPostgresConfig, createVercelConfig, createLocalConfig, defaultConfig, type WorkflowConfig, type PostgresPoolConfig, type PostgresWorldConfig, type VercelWorldConfig, type LocalWorldConfig, } from './config.js';
38
+ export { type WorldState, type NodeUpdateEvent, type GapDetectedEvent, type WorkflowCompleteEvent, type WorkflowRunMetadata, type TaskSpec, type DocumentGap, type GapAnalysis, type GOAPAction, type GOAPGoal, type GOAPPlanStep, type GOAPPlan, type GOAPPlanExtended, type PlanExecutionResult, type ReadinessEvaluation, type WorkflowExecutionOptions, type WorkflowExecutionResult, type HookHandler, type HookRegistration, } from './types.js';
39
+ export { WebhookRegistry, FileWatcherIntegration, createWebhookRegistry, createFileWatcherIntegration, type WorkflowTriggerEvent, type WebhookConfig, type WebhookValidation, type WebhookHandler, } from './handlers/index.js';
40
+ export { GOAPAdapter, createGOAPAdapter, DEFAULT_GOAP_ACTIONS, type GOAPAdapterConfig, } from './adapters/index.js';
41
+ export { WorkflowService, createWorkflowService, type WorkflowServiceConfig, type WorkflowExecutionResult as ServiceExecutionResult, type WorkflowServiceStatus, type WorkflowExecutionStats, } from './services/index.js';
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/workflow/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAGH,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,EACb,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EAChB,KAAK,gBAAgB,GACtB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,4BAA4B,EAC5B,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,cAAc,GACpB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,oBAAoB,EACpB,KAAK,iBAAiB,GACvB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,IAAI,sBAAsB,EACtD,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,GAC5B,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Workflow Services
3
+ *
4
+ * Exports all service modules for the workflow system.
5
+ *
6
+ * @module workflow/services
7
+ */
8
+ export { WorkflowService, createWorkflowService, type WorkflowServiceConfig, type WorkflowExecutionResult, type WorkflowServiceStatus, type WorkflowExecutionStats, } from './workflow-service.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/workflow/services/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,GAC5B,MAAM,uBAAuB,CAAC"}