@kici-dev/engine 0.0.0 → 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 (129) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +1 -6
  3. package/dist/audit/access-log-policy.d.ts +97 -0
  4. package/dist/audit/access-log-policy.js +195 -0
  5. package/dist/audit/activity.d.ts +156 -0
  6. package/dist/audit/activity.js +175 -0
  7. package/dist/audit/retention-policy.d.ts +157 -0
  8. package/dist/audit/retention-policy.js +364 -0
  9. package/dist/bundler/index.d.ts +3 -0
  10. package/dist/bundler/index.js +3 -0
  11. package/dist/bundler/rolldown-config.d.ts +41 -0
  12. package/dist/bundler/rolldown-config.js +40 -0
  13. package/dist/chunk-gOLHoazu.js +4 -0
  14. package/dist/env/environment-allowlist.d.ts +45 -0
  15. package/dist/env/environment-allowlist.js +69 -0
  16. package/dist/environment/index.d.ts +3 -0
  17. package/dist/environment/index.js +3 -0
  18. package/dist/environment/scope-resolver.d.ts +35 -0
  19. package/dist/environment/scope-resolver.js +77 -0
  20. package/dist/environment/types.d.ts +98 -0
  21. package/dist/environment/types.js +2 -0
  22. package/dist/index.d.ts +54 -0
  23. package/dist/index.js +45 -0
  24. package/dist/labels.d.ts +106 -0
  25. package/dist/labels.js +162 -0
  26. package/dist/metrics/metric-catalog.generated.d.ts +400 -0
  27. package/dist/metrics/metric-catalog.generated.js +510 -0
  28. package/dist/protocol/dashboard-global-workflows.d.ts +9 -0
  29. package/dist/protocol/dashboard-global-workflows.js +3 -0
  30. package/dist/protocol/event-log-payload.d.ts +16 -0
  31. package/dist/protocol/event-log-payload.js +21 -0
  32. package/dist/protocol/messages/access-log.d.ts +545 -0
  33. package/dist/protocol/messages/access-log.js +175 -0
  34. package/dist/protocol/messages/actor.d.ts +100 -0
  35. package/dist/protocol/messages/actor.js +139 -0
  36. package/dist/protocol/messages/auth.d.ts +25 -0
  37. package/dist/protocol/messages/auth.js +36 -0
  38. package/dist/protocol/messages/browser.d.ts +369 -0
  39. package/dist/protocol/messages/browser.js +225 -0
  40. package/dist/protocol/messages/capabilities.d.ts +46 -0
  41. package/dist/protocol/messages/capabilities.js +42 -0
  42. package/dist/protocol/messages/common.d.ts +53 -0
  43. package/dist/protocol/messages/common.js +55 -0
  44. package/dist/protocol/messages/dashboard-global-workflows.d.ts +166 -0
  45. package/dist/protocol/messages/dashboard-global-workflows.js +80 -0
  46. package/dist/protocol/messages/dashboard.d.ts +4068 -0
  47. package/dist/protocol/messages/dashboard.js +1237 -0
  48. package/dist/protocol/messages/event-log.d.ts +49 -0
  49. package/dist/protocol/messages/event-log.js +45 -0
  50. package/dist/protocol/messages/execution-status.d.ts +164 -0
  51. package/dist/protocol/messages/execution-status.js +166 -0
  52. package/dist/protocol/messages/join.d.ts +18 -0
  53. package/dist/protocol/messages/join.js +28 -0
  54. package/dist/protocol/messages/log-pull.d.ts +27 -0
  55. package/dist/protocol/messages/log-pull.js +36 -0
  56. package/dist/protocol/messages/observe.d.ts +75 -0
  57. package/dist/protocol/messages/observe.js +70 -0
  58. package/dist/protocol/messages/orchestrator-agent.d.ts +606 -0
  59. package/dist/protocol/messages/orchestrator-agent.js +481 -0
  60. package/dist/protocol/messages/peer.d.ts +795 -0
  61. package/dist/protocol/messages/peer.js +372 -0
  62. package/dist/protocol/messages/platform-orchestrator.d.ts +1888 -0
  63. package/dist/protocol/messages/platform-orchestrator.js +379 -0
  64. package/dist/protocol/messages/run-events.d.ts +155 -0
  65. package/dist/protocol/messages/run-events.js +115 -0
  66. package/dist/protocol/messages/saas-orchestrator.d.ts +2179 -0
  67. package/dist/protocol/messages/source-registration.d.ts +103 -0
  68. package/dist/protocol/messages/source-registration.js +109 -0
  69. package/dist/protocol/messages/test-run.d.ts +59 -0
  70. package/dist/protocol/messages/test-run.js +52 -0
  71. package/dist/protocol/version.d.ts +12 -0
  72. package/dist/protocol/version.js +17 -0
  73. package/dist/provider/changed-files-fetcher.d.ts +24 -0
  74. package/dist/provider/changed-files-fetcher.js +2 -0
  75. package/dist/provider/check-run-conclusion.d.ts +15 -0
  76. package/dist/provider/check-run-conclusion.js +19 -0
  77. package/dist/provider/check-status-poster.d.ts +15 -0
  78. package/dist/provider/check-status-poster.js +2 -0
  79. package/dist/provider/clone-token-provider.d.ts +58 -0
  80. package/dist/provider/clone-token-provider.js +2 -0
  81. package/dist/provider/contributor-resolver.d.ts +22 -0
  82. package/dist/provider/contributor-resolver.js +2 -0
  83. package/dist/provider/index.d.ts +23 -0
  84. package/dist/provider/index.js +3 -0
  85. package/dist/provider/lock-file-fetcher.d.ts +24 -0
  86. package/dist/provider/lock-file-fetcher.js +2 -0
  87. package/dist/provider/repo-url-builder.d.ts +35 -0
  88. package/dist/provider/repo-url-builder.js +2 -0
  89. package/dist/provider/types.d.ts +9 -0
  90. package/dist/provider/types.js +2 -0
  91. package/dist/provider/webhook-normalizer.d.ts +163 -0
  92. package/dist/provider/webhook-normalizer.js +2 -0
  93. package/dist/registration/registerable-trigger-type.d.ts +52 -0
  94. package/dist/registration/registerable-trigger-type.js +56 -0
  95. package/dist/scaler/resource-types.d.ts +90 -0
  96. package/dist/scaler/resource-types.js +99 -0
  97. package/dist/scaler/scaler-backend-type.d.ts +16 -0
  98. package/dist/scaler/scaler-backend-type.js +20 -0
  99. package/dist/secrets/index.d.ts +7 -0
  100. package/dist/secrets/index.js +2 -0
  101. package/dist/secrets/types.d.ts +138 -0
  102. package/dist/secrets/types.js +2 -0
  103. package/dist/state-machine/index.d.ts +2 -0
  104. package/dist/state-machine/index.js +3 -0
  105. package/dist/state-machine/machine.d.ts +34 -0
  106. package/dist/state-machine/machine.js +103 -0
  107. package/dist/state-machine/types.d.ts +34 -0
  108. package/dist/state-machine/types.js +15 -0
  109. package/dist/trigger/decision-trace.d.ts +41 -0
  110. package/dist/trigger/decision-trace.js +30 -0
  111. package/dist/trigger/jsonpath-matcher.d.ts +27 -0
  112. package/dist/trigger/jsonpath-matcher.js +92 -0
  113. package/dist/trigger/matcher.d.ts +29 -0
  114. package/dist/trigger/matcher.js +704 -0
  115. package/dist/trigger/trigger-event-type.d.ts +14 -0
  116. package/dist/trigger/trigger-event-type.js +66 -0
  117. package/dist/trigger/types.d.ts +524 -0
  118. package/dist/trigger/types.js +48 -0
  119. package/dist/webhook/signature.d.ts +15 -0
  120. package/dist/webhook/signature.js +32 -0
  121. package/dist/ws/close-codes.d.ts +28 -0
  122. package/dist/ws/close-codes.js +33 -0
  123. package/dist/ws/rate-limiter.d.ts +86 -0
  124. package/dist/ws/rate-limiter.js +136 -0
  125. package/dist/ws/ws-like.d.ts +12 -0
  126. package/dist/ws/ws-like.js +2 -0
  127. package/package.json +54 -6
  128. package/sbom.spdx.json +202 -0
  129. package/index.js +0 -3
@@ -0,0 +1,704 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ import { createTraceEntry, createWorkflowDecision } from "./decision-trace.js";
3
+ import { matchJsonPath, matchJsonPathNot } from "./jsonpath-matcher.js";
4
+ import picomatch from "picomatch";
5
+ //#region src/trigger/matcher.ts
6
+ /**
7
+ * Trigger matching engine for evaluating workflow triggers against webhook events.
8
+ * Single source of truth -- replaces duplicate logic in compiler and orchestrator.
9
+ */
10
+ function splitStringPatterns(patterns) {
11
+ const include = [];
12
+ const exclude = [];
13
+ for (const p of patterns) if (p.startsWith("!")) exclude.push(p.slice(1));
14
+ else include.push(p);
15
+ return {
16
+ include,
17
+ exclude
18
+ };
19
+ }
20
+ function splitBranchPatterns(patterns) {
21
+ const include = [];
22
+ const exclude = [];
23
+ for (const p of patterns) if (p.pattern.startsWith("!")) exclude.push({
24
+ ...p,
25
+ pattern: p.pattern.slice(1)
26
+ });
27
+ else include.push(p);
28
+ return {
29
+ include,
30
+ exclude
31
+ };
32
+ }
33
+ /**
34
+ * Match a branch pattern against a branch name.
35
+ */
36
+ function matchBranchPattern(pattern, branch) {
37
+ if (pattern.type === "glob") return picomatch.isMatch(branch, pattern.pattern);
38
+ else return new RegExp(pattern.pattern, pattern.flags).test(branch);
39
+ }
40
+ /**
41
+ * Match any of the branch patterns.
42
+ * Returns true if patterns array is empty (no filter = match all).
43
+ */
44
+ function matchAnyBranch(patterns, branch) {
45
+ if (patterns.length === 0) return true;
46
+ return patterns.some((p) => matchBranchPattern(p, branch));
47
+ }
48
+ /**
49
+ * Match path patterns against changed files.
50
+ * Patterns prefixed with ! are exclusions. Remaining patterns are inclusions.
51
+ * An all-negation array has implicit match-all semantics for non-excluded files.
52
+ */
53
+ function matchPathPatterns(paths, changedFiles) {
54
+ if (paths.length === 0) return true;
55
+ if (changedFiles.length === 0) return false;
56
+ const { include, exclude } = splitStringPatterns(paths);
57
+ let relevantFiles = changedFiles;
58
+ if (exclude.length > 0) {
59
+ relevantFiles = changedFiles.filter((file) => !exclude.some((pattern) => picomatch.isMatch(file, pattern)));
60
+ if (relevantFiles.length === 0) return false;
61
+ }
62
+ if (include.length === 0) return true;
63
+ return relevantFiles.some((file) => include.some((pattern) => picomatch.isMatch(file, pattern)));
64
+ }
65
+ /**
66
+ * Match repo patterns against a source repository identifier.
67
+ * Patterns with ! prefix in the pattern string are exclusions.
68
+ * An all-negation array has implicit match-all semantics for non-excluded repos.
69
+ * Empty array = no filtering (matches all repos).
70
+ */
71
+ function matchRepoPatterns(repos, sourceRepo) {
72
+ if (repos.length === 0) return true;
73
+ const { include, exclude } = splitBranchPatterns(repos);
74
+ if (exclude.length > 0) {
75
+ if (exclude.some((p) => matchBranchPattern(p, sourceRepo))) return false;
76
+ }
77
+ if (include.length === 0) return true;
78
+ return include.some((p) => matchBranchPattern(p, sourceRepo));
79
+ }
80
+ /**
81
+ * Evaluate repo pattern filter for a trigger against an event.
82
+ * Returns true if matched (or no filter), false if filtered out.
83
+ * Adds trace entries for debugging.
84
+ */
85
+ function evaluateRepoFilter(trigger, event, traces) {
86
+ if (trigger.repos?.length) {
87
+ if (!event.sourceRepo) {
88
+ traces.push(createTraceEntry("repo", "required", "(missing)", false));
89
+ return false;
90
+ }
91
+ const { include, exclude } = splitBranchPatterns(trigger.repos);
92
+ const repoMatch = matchRepoPatterns(trigger.repos, event.sourceRepo);
93
+ traces.push(createTraceEntry("repo", `include:[${include.map((p) => p.pattern).join(",")}] exclude:[${exclude.map((p) => p.pattern).join(",")}]`, event.sourceRepo, repoMatch));
94
+ if (!repoMatch) return false;
95
+ }
96
+ return true;
97
+ }
98
+ /**
99
+ * Match a PR trigger against a simulated event.
100
+ */
101
+ function matchPrTrigger(trigger, event, traces) {
102
+ if (event.type !== "pull_request") {
103
+ traces.push(createTraceEntry("event type", "pull_request", event.type, false));
104
+ return false;
105
+ }
106
+ traces.push(createTraceEntry("event type", "pull_request", event.type, true));
107
+ if (trigger.events.length > 0) {
108
+ const action = event.action ?? "";
109
+ const actionMatches = trigger.events.includes(action);
110
+ traces.push(createTraceEntry("action", trigger.events.join("|"), action, actionMatches));
111
+ if (!actionMatches) return false;
112
+ }
113
+ if (trigger.targetBranches.length > 0) {
114
+ const matches = matchAnyBranch(trigger.targetBranches, event.targetBranch);
115
+ traces.push(createTraceEntry("target branch", trigger.targetBranches.map((p) => p.pattern).join("|"), event.targetBranch, matches));
116
+ if (!matches) return false;
117
+ }
118
+ if (trigger.sourceBranches.length > 0) {
119
+ if (!event.sourceBranch) {
120
+ traces.push(createTraceEntry("source branch", trigger.sourceBranches.map((p) => p.pattern).join("|"), "(missing)", false, "Event has no sourceBranch but trigger requires source branch filtering"));
121
+ return false;
122
+ }
123
+ const matches = matchAnyBranch(trigger.sourceBranches, event.sourceBranch);
124
+ traces.push(createTraceEntry("source branch", trigger.sourceBranches.map((p) => p.pattern).join("|"), event.sourceBranch, matches));
125
+ if (!matches) return false;
126
+ }
127
+ if (trigger.paths.length > 0) {
128
+ const changedFiles = event.changedFiles ?? [];
129
+ const { include, exclude } = splitStringPatterns(trigger.paths);
130
+ const matches = matchPathPatterns(trigger.paths, changedFiles);
131
+ traces.push(createTraceEntry("paths", `include: [${include.join(", ")}] exclude: [${exclude.join(", ")}]`, `[${changedFiles.join(", ")}]`, matches));
132
+ if (!matches) return false;
133
+ }
134
+ if (!evaluateRepoFilter(trigger, event, traces)) return false;
135
+ return true;
136
+ }
137
+ /**
138
+ * Match a push trigger against a simulated event.
139
+ */
140
+ function matchPushTrigger(trigger, event, traces) {
141
+ if (event.type !== "push") {
142
+ traces.push(createTraceEntry("event type", "push", event.type, false));
143
+ return false;
144
+ }
145
+ traces.push(createTraceEntry("event type", "push", event.type, true));
146
+ if (trigger.branches.length > 0) {
147
+ const matches = matchAnyBranch(trigger.branches, event.targetBranch);
148
+ traces.push(createTraceEntry("branch", trigger.branches.map((p) => p.pattern).join("|"), event.targetBranch, matches));
149
+ if (!matches) return false;
150
+ }
151
+ if (trigger.paths.length > 0) {
152
+ const changedFiles = event.changedFiles ?? [];
153
+ const { include, exclude } = splitStringPatterns(trigger.paths);
154
+ const matches = matchPathPatterns(trigger.paths, changedFiles);
155
+ traces.push(createTraceEntry("paths", `include: [${include.join(", ")}] exclude: [${exclude.join(", ")}]`, `[${changedFiles.join(", ")}]`, matches));
156
+ if (!matches) return false;
157
+ }
158
+ if (!evaluateRepoFilter(trigger, event, traces)) return false;
159
+ return true;
160
+ }
161
+ /**
162
+ * Match a tag trigger against a simulated event.
163
+ * Tag name is expected in event.targetBranch (normalizer sets it there).
164
+ */
165
+ function matchTagTrigger(trigger, event, traces) {
166
+ if (event.type !== "tag") {
167
+ traces.push(createTraceEntry("event type", "tag", event.type, false));
168
+ return false;
169
+ }
170
+ traces.push(createTraceEntry("event type", "tag", event.type, true));
171
+ if (trigger.patterns.length > 0) {
172
+ const matches = matchAnyBranch(trigger.patterns, event.targetBranch);
173
+ traces.push(createTraceEntry("tag pattern", trigger.patterns.map((p) => p.pattern).join("|"), event.targetBranch, matches));
174
+ if (!matches) return false;
175
+ }
176
+ if (!evaluateRepoFilter(trigger, event, traces)) return false;
177
+ return true;
178
+ }
179
+ /**
180
+ * Match a comment trigger against a simulated event.
181
+ * Supports action filter, source filter (issue vs PR), and bodyMatch (glob/regex).
182
+ */
183
+ function matchCommentTrigger(trigger, event, traces) {
184
+ if (event.type !== "comment") {
185
+ traces.push(createTraceEntry("event type", "comment", event.type, false));
186
+ return false;
187
+ }
188
+ traces.push(createTraceEntry("event type", "comment", event.type, true));
189
+ if (trigger.actions.length > 0) {
190
+ const action = event.action ?? "";
191
+ const matches = trigger.actions.includes(action);
192
+ traces.push(createTraceEntry("action", trigger.actions.join("|"), action, matches));
193
+ if (!matches) return false;
194
+ }
195
+ if (trigger.source) {
196
+ const issue = event.payload.issue;
197
+ const isFromPr = !!(issue && "pull_request" in issue);
198
+ if (trigger.source === "issue") {
199
+ const matches = !isFromPr;
200
+ traces.push(createTraceEntry("source", "issue", isFromPr ? "pr" : "issue", matches));
201
+ if (!matches) return false;
202
+ } else {
203
+ const matches = isFromPr;
204
+ traces.push(createTraceEntry("source", "pr", isFromPr ? "pr" : "issue", matches));
205
+ if (!matches) return false;
206
+ }
207
+ }
208
+ if (trigger.bodyMatch) {
209
+ const body = event.payload.comment?.body ?? "";
210
+ if (trigger.bodyMatch.type === "glob") {
211
+ const matches = picomatch.isMatch(body, trigger.bodyMatch.pattern);
212
+ traces.push(createTraceEntry("bodyMatch (glob)", trigger.bodyMatch.pattern, body, matches));
213
+ if (!matches) return false;
214
+ } else {
215
+ const matches = new RegExp(trigger.bodyMatch.pattern, trigger.bodyMatch.flags).test(body);
216
+ traces.push(createTraceEntry("bodyMatch (regex)", trigger.bodyMatch.pattern, body, matches));
217
+ if (!matches) return false;
218
+ }
219
+ }
220
+ if (!evaluateRepoFilter(trigger, event, traces)) return false;
221
+ return true;
222
+ }
223
+ /**
224
+ * Match a review trigger against a simulated event.
225
+ * Supports action and review state filters.
226
+ */
227
+ function matchReviewTrigger(trigger, event, traces) {
228
+ if (event.type !== "review") {
229
+ traces.push(createTraceEntry("event type", "review", event.type, false));
230
+ return false;
231
+ }
232
+ traces.push(createTraceEntry("event type", "review", event.type, true));
233
+ if (trigger.actions.length > 0) {
234
+ const action = event.action ?? "";
235
+ const matches = trigger.actions.includes(action);
236
+ traces.push(createTraceEntry("action", trigger.actions.join("|"), action, matches));
237
+ if (!matches) return false;
238
+ }
239
+ if (trigger.states.length > 0) {
240
+ const state = event.payload.review?.state ?? "";
241
+ const matches = trigger.states.includes(state);
242
+ traces.push(createTraceEntry("state", trigger.states.join("|"), state, matches));
243
+ if (!matches) return false;
244
+ }
245
+ if (!evaluateRepoFilter(trigger, event, traces)) return false;
246
+ return true;
247
+ }
248
+ /**
249
+ * Match a review comment trigger against a simulated event.
250
+ * Supports action filter.
251
+ */
252
+ function matchReviewCommentTrigger(trigger, event, traces) {
253
+ if (event.type !== "review_comment") {
254
+ traces.push(createTraceEntry("event type", "review_comment", event.type, false));
255
+ return false;
256
+ }
257
+ traces.push(createTraceEntry("event type", "review_comment", event.type, true));
258
+ if (trigger.actions.length > 0) {
259
+ const action = event.action ?? "";
260
+ const matches = trigger.actions.includes(action);
261
+ traces.push(createTraceEntry("action", trigger.actions.join("|"), action, matches));
262
+ if (!matches) return false;
263
+ }
264
+ if (!evaluateRepoFilter(trigger, event, traces)) return false;
265
+ return true;
266
+ }
267
+ /**
268
+ * Match a release trigger against a simulated event.
269
+ * Supports action filter (published, created, etc.).
270
+ */
271
+ function matchReleaseTrigger(trigger, event, traces) {
272
+ if (event.type !== "release") {
273
+ traces.push(createTraceEntry("event type", "release", event.type, false));
274
+ return false;
275
+ }
276
+ traces.push(createTraceEntry("event type", "release", event.type, true));
277
+ if (trigger.actions.length > 0) {
278
+ const action = event.action ?? "";
279
+ const matches = trigger.actions.includes(action);
280
+ traces.push(createTraceEntry("action", trigger.actions.join("|"), action, matches));
281
+ if (!matches) return false;
282
+ }
283
+ if (!evaluateRepoFilter(trigger, event, traces)) return false;
284
+ return true;
285
+ }
286
+ /**
287
+ * Match a dispatch trigger against a simulated event.
288
+ * GitHub sends event_type as action for repository_dispatch.
289
+ */
290
+ function matchDispatchTrigger(trigger, event, traces) {
291
+ if (event.type !== "dispatch") {
292
+ traces.push(createTraceEntry("event type", "dispatch", event.type, false));
293
+ return false;
294
+ }
295
+ traces.push(createTraceEntry("event type", "dispatch", event.type, true));
296
+ if (trigger.types.length > 0) {
297
+ const action = event.action ?? "";
298
+ const matches = trigger.types.includes(action);
299
+ traces.push(createTraceEntry("dispatch type", trigger.types.join("|"), action, matches));
300
+ if (!matches) return false;
301
+ }
302
+ if (!evaluateRepoFilter(trigger, event, traces)) return false;
303
+ return true;
304
+ }
305
+ /**
306
+ * Match a create trigger against a simulated event.
307
+ * Checks refType and ref pattern against payload fields.
308
+ */
309
+ function matchCreateTrigger(trigger, event, traces) {
310
+ if (event.type !== "create") {
311
+ traces.push(createTraceEntry("event type", "create", event.type, false));
312
+ return false;
313
+ }
314
+ traces.push(createTraceEntry("event type", "create", event.type, true));
315
+ if (trigger.refTypes.length > 0) {
316
+ const refType = event.payload.ref_type;
317
+ const matches = trigger.refTypes.includes(refType);
318
+ traces.push(createTraceEntry("ref type", trigger.refTypes.join("|"), refType, matches));
319
+ if (!matches) return false;
320
+ }
321
+ if (trigger.patterns.length > 0) {
322
+ const ref = event.payload.ref;
323
+ const matches = matchAnyBranch(trigger.patterns, ref);
324
+ traces.push(createTraceEntry("ref pattern", trigger.patterns.map((p) => p.pattern).join("|"), ref, matches));
325
+ if (!matches) return false;
326
+ }
327
+ if (!evaluateRepoFilter(trigger, event, traces)) return false;
328
+ return true;
329
+ }
330
+ /**
331
+ * Match a delete trigger against a simulated event.
332
+ * Same structure as create trigger.
333
+ */
334
+ function matchDeleteTrigger(trigger, event, traces) {
335
+ if (event.type !== "delete") {
336
+ traces.push(createTraceEntry("event type", "delete", event.type, false));
337
+ return false;
338
+ }
339
+ traces.push(createTraceEntry("event type", "delete", event.type, true));
340
+ if (trigger.refTypes.length > 0) {
341
+ const refType = event.payload.ref_type;
342
+ const matches = trigger.refTypes.includes(refType);
343
+ traces.push(createTraceEntry("ref type", trigger.refTypes.join("|"), refType, matches));
344
+ if (!matches) return false;
345
+ }
346
+ if (trigger.patterns.length > 0) {
347
+ const ref = event.payload.ref;
348
+ const matches = matchAnyBranch(trigger.patterns, ref);
349
+ traces.push(createTraceEntry("ref pattern", trigger.patterns.map((p) => p.pattern).join("|"), ref, matches));
350
+ if (!matches) return false;
351
+ }
352
+ if (!evaluateRepoFilter(trigger, event, traces)) return false;
353
+ return true;
354
+ }
355
+ /**
356
+ * Match a status trigger against a simulated event.
357
+ * Checks context via picomatch and state filter.
358
+ */
359
+ function matchStatusTrigger(trigger, event, traces) {
360
+ if (event.type !== "status") {
361
+ traces.push(createTraceEntry("event type", "status", event.type, false));
362
+ return false;
363
+ }
364
+ traces.push(createTraceEntry("event type", "status", event.type, true));
365
+ if (trigger.contexts.length > 0) {
366
+ const context = event.payload.context ?? "";
367
+ const matches = trigger.contexts.some((pattern) => picomatch.isMatch(context, pattern));
368
+ traces.push(createTraceEntry("context", trigger.contexts.join("|"), context, matches));
369
+ if (!matches) return false;
370
+ }
371
+ if (trigger.states.length > 0) {
372
+ const state = event.payload.state ?? "";
373
+ const matches = trigger.states.includes(state);
374
+ traces.push(createTraceEntry("state", trigger.states.join("|"), state, matches));
375
+ if (!matches) return false;
376
+ }
377
+ if (!evaluateRepoFilter(trigger, event, traces)) return false;
378
+ return true;
379
+ }
380
+ /**
381
+ * Match a workflow_run trigger against a simulated event.
382
+ * Checks action, workflow name, and conclusion filters.
383
+ */
384
+ function matchWorkflowRunTrigger(trigger, event, traces) {
385
+ if (event.type !== "workflow_run") {
386
+ traces.push(createTraceEntry("event type", "workflow_run", event.type, false));
387
+ return false;
388
+ }
389
+ traces.push(createTraceEntry("event type", "workflow_run", event.type, true));
390
+ if (trigger.actions.length > 0) {
391
+ const action = event.action ?? "";
392
+ const matches = trigger.actions.includes(action);
393
+ traces.push(createTraceEntry("action", trigger.actions.join("|"), action, matches));
394
+ if (!matches) return false;
395
+ }
396
+ const workflowRun = event.payload.workflow_run;
397
+ if (trigger.workflows.length > 0) {
398
+ const name = workflowRun?.name ?? "";
399
+ const matches = trigger.workflows.includes(name);
400
+ traces.push(createTraceEntry("workflow name", trigger.workflows.join("|"), name, matches));
401
+ if (!matches) return false;
402
+ }
403
+ if (trigger.conclusions.length > 0) {
404
+ const conclusion = workflowRun?.conclusion ?? "";
405
+ const matches = trigger.conclusions.includes(conclusion);
406
+ traces.push(createTraceEntry("conclusion", trigger.conclusions.join("|"), conclusion, matches));
407
+ if (!matches) return false;
408
+ }
409
+ if (!evaluateRepoFilter(trigger, event, traces)) return false;
410
+ return true;
411
+ }
412
+ /**
413
+ * Match a fork trigger against a simulated event.
414
+ * Fork triggers match unconditionally (no filter fields).
415
+ */
416
+ function matchForkTrigger(trigger, event, traces) {
417
+ if (event.type !== "fork") {
418
+ traces.push(createTraceEntry("event type", "fork", event.type, false));
419
+ return false;
420
+ }
421
+ traces.push(createTraceEntry("event type", "fork", event.type, true));
422
+ if (!evaluateRepoFilter(trigger, event, traces)) return false;
423
+ return true;
424
+ }
425
+ /**
426
+ * Match a star trigger against a simulated event.
427
+ * Supports action filter (created, deleted).
428
+ */
429
+ function matchStarTrigger(trigger, event, traces) {
430
+ if (event.type !== "star") {
431
+ traces.push(createTraceEntry("event type", "star", event.type, false));
432
+ return false;
433
+ }
434
+ traces.push(createTraceEntry("event type", "star", event.type, true));
435
+ if (trigger.actions.length > 0) {
436
+ const action = event.action ?? "";
437
+ const matches = trigger.actions.includes(action);
438
+ traces.push(createTraceEntry("action", trigger.actions.join("|"), action, matches));
439
+ if (!matches) return false;
440
+ }
441
+ if (!evaluateRepoFilter(trigger, event, traces)) return false;
442
+ return true;
443
+ }
444
+ /**
445
+ * Match a watch trigger against a simulated event.
446
+ * Supports action filter (started).
447
+ */
448
+ function matchWatchTrigger(trigger, event, traces) {
449
+ if (event.type !== "watch") {
450
+ traces.push(createTraceEntry("event type", "watch", event.type, false));
451
+ return false;
452
+ }
453
+ traces.push(createTraceEntry("event type", "watch", event.type, true));
454
+ if (trigger.actions.length > 0) {
455
+ const action = event.action ?? "";
456
+ const matches = trigger.actions.includes(action);
457
+ traces.push(createTraceEntry("action", trigger.actions.join("|"), action, matches));
458
+ if (!matches) return false;
459
+ }
460
+ if (!evaluateRepoFilter(trigger, event, traces)) return false;
461
+ return true;
462
+ }
463
+ /**
464
+ * Match a generic webhook trigger against a simulated event.
465
+ * Matches event type against the events array, then optionally filters by action.
466
+ */
467
+ function matchWebhookTrigger(trigger, event, traces) {
468
+ const eventMatches = trigger.events.includes(event.type);
469
+ traces.push(createTraceEntry("event type", trigger.events.join("|"), event.type, eventMatches));
470
+ if (!eventMatches) return false;
471
+ if (trigger.actions.length > 0) {
472
+ const action = event.action ?? "";
473
+ const matches = trigger.actions.includes(action);
474
+ traces.push(createTraceEntry("action", trigger.actions.join("|"), action, matches));
475
+ if (!matches) return false;
476
+ }
477
+ if (!evaluateRepoFilter(trigger, event, traces)) return false;
478
+ return true;
479
+ }
480
+ /**
481
+ * Match a kici_event trigger against a simulated event.
482
+ * Checks event name, optional JSONPath match/not, and source filter.
483
+ */
484
+ function matchKiciEventTrigger(trigger, event, traces) {
485
+ if (event.type !== "kici_event") {
486
+ traces.push(createTraceEntry("event type", "kici_event", event.type, false));
487
+ return false;
488
+ }
489
+ traces.push(createTraceEntry("event type", "kici_event", event.type, true));
490
+ const eventName = event.payload.eventName ?? "";
491
+ const nameMatches = eventName === trigger.eventName;
492
+ traces.push(createTraceEntry("event name", trigger.eventName, eventName, nameMatches));
493
+ if (!nameMatches) return false;
494
+ if (trigger.match && Object.keys(trigger.match).length > 0) {
495
+ const matches = matchJsonPath(event.payload.payload ?? {}, trigger.match);
496
+ traces.push(createTraceEntry("jsonpath match", JSON.stringify(trigger.match), "(payload)", matches));
497
+ if (!matches) return false;
498
+ }
499
+ if (trigger.not && Object.keys(trigger.not).length > 0) {
500
+ const passes = matchJsonPathNot(event.payload.payload ?? {}, trigger.not);
501
+ traces.push(createTraceEntry("jsonpath not", JSON.stringify(trigger.not), "(payload)", passes));
502
+ if (!passes) return false;
503
+ }
504
+ if (trigger.source) {
505
+ const sourceRepo = event.payload.sourceRepo ?? "";
506
+ const matches = sourceRepo === trigger.source;
507
+ traces.push(createTraceEntry("source", trigger.source, sourceRepo, matches));
508
+ if (!matches) return false;
509
+ }
510
+ return true;
511
+ }
512
+ /**
513
+ * Match a workflow_complete trigger against a simulated event.
514
+ * Checks workflow name, status array, and source filter.
515
+ */
516
+ function matchWorkflowCompleteTrigger(trigger, event, traces) {
517
+ if (event.type !== "workflow_complete") {
518
+ traces.push(createTraceEntry("event type", "workflow_complete", event.type, false));
519
+ return false;
520
+ }
521
+ traces.push(createTraceEntry("event type", "workflow_complete", event.type, true));
522
+ if (trigger.name) {
523
+ const workflowName = event.payload.workflowName ?? "";
524
+ const matches = workflowName === trigger.name;
525
+ traces.push(createTraceEntry("workflow name", trigger.name, workflowName, matches));
526
+ if (!matches) return false;
527
+ }
528
+ if (trigger.status && trigger.status.length > 0) {
529
+ const status = event.payload.status ?? "";
530
+ const matches = trigger.status.includes(status);
531
+ traces.push(createTraceEntry("status", trigger.status.join("|"), status, matches));
532
+ if (!matches) return false;
533
+ }
534
+ if (trigger.source) {
535
+ const sourceRepo = event.payload.sourceRepo ?? "";
536
+ const matches = sourceRepo === trigger.source;
537
+ traces.push(createTraceEntry("source", trigger.source, sourceRepo, matches));
538
+ if (!matches) return false;
539
+ }
540
+ return true;
541
+ }
542
+ /**
543
+ * Match a job_complete trigger against a simulated event.
544
+ * Checks workflow name, job name, status array, and source filter.
545
+ */
546
+ function matchJobCompleteTrigger(trigger, event, traces) {
547
+ if (event.type !== "job_complete") {
548
+ traces.push(createTraceEntry("event type", "job_complete", event.type, false));
549
+ return false;
550
+ }
551
+ traces.push(createTraceEntry("event type", "job_complete", event.type, true));
552
+ if (trigger.workflow) {
553
+ const workflowName = event.payload.workflowName ?? "";
554
+ const matches = workflowName === trigger.workflow;
555
+ traces.push(createTraceEntry("workflow name", trigger.workflow, workflowName, matches));
556
+ if (!matches) return false;
557
+ }
558
+ if (trigger.job) {
559
+ const jobName = event.payload.jobName ?? "";
560
+ const matches = jobName === trigger.job;
561
+ traces.push(createTraceEntry("job name", trigger.job, jobName, matches));
562
+ if (!matches) return false;
563
+ }
564
+ if (trigger.status && trigger.status.length > 0) {
565
+ const status = event.payload.status ?? "";
566
+ const matches = trigger.status.includes(status);
567
+ traces.push(createTraceEntry("status", trigger.status.join("|"), status, matches));
568
+ if (!matches) return false;
569
+ }
570
+ if (trigger.source) {
571
+ const sourceRepo = event.payload.sourceRepo ?? "";
572
+ const matches = sourceRepo === trigger.source;
573
+ traces.push(createTraceEntry("source", trigger.source, sourceRepo, matches));
574
+ if (!matches) return false;
575
+ }
576
+ return true;
577
+ }
578
+ /**
579
+ * Match a generic_webhook trigger against a simulated event.
580
+ * Checks source ID, optional events array, and JSONPath match/not.
581
+ */
582
+ function matchGenericWebhookTrigger(trigger, event, traces) {
583
+ if (event.type !== "generic_webhook") {
584
+ traces.push(createTraceEntry("event type", "generic_webhook", event.type, false));
585
+ return false;
586
+ }
587
+ traces.push(createTraceEntry("event type", "generic_webhook", event.type, true));
588
+ const eventSource = event.payload.source ?? "";
589
+ const sourceMatches = eventSource === trigger.source;
590
+ traces.push(createTraceEntry("source", trigger.source, eventSource, sourceMatches));
591
+ if (!sourceMatches) return false;
592
+ if (trigger.events && trigger.events.length > 0) {
593
+ const eventType = event.payload.eventType ?? event.action ?? "";
594
+ const matches = trigger.events.includes(eventType);
595
+ traces.push(createTraceEntry("event type filter", trigger.events.join("|"), eventType, matches));
596
+ if (!matches) return false;
597
+ }
598
+ if (trigger.match && Object.keys(trigger.match).length > 0) {
599
+ const matches = matchJsonPath(event.payload, trigger.match);
600
+ traces.push(createTraceEntry("jsonpath match", JSON.stringify(trigger.match), "(payload)", matches));
601
+ if (!matches) return false;
602
+ }
603
+ if (trigger.not && Object.keys(trigger.not).length > 0) {
604
+ const passes = matchJsonPathNot(event.payload, trigger.not);
605
+ traces.push(createTraceEntry("jsonpath not", JSON.stringify(trigger.not), "(payload)", passes));
606
+ if (!passes) return false;
607
+ }
608
+ return true;
609
+ }
610
+ /**
611
+ * Match a schedule trigger against a simulated event.
612
+ * Schedule triggers match when the event type is 'schedule' and the cron expression matches.
613
+ */
614
+ function matchScheduleTrigger(trigger, event, traces) {
615
+ if (event.type !== "schedule") {
616
+ traces.push(createTraceEntry("event type", "schedule", event.type, false));
617
+ return false;
618
+ }
619
+ traces.push(createTraceEntry("event type", "schedule", event.type, true));
620
+ const cronExpression = event.payload.cronExpression ?? "";
621
+ const matches = cronExpression === trigger.cronExpression;
622
+ traces.push(createTraceEntry("cron expression", trigger.cronExpression, cronExpression, matches));
623
+ if (!matches) return false;
624
+ return true;
625
+ }
626
+ /**
627
+ * Match a lifecycle trigger against a simulated event.
628
+ * Lifecycle triggers match when event type is 'lifecycle', the lifecycle event is in the trigger's
629
+ * events array, and optionally the source repo matches.
630
+ */
631
+ function matchLifecycleTrigger(trigger, event, traces) {
632
+ if (event.type !== "lifecycle") {
633
+ traces.push(createTraceEntry("event type", "lifecycle", event.type, false));
634
+ return false;
635
+ }
636
+ traces.push(createTraceEntry("event type", "lifecycle", event.type, true));
637
+ const lifecycleEvent = event.payload.lifecycleEvent ?? "";
638
+ const eventMatches = trigger.events.includes(lifecycleEvent);
639
+ traces.push(createTraceEntry("lifecycle event", trigger.events.join("|"), lifecycleEvent, eventMatches));
640
+ if (!eventMatches) return false;
641
+ if (trigger.sources && trigger.sources.length > 0) {
642
+ const sourceRepo = event.payload.sourceRepo ?? "";
643
+ const sourceMatches = trigger.sources.includes(sourceRepo);
644
+ traces.push(createTraceEntry("source", trigger.sources.join("|"), sourceRepo, sourceMatches));
645
+ if (!sourceMatches) return false;
646
+ }
647
+ return true;
648
+ }
649
+ /**
650
+ * Match a trigger against a simulated event.
651
+ */
652
+ function matchTrigger(trigger, event, traces) {
653
+ switch (trigger._type) {
654
+ case "pr": return matchPrTrigger(trigger, event, traces);
655
+ case "push": return matchPushTrigger(trigger, event, traces);
656
+ case "tag": return matchTagTrigger(trigger, event, traces);
657
+ case "comment": return matchCommentTrigger(trigger, event, traces);
658
+ case "review": return matchReviewTrigger(trigger, event, traces);
659
+ case "review_comment": return matchReviewCommentTrigger(trigger, event, traces);
660
+ case "release": return matchReleaseTrigger(trigger, event, traces);
661
+ case "dispatch": return matchDispatchTrigger(trigger, event, traces);
662
+ case "create": return matchCreateTrigger(trigger, event, traces);
663
+ case "delete": return matchDeleteTrigger(trigger, event, traces);
664
+ case "status": return matchStatusTrigger(trigger, event, traces);
665
+ case "workflow_run": return matchWorkflowRunTrigger(trigger, event, traces);
666
+ case "fork": return matchForkTrigger(trigger, event, traces);
667
+ case "star": return matchStarTrigger(trigger, event, traces);
668
+ case "watch": return matchWatchTrigger(trigger, event, traces);
669
+ case "webhook": return matchWebhookTrigger(trigger, event, traces);
670
+ case "kici_event": return matchKiciEventTrigger(trigger, event, traces);
671
+ case "workflow_complete": return matchWorkflowCompleteTrigger(trigger, event, traces);
672
+ case "job_complete": return matchJobCompleteTrigger(trigger, event, traces);
673
+ case "generic_webhook": return matchGenericWebhookTrigger(trigger, event, traces);
674
+ case "schedule": return matchScheduleTrigger(trigger, event, traces);
675
+ case "lifecycle": return matchLifecycleTrigger(trigger, event, traces);
676
+ default: return false;
677
+ }
678
+ }
679
+ /**
680
+ * Match all triggers for a workflow against an event.
681
+ * Returns WorkflowDecision with full trace.
682
+ */
683
+ function matchWorkflowTriggers(workflow, event) {
684
+ const allTraces = [];
685
+ if (workflow.triggers.length === 0) return createWorkflowDecision(workflow.name, false, [], void 0, "No triggers defined");
686
+ for (let i = 0; i < workflow.triggers.length; i++) {
687
+ const trigger = workflow.triggers[i];
688
+ if (trigger == null) continue;
689
+ const triggerTraces = [];
690
+ if (matchTrigger(trigger, event, triggerTraces)) return createWorkflowDecision(workflow.name, true, triggerTraces, i, `Matched trigger ${i + 1} (${trigger._type})`);
691
+ allTraces.push(...triggerTraces);
692
+ }
693
+ return createWorkflowDecision(workflow.name, false, allTraces, void 0, "No triggers matched");
694
+ }
695
+ /**
696
+ * Match all workflows against an event.
697
+ */
698
+ function matchAllWorkflows(workflows, event) {
699
+ return workflows.map((w) => matchWorkflowTriggers(w, event));
700
+ }
701
+ //#endregion
702
+ export { matchAllWorkflows, matchBranchPattern, matchPathPatterns, matchRepoPatterns, matchWorkflowTriggers };
703
+
704
+ //# sourceMappingURL=matcher.js.map