beercan 0.1.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 (151) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +187 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +546 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/client.d.ts +8 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +29 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/config.d.ts +49 -0
  12. package/dist/config.d.ts.map +1 -0
  13. package/dist/config.js +61 -0
  14. package/dist/config.js.map +1 -0
  15. package/dist/core/gatekeeper.d.ts +163 -0
  16. package/dist/core/gatekeeper.d.ts.map +1 -0
  17. package/dist/core/gatekeeper.js +247 -0
  18. package/dist/core/gatekeeper.js.map +1 -0
  19. package/dist/core/job-queue.d.ts +61 -0
  20. package/dist/core/job-queue.d.ts.map +1 -0
  21. package/dist/core/job-queue.js +123 -0
  22. package/dist/core/job-queue.js.map +1 -0
  23. package/dist/core/logger.d.ts +22 -0
  24. package/dist/core/logger.d.ts.map +1 -0
  25. package/dist/core/logger.js +65 -0
  26. package/dist/core/logger.js.map +1 -0
  27. package/dist/core/role-templates.d.ts +3 -0
  28. package/dist/core/role-templates.d.ts.map +1 -0
  29. package/dist/core/role-templates.js +179 -0
  30. package/dist/core/role-templates.js.map +1 -0
  31. package/dist/core/roles.d.ts +94 -0
  32. package/dist/core/roles.d.ts.map +1 -0
  33. package/dist/core/roles.js +206 -0
  34. package/dist/core/roles.js.map +1 -0
  35. package/dist/core/runner.d.ts +76 -0
  36. package/dist/core/runner.d.ts.map +1 -0
  37. package/dist/core/runner.js +307 -0
  38. package/dist/core/runner.js.map +1 -0
  39. package/dist/events/daemon.d.ts +9 -0
  40. package/dist/events/daemon.d.ts.map +1 -0
  41. package/dist/events/daemon.js +29 -0
  42. package/dist/events/daemon.js.map +1 -0
  43. package/dist/events/event-bus.d.ts +35 -0
  44. package/dist/events/event-bus.d.ts.map +1 -0
  45. package/dist/events/event-bus.js +41 -0
  46. package/dist/events/event-bus.js.map +1 -0
  47. package/dist/events/index.d.ts +41 -0
  48. package/dist/events/index.d.ts.map +1 -0
  49. package/dist/events/index.js +57 -0
  50. package/dist/events/index.js.map +1 -0
  51. package/dist/events/sources/filesystem-source.d.ts +23 -0
  52. package/dist/events/sources/filesystem-source.d.ts.map +1 -0
  53. package/dist/events/sources/filesystem-source.js +95 -0
  54. package/dist/events/sources/filesystem-source.js.map +1 -0
  55. package/dist/events/sources/macos-source.d.ts +23 -0
  56. package/dist/events/sources/macos-source.d.ts.map +1 -0
  57. package/dist/events/sources/macos-source.js +123 -0
  58. package/dist/events/sources/macos-source.js.map +1 -0
  59. package/dist/events/sources/polling-source.d.ts +23 -0
  60. package/dist/events/sources/polling-source.d.ts.map +1 -0
  61. package/dist/events/sources/polling-source.js +47 -0
  62. package/dist/events/sources/polling-source.js.map +1 -0
  63. package/dist/events/sources/webhook-source.d.ts +23 -0
  64. package/dist/events/sources/webhook-source.d.ts.map +1 -0
  65. package/dist/events/sources/webhook-source.js +132 -0
  66. package/dist/events/sources/webhook-source.js.map +1 -0
  67. package/dist/events/trigger-manager.d.ts +78 -0
  68. package/dist/events/trigger-manager.d.ts.map +1 -0
  69. package/dist/events/trigger-manager.js +130 -0
  70. package/dist/events/trigger-manager.js.map +1 -0
  71. package/dist/index.d.ts +123 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +225 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/mcp/index.d.ts +4 -0
  76. package/dist/mcp/index.d.ts.map +1 -0
  77. package/dist/mcp/index.js +3 -0
  78. package/dist/mcp/index.js.map +1 -0
  79. package/dist/mcp/manager.d.ts +99 -0
  80. package/dist/mcp/manager.d.ts.map +1 -0
  81. package/dist/mcp/manager.js +143 -0
  82. package/dist/mcp/manager.js.map +1 -0
  83. package/dist/mcp/tool-adapter.d.ts +20 -0
  84. package/dist/mcp/tool-adapter.d.ts.map +1 -0
  85. package/dist/mcp/tool-adapter.js +29 -0
  86. package/dist/mcp/tool-adapter.js.map +1 -0
  87. package/dist/memory/embeddings.d.ts +28 -0
  88. package/dist/memory/embeddings.d.ts.map +1 -0
  89. package/dist/memory/embeddings.js +90 -0
  90. package/dist/memory/embeddings.js.map +1 -0
  91. package/dist/memory/hybrid-search.d.ts +31 -0
  92. package/dist/memory/hybrid-search.d.ts.map +1 -0
  93. package/dist/memory/hybrid-search.js +114 -0
  94. package/dist/memory/hybrid-search.js.map +1 -0
  95. package/dist/memory/index.d.ts +55 -0
  96. package/dist/memory/index.d.ts.map +1 -0
  97. package/dist/memory/index.js +175 -0
  98. package/dist/memory/index.js.map +1 -0
  99. package/dist/memory/knowledge-graph.d.ts +21 -0
  100. package/dist/memory/knowledge-graph.d.ts.map +1 -0
  101. package/dist/memory/knowledge-graph.js +118 -0
  102. package/dist/memory/knowledge-graph.js.map +1 -0
  103. package/dist/memory/schemas.d.ts +187 -0
  104. package/dist/memory/schemas.d.ts.map +1 -0
  105. package/dist/memory/schemas.js +75 -0
  106. package/dist/memory/schemas.js.map +1 -0
  107. package/dist/memory/sqlite-vec-store.d.ts +22 -0
  108. package/dist/memory/sqlite-vec-store.d.ts.map +1 -0
  109. package/dist/memory/sqlite-vec-store.js +37 -0
  110. package/dist/memory/sqlite-vec-store.js.map +1 -0
  111. package/dist/memory/working-memory.d.ts +22 -0
  112. package/dist/memory/working-memory.d.ts.map +1 -0
  113. package/dist/memory/working-memory.js +53 -0
  114. package/dist/memory/working-memory.js.map +1 -0
  115. package/dist/scheduler/index.d.ts +3 -0
  116. package/dist/scheduler/index.d.ts.map +1 -0
  117. package/dist/scheduler/index.js +2 -0
  118. package/dist/scheduler/index.js.map +1 -0
  119. package/dist/scheduler/scheduler.d.ts +82 -0
  120. package/dist/scheduler/scheduler.d.ts.map +1 -0
  121. package/dist/scheduler/scheduler.js +127 -0
  122. package/dist/scheduler/scheduler.js.map +1 -0
  123. package/dist/schemas.d.ts +328 -0
  124. package/dist/schemas.d.ts.map +1 -0
  125. package/dist/schemas.js +77 -0
  126. package/dist/schemas.js.map +1 -0
  127. package/dist/storage/database.d.ts +97 -0
  128. package/dist/storage/database.d.ts.map +1 -0
  129. package/dist/storage/database.js +685 -0
  130. package/dist/storage/database.js.map +1 -0
  131. package/dist/tools/builtin/filesystem.d.ts +11 -0
  132. package/dist/tools/builtin/filesystem.d.ts.map +1 -0
  133. package/dist/tools/builtin/filesystem.js +137 -0
  134. package/dist/tools/builtin/filesystem.js.map +1 -0
  135. package/dist/tools/builtin/memory.d.ts +13 -0
  136. package/dist/tools/builtin/memory.d.ts.map +1 -0
  137. package/dist/tools/builtin/memory.js +299 -0
  138. package/dist/tools/builtin/memory.js.map +1 -0
  139. package/dist/tools/builtin/notification.d.ts +5 -0
  140. package/dist/tools/builtin/notification.d.ts.map +1 -0
  141. package/dist/tools/builtin/notification.js +36 -0
  142. package/dist/tools/builtin/notification.js.map +1 -0
  143. package/dist/tools/builtin/web.d.ts +7 -0
  144. package/dist/tools/builtin/web.d.ts.map +1 -0
  145. package/dist/tools/builtin/web.js +191 -0
  146. package/dist/tools/builtin/web.js.map +1 -0
  147. package/dist/tools/registry.d.ts +36 -0
  148. package/dist/tools/registry.d.ts.map +1 -0
  149. package/dist/tools/registry.js +49 -0
  150. package/dist/tools/registry.js.map +1 -0
  151. package/package.json +73 -0
@@ -0,0 +1,29 @@
1
+ import chalk from "chalk";
2
+ /**
3
+ * Start the BeerCan daemon: runs scheduler + event system.
4
+ * Handles graceful shutdown on SIGTERM/SIGINT.
5
+ */
6
+ export async function startDaemon(engine, scheduler, eventManager) {
7
+ // Start scheduler
8
+ scheduler.init();
9
+ scheduler.start();
10
+ // Start event system
11
+ await eventManager.start();
12
+ console.log(chalk.bold.blue("\n🍺 BeerCan daemon running"));
13
+ console.log(chalk.dim(" Press Ctrl+C to stop\n"));
14
+ // Graceful shutdown
15
+ const shutdown = async () => {
16
+ console.log(chalk.dim("\nShutting down..."));
17
+ scheduler.stop();
18
+ await eventManager.stop();
19
+ engine.close();
20
+ process.exit(0);
21
+ };
22
+ process.on("SIGTERM", shutdown);
23
+ process.on("SIGINT", shutdown);
24
+ // Keep process alive
25
+ await new Promise(() => {
26
+ // Never resolves — daemon runs until killed
27
+ });
28
+ }
29
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/events/daemon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAqB,EACrB,SAAoB,EACpB,YAA0B;IAE1B,kBAAkB;IAClB,SAAS,CAAC,IAAI,EAAE,CAAC;IACjB,SAAS,CAAC,KAAK,EAAE,CAAC;IAElB,qBAAqB;IACrB,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;IAE3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAEnD,oBAAoB;IACpB,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC;QAC7C,SAAS,CAAC,IAAI,EAAE,CAAC;QACjB,MAAM,YAAY,CAAC,IAAI,EAAE,CAAC;QAC1B,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAE/B,qBAAqB;IACrB,MAAM,IAAI,OAAO,CAAC,GAAG,EAAE;QACrB,4CAA4C;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { EventEmitter } from "events";
2
+ import { z } from "zod";
3
+ export declare const BeerCanEventSchema: z.ZodObject<{
4
+ type: z.ZodString;
5
+ projectSlug: z.ZodString;
6
+ source: z.ZodEnum<["webhook", "filesystem", "polling", "macos", "api", "internal"]>;
7
+ data: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
8
+ timestamp: z.ZodString;
9
+ }, "strip", z.ZodTypeAny, {
10
+ type: string;
11
+ timestamp: string;
12
+ projectSlug: string;
13
+ source: "webhook" | "filesystem" | "polling" | "macos" | "api" | "internal";
14
+ data: Record<string, unknown>;
15
+ }, {
16
+ type: string;
17
+ timestamp: string;
18
+ projectSlug: string;
19
+ source: "webhook" | "filesystem" | "polling" | "macos" | "api" | "internal";
20
+ data?: Record<string, unknown> | undefined;
21
+ }>;
22
+ export type BeerCanEvent = z.infer<typeof BeerCanEventSchema>;
23
+ export declare class EventBus extends EventEmitter {
24
+ private eventLog;
25
+ private maxLogSize;
26
+ /** Publish a typed event */
27
+ publish(event: BeerCanEvent): void;
28
+ /** Subscribe to a specific event type */
29
+ subscribe(eventType: string, handler: (event: BeerCanEvent) => void): void;
30
+ /** Subscribe to ALL events */
31
+ subscribeAll(handler: (event: BeerCanEvent) => void): void;
32
+ /** Get recent events (for debugging/monitoring) */
33
+ getRecentEvents(count?: number): BeerCanEvent[];
34
+ }
35
+ //# sourceMappingURL=event-bus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../../src/events/event-bus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;EAM7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAM9D,qBAAa,QAAS,SAAQ,YAAY;IACxC,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,UAAU,CAAQ;IAE1B,4BAA4B;IAC5B,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAYlC,yCAAyC;IACzC,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI;IAI1E,8BAA8B;IAC9B,YAAY,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI;IAI1D,mDAAmD;IACnD,eAAe,CAAC,KAAK,SAAK,GAAG,YAAY,EAAE;CAG5C"}
@@ -0,0 +1,41 @@
1
+ import { EventEmitter } from "events";
2
+ import { z } from "zod";
3
+ // ── BeerCan Event Schema ────────────────────────────────────
4
+ export const BeerCanEventSchema = z.object({
5
+ type: z.string(),
6
+ projectSlug: z.string(),
7
+ source: z.enum(["webhook", "filesystem", "polling", "macos", "api", "internal"]),
8
+ data: z.record(z.unknown()).default({}),
9
+ timestamp: z.string().datetime(),
10
+ });
11
+ // ── Event Bus ───────────────────────────────────────────────
12
+ // Central pub/sub hub. All event sources publish here.
13
+ // TriggerManager subscribes to match events to triggers.
14
+ export class EventBus extends EventEmitter {
15
+ eventLog = [];
16
+ maxLogSize = 1000;
17
+ /** Publish a typed event */
18
+ publish(event) {
19
+ this.eventLog.push(event);
20
+ if (this.eventLog.length > this.maxLogSize) {
21
+ this.eventLog.shift();
22
+ }
23
+ // Emit on specific event type channel
24
+ this.emit(event.type, event);
25
+ // Also emit on wildcard channel for global listeners
26
+ this.emit("*", event);
27
+ }
28
+ /** Subscribe to a specific event type */
29
+ subscribe(eventType, handler) {
30
+ this.on(eventType, handler);
31
+ }
32
+ /** Subscribe to ALL events */
33
+ subscribeAll(handler) {
34
+ this.on("*", handler);
35
+ }
36
+ /** Get recent events (for debugging/monitoring) */
37
+ getRecentEvents(count = 50) {
38
+ return this.eventLog.slice(-count);
39
+ }
40
+ }
41
+ //# sourceMappingURL=event-bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../../src/events/event-bus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,+DAA+D;AAE/D,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAChF,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACvC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACjC,CAAC,CAAC;AAGH,+DAA+D;AAC/D,uDAAuD;AACvD,yDAAyD;AAEzD,MAAM,OAAO,QAAS,SAAQ,YAAY;IAChC,QAAQ,GAAmB,EAAE,CAAC;IAC9B,UAAU,GAAG,IAAI,CAAC;IAE1B,4BAA4B;IAC5B,OAAO,CAAC,KAAmB;QACzB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YAC3C,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACxB,CAAC;QAED,sCAAsC;QACtC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC7B,qDAAqD;QACrD,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACxB,CAAC;IAED,yCAAyC;IACzC,SAAS,CAAC,SAAiB,EAAE,OAAsC;QACjE,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,8BAA8B;IAC9B,YAAY,CAAC,OAAsC;QACjD,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACxB,CAAC;IAED,mDAAmD;IACnD,eAAe,CAAC,KAAK,GAAG,EAAE;QACxB,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;CACF"}
@@ -0,0 +1,41 @@
1
+ import { EventBus } from "./event-bus.js";
2
+ import { WebhookSource } from "./sources/webhook-source.js";
3
+ import { FilesystemSource } from "./sources/filesystem-source.js";
4
+ import { PollingSource } from "./sources/polling-source.js";
5
+ import { MacOSNativeSource } from "./sources/macos-source.js";
6
+ import { TriggerManager, type TriggerBloopExecutor } from "./trigger-manager.js";
7
+ import type { BeerCanDB } from "../storage/database.js";
8
+ export interface EventManagerConfig {
9
+ webhookPort?: number;
10
+ }
11
+ export declare class EventManager {
12
+ private bus;
13
+ private webhook;
14
+ private filesystem;
15
+ private polling;
16
+ private macos;
17
+ private triggers;
18
+ constructor(db: BeerCanDB, executor: TriggerBloopExecutor, config?: EventManagerConfig);
19
+ /** Start all event sources and trigger processing */
20
+ start(): Promise<void>;
21
+ /** Stop everything gracefully */
22
+ stop(): Promise<void>;
23
+ /** Access the event bus for custom subscriptions */
24
+ getEventBus(): EventBus;
25
+ /** Access the trigger manager for CRUD */
26
+ getTriggerManager(): TriggerManager;
27
+ /** Access sources for configuration */
28
+ getWebhookSource(): WebhookSource;
29
+ getFilesystemSource(): FilesystemSource;
30
+ getPollingSource(): PollingSource;
31
+ getMacOSSource(): MacOSNativeSource;
32
+ }
33
+ export { EventBus, BeerCanEventSchema } from "./event-bus.js";
34
+ export type { BeerCanEvent } from "./event-bus.js";
35
+ export { TriggerManager, TriggerSchema } from "./trigger-manager.js";
36
+ export type { Trigger } from "./trigger-manager.js";
37
+ export { WebhookSource } from "./sources/webhook-source.js";
38
+ export { FilesystemSource } from "./sources/filesystem-source.js";
39
+ export { PollingSource } from "./sources/polling-source.js";
40
+ export { MacOSNativeSource } from "./sources/macos-source.js";
41
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAKxD,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,GAAG,CAAW;IACtB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,KAAK,CAAoB;IACjC,OAAO,CAAC,QAAQ,CAAiB;gBAErB,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,GAAE,kBAAuB;IAS1F,qDAAqD;IAC/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAa5B,iCAAiC;IAC3B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,oDAAoD;IACpD,WAAW,IAAI,QAAQ;IAEvB,0CAA0C;IAC1C,iBAAiB,IAAI,cAAc;IAEnC,uCAAuC;IACvC,gBAAgB,IAAI,aAAa;IACjC,mBAAmB,IAAI,gBAAgB;IACvC,gBAAgB,IAAI,aAAa;IACjC,cAAc,IAAI,iBAAiB;CACpC;AAED,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC9D,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrE,YAAY,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { EventBus } from "./event-bus.js";
2
+ import { WebhookSource } from "./sources/webhook-source.js";
3
+ import { FilesystemSource } from "./sources/filesystem-source.js";
4
+ import { PollingSource } from "./sources/polling-source.js";
5
+ import { MacOSNativeSource } from "./sources/macos-source.js";
6
+ import { TriggerManager } from "./trigger-manager.js";
7
+ export class EventManager {
8
+ bus;
9
+ webhook;
10
+ filesystem;
11
+ polling;
12
+ macos;
13
+ triggers;
14
+ constructor(db, executor, config = {}) {
15
+ this.bus = new EventBus();
16
+ this.webhook = new WebhookSource(this.bus, { port: config.webhookPort ?? 3939 });
17
+ this.filesystem = new FilesystemSource(this.bus);
18
+ this.polling = new PollingSource(this.bus);
19
+ this.macos = new MacOSNativeSource(this.bus);
20
+ this.triggers = new TriggerManager(this.bus, db, executor);
21
+ }
22
+ /** Start all event sources and trigger processing */
23
+ async start() {
24
+ // Load triggers from DB
25
+ this.triggers.init();
26
+ // Start all sources
27
+ await this.webhook.start();
28
+ await this.filesystem.start();
29
+ await this.polling.start();
30
+ await this.macos.start();
31
+ console.log("[events] Event system started");
32
+ }
33
+ /** Stop everything gracefully */
34
+ async stop() {
35
+ await this.webhook.stop();
36
+ await this.filesystem.stop();
37
+ await this.polling.stop();
38
+ await this.macos.stop();
39
+ console.log("[events] Event system stopped");
40
+ }
41
+ /** Access the event bus for custom subscriptions */
42
+ getEventBus() { return this.bus; }
43
+ /** Access the trigger manager for CRUD */
44
+ getTriggerManager() { return this.triggers; }
45
+ /** Access sources for configuration */
46
+ getWebhookSource() { return this.webhook; }
47
+ getFilesystemSource() { return this.filesystem; }
48
+ getPollingSource() { return this.polling; }
49
+ getMacOSSource() { return this.macos; }
50
+ }
51
+ export { EventBus, BeerCanEventSchema } from "./event-bus.js";
52
+ export { TriggerManager, TriggerSchema } from "./trigger-manager.js";
53
+ export { WebhookSource } from "./sources/webhook-source.js";
54
+ export { FilesystemSource } from "./sources/filesystem-source.js";
55
+ export { PollingSource } from "./sources/polling-source.js";
56
+ export { MacOSNativeSource } from "./sources/macos-source.js";
57
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { EventBus } from "../event-bus.js";
2
+ export interface FilesystemWatchConfig {
3
+ projectSlug: string;
4
+ watchPaths: string[];
5
+ /** Glob patterns to include (if empty, watch all) */
6
+ includePatterns?: string[];
7
+ /** Glob patterns to exclude */
8
+ excludePatterns?: string[];
9
+ }
10
+ export declare class FilesystemSource {
11
+ private bus;
12
+ private watchers;
13
+ private configs;
14
+ private debounceTimers;
15
+ constructor(bus: EventBus);
16
+ /** Add a watch configuration */
17
+ addWatch(config: FilesystemWatchConfig): void;
18
+ start(): Promise<void>;
19
+ stop(): Promise<void>;
20
+ private emitFileEvent;
21
+ private shouldExclude;
22
+ }
23
+ //# sourceMappingURL=filesystem-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem-source.d.ts","sourceRoot":"","sources":["../../../src/events/sources/filesystem-source.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAqB,MAAM,iBAAiB,CAAC;AAK9D,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,qDAAqD;IACrD,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,+BAA+B;IAC/B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,GAAG,CAAW;IACtB,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,cAAc,CAAqC;gBAE/C,GAAG,EAAE,QAAQ;IAIzB,gCAAgC;IAChC,QAAQ,CAAC,MAAM,EAAE,qBAAqB,GAAG,IAAI;IAIvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA0CtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAY3B,OAAO,CAAC,aAAa;IAwBrB,OAAO,CAAC,aAAa;CAsBtB"}
@@ -0,0 +1,95 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ export class FilesystemSource {
4
+ bus;
5
+ watchers = [];
6
+ configs = [];
7
+ debounceTimers = new Map();
8
+ constructor(bus) {
9
+ this.bus = bus;
10
+ }
11
+ /** Add a watch configuration */
12
+ addWatch(config) {
13
+ this.configs.push(config);
14
+ }
15
+ async start() {
16
+ for (const config of this.configs) {
17
+ for (const watchPath of config.watchPaths) {
18
+ if (!fs.existsSync(watchPath)) {
19
+ console.warn(`[fs-watch] Path does not exist: ${watchPath}`);
20
+ continue;
21
+ }
22
+ try {
23
+ const watcher = fs.watch(watchPath, { recursive: true }, (eventType, filename) => {
24
+ if (!filename)
25
+ return;
26
+ // Check exclusion patterns
27
+ if (this.shouldExclude(filename, config))
28
+ return;
29
+ // Debounce rapid changes to same file
30
+ const key = `${watchPath}:${filename}`;
31
+ const existing = this.debounceTimers.get(key);
32
+ if (existing)
33
+ clearTimeout(existing);
34
+ this.debounceTimers.set(key, setTimeout(() => {
35
+ this.emitFileEvent(config.projectSlug, watchPath, filename, eventType);
36
+ this.debounceTimers.delete(key);
37
+ }, 500) // 500ms debounce
38
+ );
39
+ });
40
+ this.watchers.push(watcher);
41
+ console.log(`[fs-watch] Watching: ${watchPath} for ${config.projectSlug}`);
42
+ }
43
+ catch (err) {
44
+ console.warn(`[fs-watch] Failed to watch ${watchPath}: ${err.message}`);
45
+ }
46
+ }
47
+ }
48
+ }
49
+ async stop() {
50
+ for (const watcher of this.watchers) {
51
+ watcher.close();
52
+ }
53
+ this.watchers = [];
54
+ for (const timer of this.debounceTimers.values()) {
55
+ clearTimeout(timer);
56
+ }
57
+ this.debounceTimers.clear();
58
+ }
59
+ emitFileEvent(projectSlug, watchPath, filename, eventType) {
60
+ const fullPath = path.join(watchPath, filename);
61
+ const event = {
62
+ type: "file.changed",
63
+ projectSlug,
64
+ source: "filesystem",
65
+ data: {
66
+ eventType, // 'rename' or 'change'
67
+ filename,
68
+ fullPath,
69
+ watchPath,
70
+ exists: fs.existsSync(fullPath),
71
+ },
72
+ timestamp: new Date().toISOString(),
73
+ };
74
+ this.bus.publish(event);
75
+ }
76
+ shouldExclude(filename, config) {
77
+ // Simple pattern matching (not full glob, but covers common cases)
78
+ const excludes = config.excludePatterns ?? [
79
+ "node_modules",
80
+ ".git",
81
+ ".DS_Store",
82
+ "dist",
83
+ ];
84
+ for (const pattern of excludes) {
85
+ if (filename.includes(pattern))
86
+ return true;
87
+ }
88
+ if (config.includePatterns && config.includePatterns.length > 0) {
89
+ const ext = path.extname(filename);
90
+ return !config.includePatterns.some((p) => filename.endsWith(p) || ext === p);
91
+ }
92
+ return false;
93
+ }
94
+ }
95
+ //# sourceMappingURL=filesystem-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem-source.js","sourceRoot":"","sources":["../../../src/events/sources/filesystem-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAexB,MAAM,OAAO,gBAAgB;IACnB,GAAG,CAAW;IACd,QAAQ,GAAmB,EAAE,CAAC;IAC9B,OAAO,GAA4B,EAAE,CAAC;IACtC,cAAc,GAAG,IAAI,GAAG,EAA0B,CAAC;IAE3D,YAAY,GAAa;QACvB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED,gCAAgC;IAChC,QAAQ,CAAC,MAA6B;QACpC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,KAAK;QACT,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gBAC1C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC9B,OAAO,CAAC,IAAI,CAAC,mCAAmC,SAAS,EAAE,CAAC,CAAC;oBAC7D,SAAS;gBACX,CAAC;gBAED,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CACtB,SAAS,EACT,EAAE,SAAS,EAAE,IAAI,EAAE,EACnB,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE;wBACtB,IAAI,CAAC,QAAQ;4BAAE,OAAO;wBAEtB,2BAA2B;wBAC3B,IAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC;4BAAE,OAAO;wBAEjD,sCAAsC;wBACtC,MAAM,GAAG,GAAG,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC;wBACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;wBAC9C,IAAI,QAAQ;4BAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;wBAErC,IAAI,CAAC,cAAc,CAAC,GAAG,CACrB,GAAG,EACH,UAAU,CAAC,GAAG,EAAE;4BACd,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;4BACvE,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;wBAClC,CAAC,EAAE,GAAG,CAAC,CAAC,iBAAiB;yBAC1B,CAAC;oBACJ,CAAC,CACF,CAAC;oBAEF,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBAC5B,OAAO,CAAC,GAAG,CAAC,wBAAwB,SAAS,QAAQ,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;gBAC7E,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAClB,OAAO,CAAC,IAAI,CAAC,8BAA8B,SAAS,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC1E,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QAEnB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC;YACjD,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;IAC9B,CAAC;IAEO,aAAa,CACnB,WAAmB,EACnB,SAAiB,EACjB,QAAgB,EAChB,SAAiB;QAEjB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAChD,MAAM,KAAK,GAAiB;YAC1B,IAAI,EAAE,cAAc;YACpB,WAAW;YACX,MAAM,EAAE,YAAY;YACpB,IAAI,EAAE;gBACJ,SAAS,EAAE,uBAAuB;gBAClC,QAAQ;gBACR,QAAQ;gBACR,SAAS;gBACT,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;aAChC;YACD,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAEO,aAAa,CAAC,QAAgB,EAAE,MAA6B;QACnE,mEAAmE;QACnE,MAAM,QAAQ,GAAG,MAAM,CAAC,eAAe,IAAI;YACzC,cAAc;YACd,MAAM;YACN,WAAW;YACX,MAAM;SACP,CAAC;QAEF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,OAAO,IAAI,CAAC;QAC9C,CAAC;QAED,IAAI,MAAM,CAAC,eAAe,IAAI,MAAM,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACnC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,CACjC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CACzC,CAAC;QACJ,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
@@ -0,0 +1,23 @@
1
+ import { EventBus } from "../event-bus.js";
2
+ export interface MacOSSourceConfig {
3
+ projectSlug: string;
4
+ /** Poll interval in milliseconds (default: 60000 = 1 min) */
5
+ intervalMs?: number;
6
+ /** Which macOS services to watch */
7
+ services: Array<"calendar" | "reminders">;
8
+ }
9
+ export declare class MacOSNativeSource {
10
+ private bus;
11
+ private configs;
12
+ private timers;
13
+ private lastChecked;
14
+ private isMacOS;
15
+ constructor(bus: EventBus);
16
+ addConfig(config: MacOSSourceConfig): void;
17
+ start(): Promise<void>;
18
+ stop(): Promise<void>;
19
+ private checkService;
20
+ private checkCalendar;
21
+ private checkReminders;
22
+ }
23
+ //# sourceMappingURL=macos-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"macos-source.d.ts","sourceRoot":"","sources":["../../../src/events/sources/macos-source.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAqB,MAAM,iBAAiB,CAAC;AAM9D,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,QAAQ,EAAE,KAAK,CAAC,UAAU,GAAG,WAAW,CAAC,CAAC;CAC3C;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,GAAG,CAAW;IACtB,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,OAAO,CAAU;gBAEb,GAAG,EAAE,QAAQ;IAKzB,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAIpC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA6BtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,aAAa;IAwCrB,OAAO,CAAC,cAAc;CAkCvB"}
@@ -0,0 +1,123 @@
1
+ import { execSync } from "child_process";
2
+ import os from "os";
3
+ export class MacOSNativeSource {
4
+ bus;
5
+ configs = [];
6
+ timers = [];
7
+ lastChecked = new Map(); // service → last check timestamp
8
+ isMacOS;
9
+ constructor(bus) {
10
+ this.bus = bus;
11
+ this.isMacOS = os.platform() === "darwin";
12
+ }
13
+ addConfig(config) {
14
+ this.configs.push(config);
15
+ }
16
+ async start() {
17
+ if (!this.isMacOS) {
18
+ console.log("[macos] Not on macOS, skipping native event source");
19
+ return;
20
+ }
21
+ for (const config of this.configs) {
22
+ const interval = config.intervalMs ?? 60_000;
23
+ for (const service of config.services) {
24
+ // Initialize last check time
25
+ this.lastChecked.set(`${config.projectSlug}:${service}`, new Date().toISOString());
26
+ const timer = setInterval(() => this.checkService(config.projectSlug, service), interval);
27
+ this.timers.push(timer);
28
+ console.log(`[macos] Watching ${service} for ${config.projectSlug} (every ${interval / 1000}s)`);
29
+ }
30
+ }
31
+ }
32
+ async stop() {
33
+ for (const timer of this.timers) {
34
+ clearInterval(timer);
35
+ }
36
+ this.timers = [];
37
+ }
38
+ checkService(projectSlug, service) {
39
+ try {
40
+ switch (service) {
41
+ case "calendar":
42
+ this.checkCalendar(projectSlug);
43
+ break;
44
+ case "reminders":
45
+ this.checkReminders(projectSlug);
46
+ break;
47
+ }
48
+ }
49
+ catch (err) {
50
+ console.warn(`[macos] ${service} check failed: ${err.message}`);
51
+ }
52
+ }
53
+ checkCalendar(projectSlug) {
54
+ const key = `${projectSlug}:calendar`;
55
+ const script = `
56
+ tell application "Calendar"
57
+ set today to current date
58
+ set tomorrow to today + 1 * days
59
+ set upcomingEvents to {}
60
+ repeat with cal in calendars
61
+ set evts to (every event of cal whose start date >= today and start date < tomorrow)
62
+ repeat with e in evts
63
+ set end of upcomingEvents to {summary of e, start date of e as text}
64
+ end repeat
65
+ end repeat
66
+ return upcomingEvents as text
67
+ end tell
68
+ `;
69
+ try {
70
+ const result = execSync(`osascript -e '${script.replace(/'/g, "'\\''")}'`, {
71
+ encoding: "utf-8",
72
+ timeout: 10_000,
73
+ }).trim();
74
+ if (result && result !== this.lastChecked.get(key + ":data")) {
75
+ this.lastChecked.set(key + ":data", result);
76
+ const event = {
77
+ type: "macos.calendar.update",
78
+ projectSlug,
79
+ source: "macos",
80
+ data: { events: result, service: "calendar" },
81
+ timestamp: new Date().toISOString(),
82
+ };
83
+ this.bus.publish(event);
84
+ }
85
+ }
86
+ catch {
87
+ // Calendar might not be accessible, that's fine
88
+ }
89
+ }
90
+ checkReminders(projectSlug) {
91
+ const key = `${projectSlug}:reminders`;
92
+ const script = `
93
+ tell application "Reminders"
94
+ set incompleteTasks to {}
95
+ repeat with r in (every reminder whose completed is false)
96
+ set end of incompleteTasks to name of r
97
+ end repeat
98
+ return incompleteTasks as text
99
+ end tell
100
+ `;
101
+ try {
102
+ const result = execSync(`osascript -e '${script.replace(/'/g, "'\\''")}'`, {
103
+ encoding: "utf-8",
104
+ timeout: 10_000,
105
+ }).trim();
106
+ if (result && result !== this.lastChecked.get(key + ":data")) {
107
+ this.lastChecked.set(key + ":data", result);
108
+ const event = {
109
+ type: "macos.reminders.update",
110
+ projectSlug,
111
+ source: "macos",
112
+ data: { reminders: result, service: "reminders" },
113
+ timestamp: new Date().toISOString(),
114
+ };
115
+ this.bus.publish(event);
116
+ }
117
+ }
118
+ catch {
119
+ // Reminders might not be accessible
120
+ }
121
+ }
122
+ }
123
+ //# sourceMappingURL=macos-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"macos-source.js","sourceRoot":"","sources":["../../../src/events/sources/macos-source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { EventBus } from "../event-bus.js";
2
+ export interface PollingConfig {
3
+ projectSlug: string;
4
+ /** Unique identifier for this poll */
5
+ name: string;
6
+ /** Polling interval in milliseconds */
7
+ intervalMs: number;
8
+ /** Event type to emit */
9
+ eventType: string;
10
+ }
11
+ export type PollChecker = () => Promise<Record<string, unknown> | null>;
12
+ export declare class PollingSource {
13
+ private bus;
14
+ private timers;
15
+ private polls;
16
+ constructor(bus: EventBus);
17
+ /** Register a polling check */
18
+ addPoll(config: PollingConfig, checker: PollChecker): void;
19
+ start(): Promise<void>;
20
+ stop(): Promise<void>;
21
+ private runPoll;
22
+ }
23
+ //# sourceMappingURL=polling-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polling-source.d.ts","sourceRoot":"","sources":["../../../src/events/sources/polling-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAqB,MAAM,iBAAiB,CAAC;AAM9D,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AAExE,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAW;IACtB,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,KAAK,CAA8D;gBAE/D,GAAG,EAAE,QAAQ;IAIzB,+BAA+B;IAC/B,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI;IAIpD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAOb,OAAO;CAiBtB"}
@@ -0,0 +1,47 @@
1
+ export class PollingSource {
2
+ bus;
3
+ timers = [];
4
+ polls = [];
5
+ constructor(bus) {
6
+ this.bus = bus;
7
+ }
8
+ /** Register a polling check */
9
+ addPoll(config, checker) {
10
+ this.polls.push({ config, checker });
11
+ }
12
+ async start() {
13
+ for (const { config, checker } of this.polls) {
14
+ // Run immediately on start
15
+ this.runPoll(config, checker);
16
+ // Then schedule recurring
17
+ const timer = setInterval(() => this.runPoll(config, checker), config.intervalMs);
18
+ this.timers.push(timer);
19
+ console.log(`[polling] ${config.name}: every ${config.intervalMs / 1000}s for ${config.projectSlug}`);
20
+ }
21
+ }
22
+ async stop() {
23
+ for (const timer of this.timers) {
24
+ clearInterval(timer);
25
+ }
26
+ this.timers = [];
27
+ }
28
+ async runPoll(config, checker) {
29
+ try {
30
+ const result = await checker();
31
+ if (result) {
32
+ const event = {
33
+ type: config.eventType,
34
+ projectSlug: config.projectSlug,
35
+ source: "polling",
36
+ data: { pollName: config.name, ...result },
37
+ timestamp: new Date().toISOString(),
38
+ };
39
+ this.bus.publish(event);
40
+ }
41
+ }
42
+ catch (err) {
43
+ console.warn(`[polling] ${config.name} failed: ${err.message}`);
44
+ }
45
+ }
46
+ }
47
+ //# sourceMappingURL=polling-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polling-source.js","sourceRoot":"","sources":["../../../src/events/sources/polling-source.ts"],"names":[],"mappings":"AAkBA,MAAM,OAAO,aAAa;IAChB,GAAG,CAAW;IACd,MAAM,GAAqB,EAAE,CAAC;IAC9B,KAAK,GAA2D,EAAE,CAAC;IAE3E,YAAY,GAAa;QACvB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED,+BAA+B;IAC/B,OAAO,CAAC,MAAqB,EAAE,OAAoB;QACjD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,KAAK;QACT,KAAK,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC7C,2BAA2B;YAC3B,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAE9B,0BAA0B;YAC1B,MAAM,KAAK,GAAG,WAAW,CACvB,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,MAAM,CAAC,UAAU,CAClB,CAAC;YACF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAExB,OAAO,CAAC,GAAG,CACT,aAAa,MAAM,CAAC,IAAI,WAAW,MAAM,CAAC,UAAU,GAAG,IAAI,SAAS,MAAM,CAAC,WAAW,EAAE,CACzF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,aAAa,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IACnB,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,MAAqB,EAAE,OAAoB;QAC/D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;YAC/B,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,KAAK,GAAiB;oBAC1B,IAAI,EAAE,MAAM,CAAC,SAAS;oBACtB,WAAW,EAAE,MAAM,CAAC,WAAW;oBAC/B,MAAM,EAAE,SAAS;oBACjB,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,MAAM,EAAE;oBAC1C,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACpC,CAAC;gBACF,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,aAAa,MAAM,CAAC,IAAI,YAAY,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,23 @@
1
+ import http from "http";
2
+ import { EventBus } from "../event-bus.js";
3
+ export interface WebhookSourceConfig {
4
+ port: number;
5
+ }
6
+ export declare class WebhookSource {
7
+ private server;
8
+ private bus;
9
+ private port;
10
+ private apiHandlers;
11
+ constructor(bus: EventBus, config?: WebhookSourceConfig);
12
+ /** Register a handler for REST API routes */
13
+ registerApiHandler(method: string, path: string, handler: (req: http.IncomingMessage, res: http.ServerResponse, params: Record<string, string>) => void): void;
14
+ start(): Promise<void>;
15
+ stop(): Promise<void>;
16
+ private handleRequest;
17
+ private handleEvent;
18
+ private readBody;
19
+ private json;
20
+ /** Simple route matcher: /api/projects/:slug → { slug: "value" } */
21
+ private matchRoute;
22
+ }
23
+ //# sourceMappingURL=webhook-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook-source.d.ts","sourceRoot":"","sources":["../../../src/events/sources/webhook-source.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAqB,MAAM,iBAAiB,CAAC;AAM9D,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,GAAG,CAAW;IACtB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,WAAW,CAAyH;gBAEhI,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAE,mBAAoC;IAKvE,6CAA6C;IAC7C,kBAAkB,CAChB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,GACrG,IAAI;IAID,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAUb,aAAa;YA+Cb,WAAW;IA2BzB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,IAAI;IAKZ,oEAAoE;IACpE,OAAO,CAAC,UAAU;CAgBnB"}