@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
|
@@ -299,6 +299,7 @@ export declare const dashboardRunStateResponseSchema: z.ZodObject<{
|
|
|
299
299
|
}>;
|
|
300
300
|
routingKey: z.ZodOptional<z.ZodString>;
|
|
301
301
|
repoIdentifier: z.ZodOptional<z.ZodString>;
|
|
302
|
+
workflowRepoIdentifier: z.ZodOptional<z.ZodString>;
|
|
302
303
|
sha: z.ZodOptional<z.ZodString>;
|
|
303
304
|
ref: z.ZodOptional<z.ZodString>;
|
|
304
305
|
triggerEvent: z.ZodOptional<z.ZodString>;
|
|
@@ -6616,7 +6617,6 @@ export declare const dashboardPlatformToOrchSchema: z.ZodDiscriminatedUnion<[z.Z
|
|
|
6616
6617
|
type: z.ZodLiteral<"system">;
|
|
6617
6618
|
component: z.ZodString;
|
|
6618
6619
|
}, z.core.$strip>], "type">;
|
|
6619
|
-
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
6620
6620
|
allowedRepos: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
6621
6621
|
routingKey: z.ZodOptional<z.ZodString>;
|
|
6622
6622
|
pattern: z.ZodString;
|
|
@@ -6629,7 +6629,7 @@ export declare const dashboardPlatformToOrchSchema: z.ZodDiscriminatedUnion<[z.Z
|
|
|
6629
6629
|
routingKey: z.ZodOptional<z.ZodString>;
|
|
6630
6630
|
pattern: z.ZodString;
|
|
6631
6631
|
}, z.core.$strip>>>>;
|
|
6632
|
-
}, z.core.$
|
|
6632
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
6633
6633
|
type: z.ZodLiteral<"dashboard.access-log.list">;
|
|
6634
6634
|
requestId: z.ZodString;
|
|
6635
6635
|
actor: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
@@ -7296,6 +7296,7 @@ export declare const dashboardOrchToPlatformSchema: z.ZodDiscriminatedUnion<[z.Z
|
|
|
7296
7296
|
}>;
|
|
7297
7297
|
routingKey: z.ZodOptional<z.ZodString>;
|
|
7298
7298
|
repoIdentifier: z.ZodOptional<z.ZodString>;
|
|
7299
|
+
workflowRepoIdentifier: z.ZodOptional<z.ZodString>;
|
|
7299
7300
|
sha: z.ZodOptional<z.ZodString>;
|
|
7300
7301
|
ref: z.ZodOptional<z.ZodString>;
|
|
7301
7302
|
triggerEvent: z.ZodOptional<z.ZodString>;
|
|
@@ -8821,6 +8822,7 @@ export declare const runListItemSchema: z.ZodObject<{
|
|
|
8821
8822
|
workflowName: z.ZodString;
|
|
8822
8823
|
status: z.ZodString;
|
|
8823
8824
|
repoIdentifier: z.ZodNullable<z.ZodString>;
|
|
8825
|
+
workflowRepoIdentifier: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
8824
8826
|
sha: z.ZodNullable<z.ZodString>;
|
|
8825
8827
|
ref: z.ZodNullable<z.ZodString>;
|
|
8826
8828
|
triggerEvent: z.ZodNullable<z.ZodString>;
|
|
@@ -8878,6 +8880,7 @@ export declare const runListResponseSchema: z.ZodObject<{
|
|
|
8878
8880
|
workflowName: z.ZodString;
|
|
8879
8881
|
status: z.ZodString;
|
|
8880
8882
|
repoIdentifier: z.ZodNullable<z.ZodString>;
|
|
8883
|
+
workflowRepoIdentifier: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
8881
8884
|
sha: z.ZodNullable<z.ZodString>;
|
|
8882
8885
|
ref: z.ZodNullable<z.ZodString>;
|
|
8883
8886
|
triggerEvent: z.ZodNullable<z.ZodString>;
|
|
@@ -2203,6 +2203,13 @@ const runListItemSchema = z.object({
|
|
|
2203
2203
|
workflowName: z.string(),
|
|
2204
2204
|
status: z.string(),
|
|
2205
2205
|
repoIdentifier: z.string().nullable(),
|
|
2206
|
+
/**
|
|
2207
|
+
* The repository that DEFINES this run's workflow. Non-null only when it
|
|
2208
|
+
* differs from `repoIdentifier` — i.e. this is an organization-wide global
|
|
2209
|
+
* run, whose workflow file lives in another repo entirely. Optional so a
|
|
2210
|
+
* client parsing a response from an older Platform still validates.
|
|
2211
|
+
*/
|
|
2212
|
+
workflowRepoIdentifier: z.string().nullable().optional(),
|
|
2206
2213
|
sha: z.string().nullable(),
|
|
2207
2214
|
ref: z.string().nullable(),
|
|
2208
2215
|
triggerEvent: z.string().nullable(),
|
|
@@ -264,6 +264,7 @@ export declare const executionStatusSchema: z.ZodObject<{
|
|
|
264
264
|
}>;
|
|
265
265
|
routingKey: z.ZodOptional<z.ZodString>;
|
|
266
266
|
repoIdentifier: z.ZodOptional<z.ZodString>;
|
|
267
|
+
workflowRepoIdentifier: z.ZodOptional<z.ZodString>;
|
|
267
268
|
repoProvider: z.ZodOptional<z.ZodString>;
|
|
268
269
|
localWorkingTree: z.ZodOptional<z.ZodBoolean>;
|
|
269
270
|
sha: z.ZodOptional<z.ZodString>;
|
|
@@ -417,6 +418,7 @@ export declare const stateReplayRunSchema: z.ZodObject<{
|
|
|
417
418
|
}>;
|
|
418
419
|
routingKey: z.ZodOptional<z.ZodString>;
|
|
419
420
|
repoIdentifier: z.ZodOptional<z.ZodString>;
|
|
421
|
+
workflowRepoIdentifier: z.ZodOptional<z.ZodString>;
|
|
420
422
|
sha: z.ZodOptional<z.ZodString>;
|
|
421
423
|
ref: z.ZodOptional<z.ZodString>;
|
|
422
424
|
triggerEvent: z.ZodOptional<z.ZodString>;
|
|
@@ -468,6 +470,7 @@ export declare const stateReplaySchema: z.ZodObject<{
|
|
|
468
470
|
}>;
|
|
469
471
|
routingKey: z.ZodOptional<z.ZodString>;
|
|
470
472
|
repoIdentifier: z.ZodOptional<z.ZodString>;
|
|
473
|
+
workflowRepoIdentifier: z.ZodOptional<z.ZodString>;
|
|
471
474
|
sha: z.ZodOptional<z.ZodString>;
|
|
472
475
|
ref: z.ZodOptional<z.ZodString>;
|
|
473
476
|
triggerEvent: z.ZodOptional<z.ZodString>;
|
|
@@ -239,6 +239,15 @@ const executionStatusSchema = z.object({
|
|
|
239
239
|
routingKey: z.string().max(128).optional(),
|
|
240
240
|
repoIdentifier: z.string().max(256).optional(),
|
|
241
241
|
/**
|
|
242
|
+
* The repository that DEFINES the workflow, when that is not
|
|
243
|
+
* `repoIdentifier` — a global workflow authored in one repository and
|
|
244
|
+
* dispatched against another. Absent for every per-repository run, where the
|
|
245
|
+
* two are the same repository, so "present" is a precise marker for a
|
|
246
|
+
* cross-repository global run. Optional for backward compatibility with an
|
|
247
|
+
* older orchestrator that never sends it.
|
|
248
|
+
*/
|
|
249
|
+
workflowRepoIdentifier: z.string().max(256).optional(),
|
|
250
|
+
/**
|
|
242
251
|
* Run-level repo provider (origin host: `github` / `gitlab` / `bitbucket` /
|
|
243
252
|
* `local`). Distinct from the routing-key-derived source provider; drives the
|
|
244
253
|
* dashboard's provider-aware repo links.
|
|
@@ -359,6 +368,13 @@ const stateReplayRunSchema = z.object({
|
|
|
359
368
|
status: ExecutionRunStatus,
|
|
360
369
|
routingKey: z.string().max(128).optional(),
|
|
361
370
|
repoIdentifier: z.string().max(256).optional(),
|
|
371
|
+
/**
|
|
372
|
+
* The repository that DEFINES the workflow, when that is not
|
|
373
|
+
* `repoIdentifier`. Same meaning and same absent-for-per-repository-runs
|
|
374
|
+
* contract as on `execution.status`; carried here so a run that reaches the
|
|
375
|
+
* Platform only through the reconnect replay keeps its attribution.
|
|
376
|
+
*/
|
|
377
|
+
workflowRepoIdentifier: z.string().max(256).optional(),
|
|
362
378
|
sha: z.string().max(128).optional(),
|
|
363
379
|
ref: z.string().max(128).optional(),
|
|
364
380
|
triggerEvent: z.string().max(128).optional(),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import type { LockJob } from '../../trigger/types.js';
|
|
2
3
|
/**
|
|
3
4
|
* Cache write scope for a job's user-facing cache.
|
|
4
5
|
*
|
|
@@ -232,6 +233,54 @@ export declare const jobStatusSchema: z.ZodObject<{
|
|
|
232
233
|
encrypted: z.ZodString;
|
|
233
234
|
}, z.core.$strip>>>;
|
|
234
235
|
}, z.core.$strip>;
|
|
236
|
+
/**
|
|
237
|
+
* One candidate workflow's verdict from the pre-run global eval round — the
|
|
238
|
+
* job the agent runs once per (event × workflow repo) before any run row
|
|
239
|
+
* exists, evaluating each candidate's `filter` and then its `DynamicJobFn`s on
|
|
240
|
+
* a single dual checkout.
|
|
241
|
+
*
|
|
242
|
+
* `jobs` carries `LockJob[]` as an unvalidated pass-through, the same shape and
|
|
243
|
+
* for the same reason as `jobDispatchSchema.jobConfig`: the lock-file job shape
|
|
244
|
+
* has no Zod mirror anywhere in this package, its single source of truth is the
|
|
245
|
+
* `LockJob` interface in `trigger/types.ts`, and a hand-written Zod copy would
|
|
246
|
+
* drift and start rejecting legitimate generated jobs.
|
|
247
|
+
*
|
|
248
|
+
* Every field beyond the verdict itself is `.optional()` so an older peer
|
|
249
|
+
* tolerates the message unchanged.
|
|
250
|
+
*/
|
|
251
|
+
export declare const globalEvalCandidateResultSchema: z.ZodObject<{
|
|
252
|
+
workflowName: z.ZodString;
|
|
253
|
+
run: z.ZodBoolean;
|
|
254
|
+
jobs: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
255
|
+
indeterminate: z.ZodOptional<z.ZodBoolean>;
|
|
256
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
257
|
+
}, z.core.$strip>;
|
|
258
|
+
/** Every candidate's verdict from one global eval round, in candidate order. */
|
|
259
|
+
export declare const globalEvalRoundResultSchema: z.ZodObject<{
|
|
260
|
+
candidates: z.ZodArray<z.ZodObject<{
|
|
261
|
+
workflowName: z.ZodString;
|
|
262
|
+
run: z.ZodBoolean;
|
|
263
|
+
jobs: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
264
|
+
indeterminate: z.ZodOptional<z.ZodBoolean>;
|
|
265
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
266
|
+
}, z.core.$strip>>;
|
|
267
|
+
}, z.core.$strip>;
|
|
268
|
+
/**
|
|
269
|
+
* Typed view of {@link globalEvalCandidateResultSchema}. Declared rather than
|
|
270
|
+
* inferred so `jobs` is the real `LockJob[]` on both sides of the wire; the Zod
|
|
271
|
+
* schema stays the loose validator (see its doc comment).
|
|
272
|
+
*/
|
|
273
|
+
export interface GlobalEvalCandidateResult {
|
|
274
|
+
workflowName: string;
|
|
275
|
+
run: boolean;
|
|
276
|
+
jobs?: LockJob[];
|
|
277
|
+
indeterminate?: boolean;
|
|
278
|
+
reason?: string;
|
|
279
|
+
}
|
|
280
|
+
/** Typed view of {@link globalEvalRoundResultSchema}. */
|
|
281
|
+
export interface GlobalEvalRoundResult {
|
|
282
|
+
candidates: GlobalEvalCandidateResult[];
|
|
283
|
+
}
|
|
235
284
|
/** Reasons an agent can refuse a job.dispatch. */
|
|
236
285
|
export declare const JobRejectReason: z.ZodEnum<{
|
|
237
286
|
busy: "busy";
|
|
@@ -288,6 +288,39 @@ const jobStatusSchema = z.object({
|
|
|
288
288
|
encrypted: z.string()
|
|
289
289
|
})).optional()
|
|
290
290
|
});
|
|
291
|
+
/**
|
|
292
|
+
* One candidate workflow's verdict from the pre-run global eval round — the
|
|
293
|
+
* job the agent runs once per (event × workflow repo) before any run row
|
|
294
|
+
* exists, evaluating each candidate's `filter` and then its `DynamicJobFn`s on
|
|
295
|
+
* a single dual checkout.
|
|
296
|
+
*
|
|
297
|
+
* `jobs` carries `LockJob[]` as an unvalidated pass-through, the same shape and
|
|
298
|
+
* for the same reason as `jobDispatchSchema.jobConfig`: the lock-file job shape
|
|
299
|
+
* has no Zod mirror anywhere in this package, its single source of truth is the
|
|
300
|
+
* `LockJob` interface in `trigger/types.ts`, and a hand-written Zod copy would
|
|
301
|
+
* drift and start rejecting legitimate generated jobs.
|
|
302
|
+
*
|
|
303
|
+
* Every field beyond the verdict itself is `.optional()` so an older peer
|
|
304
|
+
* tolerates the message unchanged.
|
|
305
|
+
*/
|
|
306
|
+
const globalEvalCandidateResultSchema = z.object({
|
|
307
|
+
/** The candidate workflow's name, as it appears in the lock file. */
|
|
308
|
+
workflowName: z.string(),
|
|
309
|
+
/** Whether this workflow applies to the source repo that triggered the round. */
|
|
310
|
+
run: z.boolean(),
|
|
311
|
+
jobs: z.array(z.record(z.string(), z.unknown())).optional().describe("Jobs generated by the workflow DynamicJobFns (LockJob[])"),
|
|
312
|
+
/**
|
|
313
|
+
* Set when the verdict could not be established — the filter or a generator
|
|
314
|
+
* threw, or blew the per-candidate budget. `run` is `false` alongside it, but
|
|
315
|
+
* that is a "could not decide", not a clean "does not apply": one bad
|
|
316
|
+
* candidate never fails the round, so its siblings still carry real verdicts.
|
|
317
|
+
*/
|
|
318
|
+
indeterminate: z.boolean().optional(),
|
|
319
|
+
/** Human-readable cause, present when `indeterminate` is set. */
|
|
320
|
+
reason: z.string().optional()
|
|
321
|
+
});
|
|
322
|
+
/** Every candidate's verdict from one global eval round, in candidate order. */
|
|
323
|
+
const globalEvalRoundResultSchema = z.object({ candidates: z.array(globalEvalCandidateResultSchema) });
|
|
291
324
|
/** Reasons an agent can refuse a job.dispatch. */
|
|
292
325
|
const JobRejectReason = z.enum(["busy", "draining"]);
|
|
293
326
|
/**
|
|
@@ -945,6 +978,6 @@ const agentToOrchestratorMessageSchema = z.discriminatedUnion("type", [
|
|
|
945
978
|
stepApprovalRequestSchema
|
|
946
979
|
]);
|
|
947
980
|
//#endregion
|
|
948
|
-
export { ArtifactCompleteAckOutcome, ArtifactDownloadOutcome, ArtifactRejectReason, ArtifactUploadOutcome, CacheRefScope, JobRejectReason, StepApprovalOutcome, agentApiRequestSchema, agentApiResponseSchema, agentAuthFailureSchema, agentAuthRequestSchema, agentAuthSuccessSchema, agentLogChunkSchema, agentMetricsSchema, agentRegisterSchema, agentStatusSchema, agentStepStatusSchema, agentToOrchestratorMessageSchema, artifactsDownloadRequestSchema, artifactsDownloadResponseSchema, artifactsUploadCompleteAckSchema, artifactsUploadCompleteSchema, artifactsUploadRequestSchema, artifactsUploadResponseSchema, cacheUserRestoreRequestSchema, cacheUserRestoreResponseSchema, cacheUserSaveCompleteSchema, cacheUserSaveRequestSchema, cacheUserSaveResponseSchema, configAckSchema, eventEmitResponseSchema, eventEmitSchema, fleetBundleChunkSchema, fleetBundleErrorSchema, fleetLogsRequestSchema, gitAuthSchema, jobAckSchema, jobCancelSchema, jobConcurrencyAckSchema, jobConcurrencyReportSchema, jobDispatchSchema, jobRejectSchema, jobStatusSchema, orchestratorToAgentMessageSchema, provenanceUploadCompleteSchema, provenanceUploadDeferSchema, provenanceUploadRequestSchema, provenanceUploadResponseSchema, registerAckSchema, stepApprovalPayloadSchema, stepApprovalRequestSchema, stepApprovalResolvedSchema, upstreamSnapshotSchema };
|
|
981
|
+
export { ArtifactCompleteAckOutcome, ArtifactDownloadOutcome, ArtifactRejectReason, ArtifactUploadOutcome, CacheRefScope, JobRejectReason, StepApprovalOutcome, agentApiRequestSchema, agentApiResponseSchema, agentAuthFailureSchema, agentAuthRequestSchema, agentAuthSuccessSchema, agentLogChunkSchema, agentMetricsSchema, agentRegisterSchema, agentStatusSchema, agentStepStatusSchema, agentToOrchestratorMessageSchema, artifactsDownloadRequestSchema, artifactsDownloadResponseSchema, artifactsUploadCompleteAckSchema, artifactsUploadCompleteSchema, artifactsUploadRequestSchema, artifactsUploadResponseSchema, cacheUserRestoreRequestSchema, cacheUserRestoreResponseSchema, cacheUserSaveCompleteSchema, cacheUserSaveRequestSchema, cacheUserSaveResponseSchema, configAckSchema, eventEmitResponseSchema, eventEmitSchema, fleetBundleChunkSchema, fleetBundleErrorSchema, fleetLogsRequestSchema, gitAuthSchema, globalEvalCandidateResultSchema, globalEvalRoundResultSchema, jobAckSchema, jobCancelSchema, jobConcurrencyAckSchema, jobConcurrencyReportSchema, jobDispatchSchema, jobRejectSchema, jobStatusSchema, orchestratorToAgentMessageSchema, provenanceUploadCompleteSchema, provenanceUploadDeferSchema, provenanceUploadRequestSchema, provenanceUploadResponseSchema, registerAckSchema, stepApprovalPayloadSchema, stepApprovalRequestSchema, stepApprovalResolvedSchema, upstreamSnapshotSchema };
|
|
949
982
|
|
|
950
983
|
//# sourceMappingURL=orchestrator-agent.js.map
|
|
@@ -215,6 +215,7 @@ export declare const staleCheckrunCleanupSchema: z.ZodObject<{
|
|
|
215
215
|
repoIdentifier: z.ZodString;
|
|
216
216
|
sha: z.ZodString;
|
|
217
217
|
workflowName: z.ZodString;
|
|
218
|
+
workflowRepoIdentifier: z.ZodOptional<z.ZodString>;
|
|
218
219
|
jobNames: z.ZodArray<z.ZodString>;
|
|
219
220
|
}, z.core.$strip>>;
|
|
220
221
|
}, z.core.$strip>;
|
|
@@ -562,6 +563,7 @@ export declare const platformToOrchestratorMessageSchema: z.ZodDiscriminatedUnio
|
|
|
562
563
|
repoIdentifier: z.ZodString;
|
|
563
564
|
sha: z.ZodString;
|
|
564
565
|
workflowName: z.ZodString;
|
|
566
|
+
workflowRepoIdentifier: z.ZodOptional<z.ZodString>;
|
|
565
567
|
jobNames: z.ZodArray<z.ZodString>;
|
|
566
568
|
}, z.core.$strip>>;
|
|
567
569
|
}, z.core.$strip>, z.ZodObject<{
|
|
@@ -2762,7 +2764,6 @@ export declare const platformToOrchestratorMessageSchema: z.ZodDiscriminatedUnio
|
|
|
2762
2764
|
type: z.ZodLiteral<"system">;
|
|
2763
2765
|
component: z.ZodString;
|
|
2764
2766
|
}, z.core.$strip>], "type">;
|
|
2765
|
-
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
2766
2767
|
allowedRepos: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
2767
2768
|
routingKey: z.ZodOptional<z.ZodString>;
|
|
2768
2769
|
pattern: z.ZodString;
|
|
@@ -2775,7 +2776,7 @@ export declare const platformToOrchestratorMessageSchema: z.ZodDiscriminatedUnio
|
|
|
2775
2776
|
routingKey: z.ZodOptional<z.ZodString>;
|
|
2776
2777
|
pattern: z.ZodString;
|
|
2777
2778
|
}, z.core.$strip>>>>;
|
|
2778
|
-
}, z.core.$
|
|
2779
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
2779
2780
|
type: z.ZodLiteral<"dashboard.access-log.list">;
|
|
2780
2781
|
requestId: z.ZodString;
|
|
2781
2782
|
actor: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
@@ -3207,6 +3208,7 @@ export declare const orchestratorToPlatformMessageSchema: z.ZodDiscriminatedUnio
|
|
|
3207
3208
|
}>;
|
|
3208
3209
|
routingKey: z.ZodOptional<z.ZodString>;
|
|
3209
3210
|
repoIdentifier: z.ZodOptional<z.ZodString>;
|
|
3211
|
+
workflowRepoIdentifier: z.ZodOptional<z.ZodString>;
|
|
3210
3212
|
repoProvider: z.ZodOptional<z.ZodString>;
|
|
3211
3213
|
localWorkingTree: z.ZodOptional<z.ZodBoolean>;
|
|
3212
3214
|
sha: z.ZodOptional<z.ZodString>;
|
|
@@ -3349,6 +3351,7 @@ export declare const orchestratorToPlatformMessageSchema: z.ZodDiscriminatedUnio
|
|
|
3349
3351
|
}>;
|
|
3350
3352
|
routingKey: z.ZodOptional<z.ZodString>;
|
|
3351
3353
|
repoIdentifier: z.ZodOptional<z.ZodString>;
|
|
3354
|
+
workflowRepoIdentifier: z.ZodOptional<z.ZodString>;
|
|
3352
3355
|
sha: z.ZodOptional<z.ZodString>;
|
|
3353
3356
|
ref: z.ZodOptional<z.ZodString>;
|
|
3354
3357
|
triggerEvent: z.ZodOptional<z.ZodString>;
|
|
@@ -239,6 +239,20 @@ const staleCheckrunCleanupSchema = z.object({
|
|
|
239
239
|
repoIdentifier: z.string(),
|
|
240
240
|
sha: z.string(),
|
|
241
241
|
workflowName: z.string(),
|
|
242
|
+
/**
|
|
243
|
+
* The repository that DEFINES the workflow, when that is not the
|
|
244
|
+
* repository the run acted on — an organization-wide workflow dispatched
|
|
245
|
+
* against another repository. The orchestrator qualifies the check-run
|
|
246
|
+
* names it looks for with it, so a cleanup cannot time out the acted-on
|
|
247
|
+
* repository's own same-named check; see the orchestrator's
|
|
248
|
+
* `workflowLabel`.
|
|
249
|
+
*
|
|
250
|
+
* Additive and optional. The Platform sends it on exactly the condition
|
|
251
|
+
* that writes the mirror column — only when the two repositories differ —
|
|
252
|
+
* so an absent field and a value equal to `repoIdentifier` mean the same
|
|
253
|
+
* thing and both name the unqualified check.
|
|
254
|
+
*/
|
|
255
|
+
workflowRepoIdentifier: z.string().max(256).optional(),
|
|
242
256
|
jobNames: z.array(z.string())
|
|
243
257
|
}))
|
|
244
258
|
});
|
|
@@ -34,5 +34,19 @@ export interface CheckStatusPoster {
|
|
|
34
34
|
* unblocking a branch protection rule that requires the security check.
|
|
35
35
|
*/
|
|
36
36
|
postGlobalWorkflowsSkippedCheck(repoIdentifier: string, commitSha: string, summary: string, credentials: unknown): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Post a failing check recording that the pre-run evaluation of the
|
|
39
|
+
* organization's global workflows could not be completed, so none of the
|
|
40
|
+
* workflows it was deciding on ran for this commit.
|
|
41
|
+
*
|
|
42
|
+
* Its own check name, for the same reason as the two notices above: the
|
|
43
|
+
* security-hold check is a single named run per commit, so posting this
|
|
44
|
+
* through `postCheckStatus` would UPDATE that run and replace a pending
|
|
45
|
+
* "Held for approval" state with a completed conclusion.
|
|
46
|
+
*
|
|
47
|
+
* Optional so a provider bundle that has no notion of commit checks — or a
|
|
48
|
+
* hand-built one — is simply silent rather than failing the delivery.
|
|
49
|
+
*/
|
|
50
|
+
postGlobalEvalFailedCheck?(repoIdentifier: string, commitSha: string, summary: string, credentials: unknown): Promise<void>;
|
|
37
51
|
}
|
|
38
52
|
//# sourceMappingURL=check-status-poster.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FileContentsFetcher interface.
|
|
3
|
+
*
|
|
4
|
+
* Fetches the contents of an arbitrary repository file at a specific ref via a
|
|
5
|
+
* provider's repository API. Used by the orchestrator to evaluate content-match
|
|
6
|
+
* triggers without cloning the repo.
|
|
7
|
+
*/
|
|
8
|
+
import type { ProviderType } from './types.js';
|
|
9
|
+
export interface FileContentsFetcher {
|
|
10
|
+
readonly provider: ProviderType;
|
|
11
|
+
/**
|
|
12
|
+
* Fetch the contents of a file in a repository at a specific ref.
|
|
13
|
+
*
|
|
14
|
+
* Result shape:
|
|
15
|
+
* - `{ present: false }` -- the file does not exist (a 404 from the provider,
|
|
16
|
+
* or the path resolves to a directory rather than a file).
|
|
17
|
+
* - `{ present: true, bytes }` -- the file exists and the provider returned
|
|
18
|
+
* its inline content, decoded to a string.
|
|
19
|
+
* - `{ present: true }` (no `bytes`) -- the file exists but the provider did
|
|
20
|
+
* not return inline content (e.g. GitHub's Contents API omits content for
|
|
21
|
+
* files larger than 1 MiB). A caller MUST NOT read a missing `bytes` as an
|
|
22
|
+
* absent file.
|
|
23
|
+
*
|
|
24
|
+
* Implementations do not cap the returned content -- any size limit is the
|
|
25
|
+
* caller's concern (the orchestrator's content matcher enforces a
|
|
26
|
+
* post-materialization cap). Implementations MUST NOT fall back to a raw
|
|
27
|
+
* blob download to defeat a provider's inline-content size limit.
|
|
28
|
+
*
|
|
29
|
+
* @param owner - Repository owner (e.g. "my-org")
|
|
30
|
+
* @param repo - Repository name (e.g. "my-app")
|
|
31
|
+
* @param path - Repo-relative file path (e.g. ".kici/workflows/ci.ts")
|
|
32
|
+
* @param ref - Git ref (branch name, tag, or SHA)
|
|
33
|
+
*/
|
|
34
|
+
getFileContents(owner: string, repo: string, path: string, ref: string): Promise<{
|
|
35
|
+
present: boolean;
|
|
36
|
+
bytes?: string;
|
|
37
|
+
}>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=file-contents-fetcher.d.ts.map
|
package/dist/provider/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* - WebhookNormalizer: Webhook ingestion and event normalization
|
|
9
9
|
* - LockFileFetcher: Repository API access for lock files
|
|
10
10
|
* - ChangedFilesFetcher: Repository API access for changed files
|
|
11
|
+
* - FileContentsFetcher: Repository API access for arbitrary file contents
|
|
11
12
|
* - CloneTokenProvider: Auth token generation for agent clone
|
|
12
13
|
* - RepoUrlBuilder: Provider-specific URL construction
|
|
13
14
|
*/
|
|
@@ -16,6 +17,7 @@ export type { WebhookNormalizer, AccessCacheInvalidation } from './webhook-norma
|
|
|
16
17
|
export type { LockFileFetcher } from './lock-file-fetcher.js';
|
|
17
18
|
export { LockFileParseError } from './lock-file-parse-error.js';
|
|
18
19
|
export type { ChangedFilesFetcher, ChangedFilesResult } from './changed-files-fetcher.js';
|
|
20
|
+
export type { FileContentsFetcher } from './file-contents-fetcher.js';
|
|
19
21
|
export type { CloneTokenProvider, ProviderGitAuth } from './clone-token-provider.js';
|
|
20
22
|
export type { RepoUrlBuilder } from './repo-url-builder.js';
|
|
21
23
|
export type { ContributorResolver, ContributorInfo, ContributorPermission, } from './contributor-resolver.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reject a ReDoS-prone author-supplied regex before it is compiled.
|
|
3
|
+
*
|
|
4
|
+
* `safe-regex` is a star-height heuristic. The orchestrator is single-tenant, so
|
|
5
|
+
* a slipped-through pattern only stalls the author's own orchestrator — but every
|
|
6
|
+
* author regex the orchestrator compiles from lock-file data on the webhook path
|
|
7
|
+
* (label selectors, branch/tag/repo patterns, embedded JSONPath `/re/flags`,
|
|
8
|
+
* comment `bodyMatch`) must be checked so a catastrophic pattern is rejected at
|
|
9
|
+
* compile/registration time rather than silently compiled. Globs are linear by
|
|
10
|
+
* construction but pass through here for uniformity.
|
|
11
|
+
*
|
|
12
|
+
* `ctx` is a human label (e.g. "branch pattern", "job 'web' runsOn") woven into
|
|
13
|
+
* the thrown error so an operator can identify the offending pattern.
|
|
14
|
+
*/
|
|
15
|
+
export declare function assertSafeRegex(source: string, flags: string, ctx: string): void;
|
|
16
|
+
//# sourceMappingURL=safe-regex.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import "./rolldown-runtime-ClRpJifh.js";
|
|
2
|
+
import safeRegex from "safe-regex";
|
|
3
|
+
//#region src/safe-regex.ts
|
|
4
|
+
/**
|
|
5
|
+
* Reject a ReDoS-prone author-supplied regex before it is compiled.
|
|
6
|
+
*
|
|
7
|
+
* `safe-regex` is a star-height heuristic. The orchestrator is single-tenant, so
|
|
8
|
+
* a slipped-through pattern only stalls the author's own orchestrator — but every
|
|
9
|
+
* author regex the orchestrator compiles from lock-file data on the webhook path
|
|
10
|
+
* (label selectors, branch/tag/repo patterns, embedded JSONPath `/re/flags`,
|
|
11
|
+
* comment `bodyMatch`) must be checked so a catastrophic pattern is rejected at
|
|
12
|
+
* compile/registration time rather than silently compiled. Globs are linear by
|
|
13
|
+
* construction but pass through here for uniformity.
|
|
14
|
+
*
|
|
15
|
+
* `ctx` is a human label (e.g. "branch pattern", "job 'web' runsOn") woven into
|
|
16
|
+
* the thrown error so an operator can identify the offending pattern.
|
|
17
|
+
*/
|
|
18
|
+
function assertSafeRegex(source, flags, ctx) {
|
|
19
|
+
if (!safeRegex(new RegExp(source, flags))) throw new Error(`${ctx}: regex /${source}/${flags} is ReDoS-prone — rejected`);
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { assertSafeRegex };
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=safe-regex.js.map
|
|
@@ -3,11 +3,31 @@
|
|
|
3
3
|
* flags first with a space separator; regex flags are restricted to
|
|
4
4
|
* `[gimsuydv]`, so the separator can never collide with a pattern that starts
|
|
5
5
|
* with a space.
|
|
6
|
+
*
|
|
7
|
+
* Every pattern reaching here is author-supplied (branch/tag/repo patterns and
|
|
8
|
+
* comment `bodyMatch`), so it is ReDoS-checked before compiling. The guard runs
|
|
9
|
+
* inside the memo factory, so a benign pattern pays the check once (on cache
|
|
10
|
+
* miss) and a catastrophic one throws — and, being unsafe, is never cached, so
|
|
11
|
+
* it is rejected on every attempt. `ctx` names the dialect in the thrown error.
|
|
6
12
|
*/
|
|
7
|
-
export declare function getCompiledRegex(pattern: string, flags?: string): RegExp;
|
|
13
|
+
export declare function getCompiledRegex(pattern: string, flags?: string, ctx?: string): RegExp;
|
|
8
14
|
/**
|
|
9
15
|
* Return a memoized picomatch matcher function for the given glob pattern.
|
|
10
16
|
* `getGlobMatcher(pattern)(str)` is equivalent to `picomatch.isMatch(str, pattern)`.
|
|
11
17
|
*/
|
|
12
18
|
export declare function getGlobMatcher(pattern: string): (s: string) => boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Repo-identifier matcher. Identical to {@link getGlobMatcher} except it sets
|
|
21
|
+
* picomatch's `dot: true`, so a dot-prefixed identifier (`.hidden/repo`) is
|
|
22
|
+
* matched by `**` — `repos: ['**']` is documented as "every repo in the org",
|
|
23
|
+
* and silently excluding a whole class of identifier contradicts that.
|
|
24
|
+
*
|
|
25
|
+
* Deliberately NOT the shared matcher: `dot: true` on path globs would make
|
|
26
|
+
* `paths: ['**']` start matching `.github/**` for every existing workflow, a
|
|
27
|
+
* semantics change this does not intend.
|
|
28
|
+
*
|
|
29
|
+
* Note a bare `.` still does not match, in either mode — picomatch will not
|
|
30
|
+
* match a lone `.`. That is upstream behavior, not something this option fixes.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getRepoGlobMatcher(pattern: string): (s: string) => boolean;
|
|
13
33
|
//# sourceMappingURL=compiled-matchers.d.ts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import "../rolldown-runtime-ClRpJifh.js";
|
|
2
|
+
import { assertSafeRegex } from "../safe-regex.js";
|
|
2
3
|
import picomatch from "picomatch";
|
|
3
4
|
//#region src/trigger/compiled-matchers.ts
|
|
4
5
|
/**
|
|
@@ -22,14 +23,24 @@ function boundedGet(cache, key, make) {
|
|
|
22
23
|
}
|
|
23
24
|
const regexCache = /* @__PURE__ */ new Map();
|
|
24
25
|
const globCache = /* @__PURE__ */ new Map();
|
|
26
|
+
const repoGlobCache = /* @__PURE__ */ new Map();
|
|
25
27
|
/**
|
|
26
28
|
* Return a memoized RegExp for the given pattern + flags. The key encodes the
|
|
27
29
|
* flags first with a space separator; regex flags are restricted to
|
|
28
30
|
* `[gimsuydv]`, so the separator can never collide with a pattern that starts
|
|
29
31
|
* with a space.
|
|
32
|
+
*
|
|
33
|
+
* Every pattern reaching here is author-supplied (branch/tag/repo patterns and
|
|
34
|
+
* comment `bodyMatch`), so it is ReDoS-checked before compiling. The guard runs
|
|
35
|
+
* inside the memo factory, so a benign pattern pays the check once (on cache
|
|
36
|
+
* miss) and a catastrophic one throws — and, being unsafe, is never cached, so
|
|
37
|
+
* it is rejected on every attempt. `ctx` names the dialect in the thrown error.
|
|
30
38
|
*/
|
|
31
|
-
function getCompiledRegex(pattern, flags) {
|
|
32
|
-
return boundedGet(regexCache, `${flags ?? ""} ${pattern}`, () =>
|
|
39
|
+
function getCompiledRegex(pattern, flags, ctx = "trigger pattern") {
|
|
40
|
+
return boundedGet(regexCache, `${flags ?? ""} ${pattern}`, () => {
|
|
41
|
+
assertSafeRegex(pattern, flags ?? "", ctx);
|
|
42
|
+
return new RegExp(pattern, flags);
|
|
43
|
+
});
|
|
33
44
|
}
|
|
34
45
|
/**
|
|
35
46
|
* Return a memoized picomatch matcher function for the given glob pattern.
|
|
@@ -38,7 +49,23 @@ function getCompiledRegex(pattern, flags) {
|
|
|
38
49
|
function getGlobMatcher(pattern) {
|
|
39
50
|
return boundedGet(globCache, pattern, () => picomatch(pattern));
|
|
40
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Repo-identifier matcher. Identical to {@link getGlobMatcher} except it sets
|
|
54
|
+
* picomatch's `dot: true`, so a dot-prefixed identifier (`.hidden/repo`) is
|
|
55
|
+
* matched by `**` — `repos: ['**']` is documented as "every repo in the org",
|
|
56
|
+
* and silently excluding a whole class of identifier contradicts that.
|
|
57
|
+
*
|
|
58
|
+
* Deliberately NOT the shared matcher: `dot: true` on path globs would make
|
|
59
|
+
* `paths: ['**']` start matching `.github/**` for every existing workflow, a
|
|
60
|
+
* semantics change this does not intend.
|
|
61
|
+
*
|
|
62
|
+
* Note a bare `.` still does not match, in either mode — picomatch will not
|
|
63
|
+
* match a lone `.`. That is upstream behavior, not something this option fixes.
|
|
64
|
+
*/
|
|
65
|
+
function getRepoGlobMatcher(pattern) {
|
|
66
|
+
return boundedGet(repoGlobCache, pattern, () => picomatch(pattern, { dot: true }));
|
|
67
|
+
}
|
|
41
68
|
//#endregion
|
|
42
|
-
export { getCompiledRegex, getGlobMatcher };
|
|
69
|
+
export { getCompiledRegex, getGlobMatcher, getRepoGlobMatcher };
|
|
43
70
|
|
|
44
71
|
//# sourceMappingURL=compiled-matchers.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { LockContentRequirement } from './types.js';
|
|
2
|
+
export type { ContentFormat, ContentRequirement, LockContentRequirement } from './types.js';
|
|
3
|
+
/** Result of evaluating a `requires` list: a definite verdict, or fail-visible indeterminate. */
|
|
4
|
+
export interface ContentRequirementResult {
|
|
5
|
+
readonly pass: boolean;
|
|
6
|
+
/** Set (with `pass:false`) when a file could not be evaluated — never a silent pass. */
|
|
7
|
+
readonly indeterminate?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Parse `bytes` for the given concrete format. `text` returns the raw string;
|
|
11
|
+
* `json` uses `JSON.parse`; `yaml` uses a hardened `yaml.parse` with an explicit
|
|
12
|
+
* anchor/alias cap. Throws on a malformed document (the caller treats a throw as
|
|
13
|
+
* indeterminate).
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseForFormat(bytes: string, format: 'json' | 'yaml' | 'text'): unknown;
|
|
16
|
+
/**
|
|
17
|
+
* Evaluate an AND-ed list of content requirements against a resolved file map.
|
|
18
|
+
*
|
|
19
|
+
* Every entry must pass for the overall result to pass; an empty list passes.
|
|
20
|
+
* The first indeterminate entry short-circuits and is surfaced (fail-visible):
|
|
21
|
+
* an unevaluable file NEVER passes silently.
|
|
22
|
+
*
|
|
23
|
+
* @param reqs The lock `requires` list (each entry AND-ed).
|
|
24
|
+
* @param files Resolved file contents keyed by repo-relative path. A missing key
|
|
25
|
+
* or `{ present: false }` means the file does not exist at the ref.
|
|
26
|
+
*/
|
|
27
|
+
export declare function evaluateContentRequirements(reqs: readonly LockContentRequirement[], files: Map<string, {
|
|
28
|
+
present: boolean;
|
|
29
|
+
bytes?: string;
|
|
30
|
+
}>): ContentRequirementResult;
|
|
31
|
+
//# sourceMappingURL=content-requirements.d.ts.map
|