@plumbus/core 0.4.2 → 0.6.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 (324) hide show
  1. package/README.md +2 -1
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/ai/ai/cost-tracker.d.ts +93 -0
  4. package/dist/ai/ai/derive-ledger-usage.d.ts +10 -0
  5. package/dist/ai/ai/model-pricing.d.ts +51 -0
  6. package/dist/ai/ai/provider.d.ts +214 -0
  7. package/dist/ai/ai/refusal.d.ts +27 -0
  8. package/dist/ai/ai/usage-client.d.ts +30 -0
  9. package/dist/ai/ai-service.d.ts +1 -1
  10. package/dist/ai/ai-service.d.ts.map +1 -1
  11. package/dist/ai/ai-service.js +21 -16
  12. package/dist/ai/ai-service.js.map +1 -1
  13. package/dist/ai/cost-tracker.d.ts +17 -1
  14. package/dist/ai/cost-tracker.d.ts.map +1 -1
  15. package/dist/ai/cost-tracker.js +8 -6
  16. package/dist/ai/cost-tracker.js.map +1 -1
  17. package/dist/ai/derive-ledger-usage.d.ts +11 -0
  18. package/dist/ai/derive-ledger-usage.d.ts.map +1 -0
  19. package/dist/ai/derive-ledger-usage.js +36 -0
  20. package/dist/ai/derive-ledger-usage.js.map +1 -0
  21. package/dist/ai/index.d.ts +1 -0
  22. package/dist/ai/index.d.ts.map +1 -1
  23. package/dist/ai/index.js +1 -0
  24. package/dist/ai/index.js.map +1 -1
  25. package/dist/ai/types/config.d.ts +72 -0
  26. package/dist/ai/types/enums.d.ts +73 -0
  27. package/dist/api/route-generator.d.ts.map +1 -1
  28. package/dist/api/route-generator.js +27 -14
  29. package/dist/api/route-generator.js.map +1 -1
  30. package/dist/cli/cli.d.ts.map +1 -1
  31. package/dist/cli/cli.js +3 -1
  32. package/dist/cli/cli.js.map +1 -1
  33. package/dist/cli/commands/dev.d.ts.map +1 -1
  34. package/dist/cli/commands/dev.js +38 -149
  35. package/dist/cli/commands/dev.js.map +1 -1
  36. package/dist/cli/commands/doctor.d.ts +6 -0
  37. package/dist/cli/commands/doctor.d.ts.map +1 -1
  38. package/dist/cli/commands/doctor.js +92 -4
  39. package/dist/cli/commands/doctor.js.map +1 -1
  40. package/dist/cli/commands/event.d.ts.map +1 -1
  41. package/dist/cli/commands/event.js +3 -0
  42. package/dist/cli/commands/event.js.map +1 -1
  43. package/dist/cli/commands/events-ops.d.ts +4 -0
  44. package/dist/cli/commands/events-ops.d.ts.map +1 -0
  45. package/dist/cli/commands/events-ops.js +203 -0
  46. package/dist/cli/commands/events-ops.js.map +1 -0
  47. package/dist/cli/commands/flow-schedule-list.d.ts +31 -0
  48. package/dist/cli/commands/flow-schedule-list.d.ts.map +1 -0
  49. package/dist/cli/commands/flow-schedule-list.js +93 -0
  50. package/dist/cli/commands/flow-schedule-list.js.map +1 -0
  51. package/dist/cli/commands/flow.d.ts.map +1 -1
  52. package/dist/cli/commands/flow.js +75 -1
  53. package/dist/cli/commands/flow.js.map +1 -1
  54. package/dist/cli/commands/generate.d.ts +4 -0
  55. package/dist/cli/commands/generate.d.ts.map +1 -1
  56. package/dist/cli/commands/generate.js +94 -3
  57. package/dist/cli/commands/generate.js.map +1 -1
  58. package/dist/cli/commands/index.d.ts +2 -0
  59. package/dist/cli/commands/index.d.ts.map +1 -1
  60. package/dist/cli/commands/index.js +2 -0
  61. package/dist/cli/commands/index.js.map +1 -1
  62. package/dist/cli/commands/init.d.ts +1 -1
  63. package/dist/cli/commands/init.d.ts.map +1 -1
  64. package/dist/cli/commands/init.js +55 -4
  65. package/dist/cli/commands/init.js.map +1 -1
  66. package/dist/cli/commands/mcp.d.ts.map +1 -1
  67. package/dist/cli/commands/mcp.js +2 -0
  68. package/dist/cli/commands/mcp.js.map +1 -1
  69. package/dist/cli/commands/start.d.ts +3 -6
  70. package/dist/cli/commands/start.d.ts.map +1 -1
  71. package/dist/cli/commands/start.js +71 -180
  72. package/dist/cli/commands/start.js.map +1 -1
  73. package/dist/cli/commands/verify.d.ts +3 -1
  74. package/dist/cli/commands/verify.d.ts.map +1 -1
  75. package/dist/cli/commands/verify.js +17 -9
  76. package/dist/cli/commands/verify.js.map +1 -1
  77. package/dist/cli/commands/voice.d.ts +12 -0
  78. package/dist/cli/commands/voice.d.ts.map +1 -0
  79. package/dist/cli/commands/voice.js +109 -0
  80. package/dist/cli/commands/voice.js.map +1 -0
  81. package/dist/cli/commands/worker.d.ts +19 -0
  82. package/dist/cli/commands/worker.d.ts.map +1 -0
  83. package/dist/cli/commands/worker.js +234 -0
  84. package/dist/cli/commands/worker.js.map +1 -0
  85. package/dist/cli/mcp-serve-context.d.ts +3 -0
  86. package/dist/cli/mcp-serve-context.d.ts.map +1 -1
  87. package/dist/cli/mcp-serve-context.js +133 -111
  88. package/dist/cli/mcp-serve-context.js.map +1 -1
  89. package/dist/cli/templates/resources.d.ts.map +1 -1
  90. package/dist/cli/templates/resources.js +7 -2
  91. package/dist/cli/templates/resources.js.map +1 -1
  92. package/dist/cli/utils.d.ts +4 -0
  93. package/dist/cli/utils.d.ts.map +1 -1
  94. package/dist/cli/utils.js +9 -0
  95. package/dist/cli/utils.js.map +1 -1
  96. package/dist/cli/voice-agent-bootstrap.d.ts +22 -0
  97. package/dist/cli/voice-agent-bootstrap.d.ts.map +1 -0
  98. package/dist/cli/voice-agent-bootstrap.js +12 -0
  99. package/dist/cli/voice-agent-bootstrap.js.map +1 -0
  100. package/dist/cli/voice-serve-context.d.ts +7 -0
  101. package/dist/cli/voice-serve-context.d.ts.map +1 -0
  102. package/dist/cli/voice-serve-context.js +26 -0
  103. package/dist/cli/voice-serve-context.js.map +1 -0
  104. package/dist/data/drift-inspector.d.ts +2 -2
  105. package/dist/data/drift-inspector.d.ts.map +1 -1
  106. package/dist/data/drift-inspector.js +2 -1
  107. package/dist/data/drift-inspector.js.map +1 -1
  108. package/dist/data/migration.d.ts.map +1 -1
  109. package/dist/data/migration.js +2 -0
  110. package/dist/data/migration.js.map +1 -1
  111. package/dist/define/defineCapability.d.ts +5 -0
  112. package/dist/define/defineCapability.d.ts.map +1 -1
  113. package/dist/define/defineCapability.js +23 -0
  114. package/dist/define/defineCapability.js.map +1 -1
  115. package/dist/errors/http.d.ts.map +1 -1
  116. package/dist/errors/http.js +1 -0
  117. package/dist/errors/http.js.map +1 -1
  118. package/dist/errors/index.d.ts.map +1 -1
  119. package/dist/errors/index.js +1 -0
  120. package/dist/errors/index.js.map +1 -1
  121. package/dist/events/dispatcher.d.ts +4 -0
  122. package/dist/events/dispatcher.d.ts.map +1 -1
  123. package/dist/events/dispatcher.js +24 -1
  124. package/dist/events/dispatcher.js.map +1 -1
  125. package/dist/events/emitter.d.ts +2 -0
  126. package/dist/events/emitter.d.ts.map +1 -1
  127. package/dist/events/emitter.js +6 -3
  128. package/dist/events/emitter.js.map +1 -1
  129. package/dist/events/queue-adapter.d.ts +7 -0
  130. package/dist/events/queue-adapter.d.ts.map +1 -0
  131. package/dist/events/queue-adapter.js +4 -0
  132. package/dist/events/queue-adapter.js.map +1 -0
  133. package/dist/events/queue.d.ts +16 -13
  134. package/dist/events/queue.d.ts.map +1 -1
  135. package/dist/events/queue.js +79 -22
  136. package/dist/events/queue.js.map +1 -1
  137. package/dist/events/worker.d.ts +4 -0
  138. package/dist/events/worker.d.ts.map +1 -1
  139. package/dist/events/worker.js +47 -1
  140. package/dist/events/worker.js.map +1 -1
  141. package/dist/execution/canonical-name.d.ts +13 -0
  142. package/dist/execution/canonical-name.d.ts.map +1 -0
  143. package/dist/execution/canonical-name.js +17 -0
  144. package/dist/execution/canonical-name.js.map +1 -0
  145. package/dist/execution/capability-executor.d.ts +1 -1
  146. package/dist/execution/capability-executor.d.ts.map +1 -1
  147. package/dist/execution/capability-executor.js +52 -24
  148. package/dist/execution/capability-executor.js.map +1 -1
  149. package/dist/execution/capability-invocation.d.ts +34 -0
  150. package/dist/execution/capability-invocation.d.ts.map +1 -0
  151. package/dist/execution/capability-invocation.js +138 -0
  152. package/dist/execution/capability-invocation.js.map +1 -0
  153. package/dist/execution/capability-registry.d.ts +6 -4
  154. package/dist/execution/capability-registry.d.ts.map +1 -1
  155. package/dist/execution/capability-registry.js +13 -7
  156. package/dist/execution/capability-registry.js.map +1 -1
  157. package/dist/execution/context-factory.d.ts.map +1 -1
  158. package/dist/execution/context-factory.js +18 -1
  159. package/dist/execution/context-factory.js.map +1 -1
  160. package/dist/execution/index.d.ts +4 -0
  161. package/dist/execution/index.d.ts.map +1 -1
  162. package/dist/execution/index.js +2 -0
  163. package/dist/execution/index.js.map +1 -1
  164. package/dist/execution/invocation-emit-scope.d.ts +11 -0
  165. package/dist/execution/invocation-emit-scope.d.ts.map +1 -0
  166. package/dist/execution/invocation-emit-scope.js +8 -0
  167. package/dist/execution/invocation-emit-scope.js.map +1 -0
  168. package/dist/flows/engine.d.ts +7 -1
  169. package/dist/flows/engine.d.ts.map +1 -1
  170. package/dist/flows/engine.js +75 -10
  171. package/dist/flows/engine.js.map +1 -1
  172. package/dist/flows/flow-delayed.d.ts +34 -0
  173. package/dist/flows/flow-delayed.d.ts.map +1 -0
  174. package/dist/flows/flow-delayed.js +60 -0
  175. package/dist/flows/flow-delayed.js.map +1 -0
  176. package/dist/flows/flow-queue.d.ts +10 -0
  177. package/dist/flows/flow-queue.d.ts.map +1 -0
  178. package/dist/flows/flow-queue.js +25 -0
  179. package/dist/flows/flow-queue.js.map +1 -0
  180. package/dist/flows/scheduler.d.ts +0 -12
  181. package/dist/flows/scheduler.d.ts.map +1 -1
  182. package/dist/flows/scheduler.js +15 -0
  183. package/dist/flows/scheduler.js.map +1 -1
  184. package/dist/flows/schema.d.ts +17 -0
  185. package/dist/flows/schema.d.ts.map +1 -1
  186. package/dist/flows/schema.js +2 -0
  187. package/dist/flows/schema.js.map +1 -1
  188. package/dist/flows/step-consumer.d.ts +24 -0
  189. package/dist/flows/step-consumer.d.ts.map +1 -0
  190. package/dist/flows/step-consumer.js +72 -0
  191. package/dist/flows/step-consumer.js.map +1 -0
  192. package/dist/flows/triggers.d.ts +1 -1
  193. package/dist/flows/triggers.d.ts.map +1 -1
  194. package/dist/flows/triggers.js +5 -7
  195. package/dist/flows/triggers.js.map +1 -1
  196. package/dist/governance/capability-source-scan.d.ts +7 -0
  197. package/dist/governance/capability-source-scan.d.ts.map +1 -0
  198. package/dist/governance/capability-source-scan.js +80 -0
  199. package/dist/governance/capability-source-scan.js.map +1 -0
  200. package/dist/governance/rules/architecture.d.ts.map +1 -1
  201. package/dist/governance/rules/architecture.js +2 -0
  202. package/dist/governance/rules/architecture.js.map +1 -1
  203. package/dist/governance/rules/capability-dependencies.d.ts +8 -0
  204. package/dist/governance/rules/capability-dependencies.d.ts.map +1 -0
  205. package/dist/governance/rules/capability-dependencies.js +195 -0
  206. package/dist/governance/rules/capability-dependencies.js.map +1 -0
  207. package/dist/governance/rules/index.d.ts +2 -0
  208. package/dist/governance/rules/index.d.ts.map +1 -1
  209. package/dist/governance/rules/index.js +2 -0
  210. package/dist/governance/rules/index.js.map +1 -1
  211. package/dist/governance/rules/worker.d.ts +9 -0
  212. package/dist/governance/rules/worker.d.ts.map +1 -0
  213. package/dist/governance/rules/worker.js +89 -0
  214. package/dist/governance/rules/worker.js.map +1 -0
  215. package/dist/index.d.ts +8 -3
  216. package/dist/index.d.ts.map +1 -1
  217. package/dist/index.js +4 -2
  218. package/dist/index.js.map +1 -1
  219. package/dist/jobs/dispatch.d.ts +18 -0
  220. package/dist/jobs/dispatch.d.ts.map +1 -0
  221. package/dist/jobs/dispatch.js +50 -0
  222. package/dist/jobs/dispatch.js.map +1 -0
  223. package/dist/jobs/index.d.ts +9 -0
  224. package/dist/jobs/index.d.ts.map +1 -0
  225. package/dist/jobs/index.js +8 -0
  226. package/dist/jobs/index.js.map +1 -0
  227. package/dist/jobs/routes.d.ts +10 -0
  228. package/dist/jobs/routes.d.ts.map +1 -0
  229. package/dist/jobs/routes.js +44 -0
  230. package/dist/jobs/routes.js.map +1 -0
  231. package/dist/jobs/schema.d.ts +264 -0
  232. package/dist/jobs/schema.d.ts.map +1 -0
  233. package/dist/jobs/schema.js +34 -0
  234. package/dist/jobs/schema.js.map +1 -0
  235. package/dist/jobs/service.d.ts +52 -0
  236. package/dist/jobs/service.d.ts.map +1 -0
  237. package/dist/jobs/service.js +168 -0
  238. package/dist/jobs/service.js.map +1 -0
  239. package/dist/jobs/types.d.ts +30 -0
  240. package/dist/jobs/types.d.ts.map +1 -0
  241. package/dist/jobs/types.js +4 -0
  242. package/dist/jobs/types.js.map +1 -0
  243. package/dist/mcp/manifest-generator.d.ts.map +1 -1
  244. package/dist/mcp/manifest-generator.js +3 -2
  245. package/dist/mcp/manifest-generator.js.map +1 -1
  246. package/dist/observability/metrics.d.ts +9 -1
  247. package/dist/observability/metrics.d.ts.map +1 -1
  248. package/dist/observability/metrics.js +28 -1
  249. package/dist/observability/metrics.js.map +1 -1
  250. package/dist/runtime/bootstrap.d.ts +51 -0
  251. package/dist/runtime/bootstrap.d.ts.map +1 -0
  252. package/dist/runtime/bootstrap.js +140 -0
  253. package/dist/runtime/bootstrap.js.map +1 -0
  254. package/dist/runtime/index.d.ts +7 -0
  255. package/dist/runtime/index.d.ts.map +1 -0
  256. package/dist/runtime/index.js +6 -0
  257. package/dist/runtime/index.js.map +1 -0
  258. package/dist/runtime/load-extensions.d.ts +4 -0
  259. package/dist/runtime/load-extensions.d.ts.map +1 -0
  260. package/dist/runtime/load-extensions.js +41 -0
  261. package/dist/runtime/load-extensions.js.map +1 -0
  262. package/dist/runtime/queue-factory.d.ts +44 -0
  263. package/dist/runtime/queue-factory.d.ts.map +1 -0
  264. package/dist/runtime/queue-factory.js +156 -0
  265. package/dist/runtime/queue-factory.js.map +1 -0
  266. package/dist/runtime/register-consumers.d.ts +29 -0
  267. package/dist/runtime/register-consumers.d.ts.map +1 -0
  268. package/dist/runtime/register-consumers.js +233 -0
  269. package/dist/runtime/register-consumers.js.map +1 -0
  270. package/dist/runtime/start-worker-pool.d.ts +32 -0
  271. package/dist/runtime/start-worker-pool.d.ts.map +1 -0
  272. package/dist/runtime/start-worker-pool.js +91 -0
  273. package/dist/runtime/start-worker-pool.js.map +1 -0
  274. package/dist/runtime/worker-health.d.ts +19 -0
  275. package/dist/runtime/worker-health.d.ts.map +1 -0
  276. package/dist/runtime/worker-health.js +41 -0
  277. package/dist/runtime/worker-health.js.map +1 -0
  278. package/dist/server/bootstrap.d.ts +6 -0
  279. package/dist/server/bootstrap.d.ts.map +1 -1
  280. package/dist/server/bootstrap.js +24 -1
  281. package/dist/server/bootstrap.js.map +1 -1
  282. package/dist/testing/context.d.ts +3 -0
  283. package/dist/testing/context.d.ts.map +1 -1
  284. package/dist/testing/context.js +12 -0
  285. package/dist/testing/context.js.map +1 -1
  286. package/dist/testing/e2e.d.ts +6 -0
  287. package/dist/testing/e2e.d.ts.map +1 -1
  288. package/dist/testing/e2e.js +2 -0
  289. package/dist/testing/e2e.js.map +1 -1
  290. package/dist/testing/simulate-flow.d.ts.map +1 -1
  291. package/dist/testing/simulate-flow.js +10 -0
  292. package/dist/testing/simulate-flow.js.map +1 -1
  293. package/dist/types/capability.d.ts +8 -0
  294. package/dist/types/capability.d.ts.map +1 -1
  295. package/dist/types/capability.js.map +1 -1
  296. package/dist/types/config.d.ts +2 -0
  297. package/dist/types/config.d.ts.map +1 -1
  298. package/dist/types/context.d.ts +49 -1
  299. package/dist/types/context.d.ts.map +1 -1
  300. package/dist/types/enums.d.ts +1 -0
  301. package/dist/types/enums.d.ts.map +1 -1
  302. package/dist/types/enums.js +1 -0
  303. package/dist/types/enums.js.map +1 -1
  304. package/dist/types/errors.d.ts +1 -0
  305. package/dist/types/errors.d.ts.map +1 -1
  306. package/dist/types/event.d.ts +10 -0
  307. package/dist/types/event.d.ts.map +1 -1
  308. package/dist/types/event.js +5 -1
  309. package/dist/types/event.js.map +1 -1
  310. package/dist/worker/bootstrap.d.ts +32 -1
  311. package/dist/worker/bootstrap.d.ts.map +1 -1
  312. package/dist/worker/bootstrap.js +166 -2
  313. package/dist/worker/bootstrap.js.map +1 -1
  314. package/instructions/capabilities.md +36 -1
  315. package/instructions/deployment.md +96 -11
  316. package/instructions/events.md +11 -0
  317. package/instructions/flows.md +12 -4
  318. package/instructions/governance.md +6 -0
  319. package/instructions/mcp.md +1 -1
  320. package/instructions/patterns.md +1 -0
  321. package/instructions/security.md +9 -0
  322. package/instructions/testing.md +12 -1
  323. package/instructions/upgrading-0.5-capabilities.md +181 -0
  324. package/package.json +16 -4
@@ -0,0 +1,7 @@
1
+ import type { PlumbusConfig } from '../types/config.js';
2
+ import type { RuntimeQueues } from '../runtime/queue-factory.js';
3
+ /** Factory that creates runtime queue triplets for a deployment environment. */
4
+ export interface QueueAdapterFactory {
5
+ createQueues(config: PlumbusConfig): Promise<RuntimeQueues>;
6
+ }
7
+ //# sourceMappingURL=queue-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-adapter.d.ts","sourceRoot":"","sources":["../../src/events/queue-adapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,gFAAgF;AAChF,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CAC7D"}
@@ -0,0 +1,4 @@
1
+ // ── Queue Adapter Interface ──
2
+ // Pluggable factory for durable queue backends (Redis v1; SQS/Kafka later).
3
+ export {};
4
+ //# sourceMappingURL=queue-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-adapter.js","sourceRoot":"","sources":["../../src/events/queue-adapter.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,4EAA4E"}
@@ -40,19 +40,22 @@ export interface RedisClient {
40
40
  rpoplpush?(source: string, destination: string): Promise<string | null>;
41
41
  lrem(key: string, count: number, value: string): Promise<number>;
42
42
  lrange(key: string, start: number, stop: number): Promise<string[]>;
43
+ llen?(key: string): Promise<number>;
44
+ zadd?(key: string, score: number, member: string): Promise<number>;
45
+ zrangebyscore?(key: string, min: number, max: number, options?: {
46
+ limit?: number;
47
+ }): Promise<string[]>;
48
+ zrem?(key: string, member: string): Promise<number>;
49
+ ping?(): Promise<string>;
50
+ eval?(script: string, options: {
51
+ keys: string[];
52
+ arguments: string[];
53
+ }): Promise<unknown>;
43
54
  quit(): Promise<unknown>;
44
55
  }
45
- /**
46
- * Create a Redis-backed event queue.
47
- *
48
- * Uses a simple list-based pattern:
49
- * - Publish: LPUSH events to the queue list
50
- * - Subscribe: Poll with RPOPLPUSH to a processing list
51
- * - Ack: LREM from processing list after successful handling
52
- *
53
- * This provides at-least-once delivery with crash recovery:
54
- * if the consumer crashes, unacknowledged events remain in the
55
- * processing list and can be recovered.
56
- */
57
- export declare function createRedisQueue(client: RedisClient, config?: Partial<RedisQueueConfig>): EventQueue;
56
+ export interface RedisQueueOptions extends Partial<RedisQueueConfig> {
57
+ /** When false, close() does not quit the shared Redis client (default: true). */
58
+ ownsClient?: boolean;
59
+ }
60
+ export declare function createRedisQueue(client: RedisClient, config?: RedisQueueOptions): EventQueue;
58
61
  //# sourceMappingURL=queue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/events/queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,iDAAiD;IACjD,OAAO,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,qEAAqE;IACrE,SAAS,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC;IAC3E,4CAA4C;IAC5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,UAAU,CA+BhD;AAOD,MAAM,WAAW,gBAAgB;IAC/B,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+FAA+F;IAC/F,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,8EAA8E;AAC9E,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzD,UAAU,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC1F,SAAS,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACxE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjE,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACpE,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,WAAW,EACnB,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GACjC,UAAU,CAwFZ"}
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/events/queue.ts"],"names":[],"mappings":"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"}
@@ -34,45 +34,100 @@ export function createInMemoryQueue() {
34
34
  },
35
35
  };
36
36
  }
37
- /**
38
- * Create a Redis-backed event queue.
39
- *
40
- * Uses a simple list-based pattern:
41
- * - Publish: LPUSH events to the queue list
42
- * - Subscribe: Poll with RPOPLPUSH to a processing list
43
- * - Ack: LREM from processing list after successful handling
44
- *
45
- * This provides at-least-once delivery with crash recovery:
46
- * if the consumer crashes, unacknowledged events remain in the
47
- * processing list and can be recovered.
48
- */
37
+ function parseProcessingEntry(raw) {
38
+ try {
39
+ const parsed = JSON.parse(raw);
40
+ if (typeof parsed.envelope === 'string' && typeof parsed.dequeuedAt === 'number') {
41
+ return { raw, dequeuedAt: parsed.dequeuedAt };
42
+ }
43
+ }
44
+ catch {
45
+ /* legacy plain envelope payload */
46
+ }
47
+ return { raw, dequeuedAt: 0 };
48
+ }
49
+ function wrapForProcessing(envelopeJson) {
50
+ return JSON.stringify({ envelope: envelopeJson, dequeuedAt: Date.now() });
51
+ }
52
+ function unwrapEnvelope(raw) {
53
+ try {
54
+ const parsed = JSON.parse(raw);
55
+ if (typeof parsed.envelope === 'string') {
56
+ return parsed.envelope;
57
+ }
58
+ }
59
+ catch {
60
+ /* legacy */
61
+ }
62
+ return raw;
63
+ }
49
64
  export function createRedisQueue(client, config) {
50
65
  const prefix = config?.prefix ?? 'plumbus:events';
51
66
  const pollIntervalMs = config?.pollIntervalMs ?? 1000;
67
+ const visibilityTimeoutMs = (config?.visibilityTimeoutSec ?? 30) * 1000;
68
+ const ownsClient = config?.ownsClient ?? true;
52
69
  const queueKey = `${prefix}:pending`;
53
70
  const processingKey = `${prefix}:processing`;
71
+ const REWRAP_SCRIPT = `
72
+ local raw = redis.call('RPOPLPUSH', KEYS[1], KEYS[2])
73
+ if not raw then return nil end
74
+ local wrapped = cjson.encode({ envelope = raw, dequeuedAt = tonumber(ARGV[1]) })
75
+ redis.call('LREM', KEYS[2], 1, raw)
76
+ redis.call('LPUSH', KEYS[2], wrapped)
77
+ return wrapped
78
+ `;
79
+ async function dequeueWrapped() {
80
+ if (client.eval) {
81
+ const result = await client.eval(REWRAP_SCRIPT, {
82
+ keys: [queueKey, processingKey],
83
+ arguments: [String(Date.now())],
84
+ });
85
+ return typeof result === 'string' ? result : null;
86
+ }
87
+ let raw = null;
88
+ if (client.rpoplpush) {
89
+ raw = await client.rpoplpush(queueKey, processingKey);
90
+ }
91
+ else if (client.brpoplpush) {
92
+ raw = await client.brpoplpush(queueKey, processingKey, 0);
93
+ }
94
+ if (!raw)
95
+ return null;
96
+ const wrapped = wrapForProcessing(raw);
97
+ await client.lrem(processingKey, 1, raw);
98
+ await client.lpush(processingKey, wrapped);
99
+ return wrapped;
100
+ }
54
101
  const subscribers = [];
55
102
  let closed = false;
56
103
  let pollTimer = null;
57
104
  let polling = false;
105
+ async function recoverStaleProcessing() {
106
+ const processing = await client.lrange(processingKey, 0, -1);
107
+ const now = Date.now();
108
+ for (const entry of processing) {
109
+ const { raw, dequeuedAt } = parseProcessingEntry(entry);
110
+ const isLegacy = dequeuedAt === 0;
111
+ const isStale = isLegacy || (dequeuedAt > 0 && now - dequeuedAt >= visibilityTimeoutMs);
112
+ if (isStale) {
113
+ await client.lrem(processingKey, 1, raw);
114
+ await client.lpush(queueKey, unwrapEnvelope(raw));
115
+ }
116
+ }
117
+ }
58
118
  async function pollOnce() {
59
119
  if (closed || polling || subscribers.length === 0)
60
120
  return;
61
121
  polling = true;
62
122
  try {
63
- // Move one item from pending to processing atomically
64
- let raw = null;
65
- if (client.rpoplpush) {
66
- raw = await client.rpoplpush(queueKey, processingKey);
67
- }
68
- else if (client.brpoplpush) {
69
- raw = await client.brpoplpush(queueKey, processingKey, 0);
70
- }
123
+ await recoverStaleProcessing();
124
+ const raw = await dequeueWrapped();
71
125
  if (!raw) {
72
126
  polling = false;
73
127
  return;
74
128
  }
75
- const envelope = JSON.parse(raw);
129
+ const envelopeJson = unwrapEnvelope(raw);
130
+ const envelope = JSON.parse(envelopeJson);
76
131
  // Restore Date object
77
132
  if (typeof envelope.occurredAt === 'string') {
78
133
  envelope.occurredAt = new Date(envelope.occurredAt);
@@ -128,7 +183,9 @@ export function createRedisQueue(client, config) {
128
183
  pollTimer = null;
129
184
  }
130
185
  subscribers.length = 0;
131
- await client.quit();
186
+ if (ownsClient) {
187
+ await client.quit();
188
+ }
132
189
  },
133
190
  };
134
191
  }
@@ -1 +1 @@
1
- {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/events/queue.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/events/queue.ts"],"names":[],"mappings":"AAgBA;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,WAAW,GAAsD,EAAE,CAAC;IAC1E,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,MAAM,OAAO,GAAoB,EAAE,CAAC;IAEpC,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,QAAuB;YACnC,IAAI,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAC/C,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,CAAC;gBAClC,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;oBACrC,uCAAuC;gBACzC,CAAC,CAAC,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,SAAS,CAAC,OAAmD;YAC3D,IAAI,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAC/C,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC1B,OAAO,GAAG,EAAE;gBACV,MAAM,GAAG,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBACzC,IAAI,GAAG,KAAK,CAAC,CAAC;oBAAE,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAC7C,CAAC,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,KAAK;YACT,MAAM,GAAG,IAAI,CAAC;YACd,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAClC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;QACzB,CAAC;KACF,CAAC;AACJ,CAAC;AAmED,SAAS,oBAAoB,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA+C,CAAC;QAC7E,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;YACjF,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC;QAChD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,mCAAmC;IACrC,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;AAChC,CAAC;AAED,SAAS,iBAAiB,CAAC,YAAoB;IAC7C,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IACjC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA0B,CAAC;QACxD,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACxC,OAAO,MAAM,CAAC,QAAQ,CAAC;QACzB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAmB,EAAE,MAA0B;IAC9E,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,IAAI,gBAAgB,CAAC;IAClD,MAAM,cAAc,GAAG,MAAM,EAAE,cAAc,IAAI,IAAI,CAAC;IACtD,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,oBAAoB,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACxE,MAAM,UAAU,GAAG,MAAM,EAAE,UAAU,IAAI,IAAI,CAAC;IAC9C,MAAM,QAAQ,GAAG,GAAG,MAAM,UAAU,CAAC;IACrC,MAAM,aAAa,GAAG,GAAG,MAAM,aAAa,CAAC;IAE7C,MAAM,aAAa,GAAG;;;;;;;CAOvB,CAAC;IAEA,KAAK,UAAU,cAAc;QAC3B,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE;gBAC9C,IAAI,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC;gBAC/B,SAAS,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;aAChC,CAAC,CAAC;YACH,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;QACpD,CAAC;QAED,IAAI,GAAG,GAAkB,IAAI,CAAC;QAC9B,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACrB,GAAG,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QACxD,CAAC;aAAM,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YAC7B,GAAG,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;QAC5D,CAAC;QACD,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QAEtB,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACvC,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QACzC,MAAM,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAC3C,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,WAAW,GAAsD,EAAE,CAAC;IAC1E,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,SAAS,GAA0C,IAAI,CAAC;IAC5D,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,KAAK,UAAU,sBAAsB;QACnC,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YAC/B,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;YACxD,MAAM,QAAQ,GAAG,UAAU,KAAK,CAAC,CAAC;YAClC,MAAM,OAAO,GAAG,QAAQ,IAAI,CAAC,UAAU,GAAG,CAAC,IAAI,GAAG,GAAG,UAAU,IAAI,mBAAmB,CAAC,CAAC;YACxF,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;gBACzC,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,UAAU,QAAQ;QACrB,IAAI,MAAM,IAAI,OAAO,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAC1D,OAAO,GAAG,IAAI,CAAC;QAEf,IAAI,CAAC;YACH,MAAM,sBAAsB,EAAE,CAAC;YAE/B,MAAM,GAAG,GAAG,MAAM,cAAc,EAAE,CAAC;YACnC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,OAAO,GAAG,KAAK,CAAC;gBAChB,OAAO;YACT,CAAC;YAED,MAAM,YAAY,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;YACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAkB,CAAC;YAC3D,sBAAsB;YACtB,IAAI,OAAO,QAAQ,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;gBAC5C,QAAQ,CAAC,UAAU,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YACtD,CAAC;YAED,6BAA6B;YAC7B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAE1F,gEAAgE;YAChE,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC;YACjE,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,oDAAoD;QACtD,CAAC;gBAAS,CAAC;YACT,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;IACH,CAAC;IAED,SAAS,YAAY;QACnB,IAAI,SAAS;YAAE,OAAO;QACtB,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;YAC3B,KAAK,QAAQ,EAAE,CAAC;QAClB,CAAC,EAAE,cAAc,CAAC,CAAC;IACrB,CAAC;IAED,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,QAAuB;YACnC,IAAI,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC3C,CAAC;QAED,SAAS,CAAC,OAAmD;YAC3D,IAAI,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAC/C,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC1B,YAAY,EAAE,CAAC;YACf,OAAO,GAAG,EAAE;gBACV,MAAM,GAAG,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBACzC,IAAI,GAAG,KAAK,CAAC,CAAC;oBAAE,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBAC3C,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,EAAE,CAAC;oBAC1C,aAAa,CAAC,SAAS,CAAC,CAAC;oBACzB,SAAS,GAAG,IAAI,CAAC;gBACnB,CAAC;YACH,CAAC,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,KAAK;YACT,MAAM,GAAG,IAAI,CAAC;YACd,IAAI,SAAS,EAAE,CAAC;gBACd,aAAa,CAAC,SAAS,CAAC,CAAC;gBACzB,SAAS,GAAG,IAAI,CAAC;YACnB,CAAC;YACD,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;YACvB,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YACtB,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,4 +1,6 @@
1
1
  import type { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
2
+ import type { PlumbusMetrics } from '../observability/metrics.js';
3
+ import type { AuditService } from '../types/audit.js';
2
4
  import type { EventEnvelope } from '../types/event.js';
3
5
  import type { ConsumerRegistry } from './consumer-registry.js';
4
6
  import type { IdempotencyService } from './idempotency.js';
@@ -8,6 +10,8 @@ export interface WorkerConfig {
8
10
  queue: EventQueue;
9
11
  consumers: ConsumerRegistry;
10
12
  idempotency: IdempotencyService;
13
+ audit?: AuditService;
14
+ metrics?: PlumbusMetrics;
11
15
  /** Default max retries per consumer (default: 3) */
12
16
  defaultMaxRetries?: number;
13
17
  /** Base delay in ms for exponential backoff between retries (default: 100) */
@@ -1 +1 @@
1
- {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/events/worker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,kBAAkB,CAAC;IACvB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,WAAW,EAAE,kBAAkB,CAAC;IAChC,oDAAoD;IACpD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8EAA8E;IAC9E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,8CAA8C;IAC9C,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY;IA0ElD,qDAAqD;wBAlDtB,aAAa,KAAG,OAAO,CAAC,IAAI,CAAC;IAqD5D,qCAAqC;aAC5B,IAAI;IAKb,sBAAsB;YACd,IAAI;wBAOK,OAAO;EAI3B"}
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/events/worker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,kBAAkB,CAAC;IACvB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,WAAW,EAAE,kBAAkB,CAAC;IAChC,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,oDAAoD;IACpD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8EAA8E;IAC9E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,8CAA8C;IAC9C,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY;IA0HlD,qDAAqD;wBAhGtB,aAAa,KAAG,OAAO,CAAC,IAAI,CAAC;IAmG5D,qCAAqC;aAC5B,IAAI;IAKb,sBAAsB;YACd,IAAI;wBAOK,OAAO;EAI3B"}
@@ -1,3 +1,4 @@
1
+ import { createJobService } from '../jobs/service.js';
1
2
  import { deadLetterTable } from './outbox.js';
2
3
  /**
3
4
  * Creates an event delivery worker that subscribes to the queue,
@@ -7,7 +8,7 @@ import { deadLetterTable } from './outbox.js';
7
8
  * Returns start/stop controls.
8
9
  */
9
10
  export function createEventWorker(config) {
10
- const { db, queue, consumers, idempotency, defaultMaxRetries = 3, retryBackoffBaseMs = 100, retryBackoffMaxMs = 5000, } = config;
11
+ const { db, queue, consumers, idempotency, defaultMaxRetries = 3, metrics, audit, retryBackoffBaseMs = 100, retryBackoffMaxMs = 5000, } = config;
11
12
  let unsubscribe = null;
12
13
  /** Compute exponential backoff with jitter */
13
14
  function computeRetryDelay(attempt) {
@@ -20,6 +21,7 @@ export function createEventWorker(config) {
20
21
  }
21
22
  async function deliver(envelope) {
22
23
  const matched = consumers.getConsumers(envelope.eventType, envelope.version);
24
+ const deliveryStarted = Date.now();
23
25
  for (const consumer of matched) {
24
26
  const maxRetries = consumer.maxRetries ?? defaultMaxRetries;
25
27
  // Idempotency guard
@@ -32,6 +34,14 @@ export function createEventWorker(config) {
32
34
  while (attempt < maxRetries && !succeeded) {
33
35
  attempt++;
34
36
  try {
37
+ await audit?.record('event.consumer.attempt', {
38
+ eventId: envelope.id,
39
+ eventType: envelope.eventType,
40
+ consumerId: consumer.id,
41
+ attempt,
42
+ tenantId: envelope.tenantId,
43
+ outcome: 'pending',
44
+ });
35
45
  await consumer.handler(envelope);
36
46
  succeeded = true;
37
47
  }
@@ -44,8 +54,34 @@ export function createEventWorker(config) {
44
54
  }
45
55
  if (succeeded) {
46
56
  await idempotency.markProcessed(envelope.id, consumer.id);
57
+ metrics?.eventDelivered.inc({ consumer: consumer.id });
58
+ metrics?.eventDeliveryDuration.observe(Date.now() - deliveryStarted, {
59
+ consumer: consumer.id,
60
+ outcome: 'delivered',
61
+ });
62
+ await audit?.record('event.consumer.delivered', {
63
+ eventId: envelope.id,
64
+ eventType: envelope.eventType,
65
+ consumerId: consumer.id,
66
+ tenantId: envelope.tenantId,
67
+ outcome: 'success',
68
+ });
47
69
  }
48
70
  else {
71
+ metrics?.eventFailed.inc({ consumer: consumer.id });
72
+ metrics?.eventDeliveryDuration.observe(Date.now() - deliveryStarted, {
73
+ consumer: consumer.id,
74
+ outcome: 'failed',
75
+ });
76
+ await audit?.record('event.consumer.dead_lettered', {
77
+ eventId: envelope.id,
78
+ eventType: envelope.eventType,
79
+ consumerId: consumer.id,
80
+ tenantId: envelope.tenantId,
81
+ lastError,
82
+ attempts: attempt,
83
+ outcome: 'dead_lettered',
84
+ });
49
85
  // Dead-letter
50
86
  await db.insert(deadLetterTable).values({
51
87
  eventId: envelope.id,
@@ -61,6 +97,16 @@ export function createEventWorker(config) {
61
97
  tenantId: envelope.tenantId,
62
98
  },
63
99
  });
100
+ if (consumer.id.startsWith('job:')) {
101
+ const payload = envelope.payload;
102
+ if (payload.jobExecutionId) {
103
+ const jobs = createJobService(db);
104
+ await jobs.markDeadLettered(payload.jobExecutionId, {
105
+ code: 'delivery_exhausted',
106
+ message: lastError ?? 'Job delivery exhausted retries',
107
+ });
108
+ }
109
+ }
64
110
  }
65
111
  }
66
112
  }
@@ -1 +1 @@
1
- {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/events/worker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/events/worker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /** Minimal shape for deriving a registered capability name. */
2
+ export interface CanonicalCapabilityRef {
3
+ domain: string;
4
+ name: string;
5
+ }
6
+ /**
7
+ * Canonical registered capability name: `<domain>.<capabilityName>`.
8
+ * Used for registry lookup, effects.capabilities, flow steps, invoke, manifests, and audit.
9
+ */
10
+ export declare function getCanonicalCapabilityName(ref: CanonicalCapabilityRef): string;
11
+ /** True when `value` looks like a canonical capability name (contains a domain prefix). */
12
+ export declare function isCanonicalCapabilityName(value: string): boolean;
13
+ //# sourceMappingURL=canonical-name.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical-name.d.ts","sourceRoot":"","sources":["../../src/execution/canonical-name.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,sBAAsB,GAAG,MAAM,CAE9E;AAED,2FAA2F;AAC3F,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAOhE"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Canonical registered capability name: `<domain>.<capabilityName>`.
3
+ * Used for registry lookup, effects.capabilities, flow steps, invoke, manifests, and audit.
4
+ */
5
+ export function getCanonicalCapabilityName(ref) {
6
+ return `${ref.domain}.${ref.name}`;
7
+ }
8
+ /** True when `value` looks like a canonical capability name (contains a domain prefix). */
9
+ export function isCanonicalCapabilityName(value) {
10
+ const trimmed = value.trim();
11
+ if (!trimmed.includes('.')) {
12
+ return false;
13
+ }
14
+ const dot = trimmed.indexOf('.');
15
+ return dot > 0 && dot < trimmed.length - 1;
16
+ }
17
+ //# sourceMappingURL=canonical-name.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical-name.js","sourceRoot":"","sources":["../../src/execution/canonical-name.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CAAC,GAA2B;IACpE,OAAO,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;AACrC,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,yBAAyB,CAAC,KAAa;IACrD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,OAAO,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;AAC7C,CAAC"}
@@ -15,7 +15,7 @@ export type CapabilityResult<T = unknown> = ExecutionResult<T> | ExecutionFailur
15
15
  * Execute a capability through the full pipeline:
16
16
  * 1. Validate input
17
17
  * 2. Evaluate access policy
18
- * 3. Execute handler
18
+ * 3. Execute handler (with scoped ctx.capabilities)
19
19
  * 4. Validate output
20
20
  * 5. Record audit
21
21
  */
@@ -1 +1 @@
1
- {"version":3,"file":"capability-executor.d.ts","sourceRoot":"","sources":["../../src/execution/capability-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAG7B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG3D,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC1C,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,CAAC,CAAC;CACT;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,gBAAgB,CAAC;CACzB;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,GAAG,OAAO,IAAI,eAAe,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC;AAElF;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,SAAS,CAAC,CAAC,UAAU,EAAE,OAAO,SAAS,CAAC,CAAC,UAAU,EAC/F,UAAU,EAAE,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/C,GAAG,EAAE,gBAAgB,EACrB,QAAQ,EAAE,OAAO,GAChB,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAkG7C"}
1
+ {"version":3,"file":"capability-executor.d.ts","sourceRoot":"","sources":["../../src/execution/capability-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAG7B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAU3D,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC1C,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,CAAC,CAAC;CACT;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,gBAAgB,CAAC;CACzB;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,GAAG,OAAO,IAAI,eAAe,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC;AAElF;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,SAAS,CAAC,CAAC,UAAU,EAAE,OAAO,SAAS,CAAC,CAAC,UAAU,EAC/F,UAAU,EAAE,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/C,GAAG,EAAE,gBAAgB,EACrB,QAAQ,EAAE,OAAO,GAChB,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CA6H7C"}
@@ -1,23 +1,26 @@
1
1
  import { isProviderAPIError } from '../ai/provider.js';
2
2
  import { isPlumbusError } from '../errors/index.js';
3
3
  import { evaluateAccess } from './authorization.js';
4
+ import { getCanonicalCapabilityName } from './canonical-name.js';
5
+ import { createCapabilityInvokeService, createUnavailableCapabilityService, stripHandlerRuntime, } from './capability-invocation.js';
4
6
  /**
5
7
  * Execute a capability through the full pipeline:
6
8
  * 1. Validate input
7
9
  * 2. Evaluate access policy
8
- * 3. Execute handler
10
+ * 3. Execute handler (with scoped ctx.capabilities)
9
11
  * 4. Validate output
10
12
  * 5. Record audit
11
13
  */
12
14
  export async function executeCapability(capability, ctx, rawInput) {
15
+ const canonicalName = getCanonicalCapabilityName(capability);
13
16
  // 1. Validate input against schema
14
17
  const inputResult = capability.input.safeParse(rawInput);
15
18
  if (!inputResult.success) {
16
19
  const error = ctx.errors.validation('Invalid input', {
17
- capability: capability.name,
20
+ capability: canonicalName,
18
21
  issues: inputResult.error.issues,
19
22
  });
20
- await recordAudit(ctx, capability, 'failure', { error });
23
+ await recordAudit(ctx, capability, canonicalName, 'failure', { error });
21
24
  return { success: false, error };
22
25
  }
23
26
  const input = inputResult.data;
@@ -25,26 +28,42 @@ export async function executeCapability(capability, ctx, rawInput) {
25
28
  const authResult = evaluateAccess(capability.access, ctx.auth);
26
29
  if (!authResult.allowed) {
27
30
  const error = ctx.errors.forbidden(authResult.reason ?? 'Access denied', {
28
- capability: capability.name,
31
+ capability: canonicalName,
29
32
  });
30
- await recordAudit(ctx, capability, 'denied', { error });
33
+ await recordAudit(ctx, capability, canonicalName, 'denied', { error });
31
34
  return { success: false, error };
32
35
  }
33
- // 3. Execute handler
36
+ // 3. Execute handler with scoped capabilities service (invoker not exposed on __runtime)
37
+ const invoker = ctx.__runtime?.invokeCapability;
38
+ const resolveCapability = ctx.__runtime?.resolveCapability;
39
+ const emitScope = ctx.__runtime?.invocationEmitScope;
40
+ const invocationRuntime = invoker && resolveCapability
41
+ ? { invoker: invoker, resolveCapability, emitScope }
42
+ : undefined;
43
+ const handlerCtx = {
44
+ ...ctx,
45
+ capabilities: invocationRuntime
46
+ ? createCapabilityInvokeService(capability, ctx, invocationRuntime)
47
+ : createUnavailableCapabilityService(ctx),
48
+ __runtime: stripHandlerRuntime(ctx.__runtime),
49
+ };
50
+ if (emitScope) {
51
+ emitScope.executingCapability = canonicalName;
52
+ }
34
53
  let rawOutput;
35
54
  try {
36
- rawOutput = await capability.handler(ctx, input);
55
+ rawOutput = await capability.handler(handlerCtx, input);
37
56
  }
38
57
  catch (err) {
39
58
  // If the handler threw a PlumbusError, surface it directly
40
59
  if (isPlumbusError(err)) {
41
- await recordAudit(ctx, capability, 'failure', { error: err });
60
+ await recordAudit(ctx, capability, canonicalName, 'failure', { error: err });
42
61
  return { success: false, error: err };
43
62
  }
44
63
  if (isProviderAPIError(err) && err.retryable) {
45
64
  const statusCode = err.statusCode === 429 ? 503 : (err.statusCode ?? 503);
46
65
  const error = ctx.errors.internal('AI provider temporarily unavailable. Please try again in a moment.', {
47
- capability: capability.name,
66
+ capability: canonicalName,
48
67
  message: err.message,
49
68
  provider: err.providerName,
50
69
  retryAttempts: err.attempts,
@@ -52,13 +71,13 @@ export async function executeCapability(capability, ctx, rawInput) {
52
71
  upstreamStatusCode: err.statusCode,
53
72
  httpStatus: statusCode,
54
73
  });
55
- ctx.logger.error(`Capability "${capability.name}" failed due to transient AI provider error`, {
74
+ ctx.logger.error(`Capability "${canonicalName}" failed due to transient AI provider error`, {
56
75
  error: err.message,
57
76
  provider: err.providerName,
58
77
  upstreamStatusCode: err.statusCode,
59
78
  attempts: err.attempts,
60
79
  });
61
- await recordAudit(ctx, capability, 'failure', { error });
80
+ await recordAudit(ctx, capability, canonicalName, 'failure', { error });
62
81
  return { success: false, error };
63
82
  }
64
83
  const causeMessage = err instanceof Error && err.cause instanceof Error ? err.cause.message : undefined;
@@ -68,51 +87,60 @@ export async function executeCapability(capability, ctx, rawInput) {
68
87
  ? err.message
69
88
  : String(err);
70
89
  const error = ctx.errors.internal('Capability execution failed', {
71
- capability: capability.name,
90
+ capability: canonicalName,
72
91
  message: errorMessage,
73
92
  });
74
- ctx.logger.error(`Capability "${capability.name}" threw an error`, {
93
+ ctx.logger.error(`Capability "${canonicalName}" threw an error`, {
75
94
  error: errorMessage,
76
95
  });
77
- await recordAudit(ctx, capability, 'failure', { error });
96
+ await recordAudit(ctx, capability, canonicalName, 'failure', { error });
78
97
  return { success: false, error };
79
98
  }
99
+ finally {
100
+ if (emitScope) {
101
+ emitScope.executingCapability = undefined;
102
+ }
103
+ }
80
104
  // 4. Validate output against schema
81
105
  const outputResult = capability.output.safeParse(rawOutput);
82
106
  if (!outputResult.success) {
83
107
  const error = ctx.errors.internal('Invalid output from capability', {
84
- capability: capability.name,
108
+ capability: canonicalName,
85
109
  issues: outputResult.error.issues,
86
110
  });
87
- ctx.logger.error(`Capability "${capability.name}" returned invalid output`, {
111
+ ctx.logger.error(`Capability "${canonicalName}" returned invalid output`, {
88
112
  issues: outputResult.error.issues,
89
113
  });
90
- await recordAudit(ctx, capability, 'failure', { error });
114
+ await recordAudit(ctx, capability, canonicalName, 'failure', { error });
91
115
  return { success: false, error };
92
116
  }
93
117
  // 5. Record success audit
94
- await recordAudit(ctx, capability, 'success');
118
+ await recordAudit(ctx, capability, canonicalName, 'success');
95
119
  return { success: true, data: outputResult.data };
96
120
  }
97
- async function recordAudit(ctx, capability, outcome, metadata) {
98
- // Skip if audit is explicitly disabled for this capability
121
+ async function recordAudit(ctx, capability, canonicalName, outcome, metadata) {
99
122
  if (capability.audit?.enabled === false)
100
123
  return;
101
- const auditEvent = capability.audit?.event ?? `capability.${capability.name}`;
124
+ const auditEvent = capability.audit?.event ?? `capability.${canonicalName}`;
125
+ const stack = ctx.__runtime?.capabilityStack ?? [];
126
+ const caller = ctx.__runtime?.invocationCaller;
127
+ const correlationId = ctx.__runtime?.correlationId;
102
128
  try {
103
129
  await ctx.audit.record(auditEvent, {
104
- capability: capability.name,
130
+ capability: canonicalName,
105
131
  domain: capability.domain,
106
132
  kind: capability.kind,
107
133
  outcome,
108
134
  actor: ctx.auth.userId,
109
135
  tenantId: ctx.auth.tenantId,
136
+ ...(caller ? { caller } : {}),
137
+ ...(stack.length > 0 ? { capabilityStack: stack } : {}),
138
+ ...(correlationId ? { correlationId } : {}),
110
139
  ...metadata,
111
140
  });
112
141
  }
113
142
  catch {
114
- // Audit failures should not break capability execution
115
- ctx.logger.error(`Failed to record audit for capability "${capability.name}"`);
143
+ ctx.logger.error(`Failed to record audit for capability "${canonicalName}"`);
116
144
  }
117
145
  }
118
146
  //# sourceMappingURL=capability-executor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"capability-executor.js","sourceRoot":"","sources":["../../src/execution/capability-executor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"capability-executor.js","sourceRoot":"","sources":["../../src/execution/capability-executor.ts"],"names":[],"mappings":"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"}