@kici-dev/engine 0.4.0 → 0.5.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.
- package/dist/context/host-match.js +2 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +7 -5
- package/dist/labels/compile.d.ts +2 -7
- package/dist/labels/compile.js +1 -10
- package/dist/labels.d.ts +8 -0
- package/dist/labels.js +9 -1
- package/dist/metrics/catalog-policy.d.ts +11 -0
- package/dist/metrics/catalog-policy.js +13 -3
- package/dist/metrics/metric-catalog.generated.d.ts +30 -0
- package/dist/metrics/metric-catalog.generated.js +36 -0
- package/dist/protocol/messages/dashboard-global-workflows.d.ts +8 -3
- package/dist/protocol/messages/dashboard-global-workflows.js +20 -3
- package/dist/protocol/messages/dashboard.d.ts +5 -2
- package/dist/protocol/messages/dashboard.js +7 -0
- package/dist/protocol/messages/execution-status.d.ts +3 -0
- package/dist/protocol/messages/execution-status.js +16 -0
- package/dist/protocol/messages/orchestrator-agent.d.ts +49 -0
- package/dist/protocol/messages/orchestrator-agent.js +34 -1
- package/dist/protocol/messages/platform-orchestrator.d.ts +5 -2
- package/dist/protocol/messages/platform-orchestrator.js +14 -0
- package/dist/provider/check-status-poster.d.ts +14 -0
- package/dist/provider/file-contents-fetcher.d.ts +39 -0
- package/dist/provider/file-contents-fetcher.js +2 -0
- package/dist/provider/index.d.ts +2 -0
- package/dist/safe-regex.d.ts +16 -0
- package/dist/safe-regex.js +24 -0
- package/dist/trigger/compiled-matchers.d.ts +21 -1
- package/dist/trigger/compiled-matchers.js +30 -3
- package/dist/trigger/content-requirements.d.ts +31 -0
- package/dist/trigger/content-requirements.js +125 -0
- package/dist/trigger/decision-trace.d.ts +89 -0
- package/dist/trigger/decision-trace.js +96 -1
- package/dist/trigger/jsonpath-matcher.js +5 -1
- package/dist/trigger/matcher.js +57 -8
- package/dist/trigger/text-match.d.ts +27 -0
- package/dist/trigger/text-match.js +86 -0
- package/dist/trigger/types.d.ts +179 -17
- package/dist/trigger/types.js +32 -5
- package/package.json +10 -1
- package/sbom.spdx.json +30 -5
package/dist/trigger/types.d.ts
CHANGED
|
@@ -29,6 +29,10 @@
|
|
|
29
29
|
* Schema version 30 (BREAKING): renames job-level `environments` to `contexts`.
|
|
30
30
|
* Schema version 31 (additive): adds the workflows_failed_batch lock trigger.
|
|
31
31
|
* Schema version 32 (additive): adds LockJob.sandbox (per-job escape-hatch request).
|
|
32
|
+
* Schema version 33 (additive): adds `requires` (declarative static content filter) to the push/pr/tag git-event triggers.
|
|
33
|
+
* Schema version 34 (additive): adds LockWorkflow.hasFilter (workflow-level pre-dispatch filter predicate).
|
|
34
|
+
* Schema version 35 (additive): adds `commitMessage` (LockTextMatch) to the push/pr/tag
|
|
35
|
+
* git-event triggers, and contains/notContains/notMatches to LockContentRequirement.
|
|
32
36
|
*/
|
|
33
37
|
import { z } from 'zod';
|
|
34
38
|
import type { ProviderType } from '../provider/types.js';
|
|
@@ -41,7 +45,7 @@ import { ExecutionJobStatus } from '../protocol/messages/execution-status.js';
|
|
|
41
45
|
* schema change (additive or breaking); the bump-history comment above records
|
|
42
46
|
* which. See `BREAKING_FLOOR` for the compatibility-window semantics.
|
|
43
47
|
*/
|
|
44
|
-
export declare const SCHEMA_VERSION:
|
|
48
|
+
export declare const SCHEMA_VERSION: 35;
|
|
45
49
|
/**
|
|
46
50
|
* Oldest lock schema version this codebase can still read correctly — the lower
|
|
47
51
|
* bound of the acceptance window.
|
|
@@ -54,8 +58,8 @@ export declare const SCHEMA_VERSION: 32;
|
|
|
54
58
|
* Bump rule: move this to the current `SCHEMA_VERSION` ONLY in the commit that
|
|
55
59
|
* lands a `BREAKING` schema change (see the bump-history convention above). It
|
|
56
60
|
* currently sits at 30 because v30 (`environments`→`contexts`) was the most
|
|
57
|
-
* recent breaking bump; v31
|
|
58
|
-
* correctly.
|
|
61
|
+
* recent breaking bump; v31 through v35 were additive, so a v30 lock still
|
|
62
|
+
* reads correctly.
|
|
59
63
|
*/
|
|
60
64
|
export declare const BREAKING_FLOOR: 30;
|
|
61
65
|
/**
|
|
@@ -92,6 +96,121 @@ export interface LockBranchPattern {
|
|
|
92
96
|
readonly pattern: string;
|
|
93
97
|
readonly flags?: string;
|
|
94
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* A declarative query over one piece of text: literal substrings and/or a
|
|
101
|
+
* regex, in either direction. Pure DATA the orchestrator interprets — never
|
|
102
|
+
* author code — so it is safe to evaluate inside the orchestrator under the
|
|
103
|
+
* execution-purity model.
|
|
104
|
+
*
|
|
105
|
+
* Every entry in a list is a CONJUNCT: `contains: [a, b]` means the text
|
|
106
|
+
* contains `a` AND contains `b`. OR is expressed by declaring two triggers,
|
|
107
|
+
* since a workflow's trigger list is already "first match wins".
|
|
108
|
+
*
|
|
109
|
+
* This is the SDK-facing shape a workflow author writes; the compiler
|
|
110
|
+
* normalizes it to {@link LockTextMatch}.
|
|
111
|
+
*/
|
|
112
|
+
export interface TextMatch {
|
|
113
|
+
/** Literal substring(s). Every entry must be present. */
|
|
114
|
+
readonly contains?: string | readonly string[];
|
|
115
|
+
/** Literal substring(s). No entry may be present. */
|
|
116
|
+
readonly notContains?: string | readonly string[];
|
|
117
|
+
/** Regex(es), as a RegExp or a `/pattern/flags` string. Every one must match. */
|
|
118
|
+
readonly matches?: string | RegExp | readonly (string | RegExp)[];
|
|
119
|
+
/** Regex(es). None may match. */
|
|
120
|
+
readonly notMatches?: string | RegExp | readonly (string | RegExp)[];
|
|
121
|
+
/**
|
|
122
|
+
* Case-insensitive comparison for `contains`/`notContains` ONLY. Default false.
|
|
123
|
+
* It deliberately does not touch the regex keys: a regex already carries its
|
|
124
|
+
* own flags, and injecting `i` into a pattern whose author omitted it would
|
|
125
|
+
* silently change its meaning.
|
|
126
|
+
*/
|
|
127
|
+
readonly ignoreCase?: boolean;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Lock-file form of {@link TextMatch}. The compiler normalizes every key to a
|
|
131
|
+
* flat array, and every regex to a `/pattern/flags` string, so the orchestrator
|
|
132
|
+
* matcher has exactly one shape to interpret.
|
|
133
|
+
*/
|
|
134
|
+
export interface LockTextMatch {
|
|
135
|
+
readonly contains?: readonly string[];
|
|
136
|
+
readonly notContains?: readonly string[];
|
|
137
|
+
/** Always in `/pattern/flags` form. */
|
|
138
|
+
readonly matches?: readonly string[];
|
|
139
|
+
/** Always in `/pattern/flags` form. */
|
|
140
|
+
readonly notMatches?: readonly string[];
|
|
141
|
+
readonly ignoreCase?: boolean;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* How a file's bytes are parsed before a content query runs.
|
|
145
|
+
* `auto` picks by extension: `.json` → json, `.yaml`/`.yml` → yaml, else text.
|
|
146
|
+
*/
|
|
147
|
+
export type ContentFormat = 'json' | 'yaml' | 'text' | 'auto';
|
|
148
|
+
/**
|
|
149
|
+
* Declarative static content filter: a query over the bytes of one source file
|
|
150
|
+
* at the event's ref. Pure DATA the orchestrator's own matcher interprets — never
|
|
151
|
+
* author code — so it is safe to evaluate in the orchestrator (Part B of the
|
|
152
|
+
* execution-purity model). Query keys
|
|
153
|
+
* (`exists`/`match`/`not`/`contains`/`notContains`/`matches`/`notMatches`) are
|
|
154
|
+
* AND-ed within an entry; `absent` is mutually exclusive with them and passes
|
|
155
|
+
* only when the file is missing.
|
|
156
|
+
*
|
|
157
|
+
* This is the SDK-facing shape a workflow author writes, which accepts a scalar
|
|
158
|
+
* or `RegExp` where the lock form ({@link LockContentRequirement}) carries a flat
|
|
159
|
+
* array of `/pattern/flags` strings — the compiler normalizes one to the other.
|
|
160
|
+
*/
|
|
161
|
+
export interface ContentRequirement {
|
|
162
|
+
/** Repo-relative path of the file to query. */
|
|
163
|
+
readonly file: string;
|
|
164
|
+
/** Parse format; defaults to `auto` when unset. */
|
|
165
|
+
readonly format?: ContentFormat;
|
|
166
|
+
/** JSONPath expressions that must each resolve to ≥1 node (json/yaml only). */
|
|
167
|
+
readonly exists?: readonly string[];
|
|
168
|
+
/** JSONPath → expected-value map; every expression must match (json/yaml only). */
|
|
169
|
+
readonly match?: Record<string, unknown>;
|
|
170
|
+
/** JSONPath → value map; passes only when NONE match (json/yaml only). */
|
|
171
|
+
readonly not?: Record<string, unknown>;
|
|
172
|
+
/** Literal substring(s) that must ALL be present in the raw file text. */
|
|
173
|
+
readonly contains?: string | readonly string[];
|
|
174
|
+
/** Literal substring(s) of which NONE may be present in the raw file text. */
|
|
175
|
+
readonly notContains?: string | readonly string[];
|
|
176
|
+
/** Regex(es) that must ALL match the raw file text (RegExp or `/pattern/flags`). */
|
|
177
|
+
readonly matches?: string | RegExp | readonly (string | RegExp)[];
|
|
178
|
+
/** Regex(es) of which NONE may match the raw file text. */
|
|
179
|
+
readonly notMatches?: string | RegExp | readonly (string | RegExp)[];
|
|
180
|
+
/** Case-insensitive `contains`/`notContains`. Default false. */
|
|
181
|
+
readonly ignoreCase?: boolean;
|
|
182
|
+
/** When true, the entry passes only if the file is absent. Excludes all query keys. */
|
|
183
|
+
readonly absent?: boolean;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Lock-file form of {@link ContentRequirement}. The compiler normalizes each
|
|
187
|
+
* raw-text key to the flat {@link LockTextMatch} shape, so the orchestrator
|
|
188
|
+
* matcher has one shape to interpret.
|
|
189
|
+
*/
|
|
190
|
+
export interface LockContentRequirement {
|
|
191
|
+
readonly file: string;
|
|
192
|
+
readonly format?: ContentFormat;
|
|
193
|
+
readonly exists?: readonly string[];
|
|
194
|
+
readonly match?: Record<string, unknown>;
|
|
195
|
+
readonly not?: Record<string, unknown>;
|
|
196
|
+
readonly contains?: readonly string[];
|
|
197
|
+
readonly notContains?: readonly string[];
|
|
198
|
+
readonly matches?: readonly string[];
|
|
199
|
+
readonly notMatches?: readonly string[];
|
|
200
|
+
readonly ignoreCase?: boolean;
|
|
201
|
+
readonly absent?: boolean;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Resolve a content requirement's parse format to a concrete value. An explicit
|
|
205
|
+
* non-`auto` format is returned as-is; `auto` (or unset) is resolved by the file
|
|
206
|
+
* extension: `.json` → json, `.yaml`/`.yml` → yaml, everything else text.
|
|
207
|
+
*
|
|
208
|
+
* Yaml-free (pure string logic) so it lives in the browser-safe barrel and is
|
|
209
|
+
* the single source of truth for both the compiler's compile-time serializer and
|
|
210
|
+
* the orchestrator's eval-time matcher — the two can never disagree about how a
|
|
211
|
+
* file's format is picked.
|
|
212
|
+
*/
|
|
213
|
+
export declare function resolveContentFormat(file: string, format: ContentFormat | undefined): 'json' | 'yaml' | 'text';
|
|
95
214
|
/**
|
|
96
215
|
* PR trigger in lock file.
|
|
97
216
|
* Optimized for orchestrator event matching - flat structure with all filters accessible.
|
|
@@ -103,6 +222,10 @@ export interface LockPrTrigger {
|
|
|
103
222
|
readonly sourceBranches: readonly LockBranchPattern[];
|
|
104
223
|
readonly paths: readonly string[];
|
|
105
224
|
readonly repos?: readonly LockBranchPattern[];
|
|
225
|
+
/** Declarative static content filter over source files at the event ref (AND-ed). */
|
|
226
|
+
readonly requires?: readonly LockContentRequirement[];
|
|
227
|
+
/** Declarative static filter over the event's commit message / PR title+body. */
|
|
228
|
+
readonly commitMessage?: LockTextMatch;
|
|
106
229
|
}
|
|
107
230
|
/**
|
|
108
231
|
* Push trigger in lock file.
|
|
@@ -113,6 +236,10 @@ export interface LockPushTrigger {
|
|
|
113
236
|
readonly branches: readonly LockBranchPattern[];
|
|
114
237
|
readonly paths: readonly string[];
|
|
115
238
|
readonly repos?: readonly LockBranchPattern[];
|
|
239
|
+
/** Declarative static content filter over source files at the event ref (AND-ed). */
|
|
240
|
+
readonly requires?: readonly LockContentRequirement[];
|
|
241
|
+
/** Declarative static filter over the event's commit message / PR title+body. */
|
|
242
|
+
readonly commitMessage?: LockTextMatch;
|
|
116
243
|
}
|
|
117
244
|
/**
|
|
118
245
|
* Tag trigger in lock file.
|
|
@@ -122,6 +249,10 @@ export interface LockTagTrigger {
|
|
|
122
249
|
readonly _type: 'tag';
|
|
123
250
|
readonly patterns: readonly LockBranchPattern[];
|
|
124
251
|
readonly repos?: readonly LockBranchPattern[];
|
|
252
|
+
/** Declarative static content filter over source files at the event ref (AND-ed). */
|
|
253
|
+
readonly requires?: readonly LockContentRequirement[];
|
|
254
|
+
/** Declarative static filter over the event's commit message / PR title+body. */
|
|
255
|
+
readonly commitMessage?: LockTextMatch;
|
|
125
256
|
}
|
|
126
257
|
/**
|
|
127
258
|
* Comment trigger in lock file.
|
|
@@ -426,17 +557,27 @@ export type LockStepEntry = LockStep | LockParallelStep;
|
|
|
426
557
|
/** Type guard distinguishing a parallel group from an ordinary lock step. */
|
|
427
558
|
export declare function isLockParallelStep(entry: LockStepEntry): entry is LockParallelStep;
|
|
428
559
|
/**
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
432
|
-
*
|
|
433
|
-
*
|
|
560
|
+
* Serialized inline expression for a dynamic env/context/concurrencyGroup
|
|
561
|
+
* field, shaped as `{ _type: 'inline', expression: '(event) => ...' }`
|
|
562
|
+
* alongside the existing 'static' and 'dynamic' discriminants.
|
|
563
|
+
*
|
|
564
|
+
* @deprecated Schema v11 inline expressions are no longer evaluated in the
|
|
565
|
+
* orchestrator. Dynamic env/context/concurrencyGroup fields are resolved on the
|
|
566
|
+
* eval agent's init-runner. The compiler no longer emits this type; readers keep
|
|
567
|
+
* recognizing it only to defer an old lock's field to the init round. Removed at
|
|
568
|
+
* the next major (v1.0.0).
|
|
434
569
|
*/
|
|
435
570
|
export interface LockInlineValue {
|
|
436
571
|
readonly _type: 'inline';
|
|
437
572
|
readonly expression: string;
|
|
438
573
|
}
|
|
439
|
-
/**
|
|
574
|
+
/**
|
|
575
|
+
* Type guard for inline expression values.
|
|
576
|
+
*
|
|
577
|
+
* @deprecated See {@link LockInlineValue}. Retained only so a reader can
|
|
578
|
+
* recognize an old lock's inline field and defer it to the eval agent's
|
|
579
|
+
* init-runner. Removed at the next major (v1.0.0).
|
|
580
|
+
*/
|
|
440
581
|
export declare function isLockInlineValue(value: unknown): value is LockInlineValue;
|
|
441
582
|
/**
|
|
442
583
|
* Author-facing keyword sugar for a `needs` edge's run condition. Each keyword
|
|
@@ -640,21 +781,28 @@ export interface LockJob {
|
|
|
640
781
|
readonly rules?: readonly LockRule[];
|
|
641
782
|
readonly description?: string;
|
|
642
783
|
/**
|
|
643
|
-
* Bound contexts in merge order. Each entry is a static name
|
|
644
|
-
*
|
|
645
|
-
*
|
|
784
|
+
* Bound contexts in merge order. Each entry is a static name; `dynamic` is set
|
|
785
|
+
* when it is a function resolved on the eval agent's init-runner. Later entries
|
|
786
|
+
* override earlier ones on name collisions. The `LockInlineValue` shape is a
|
|
787
|
+
* deprecated form still accepted from old locks (see {@link LockInlineValue}).
|
|
646
788
|
*/
|
|
647
789
|
readonly contexts?: ReadonlyArray<{
|
|
648
790
|
value: string | LockInlineValue;
|
|
649
791
|
dynamic: boolean;
|
|
650
792
|
}>;
|
|
651
|
-
/**
|
|
793
|
+
/**
|
|
794
|
+
* Static environment variables. A deprecated `LockInlineValue` shape is still
|
|
795
|
+
* accepted from old locks (see {@link LockInlineValue}).
|
|
796
|
+
*/
|
|
652
797
|
readonly env?: Record<string, string> | LockInlineValue;
|
|
653
|
-
/** When true, env is dynamic (function) -- resolved
|
|
798
|
+
/** When true, env is dynamic (function) -- resolved on the eval agent's init-runner. */
|
|
654
799
|
readonly dynamicEnv?: boolean;
|
|
655
|
-
/**
|
|
800
|
+
/**
|
|
801
|
+
* Concurrency group name (static string). A deprecated `LockInlineValue` shape
|
|
802
|
+
* is still accepted from old locks (see {@link LockInlineValue}).
|
|
803
|
+
*/
|
|
656
804
|
readonly concurrencyGroup?: string | LockInlineValue;
|
|
657
|
-
/** When true, concurrencyGroup is dynamic (function) -- resolved
|
|
805
|
+
/** When true, concurrencyGroup is dynamic (function) -- resolved on the eval agent's init-runner. */
|
|
658
806
|
readonly dynamicConcurrencyGroup?: boolean;
|
|
659
807
|
/** Total job wall-clock timeout in milliseconds (init + all steps + hooks). Threaded to the agent via jobConfig. */
|
|
660
808
|
readonly timeout?: number;
|
|
@@ -769,6 +917,13 @@ export interface LockWorkflow {
|
|
|
769
917
|
readonly timeout?: number;
|
|
770
918
|
/** Normalized approval gate; when set the whole run is held before any job dispatches. */
|
|
771
919
|
readonly approval?: LockApproval;
|
|
920
|
+
/**
|
|
921
|
+
* True when the workflow declares a `filter` predicate. A bare flag, not a
|
|
922
|
+
* source reference: `LockWorkflow.source` already identifies the module and
|
|
923
|
+
* export, so the eval agent loads it and reads `.filter` off the workflow
|
|
924
|
+
* object. Mirrors the `dynamicEnv` / `dynamicConcurrencyGroup` convention.
|
|
925
|
+
*/
|
|
926
|
+
readonly hasFilter?: boolean;
|
|
772
927
|
}
|
|
773
928
|
/**
|
|
774
929
|
* Complete lock file structure.
|
|
@@ -783,7 +938,7 @@ export interface LockWorkflow {
|
|
|
783
938
|
* v8 adds runsOn polymorphic type (string | string[] | selector) and excludeLabels.
|
|
784
939
|
* v9 adds repos/notRepos repo pattern fields to git-event triggers for global workflow matching.
|
|
785
940
|
* v10 removes notRepos/notPaths fields; negative patterns use ! prefix in repos/paths arrays.
|
|
786
|
-
* v11 adds LockInlineValue type
|
|
941
|
+
* v11 adds the LockInlineValue type (deprecated; inline dynamic fields are resolved on the eval agent).
|
|
787
942
|
* v12 adds workflow-level registries and installEnv for private npm registry auth.
|
|
788
943
|
* v13 adds job-level and workflow-level timeout.
|
|
789
944
|
*/
|
|
@@ -869,6 +1024,13 @@ export interface SimulatedEvent {
|
|
|
869
1024
|
* to the previous owner.
|
|
870
1025
|
*/
|
|
871
1026
|
senderUserId?: string;
|
|
1027
|
+
/**
|
|
1028
|
+
* Text a `commitMessage` trigger filter is tested against: the full head-commit
|
|
1029
|
+
* message for push/tag, or PR title + body for pull-request events. Absent when
|
|
1030
|
+
* the provider payload carries none — which a `commitMessage` filter treats as
|
|
1031
|
+
* INDETERMINATE (fail-visible), never as an empty string.
|
|
1032
|
+
*/
|
|
1033
|
+
commitMessage?: string;
|
|
872
1034
|
/** Repository identifier where the event occurred (e.g., "owner/repo").
|
|
873
1035
|
* Used by global workflow repo pattern matching. */
|
|
874
1036
|
sourceRepo?: string;
|
package/dist/trigger/types.js
CHANGED
|
@@ -34,13 +34,17 @@ import { z } from "zod";
|
|
|
34
34
|
* Schema version 30 (BREAKING): renames job-level `environments` to `contexts`.
|
|
35
35
|
* Schema version 31 (additive): adds the workflows_failed_batch lock trigger.
|
|
36
36
|
* Schema version 32 (additive): adds LockJob.sandbox (per-job escape-hatch request).
|
|
37
|
+
* Schema version 33 (additive): adds `requires` (declarative static content filter) to the push/pr/tag git-event triggers.
|
|
38
|
+
* Schema version 34 (additive): adds LockWorkflow.hasFilter (workflow-level pre-dispatch filter predicate).
|
|
39
|
+
* Schema version 35 (additive): adds `commitMessage` (LockTextMatch) to the push/pr/tag
|
|
40
|
+
* git-event triggers, and contains/notContains/notMatches to LockContentRequirement.
|
|
37
41
|
*/
|
|
38
42
|
/**
|
|
39
43
|
* Schema version the compiler emits into every lock file. Incremented on ANY
|
|
40
44
|
* schema change (additive or breaking); the bump-history comment above records
|
|
41
45
|
* which. See `BREAKING_FLOOR` for the compatibility-window semantics.
|
|
42
46
|
*/
|
|
43
|
-
const SCHEMA_VERSION =
|
|
47
|
+
const SCHEMA_VERSION = 35;
|
|
44
48
|
/**
|
|
45
49
|
* Oldest lock schema version this codebase can still read correctly — the lower
|
|
46
50
|
* bound of the acceptance window.
|
|
@@ -53,15 +57,38 @@ const SCHEMA_VERSION = 32;
|
|
|
53
57
|
* Bump rule: move this to the current `SCHEMA_VERSION` ONLY in the commit that
|
|
54
58
|
* lands a `BREAKING` schema change (see the bump-history convention above). It
|
|
55
59
|
* currently sits at 30 because v30 (`environments`→`contexts`) was the most
|
|
56
|
-
* recent breaking bump; v31
|
|
57
|
-
* correctly.
|
|
60
|
+
* recent breaking bump; v31 through v35 were additive, so a v30 lock still
|
|
61
|
+
* reads correctly.
|
|
58
62
|
*/
|
|
59
63
|
const BREAKING_FLOOR = 30;
|
|
64
|
+
/**
|
|
65
|
+
* Resolve a content requirement's parse format to a concrete value. An explicit
|
|
66
|
+
* non-`auto` format is returned as-is; `auto` (or unset) is resolved by the file
|
|
67
|
+
* extension: `.json` → json, `.yaml`/`.yml` → yaml, everything else text.
|
|
68
|
+
*
|
|
69
|
+
* Yaml-free (pure string logic) so it lives in the browser-safe barrel and is
|
|
70
|
+
* the single source of truth for both the compiler's compile-time serializer and
|
|
71
|
+
* the orchestrator's eval-time matcher — the two can never disagree about how a
|
|
72
|
+
* file's format is picked.
|
|
73
|
+
*/
|
|
74
|
+
function resolveContentFormat(file, format) {
|
|
75
|
+
if (format && format !== "auto") return format;
|
|
76
|
+
const lower = file.toLowerCase();
|
|
77
|
+
if (lower.endsWith(".json")) return "json";
|
|
78
|
+
if (lower.endsWith(".yaml") || lower.endsWith(".yml")) return "yaml";
|
|
79
|
+
return "text";
|
|
80
|
+
}
|
|
60
81
|
/** Type guard distinguishing a parallel group from an ordinary lock step. */
|
|
61
82
|
function isLockParallelStep(entry) {
|
|
62
83
|
return entry.kind === "parallel";
|
|
63
84
|
}
|
|
64
|
-
/**
|
|
85
|
+
/**
|
|
86
|
+
* Type guard for inline expression values.
|
|
87
|
+
*
|
|
88
|
+
* @deprecated See {@link LockInlineValue}. Retained only so a reader can
|
|
89
|
+
* recognize an old lock's inline field and defer it to the eval agent's
|
|
90
|
+
* init-runner. Removed at the next major (v1.0.0).
|
|
91
|
+
*/
|
|
65
92
|
function isLockInlineValue(value) {
|
|
66
93
|
return typeof value === "object" && value !== null && value._type === "inline";
|
|
67
94
|
}
|
|
@@ -178,6 +205,6 @@ const changedFilesStatusSchema = z.enum([
|
|
|
178
205
|
"skipped"
|
|
179
206
|
]);
|
|
180
207
|
//#endregion
|
|
181
|
-
export { BREAKING_FLOOR, NeedsEntrySchema, NeedsGroupEntrySchema, NeedsRunOn, NeedsWhen, OnUnreachableMode, RunsOnPick, SANDBOX_NETWORK_MODES, SCHEMA_VERSION, changedFilesStatusSchema, isLockDynamicJobFn, isLockInlineValue, isLockParallelStep, isLockStaticJob, resolveWhenToRunOn };
|
|
208
|
+
export { BREAKING_FLOOR, NeedsEntrySchema, NeedsGroupEntrySchema, NeedsRunOn, NeedsWhen, OnUnreachableMode, RunsOnPick, SANDBOX_NETWORK_MODES, SCHEMA_VERSION, changedFilesStatusSchema, isLockDynamicJobFn, isLockInlineValue, isLockParallelStep, isLockStaticJob, resolveContentFormat, resolveWhenToRunOn };
|
|
182
209
|
|
|
183
210
|
//# sourceMappingURL=types.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kici-dev/engine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Shared business logic for the KiCI CI/CD stack: protocol, triggers, state machine, and provider interfaces used by the Platform relay, orchestrator, and compiler.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ci",
|
|
@@ -45,10 +45,18 @@
|
|
|
45
45
|
"import": "./dist/trigger/trigger-event-type.js",
|
|
46
46
|
"types": "./dist/trigger/trigger-event-type.d.ts"
|
|
47
47
|
},
|
|
48
|
+
"./trigger/content-requirements": {
|
|
49
|
+
"import": "./dist/trigger/content-requirements.js",
|
|
50
|
+
"types": "./dist/trigger/content-requirements.d.ts"
|
|
51
|
+
},
|
|
48
52
|
"./webhook/signature": {
|
|
49
53
|
"import": "./dist/webhook/signature.js",
|
|
50
54
|
"types": "./dist/webhook/signature.d.ts"
|
|
51
55
|
},
|
|
56
|
+
"./safe-regex": {
|
|
57
|
+
"import": "./dist/safe-regex.js",
|
|
58
|
+
"types": "./dist/safe-regex.d.ts"
|
|
59
|
+
},
|
|
52
60
|
"./labels/compile": {
|
|
53
61
|
"import": "./dist/labels/compile.js",
|
|
54
62
|
"types": "./dist/labels/compile.d.ts"
|
|
@@ -135,6 +143,7 @@
|
|
|
135
143
|
"jsonpath-plus": "^10.4.0",
|
|
136
144
|
"picomatch": "^4.0.5",
|
|
137
145
|
"safe-regex": "^2.1.1",
|
|
146
|
+
"yaml": "^2.9.0",
|
|
138
147
|
"zod": "^4.4.3"
|
|
139
148
|
},
|
|
140
149
|
"devDependencies": {
|
package/sbom.spdx.json
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"spdxVersion": "SPDX-2.3",
|
|
3
3
|
"dataLicense": "CC0-1.0",
|
|
4
4
|
"SPDXID": "SPDXRef-DOCUMENT",
|
|
5
|
-
"name": "@kici-dev/engine@0.
|
|
6
|
-
"documentNamespace": "https://kici.dev/sbom/%40kici-dev%2Fengine/0.
|
|
5
|
+
"name": "@kici-dev/engine@0.5.0",
|
|
6
|
+
"documentNamespace": "https://kici.dev/sbom/%40kici-dev%2Fengine/0.5.0/4dbbd65e-049d-4dc9-8c49-6e9d7ed4bc9e",
|
|
7
7
|
"creationInfo": {
|
|
8
|
-
"created": "2026-08-
|
|
8
|
+
"created": "2026-08-15T19:15:34Z",
|
|
9
9
|
"creators": [
|
|
10
10
|
"Tool: kici-sbom-generator"
|
|
11
11
|
]
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
{
|
|
55
55
|
"SPDXID": "SPDXRef-RootPackage",
|
|
56
56
|
"name": "@kici-dev/engine",
|
|
57
|
-
"versionInfo": "0.
|
|
57
|
+
"versionInfo": "0.5.0",
|
|
58
58
|
"downloadLocation": "NOASSERTION",
|
|
59
59
|
"filesAnalyzed": false,
|
|
60
60
|
"licenseConcluded": "NOASSERTION",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
{
|
|
66
66
|
"referenceCategory": "PACKAGE-MANAGER",
|
|
67
67
|
"referenceType": "purl",
|
|
68
|
-
"referenceLocator": "pkg:npm/%40kici-dev/engine@0.
|
|
68
|
+
"referenceLocator": "pkg:npm/%40kici-dev/engine@0.5.0"
|
|
69
69
|
}
|
|
70
70
|
],
|
|
71
71
|
"description": "Shared business logic for the KiCI CI/CD stack: protocol, triggers, state machine, and provider interfaces used by the Platform relay, orchestrator, and compiler.",
|
|
@@ -191,6 +191,26 @@
|
|
|
191
191
|
"description": "detect possibly catastrophic, exponential-time regular expressions",
|
|
192
192
|
"homepage": "https://github.com/davisjam/safe-regex"
|
|
193
193
|
},
|
|
194
|
+
{
|
|
195
|
+
"SPDXID": "SPDXRef-Package-yaml-2.9.0",
|
|
196
|
+
"name": "yaml",
|
|
197
|
+
"versionInfo": "2.9.0",
|
|
198
|
+
"downloadLocation": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz",
|
|
199
|
+
"filesAnalyzed": false,
|
|
200
|
+
"licenseConcluded": "NOASSERTION",
|
|
201
|
+
"licenseDeclared": "ISC",
|
|
202
|
+
"copyrightText": "NOASSERTION",
|
|
203
|
+
"supplier": "NOASSERTION",
|
|
204
|
+
"externalRefs": [
|
|
205
|
+
{
|
|
206
|
+
"referenceCategory": "PACKAGE-MANAGER",
|
|
207
|
+
"referenceType": "purl",
|
|
208
|
+
"referenceLocator": "pkg:npm/yaml@2.9.0"
|
|
209
|
+
}
|
|
210
|
+
],
|
|
211
|
+
"description": "JavaScript parser and stringifier for YAML",
|
|
212
|
+
"homepage": "https://eemeli.org/yaml/"
|
|
213
|
+
},
|
|
194
214
|
{
|
|
195
215
|
"SPDXID": "SPDXRef-Package-zod-4.4.3",
|
|
196
216
|
"name": "zod",
|
|
@@ -248,6 +268,11 @@
|
|
|
248
268
|
"relatedSpdxElement": "SPDXRef-Package-safe-regex-2.1.1",
|
|
249
269
|
"relationshipType": "DEPENDS_ON"
|
|
250
270
|
},
|
|
271
|
+
{
|
|
272
|
+
"spdxElementId": "SPDXRef-RootPackage",
|
|
273
|
+
"relatedSpdxElement": "SPDXRef-Package-yaml-2.9.0",
|
|
274
|
+
"relationshipType": "DEPENDS_ON"
|
|
275
|
+
},
|
|
251
276
|
{
|
|
252
277
|
"spdxElementId": "SPDXRef-RootPackage",
|
|
253
278
|
"relatedSpdxElement": "SPDXRef-Package-zod-4.4.3",
|