@kilnai/runtime 0.1.1

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 (205) hide show
  1. package/dist/a2a/a2a-client.d.ts +6 -0
  2. package/dist/a2a/a2a-client.d.ts.map +1 -0
  3. package/dist/a2a/a2a-client.js +112 -0
  4. package/dist/a2a/a2a-client.js.map +1 -0
  5. package/dist/a2a/index.d.ts +2 -0
  6. package/dist/a2a/index.d.ts.map +1 -0
  7. package/dist/a2a/index.js +3 -0
  8. package/dist/a2a/index.js.map +1 -0
  9. package/dist/channels/api-channel.d.ts +43 -0
  10. package/dist/channels/api-channel.d.ts.map +1 -0
  11. package/dist/channels/api-channel.js +95 -0
  12. package/dist/channels/api-channel.js.map +1 -0
  13. package/dist/channels/channel-registry.d.ts +25 -0
  14. package/dist/channels/channel-registry.d.ts.map +1 -0
  15. package/dist/channels/channel-registry.js +49 -0
  16. package/dist/channels/channel-registry.js.map +1 -0
  17. package/dist/channels/channel-router.d.ts +43 -0
  18. package/dist/channels/channel-router.d.ts.map +1 -0
  19. package/dist/channels/channel-router.js +72 -0
  20. package/dist/channels/channel-router.js.map +1 -0
  21. package/dist/channels/cli-channel.d.ts +19 -0
  22. package/dist/channels/cli-channel.d.ts.map +1 -0
  23. package/dist/channels/cli-channel.js +37 -0
  24. package/dist/channels/cli-channel.js.map +1 -0
  25. package/dist/channels/event-bridge.d.ts +27 -0
  26. package/dist/channels/event-bridge.d.ts.map +1 -0
  27. package/dist/channels/event-bridge.js +83 -0
  28. package/dist/channels/event-bridge.js.map +1 -0
  29. package/dist/channels/index.d.ts +17 -0
  30. package/dist/channels/index.d.ts.map +1 -0
  31. package/dist/channels/index.js +12 -0
  32. package/dist/channels/index.js.map +1 -0
  33. package/dist/channels/message-formatter.d.ts +4 -0
  34. package/dist/channels/message-formatter.d.ts.map +1 -0
  35. package/dist/channels/message-formatter.js +32 -0
  36. package/dist/channels/message-formatter.js.map +1 -0
  37. package/dist/channels/slack-channel.d.ts +32 -0
  38. package/dist/channels/slack-channel.d.ts.map +1 -0
  39. package/dist/channels/slack-channel.js +71 -0
  40. package/dist/channels/slack-channel.js.map +1 -0
  41. package/dist/channels/types.d.ts +27 -0
  42. package/dist/channels/types.d.ts.map +1 -0
  43. package/dist/channels/types.js +12 -0
  44. package/dist/channels/types.js.map +1 -0
  45. package/dist/channels/web-channel.d.ts +37 -0
  46. package/dist/channels/web-channel.d.ts.map +1 -0
  47. package/dist/channels/web-channel.js +112 -0
  48. package/dist/channels/web-channel.js.map +1 -0
  49. package/dist/channels/whatsapp-api.d.ts +20 -0
  50. package/dist/channels/whatsapp-api.d.ts.map +1 -0
  51. package/dist/channels/whatsapp-api.js +44 -0
  52. package/dist/channels/whatsapp-api.js.map +1 -0
  53. package/dist/channels/whatsapp-channel.d.ts +32 -0
  54. package/dist/channels/whatsapp-channel.d.ts.map +1 -0
  55. package/dist/channels/whatsapp-channel.js +85 -0
  56. package/dist/channels/whatsapp-channel.js.map +1 -0
  57. package/dist/gateway/app-resolver.d.ts +11 -0
  58. package/dist/gateway/app-resolver.d.ts.map +1 -0
  59. package/dist/gateway/app-resolver.js +36 -0
  60. package/dist/gateway/app-resolver.js.map +1 -0
  61. package/dist/gateway/approval-registry.d.ts +19 -0
  62. package/dist/gateway/approval-registry.d.ts.map +1 -0
  63. package/dist/gateway/approval-registry.js +49 -0
  64. package/dist/gateway/approval-registry.js.map +1 -0
  65. package/dist/gateway/budget-middleware.d.ts +47 -0
  66. package/dist/gateway/budget-middleware.d.ts.map +1 -0
  67. package/dist/gateway/budget-middleware.js +88 -0
  68. package/dist/gateway/budget-middleware.js.map +1 -0
  69. package/dist/gateway/config-validator.d.ts +31 -0
  70. package/dist/gateway/config-validator.d.ts.map +1 -0
  71. package/dist/gateway/config-validator.js +68 -0
  72. package/dist/gateway/config-validator.js.map +1 -0
  73. package/dist/gateway/delegation-handler.d.ts +53 -0
  74. package/dist/gateway/delegation-handler.d.ts.map +1 -0
  75. package/dist/gateway/delegation-handler.js +257 -0
  76. package/dist/gateway/delegation-handler.js.map +1 -0
  77. package/dist/gateway/delegation-routes.d.ts +7 -0
  78. package/dist/gateway/delegation-routes.d.ts.map +1 -0
  79. package/dist/gateway/delegation-routes.js +48 -0
  80. package/dist/gateway/delegation-routes.js.map +1 -0
  81. package/dist/gateway/dev-inspector.d.ts +2 -0
  82. package/dist/gateway/dev-inspector.d.ts.map +1 -0
  83. package/dist/gateway/dev-inspector.js +355 -0
  84. package/dist/gateway/dev-inspector.js.map +1 -0
  85. package/dist/gateway/dev-orchestrator.d.ts +24 -0
  86. package/dist/gateway/dev-orchestrator.d.ts.map +1 -0
  87. package/dist/gateway/dev-orchestrator.js +71 -0
  88. package/dist/gateway/dev-orchestrator.js.map +1 -0
  89. package/dist/gateway/dev-routes-types.d.ts +39 -0
  90. package/dist/gateway/dev-routes-types.d.ts.map +1 -0
  91. package/dist/gateway/dev-routes-types.js +3 -0
  92. package/dist/gateway/dev-routes-types.js.map +1 -0
  93. package/dist/gateway/dev-routes.d.ts +53 -0
  94. package/dist/gateway/dev-routes.d.ts.map +1 -0
  95. package/dist/gateway/dev-routes.js +217 -0
  96. package/dist/gateway/dev-routes.js.map +1 -0
  97. package/dist/gateway/dev-token-store.d.ts +19 -0
  98. package/dist/gateway/dev-token-store.d.ts.map +1 -0
  99. package/dist/gateway/dev-token-store.js +40 -0
  100. package/dist/gateway/dev-token-store.js.map +1 -0
  101. package/dist/gateway/gateway-routes.d.ts +46 -0
  102. package/dist/gateway/gateway-routes.d.ts.map +1 -0
  103. package/dist/gateway/gateway-routes.js +143 -0
  104. package/dist/gateway/gateway-routes.js.map +1 -0
  105. package/dist/gateway/gateway-server.d.ts +25 -0
  106. package/dist/gateway/gateway-server.d.ts.map +1 -0
  107. package/dist/gateway/gateway-server.js +736 -0
  108. package/dist/gateway/gateway-server.js.map +1 -0
  109. package/dist/gateway/health-registry.d.ts +18 -0
  110. package/dist/gateway/health-registry.d.ts.map +1 -0
  111. package/dist/gateway/health-registry.js +40 -0
  112. package/dist/gateway/health-registry.js.map +1 -0
  113. package/dist/gateway/memory-routes.d.ts +12 -0
  114. package/dist/gateway/memory-routes.d.ts.map +1 -0
  115. package/dist/gateway/memory-routes.js +32 -0
  116. package/dist/gateway/memory-routes.js.map +1 -0
  117. package/dist/gateway/mode-b-routes.d.ts +14 -0
  118. package/dist/gateway/mode-b-routes.d.ts.map +1 -0
  119. package/dist/gateway/mode-b-routes.js +96 -0
  120. package/dist/gateway/mode-b-routes.js.map +1 -0
  121. package/dist/gateway/safety-middleware.d.ts +21 -0
  122. package/dist/gateway/safety-middleware.d.ts.map +1 -0
  123. package/dist/gateway/safety-middleware.js +175 -0
  124. package/dist/gateway/safety-middleware.js.map +1 -0
  125. package/dist/gateway/security-middleware.d.ts +12 -0
  126. package/dist/gateway/security-middleware.d.ts.map +1 -0
  127. package/dist/gateway/security-middleware.js +62 -0
  128. package/dist/gateway/security-middleware.js.map +1 -0
  129. package/dist/gateway/tenant-admin-routes.d.ts +15 -0
  130. package/dist/gateway/tenant-admin-routes.d.ts.map +1 -0
  131. package/dist/gateway/tenant-admin-routes.js +148 -0
  132. package/dist/gateway/tenant-admin-routes.js.map +1 -0
  133. package/dist/gateway/tenant-routes.d.ts +15 -0
  134. package/dist/gateway/tenant-routes.d.ts.map +1 -0
  135. package/dist/gateway/tenant-routes.js +107 -0
  136. package/dist/gateway/tenant-routes.js.map +1 -0
  137. package/dist/gateway/whatsapp-webhook-routes.d.ts +15 -0
  138. package/dist/gateway/whatsapp-webhook-routes.d.ts.map +1 -0
  139. package/dist/gateway/whatsapp-webhook-routes.js +217 -0
  140. package/dist/gateway/whatsapp-webhook-routes.js.map +1 -0
  141. package/dist/gateway/ws-routes.d.ts +19 -0
  142. package/dist/gateway/ws-routes.d.ts.map +1 -0
  143. package/dist/gateway/ws-routes.js +79 -0
  144. package/dist/gateway/ws-routes.js.map +1 -0
  145. package/dist/index.d.ts +64 -0
  146. package/dist/index.d.ts.map +1 -0
  147. package/dist/index.js +44 -0
  148. package/dist/index.js.map +1 -0
  149. package/dist/session/index.d.ts +6 -0
  150. package/dist/session/index.d.ts.map +1 -0
  151. package/dist/session/index.js +4 -0
  152. package/dist/session/index.js.map +1 -0
  153. package/dist/session/mode-b-orchestrator.d.ts +43 -0
  154. package/dist/session/mode-b-orchestrator.d.ts.map +1 -0
  155. package/dist/session/mode-b-orchestrator.js +224 -0
  156. package/dist/session/mode-b-orchestrator.js.map +1 -0
  157. package/dist/session/mode-b-session.d.ts +29 -0
  158. package/dist/session/mode-b-session.d.ts.map +1 -0
  159. package/dist/session/mode-b-session.js +50 -0
  160. package/dist/session/mode-b-session.js.map +1 -0
  161. package/dist/session/session-registry.d.ts +15 -0
  162. package/dist/session/session-registry.d.ts.map +1 -0
  163. package/dist/session/session-registry.js +60 -0
  164. package/dist/session/session-registry.js.map +1 -0
  165. package/dist/tenant/index.d.ts +3 -0
  166. package/dist/tenant/index.d.ts.map +1 -0
  167. package/dist/tenant/index.js +3 -0
  168. package/dist/tenant/index.js.map +1 -0
  169. package/dist/tenant/system-prompt-builder.d.ts +3 -0
  170. package/dist/tenant/system-prompt-builder.d.ts.map +1 -0
  171. package/dist/tenant/system-prompt-builder.js +76 -0
  172. package/dist/tenant/system-prompt-builder.js.map +1 -0
  173. package/dist/tenant/tenant-registry.d.ts +33 -0
  174. package/dist/tenant/tenant-registry.d.ts.map +1 -0
  175. package/dist/tenant/tenant-registry.js +156 -0
  176. package/dist/tenant/tenant-registry.js.map +1 -0
  177. package/dist/trigger/event-listener.d.ts +22 -0
  178. package/dist/trigger/event-listener.d.ts.map +1 -0
  179. package/dist/trigger/event-listener.js +64 -0
  180. package/dist/trigger/event-listener.js.map +1 -0
  181. package/dist/trigger/index.d.ts +10 -0
  182. package/dist/trigger/index.d.ts.map +1 -0
  183. package/dist/trigger/index.js +7 -0
  184. package/dist/trigger/index.js.map +1 -0
  185. package/dist/trigger/scheduler.d.ts +22 -0
  186. package/dist/trigger/scheduler.d.ts.map +1 -0
  187. package/dist/trigger/scheduler.js +77 -0
  188. package/dist/trigger/scheduler.js.map +1 -0
  189. package/dist/trigger/trigger-executor.d.ts +14 -0
  190. package/dist/trigger/trigger-executor.d.ts.map +1 -0
  191. package/dist/trigger/trigger-executor.js +47 -0
  192. package/dist/trigger/trigger-executor.js.map +1 -0
  193. package/dist/trigger/trigger-registry.d.ts +28 -0
  194. package/dist/trigger/trigger-registry.d.ts.map +1 -0
  195. package/dist/trigger/trigger-registry.js +118 -0
  196. package/dist/trigger/trigger-registry.js.map +1 -0
  197. package/dist/trigger/webhook-handler.d.ts +11 -0
  198. package/dist/trigger/webhook-handler.d.ts.map +1 -0
  199. package/dist/trigger/webhook-handler.js +71 -0
  200. package/dist/trigger/webhook-handler.js.map +1 -0
  201. package/dist/utils/hmac.d.ts +15 -0
  202. package/dist/utils/hmac.d.ts.map +1 -0
  203. package/dist/utils/hmac.js +27 -0
  204. package/dist/utils/hmac.js.map +1 -0
  205. package/package.json +53 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tenant/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACxG,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { TenantConfig } from "@kilnai/core";
2
+ export declare function buildTenantSystemPrompt(tenant: TenantConfig): string;
3
+ //# sourceMappingURL=system-prompt-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-prompt-builder.d.ts","sourceRoot":"","sources":["../../src/tenant/system-prompt-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CA6EpE"}
@@ -0,0 +1,76 @@
1
+ export function buildTenantSystemPrompt(tenant) {
2
+ const parts = [];
3
+ // Opening line
4
+ parts.push(`You are the virtual assistant for "${tenant.name}".`);
5
+ // Description
6
+ if (tenant.description) {
7
+ parts.push(tenant.description);
8
+ }
9
+ // Tone instruction
10
+ const lang = tenant.language ?? "es-MX";
11
+ switch (tenant.tone) {
12
+ case "formal":
13
+ parts.push("Use a formal and professional tone in all your responses.");
14
+ break;
15
+ case "casual":
16
+ parts.push("Use a casual and relaxed tone in your responses.");
17
+ break;
18
+ case "friendly":
19
+ parts.push("Use a friendly and approachable tone in your responses.");
20
+ break;
21
+ default:
22
+ parts.push("Use a friendly and approachable tone in your responses.");
23
+ break;
24
+ }
25
+ // Services
26
+ if (tenant.services && tenant.services.length > 0) {
27
+ parts.push("");
28
+ parts.push("## Services");
29
+ for (const svc of tenant.services) {
30
+ let line = `- ${svc.name}`;
31
+ const details = [];
32
+ if (svc.price)
33
+ details.push(svc.price);
34
+ if (svc.duration)
35
+ details.push(svc.duration);
36
+ if (details.length > 0)
37
+ line += ` — ${details.join(", ")}`;
38
+ if (svc.description)
39
+ line += `: ${svc.description}`;
40
+ parts.push(line);
41
+ }
42
+ }
43
+ // Hours
44
+ if (tenant.hours && Object.keys(tenant.hours).length > 0) {
45
+ parts.push("");
46
+ parts.push("## Business Hours");
47
+ for (const [day, hours] of Object.entries(tenant.hours)) {
48
+ parts.push(`- ${day}: ${hours}`);
49
+ }
50
+ }
51
+ // FAQ
52
+ if (tenant.faqEntries && tenant.faqEntries.length > 0) {
53
+ parts.push("");
54
+ parts.push("## Frequently Asked Questions");
55
+ for (const faq of tenant.faqEntries) {
56
+ parts.push(`**Q:** ${faq.q}`);
57
+ parts.push(`**A:** ${faq.r}`);
58
+ }
59
+ }
60
+ // Escalation
61
+ if (tenant.escalationContact) {
62
+ let escalation = `If you cannot resolve something, escalate to: ${tenant.escalationContact.name}`;
63
+ if (tenant.escalationContact.phone)
64
+ escalation += ` (${tenant.escalationContact.phone})`;
65
+ if (tenant.escalationContact.email)
66
+ escalation += ` <${tenant.escalationContact.email}>`;
67
+ parts.push("");
68
+ parts.push(escalation);
69
+ }
70
+ // Closing instructions: language directive and guardrails
71
+ parts.push("");
72
+ parts.push(`Always respond in ${lang}.`);
73
+ parts.push("Be concise. Do not fabricate information you do not know. Only respond about this business.");
74
+ return parts.join("\n");
75
+ }
76
+ //# sourceMappingURL=system-prompt-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-prompt-builder.js","sourceRoot":"","sources":["../../src/tenant/system-prompt-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { KilnError } from "@kilnai/core";
2
+ import type { TenantConfig, SecretStore } from "@kilnai/core";
3
+ export declare class TenantNotFoundError extends KilnError {
4
+ constructor(tenantId: string);
5
+ }
6
+ export declare class TenantValidationFailedError extends KilnError {
7
+ readonly errors: readonly {
8
+ field: string;
9
+ message: string;
10
+ }[];
11
+ constructor(errors: readonly {
12
+ field: string;
13
+ message: string;
14
+ }[]);
15
+ }
16
+ export declare class TenantRegistry {
17
+ private readonly storageDir;
18
+ private readonly secretStore;
19
+ private readonly tenants;
20
+ constructor(storageDir: string, secretStore?: SecretStore);
21
+ private encryptSensitiveFields;
22
+ private hydrateSecrets;
23
+ private deleteSecrets;
24
+ load(): void;
25
+ get(tenantId: string): TenantConfig | undefined;
26
+ list(appName?: string): readonly TenantConfig[];
27
+ create(config: TenantConfig): TenantConfig;
28
+ update(tenantId: string, patch: Partial<Omit<TenantConfig, "tenantId" | "appName" | "createdAt">>): TenantConfig;
29
+ remove(tenantId: string): boolean;
30
+ resolveByPhone(phoneNumberId: string, appName: string): TenantConfig | undefined;
31
+ private persist;
32
+ }
33
+ //# sourceMappingURL=tenant-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-registry.d.ts","sourceRoot":"","sources":["../../src/tenant/tenant-registry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAO9D,qBAAa,mBAAoB,SAAQ,SAAS;gBACpC,QAAQ,EAAE,MAAM;CAO7B;AAED,qBAAa,2BAA4B,SAAQ,SAAS;IACxD,QAAQ,CAAC,MAAM,EAAE,SAAS;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;gBACnD,MAAM,EAAE,SAAS;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE;CAQlE;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA0B;IACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;gBAE/C,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,WAAW;IAKzD,OAAO,CAAC,sBAAsB;IAc9B,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,aAAa;IAOrB,IAAI,IAAI,IAAI;IAWZ,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAM/C,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,YAAY,EAAE;IAK/C,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY;IAgB1C,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,GAAG,SAAS,GAAG,WAAW,CAAC,CAAC,GAAG,YAAY;IA0BhH,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IASjC,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAahF,OAAO,CAAC,OAAO;CAKhB"}
@@ -0,0 +1,156 @@
1
+ import { mkdirSync, writeFileSync, readFileSync, readdirSync, existsSync, unlinkSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { KilnError } from "@kilnai/core";
4
+ import { validateTenantConfig } from "@kilnai/core";
5
+ const SENSITIVE_FIELDS = ["whatsappAccessToken", "whatsappVerifyToken"];
6
+ const ENCRYPTED_PLACEHOLDER = "[encrypted]";
7
+ export class TenantNotFoundError extends KilnError {
8
+ constructor(tenantId) {
9
+ super("TENANT_NOT_FOUND", `Tenant not found: ${tenantId}`, {
10
+ context: { tenantId },
11
+ retryable: false,
12
+ });
13
+ this.name = "TenantNotFoundError";
14
+ }
15
+ }
16
+ export class TenantValidationFailedError extends KilnError {
17
+ errors;
18
+ constructor(errors) {
19
+ super("TENANT_VALIDATION_FAILED", `Tenant validation failed: ${errors.map((e) => `${e.field}: ${e.message}`).join(", ")}`, {
20
+ context: { errors },
21
+ retryable: false,
22
+ });
23
+ this.name = "TenantValidationFailedError";
24
+ this.errors = errors;
25
+ }
26
+ }
27
+ export class TenantRegistry {
28
+ storageDir;
29
+ secretStore;
30
+ tenants = new Map();
31
+ constructor(storageDir, secretStore) {
32
+ this.storageDir = storageDir;
33
+ this.secretStore = secretStore;
34
+ }
35
+ encryptSensitiveFields(config) {
36
+ if (!this.secretStore)
37
+ return config;
38
+ const result = { ...config };
39
+ for (const field of SENSITIVE_FIELDS) {
40
+ const value = config[field];
41
+ if (typeof value === "string" && value !== ENCRYPTED_PLACEHOLDER) {
42
+ const secretKey = `tenant:${config.tenantId}:${field}`;
43
+ this.secretStore.set(secretKey, value);
44
+ result[field] = ENCRYPTED_PLACEHOLDER;
45
+ }
46
+ }
47
+ return result;
48
+ }
49
+ hydrateSecrets(config) {
50
+ if (!this.secretStore)
51
+ return config;
52
+ const result = { ...config };
53
+ for (const field of SENSITIVE_FIELDS) {
54
+ const value = config[field];
55
+ if (value === ENCRYPTED_PLACEHOLDER) {
56
+ const secretKey = `tenant:${config.tenantId}:${field}`;
57
+ const decrypted = this.secretStore.get(secretKey);
58
+ if (decrypted !== null)
59
+ result[field] = decrypted;
60
+ }
61
+ }
62
+ return result;
63
+ }
64
+ deleteSecrets(tenantId) {
65
+ if (!this.secretStore)
66
+ return;
67
+ for (const field of SENSITIVE_FIELDS) {
68
+ this.secretStore.delete(`tenant:${tenantId}:${field}`);
69
+ }
70
+ }
71
+ load() {
72
+ if (!existsSync(this.storageDir))
73
+ return;
74
+ const files = readdirSync(this.storageDir).filter((f) => f.endsWith(".json"));
75
+ for (const file of files) {
76
+ const content = readFileSync(join(this.storageDir, file), "utf-8");
77
+ const config = JSON.parse(content);
78
+ // Store the persisted (potentially encrypted) config in memory map
79
+ this.tenants.set(config.tenantId, config);
80
+ }
81
+ }
82
+ get(tenantId) {
83
+ const config = this.tenants.get(tenantId);
84
+ if (!config)
85
+ return undefined;
86
+ return this.hydrateSecrets(config);
87
+ }
88
+ list(appName) {
89
+ const all = [...this.tenants.values()];
90
+ return appName ? all.filter((t) => t.appName === appName) : all;
91
+ }
92
+ create(config) {
93
+ if (this.tenants.has(config.tenantId)) {
94
+ throw new TenantValidationFailedError([
95
+ { field: "tenantId", message: `duplicate tenantId "${config.tenantId}"` },
96
+ ]);
97
+ }
98
+ const errors = validateTenantConfig(config);
99
+ if (errors.length > 0) {
100
+ throw new TenantValidationFailedError(errors);
101
+ }
102
+ const encrypted = this.encryptSensitiveFields(config);
103
+ this.tenants.set(config.tenantId, encrypted);
104
+ this.persist(encrypted);
105
+ return this.hydrateSecrets(encrypted);
106
+ }
107
+ update(tenantId, patch) {
108
+ const existing = this.tenants.get(tenantId);
109
+ if (!existing)
110
+ throw new TenantNotFoundError(tenantId);
111
+ // Hydrate existing secrets before merging patch so we can re-encrypt properly
112
+ const hydrated = this.hydrateSecrets(existing);
113
+ const updated = {
114
+ ...hydrated,
115
+ ...patch,
116
+ tenantId: existing.tenantId,
117
+ appName: existing.appName,
118
+ createdAt: existing.createdAt,
119
+ updatedAt: new Date().toISOString(),
120
+ };
121
+ const errors = validateTenantConfig(updated);
122
+ if (errors.length > 0) {
123
+ throw new TenantValidationFailedError(errors);
124
+ }
125
+ const encrypted = this.encryptSensitiveFields(updated);
126
+ this.tenants.set(tenantId, encrypted);
127
+ this.persist(encrypted);
128
+ return this.hydrateSecrets(encrypted);
129
+ }
130
+ remove(tenantId) {
131
+ if (!this.tenants.has(tenantId))
132
+ return false;
133
+ this.tenants.delete(tenantId);
134
+ this.deleteSecrets(tenantId);
135
+ const filePath = join(this.storageDir, `${tenantId}.json`);
136
+ if (existsSync(filePath))
137
+ unlinkSync(filePath);
138
+ return true;
139
+ }
140
+ resolveByPhone(phoneNumberId, appName) {
141
+ for (const tenant of this.tenants.values()) {
142
+ if (tenant.appName === appName &&
143
+ tenant.whatsappPhoneNumberId === phoneNumberId &&
144
+ tenant.enabled) {
145
+ return tenant;
146
+ }
147
+ }
148
+ return undefined;
149
+ }
150
+ persist(config) {
151
+ mkdirSync(this.storageDir, { recursive: true });
152
+ const filePath = join(this.storageDir, `${config.tenantId}.json`);
153
+ writeFileSync(filePath, JSON.stringify(config, null, 2), "utf-8");
154
+ }
155
+ }
156
+ //# sourceMappingURL=tenant-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-registry.js","sourceRoot":"","sources":["../../src/tenant/tenant-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { EventBus, EventTrigger, KilnEvent } from "@kilnai/core";
2
+ /** Check if an event matches a trigger's filter (shallow equality) */
3
+ export declare function matchesFilter(event: KilnEvent, filter: Record<string, unknown> | undefined): boolean;
4
+ export interface EventListenerConfig {
5
+ readonly appName: string;
6
+ readonly eventBus: EventBus;
7
+ }
8
+ /** Manages event trigger subscriptions */
9
+ export declare class EventListener {
10
+ private readonly config;
11
+ private readonly triggers;
12
+ private readonly unsubscribers;
13
+ private started;
14
+ constructor(config: EventListenerConfig);
15
+ /** Register an event trigger */
16
+ register(trigger: EventTrigger): void;
17
+ /** Start listening for events */
18
+ start(): void;
19
+ /** Stop listening for events */
20
+ stop(): void;
21
+ }
22
+ //# sourceMappingURL=event-listener.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-listener.d.ts","sourceRoot":"","sources":["../../src/trigger/event-listener.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAItE,sEAAsE;AACtE,wBAAgB,aAAa,CAC3B,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC1C,OAAO,CAST;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;CAC7B;AAED,0CAA0C;AAC1C,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;IAC/C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsB;IACpD,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,mBAAmB;IAIvC,gCAAgC;IAChC,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAKrC,iCAAiC;IACjC,KAAK,IAAI,IAAI;IA+Bb,gCAAgC;IAChC,IAAI,IAAI,IAAI;CAKb"}
@@ -0,0 +1,64 @@
1
+ // Event listener: subscribes to EventBus, evaluates trigger filters, fires callback
2
+ // Shallow equality filter matching on event properties
3
+ import { executeTrigger } from "./trigger-executor.js";
4
+ /** Check if an event matches a trigger's filter (shallow equality) */
5
+ export function matchesFilter(event, filter) {
6
+ if (!filter)
7
+ return true;
8
+ const record = event;
9
+ for (const [key, value] of Object.entries(filter)) {
10
+ if (record[key] !== value)
11
+ return false;
12
+ }
13
+ return true;
14
+ }
15
+ /** Manages event trigger subscriptions */
16
+ export class EventListener {
17
+ config;
18
+ triggers = [];
19
+ unsubscribers = [];
20
+ started = false;
21
+ constructor(config) {
22
+ this.config = config;
23
+ }
24
+ /** Register an event trigger */
25
+ register(trigger) {
26
+ if (trigger.enabled === false)
27
+ return;
28
+ this.triggers.push(trigger);
29
+ }
30
+ /** Start listening for events */
31
+ start() {
32
+ if (this.started)
33
+ return;
34
+ this.started = true;
35
+ for (const trigger of this.triggers) {
36
+ const handler = (event) => {
37
+ if (!matchesFilter(event, trigger.filter))
38
+ return;
39
+ const ctx = {
40
+ appName: this.config.appName,
41
+ eventBus: this.config.eventBus,
42
+ sessionId: `event-${this.config.appName}-${trigger.name}-${Date.now()}`,
43
+ };
44
+ try {
45
+ executeTrigger(trigger, event, ctx);
46
+ }
47
+ catch {
48
+ // Error already emitted by executeTrigger
49
+ }
50
+ };
51
+ this.config.eventBus.on(trigger.event, handler);
52
+ const eventType = trigger.event;
53
+ this.unsubscribers.push(() => this.config.eventBus.off(eventType, handler));
54
+ }
55
+ }
56
+ /** Stop listening for events */
57
+ stop() {
58
+ for (const unsub of this.unsubscribers)
59
+ unsub();
60
+ this.unsubscribers.length = 0;
61
+ this.started = false;
62
+ }
63
+ }
64
+ //# sourceMappingURL=event-listener.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-listener.js","sourceRoot":"","sources":["../../src/trigger/event-listener.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,uDAAuD;AAGvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,sEAAsE;AACtE,MAAM,UAAU,aAAa,CAC3B,KAAgB,EAChB,MAA2C;IAE3C,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,MAAM,MAAM,GAAG,KAA2C,CAAC;IAC3D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,KAAK;YAAE,OAAO,KAAK,CAAC;IAC1C,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAOD,0CAA0C;AAC1C,MAAM,OAAO,aAAa;IACP,MAAM,CAAsB;IAC5B,QAAQ,GAAmB,EAAE,CAAC;IAC9B,aAAa,GAAmB,EAAE,CAAC;IAC5C,OAAO,GAAG,KAAK,CAAC;IAExB,YAAY,MAA2B;QACrC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,gCAAgC;IAChC,QAAQ,CAAC,OAAqB;QAC5B,IAAI,OAAO,CAAC,OAAO,KAAK,KAAK;YAAE,OAAO;QACtC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,iCAAiC;IACjC,KAAK;QACH,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QAEpB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,MAAM,OAAO,GAAG,CAAC,KAAgB,EAAE,EAAE;gBACnC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC;oBAAE,OAAO;gBAElD,MAAM,GAAG,GAA4B;oBACnC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;oBAC5B,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;oBAC9B,SAAS,EAAE,SAAS,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE;iBACxE,CAAC;gBAEF,IAAI,CAAC;oBACH,cAAc,CACZ,OAAO,EACP,KAA2C,EAC3C,GAAG,CACJ,CAAC;gBACJ,CAAC;gBAAC,MAAM,CAAC;oBACP,0CAA0C;gBAC5C,CAAC;YACH,CAAC,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,KAAyC,EAAE,OAAO,CAAC,CAAC;YACpF,MAAM,SAAS,GAAG,OAAO,CAAC,KAAyC,CAAC;YACpE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IAED,gCAAgC;IAChC,IAAI;QACF,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa;YAAE,KAAK,EAAE,CAAC;QAChD,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACvB,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ export { TriggerRegistry } from "./trigger-registry.js";
2
+ export type { TriggerRegistryConfig } from "./trigger-registry.js";
3
+ export { createWebhookHandler, validateWebhookSignature } from "./webhook-handler.js";
4
+ export type { WebhookHandlerConfig } from "./webhook-handler.js";
5
+ export { EventListener, matchesFilter } from "./event-listener.js";
6
+ export type { EventListenerConfig } from "./event-listener.js";
7
+ export { Scheduler } from "./scheduler.js";
8
+ export { executeTrigger, interpolateTemplate } from "./trigger-executor.js";
9
+ export type { TriggerExecutionContext } from "./trigger-executor.js";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/trigger/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,YAAY,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AACtF,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACnE,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5E,YAAY,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,7 @@
1
+ // Trigger runtime: webhook handlers, event listeners, cron schedulers
2
+ export { TriggerRegistry } from "./trigger-registry.js";
3
+ export { createWebhookHandler, validateWebhookSignature } from "./webhook-handler.js";
4
+ export { EventListener, matchesFilter } from "./event-listener.js";
5
+ export { Scheduler } from "./scheduler.js";
6
+ export { executeTrigger, interpolateTemplate } from "./trigger-executor.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/trigger/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAEtF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { EventBus, ScheduleTrigger } from "@kilnai/core";
2
+ /** Manages cron-based schedule triggers */
3
+ export declare class Scheduler {
4
+ private readonly config;
5
+ private readonly entries;
6
+ private started;
7
+ constructor(config: {
8
+ appName: string;
9
+ eventBus: EventBus;
10
+ });
11
+ /** Register a schedule trigger */
12
+ register(trigger: ScheduleTrigger): void;
13
+ /** Start all schedule timers */
14
+ start(): void;
15
+ /** Stop all schedule timers */
16
+ stop(): void;
17
+ /** Schedule the next fire for a given entry */
18
+ private scheduleNext;
19
+ /** Fire a schedule trigger */
20
+ private fire;
21
+ }
22
+ //# sourceMappingURL=scheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/trigger/scheduler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAsB,MAAM,cAAc,CAAC;AAUlF,2CAA2C;AAC3C,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IACjE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAC/C,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,QAAQ,CAAA;KAAE;IAI3D,kCAAkC;IAClC,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAKxC,gCAAgC;IAChC,KAAK,IAAI,IAAI;IASb,+BAA+B;IAC/B,IAAI,IAAI,IAAI;IAUZ,+CAA+C;IAC/C,OAAO,CAAC,YAAY;IAcpB,8BAA8B;IAC9B,OAAO,CAAC,IAAI;CA0Bb"}
@@ -0,0 +1,77 @@
1
+ // Scheduler: manages cron-based timers for schedule triggers
2
+ // Uses setTimeout chains (not setInterval) for drift-free scheduling
3
+ import { parseCronExpression, nextFireTime } from "@kilnai/core";
4
+ import { executeTrigger } from "./trigger-executor.js";
5
+ /** Manages cron-based schedule triggers */
6
+ export class Scheduler {
7
+ config;
8
+ entries = [];
9
+ started = false;
10
+ constructor(config) {
11
+ this.config = config;
12
+ }
13
+ /** Register a schedule trigger */
14
+ register(trigger) {
15
+ if (trigger.enabled === false)
16
+ return;
17
+ this.entries.push({ trigger, timer: null });
18
+ }
19
+ /** Start all schedule timers */
20
+ start() {
21
+ if (this.started)
22
+ return;
23
+ this.started = true;
24
+ for (const entry of this.entries) {
25
+ this.scheduleNext(entry);
26
+ }
27
+ }
28
+ /** Stop all schedule timers */
29
+ stop() {
30
+ for (const entry of this.entries) {
31
+ if (entry.timer) {
32
+ clearTimeout(entry.timer);
33
+ entry.timer = null;
34
+ }
35
+ }
36
+ this.started = false;
37
+ }
38
+ /** Schedule the next fire for a given entry */
39
+ scheduleNext(entry) {
40
+ const cron = parseCronExpression(entry.trigger.cron);
41
+ const now = new Date();
42
+ const next = nextFireTime(cron, now);
43
+ const delay = next.getTime() - now.getTime();
44
+ entry.timer = setTimeout(() => {
45
+ this.fire(entry);
46
+ if (this.started) {
47
+ this.scheduleNext(entry);
48
+ }
49
+ }, Math.max(delay, 0));
50
+ }
51
+ /** Fire a schedule trigger */
52
+ fire(entry) {
53
+ const { trigger } = entry;
54
+ // Emit schedule_fired event
55
+ const firedEvent = {
56
+ type: "schedule_fired",
57
+ timestamp: new Date(),
58
+ sessionId: `schedule-${this.config.appName}-${trigger.name}`,
59
+ triggerName: trigger.name,
60
+ cron: trigger.cron,
61
+ team: trigger.team,
62
+ };
63
+ this.config.eventBus.emit(firedEvent);
64
+ const ctx = {
65
+ appName: this.config.appName,
66
+ eventBus: this.config.eventBus,
67
+ sessionId: `schedule-${this.config.appName}-${trigger.name}-${Date.now()}`,
68
+ };
69
+ try {
70
+ executeTrigger(trigger, {}, ctx);
71
+ }
72
+ catch {
73
+ // Error already emitted by executeTrigger
74
+ }
75
+ }
76
+ }
77
+ //# sourceMappingURL=scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/trigger/scheduler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { EventBus, Trigger } from "@kilnai/core";
2
+ /** Interpolate {{payload.field}} placeholders in a task template */
3
+ export declare function interpolateTemplate(template: string, payload: Record<string, unknown>): string;
4
+ export interface TriggerExecutionContext {
5
+ readonly appName: string;
6
+ readonly eventBus: EventBus;
7
+ readonly sessionId: string;
8
+ }
9
+ /** Execute a trigger: interpolate template and emit events */
10
+ export declare function executeTrigger(trigger: Trigger, payload: Record<string, unknown>, ctx: TriggerExecutionContext): {
11
+ team: string;
12
+ task: string;
13
+ };
14
+ //# sourceMappingURL=trigger-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trigger-executor.d.ts","sourceRoot":"","sources":["../../src/trigger/trigger-executor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAyC,MAAM,cAAc,CAAC;AAE7F,oEAAoE;AACpE,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,MAAM,CAUR;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,8DAA8D;AAC9D,wBAAgB,cAAc,CAC5B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,GAAG,EAAE,uBAAuB,GAC3B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CA8BhC"}
@@ -0,0 +1,47 @@
1
+ // Trigger executor: interpolates task templates and fires triggers
2
+ // Pure function + event emission -- no external deps beyond core types
3
+ /** Interpolate {{payload.field}} placeholders in a task template */
4
+ export function interpolateTemplate(template, payload) {
5
+ return template.replace(/\{\{payload\.(\w+(?:\.\w+)*)\}\}/g, (_match, path) => {
6
+ const parts = path.split(".");
7
+ let value = payload;
8
+ for (const part of parts) {
9
+ if (value == null || typeof value !== "object")
10
+ return "";
11
+ value = value[part];
12
+ }
13
+ return value == null ? "" : String(value);
14
+ });
15
+ }
16
+ /** Execute a trigger: interpolate template and emit events */
17
+ export function executeTrigger(trigger, payload, ctx) {
18
+ const task = trigger.task
19
+ ? interpolateTemplate(trigger.task, payload)
20
+ : `Trigger ${trigger.name} fired`;
21
+ try {
22
+ const firedEvent = {
23
+ type: "trigger_fired",
24
+ timestamp: new Date(),
25
+ sessionId: ctx.sessionId,
26
+ triggerName: trigger.name,
27
+ triggerType: trigger.type,
28
+ team: trigger.team,
29
+ task,
30
+ };
31
+ ctx.eventBus.emit(firedEvent);
32
+ return { team: trigger.team, task };
33
+ }
34
+ catch (err) {
35
+ const failedEvent = {
36
+ type: "trigger_failed",
37
+ timestamp: new Date(),
38
+ sessionId: ctx.sessionId,
39
+ triggerName: trigger.name,
40
+ triggerType: trigger.type,
41
+ error: err instanceof Error ? err.message : String(err),
42
+ };
43
+ ctx.eventBus.emit(failedEvent);
44
+ throw err;
45
+ }
46
+ }
47
+ //# sourceMappingURL=trigger-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trigger-executor.js","sourceRoot":"","sources":["../../src/trigger/trigger-executor.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,uEAAuE;AAIvE,oEAAoE;AACpE,MAAM,UAAU,mBAAmB,CACjC,QAAgB,EAChB,OAAgC;IAEhC,OAAO,QAAQ,CAAC,OAAO,CAAC,mCAAmC,EAAE,CAAC,MAAM,EAAE,IAAY,EAAE,EAAE;QACpF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,KAAK,GAAY,OAAO,CAAC;QAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;gBAAE,OAAO,EAAE,CAAC;YAC1D,KAAK,GAAI,KAAiC,CAAC,IAAI,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC;AAQD,8DAA8D;AAC9D,MAAM,UAAU,cAAc,CAC5B,OAAgB,EAChB,OAAgC,EAChC,GAA4B;IAE5B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI;QACvB,CAAC,CAAC,mBAAmB,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;QAC5C,CAAC,CAAC,WAAW,OAAO,CAAC,IAAI,QAAQ,CAAC;IAEpC,IAAI,CAAC;QACH,MAAM,UAAU,GAAsB;YACpC,IAAI,EAAE,eAAe;YACrB,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,WAAW,EAAE,OAAO,CAAC,IAAI;YACzB,WAAW,EAAE,OAAO,CAAC,IAAI;YACzB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI;SACL,CAAC;QACF,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAE9B,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;IACtC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,WAAW,GAAuB;YACtC,IAAI,EAAE,gBAAgB;YACtB,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,WAAW,EAAE,OAAO,CAAC,IAAI;YACzB,WAAW,EAAE,OAAO,CAAC,IAAI;YACzB,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC;QACF,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC/B,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { EventBus, Trigger } from "@kilnai/core";
2
+ import type { Hono } from "hono";
3
+ export interface TriggerRegistryConfig {
4
+ readonly eventBus: EventBus;
5
+ }
6
+ /** Central registry managing triggers across all apps */
7
+ export declare class TriggerRegistry {
8
+ private readonly config;
9
+ private readonly apps;
10
+ private started;
11
+ constructor(config: TriggerRegistryConfig);
12
+ /** Register all triggers for an app */
13
+ registerApp(appName: string, triggers: readonly Trigger[]): void;
14
+ /** Get the webhook Hono app for an app (to mount in gateway) */
15
+ getWebhookApp(appName: string): Hono | null;
16
+ /** Start all event listeners and schedulers */
17
+ start(): void;
18
+ /** Stop all event listeners, schedulers, and clear timers */
19
+ stop(): void;
20
+ /** List all registered triggers across all apps (for dev/debug) */
21
+ listAll(): {
22
+ appName: string;
23
+ name: string;
24
+ type: string;
25
+ enabled: boolean;
26
+ }[];
27
+ }
28
+ //# sourceMappingURL=trigger-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trigger-registry.d.ts","sourceRoot":"","sources":["../../src/trigger/trigger-registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,QAAQ,EACR,OAAO,EAIR,MAAM,cAAc,CAAC;AAKtB,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAEjC,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;CAC7B;AAYD,yDAAyD;AACzD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkC;IACvD,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,qBAAqB;IAIzC,uCAAuC;IACvC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI;IAyDhE,gEAAgE;IAChE,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAI3C,+CAA+C;IAC/C,KAAK,IAAI,IAAI;IAUb,6DAA6D;IAC7D,IAAI,IAAI,IAAI;IAQZ,mEAAmE;IACnE,OAAO,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,EAAE;CAgC/E"}