@kici-dev/engine 0.0.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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,163 @@
1
+ /**
2
+ * WebhookNormalizer interface.
3
+ *
4
+ * Translates provider-specific webhook HTTP requests into KiCI's universal
5
+ * SimulatedEvent format. Each provider implements this to handle its own
6
+ * header conventions, signature schemes, and payload structures.
7
+ */
8
+ import type { SimulatedEvent } from '../trigger/types.js';
9
+ import type { ProviderType } from './types.js';
10
+ /**
11
+ * Discriminated union describing which `ContributorCache` entries a webhook
12
+ * event invalidates. Returned by `WebhookNormalizer.getAccessCacheInvalidations`.
13
+ *
14
+ * Three scopes:
15
+ * - `repo-user`: a single `{repo, user}` permission changed (e.g. GitHub
16
+ * `member` event on a specific collaborator).
17
+ * - `repo`: every contributor's effective permission on a repo may have
18
+ * shifted (e.g. a team was added/removed from the repo).
19
+ * - `user-in-org`: a user's org membership changed, so any repo under that
20
+ * org may now return a different permission for them.
21
+ */
22
+ export type AccessCacheInvalidation = {
23
+ kind: 'repo-user';
24
+ repoFullName: string;
25
+ username: string;
26
+ } | {
27
+ kind: 'repo';
28
+ repoFullName: string;
29
+ } | {
30
+ kind: 'user-in-org';
31
+ orgLogin: string;
32
+ username: string;
33
+ };
34
+ export interface WebhookNormalizer {
35
+ readonly provider: ProviderType;
36
+ /**
37
+ * Extract a routing key from webhook headers/payload.
38
+ *
39
+ * The routing key uniquely identifies a webhook source within KiCI.
40
+ * Format: "{provider}:{provider-specific-id}"
41
+ *
42
+ * Examples:
43
+ * - GitHub: "github:12345" from X-GitHub-Hook-Installation-Target-ID header
44
+ * - GitLab: "gitlab:67890" from payload.project.id
45
+ * - Bitbucket: "bitbucket:{uuid}" from payload.repository.uuid
46
+ */
47
+ extractRoutingKey(headers: Record<string, string>, payload: unknown): string | null;
48
+ /**
49
+ * Extract a unique delivery ID for deduplication.
50
+ *
51
+ * Examples:
52
+ * - GitHub: X-GitHub-Delivery header
53
+ * - GitLab: X-Gitlab-Event-UUID header
54
+ * - Bitbucket: X-Request-UUID header
55
+ */
56
+ extractDeliveryId(headers: Record<string, string>): string | null;
57
+ /**
58
+ * Extract the event type from headers.
59
+ *
60
+ * Returns the provider-specific event type string (not yet normalized).
61
+ *
62
+ * Examples:
63
+ * - GitHub: X-GitHub-Event header ("push", "pull_request")
64
+ * - GitLab: X-Gitlab-Event header ("Push Hook", "Merge Request Hook")
65
+ * - Bitbucket: X-Event-Key header ("repo:push", "pullrequest:created")
66
+ */
67
+ extractEventType(headers: Record<string, string>): string | null;
68
+ /**
69
+ * Verify webhook signature or token.
70
+ *
71
+ * Each provider has its own verification scheme:
72
+ * - GitHub: HMAC-SHA256 with X-Hub-Signature-256 header
73
+ * - GitLab: Plain token comparison with X-Gitlab-Token header
74
+ * - Bitbucket: HMAC-SHA256 with X-Hub-Signature header
75
+ *
76
+ * @param body - Raw request body as string
77
+ * @param headers - Request headers (lowercase keys)
78
+ * @param secret - Webhook secret/token configured for this source
79
+ * @returns true if signature/token is valid
80
+ */
81
+ verifySignature(body: string, headers: Record<string, string>, secret: string): boolean;
82
+ /**
83
+ * Normalize a provider-specific webhook into a SimulatedEvent.
84
+ *
85
+ * Maps provider event types to universal 'pull_request' | 'push' types.
86
+ * Returns null if the event type is not relevant for trigger matching
87
+ * (e.g., GitHub "star" events, GitLab "Pipeline Hook" events).
88
+ *
89
+ * @param eventType - Provider-specific event type (from extractEventType)
90
+ * @param action - Event action/sub-type, if applicable (e.g., "opened" for PRs)
91
+ * @param payload - Raw webhook payload
92
+ * @returns Normalized SimulatedEvent, or null if not matchable
93
+ */
94
+ normalizeEvent(eventType: string, action: string | null, payload: unknown): SimulatedEvent | null;
95
+ /**
96
+ * Extract the repository identifier from a webhook payload.
97
+ *
98
+ * Returns a string in "owner/repo" format, or null if the payload
99
+ * does not contain repository information (e.g., generic webhooks).
100
+ *
101
+ * Examples:
102
+ * - GitHub: "octocat/Hello-World" from payload.repository.full_name
103
+ * - GitLab: "group/project" from payload.project.path_with_namespace
104
+ * - Generic/internal: may return null if no repo concept
105
+ */
106
+ extractRepoIdentifier(payload: unknown): string | null;
107
+ /**
108
+ * Extract the commit SHA or ref for lock file fetching from a webhook payload.
109
+ *
110
+ * Returns a commit SHA, branch name, or 'HEAD' as a fallback.
111
+ * Each provider maps event types to the appropriate payload field.
112
+ *
113
+ * Examples:
114
+ * - GitHub push: payload.after
115
+ * - GitHub pull_request: payload.pull_request.head.sha
116
+ * - Generic: 'HEAD' (no ref concept)
117
+ *
118
+ * @param eventType - Provider-specific event type (from extractEventType)
119
+ * @param payload - Raw webhook payload
120
+ */
121
+ extractRef(eventType: string, payload: unknown): string;
122
+ /**
123
+ * Extract provider-specific credentials from a webhook payload.
124
+ *
125
+ * Returns an object with provider-specific credential fields needed
126
+ * for downstream operations (clone tokens, API calls, etc.).
127
+ *
128
+ * Examples:
129
+ * - GitHub: { installationId: 12345 } from payload.installation.id
130
+ * - Generic: {} (no credentials in payload)
131
+ */
132
+ extractCredentials(payload: unknown): Record<string, unknown>;
133
+ /**
134
+ * Extract the repository's default branch from the webhook payload.
135
+ *
136
+ * Optional. When implemented, the orchestrator uses this hook to decide
137
+ * whether a push event targets the default branch (required for workflow
138
+ * registration extraction). When omitted, the orchestrator falls back to
139
+ * the hardcoded `payload.repository.default_branch` shape.
140
+ *
141
+ * Returns null when the field is missing or cannot be resolved.
142
+ */
143
+ extractDefaultBranch?(payload: unknown): string | null;
144
+ /**
145
+ * Map a webhook event to the `ContributorCache` entries it should drop.
146
+ *
147
+ * Optional. When implemented, the orchestrator calls this before
148
+ * `normalizeEvent` and invalidates every returned entry so the next
149
+ * permission check hits the provider API instead of relying on stale
150
+ * cached data. Events that do not imply a permission shift (most events,
151
+ * including `push` / `pull_request` / etc.) should return `[]`.
152
+ *
153
+ * The caller is responsible for pairing the returned entries with the
154
+ * `provider` field of the matched bundle — this method receives no
155
+ * provider argument.
156
+ *
157
+ * @param eventType Provider-specific event type (from extractEventType).
158
+ * @param action Event action/sub-type, if applicable.
159
+ * @param payload Raw webhook payload.
160
+ */
161
+ getAccessCacheInvalidations?(eventType: string, action: string | null, payload: unknown): AccessCacheInvalidation[];
162
+ }
163
+ //# sourceMappingURL=webhook-normalizer.d.ts.map
@@ -0,0 +1,2 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ export {};
@@ -0,0 +1,52 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Trigger types whose owning workflows must be stored in workflow_registrations
4
+ * so the orchestrator can resolve them from an index lookup instead of
5
+ * re-fetching a lock file per inbound event.
6
+ *
7
+ * Two families live in this list:
8
+ *
9
+ * 1. Non-Git-provider triggers (kici_event, schedule, webhook, lifecycle, …)
10
+ * — these have no per-repo lock file pipeline to fall back to, so the
11
+ * registration index is the authoritative source for matching.
12
+ *
13
+ * 2. Git-provider triggers (push, pr, tag, release, …) — these ARE still
14
+ * matched via the per-event lock file pipeline on the same-source path
15
+ * (e.g. a real GitHub push webhook). Registering them in addition is
16
+ * what makes cross-source dispatch work for a generic webhook that
17
+ * targets an externally-hosted repo (phase 28.5): the cross-source
18
+ * branch looks up `(customer_id, repo_identifier)` and reuses the
19
+ * stored `provider_context` (installation id, app id, …) to mint
20
+ * credentials for the actual provider bundle that owns the repo.
21
+ * Without this, a workflow whose only trigger is `push()` is invisible
22
+ * to cross-source dispatch and generic webhooks targeting its repo
23
+ * silently no-op.
24
+ *
25
+ * Access values: RegisterableTriggerType.enum.kici_event, etc.
26
+ */
27
+ export declare const RegisterableTriggerType: z.ZodEnum<{
28
+ status: "status";
29
+ generic_webhook: "generic_webhook";
30
+ pr: "pr";
31
+ push: "push";
32
+ tag: "tag";
33
+ comment: "comment";
34
+ review: "review";
35
+ review_comment: "review_comment";
36
+ release: "release";
37
+ dispatch: "dispatch";
38
+ create: "create";
39
+ delete: "delete";
40
+ workflow_run: "workflow_run";
41
+ fork: "fork";
42
+ star: "star";
43
+ watch: "watch";
44
+ webhook: "webhook";
45
+ kici_event: "kici_event";
46
+ workflow_complete: "workflow_complete";
47
+ job_complete: "job_complete";
48
+ schedule: "schedule";
49
+ lifecycle: "lifecycle";
50
+ }>;
51
+ export type RegisterableTriggerType = z.infer<typeof RegisterableTriggerType>;
52
+ //# sourceMappingURL=registerable-trigger-type.d.ts.map
@@ -0,0 +1,56 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ import { z } from "zod";
3
+ //#region src/registration/registerable-trigger-type.ts
4
+ /**
5
+ * Trigger types whose owning workflows must be stored in workflow_registrations
6
+ * so the orchestrator can resolve them from an index lookup instead of
7
+ * re-fetching a lock file per inbound event.
8
+ *
9
+ * Two families live in this list:
10
+ *
11
+ * 1. Non-Git-provider triggers (kici_event, schedule, webhook, lifecycle, …)
12
+ * — these have no per-repo lock file pipeline to fall back to, so the
13
+ * registration index is the authoritative source for matching.
14
+ *
15
+ * 2. Git-provider triggers (push, pr, tag, release, …) — these ARE still
16
+ * matched via the per-event lock file pipeline on the same-source path
17
+ * (e.g. a real GitHub push webhook). Registering them in addition is
18
+ * what makes cross-source dispatch work for a generic webhook that
19
+ * targets an externally-hosted repo (phase 28.5): the cross-source
20
+ * branch looks up `(customer_id, repo_identifier)` and reuses the
21
+ * stored `provider_context` (installation id, app id, …) to mint
22
+ * credentials for the actual provider bundle that owns the repo.
23
+ * Without this, a workflow whose only trigger is `push()` is invisible
24
+ * to cross-source dispatch and generic webhooks targeting its repo
25
+ * silently no-op.
26
+ *
27
+ * Access values: RegisterableTriggerType.enum.kici_event, etc.
28
+ */
29
+ const RegisterableTriggerType = z.enum([
30
+ "kici_event",
31
+ "workflow_complete",
32
+ "job_complete",
33
+ "generic_webhook",
34
+ "schedule",
35
+ "lifecycle",
36
+ "webhook",
37
+ "push",
38
+ "pr",
39
+ "tag",
40
+ "comment",
41
+ "review",
42
+ "review_comment",
43
+ "release",
44
+ "dispatch",
45
+ "create",
46
+ "delete",
47
+ "status",
48
+ "workflow_run",
49
+ "fork",
50
+ "star",
51
+ "watch"
52
+ ]);
53
+ //#endregion
54
+ export { RegisterableTriggerType };
55
+
56
+ //# sourceMappingURL=registerable-trigger-type.js.map
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Resource request and limit types for jobs and scalers.
3
+ *
4
+ * Single source of truth — re-exported from the engine barrel and consumed by:
5
+ * - SDK (`Job` / `JobOptions` `resources` field)
6
+ * - compiler (compile-time validation + lockfile emission)
7
+ * - orchestrator (scaler accounting + backend enforcement)
8
+ * - dashboard (read-only display)
9
+ *
10
+ * Shape is K8s-style requests/limits split:
11
+ * - `requests` drive the scheduler's cap math (per-scaler / per-orch / per-machine).
12
+ * - `limits` drive kernel-side enforcement (Docker memory + nanoCpus, FC memSizeMib + vcpuCount,
13
+ * optional bare-metal systemd-run scope).
14
+ *
15
+ * Mirroring rule (applied at the orchestrator's resolve step):
16
+ * - request-only ⇒ limit = request
17
+ * - limit-only ⇒ request = limit
18
+ * - neither ⇒ scaler default
19
+ * - nothing anywhere ⇒ 0/0 (job counts toward agent-count cap only)
20
+ */
21
+ import { z } from 'zod';
22
+ /**
23
+ * A single resource specification (cpus + memory).
24
+ *
25
+ * - `cpus`: fractional cores (e.g., 1.5 means 1.5 cores).
26
+ * - `memory`: container-style suffix (e.g., "2g", "512m", "1024k").
27
+ * No K8s "Mi/Gi" units — one parser, one format across the codebase.
28
+ */
29
+ export interface ResourceSpec {
30
+ /** CPU in fractional cores. */
31
+ cpus?: number;
32
+ /** Memory limit, e.g. "2g", "512m", "1024k". */
33
+ memory?: string;
34
+ }
35
+ /**
36
+ * Per-job resource request (declared in workflow source, threaded through to scaler).
37
+ *
38
+ * `requests` drive scheduling math (cap aggregation).
39
+ * `limits` drive kernel-side enforcement of the spawned agent.
40
+ */
41
+ export interface ResourceRequest {
42
+ /** Requests drive the scheduler's cap math (per-scaler / per-orch / per-machine). */
43
+ requests?: ResourceSpec;
44
+ /** Limits drive kernel enforcement (Docker memory + nanoCpus, FC memSizeMib + vcpuCount, optional bare-metal systemd-run scope). */
45
+ limits?: ResourceSpec;
46
+ }
47
+ /**
48
+ * Zod schema for a single resource spec (cpus + memory).
49
+ */
50
+ export declare const resourceSpecSchema: z.ZodObject<{
51
+ cpus: z.ZodOptional<z.ZodNumber>;
52
+ memory: z.ZodOptional<z.ZodString>;
53
+ }, z.core.$strict>;
54
+ /**
55
+ * Zod schema for the nested request/limit form.
56
+ */
57
+ export declare const resourceRequestNestedSchema: z.ZodObject<{
58
+ requests: z.ZodOptional<z.ZodObject<{
59
+ cpus: z.ZodOptional<z.ZodNumber>;
60
+ memory: z.ZodOptional<z.ZodString>;
61
+ }, z.core.$strict>>;
62
+ limits: z.ZodOptional<z.ZodObject<{
63
+ cpus: z.ZodOptional<z.ZodNumber>;
64
+ memory: z.ZodOptional<z.ZodString>;
65
+ }, z.core.$strict>>;
66
+ }, z.core.$strict>;
67
+ /**
68
+ * Parse a memory string with unit suffix to bytes.
69
+ *
70
+ * Supported formats:
71
+ * - "512m" or "512M" -> 536870912 (512 * 1024^2)
72
+ * - "2g" or "2G" -> 2147483648 (2 * 1024^3)
73
+ * - "1024k" or "1024K" -> 1048576 (1024 * 1024)
74
+ *
75
+ * @throws Error if the format is invalid
76
+ */
77
+ export declare function parseMemoryString(memory: string): number;
78
+ /**
79
+ * Validate a `ResourceRequest` literal (e.g., from compile-time SDK input).
80
+ *
81
+ * Checks:
82
+ * - `memory` strings parse via `parseMemoryString`.
83
+ * - `cpus` are positive numbers ≤ 256 (max practical scaler).
84
+ * - When both `requests` and `limits` are set on the same dimension,
85
+ * `requests <= limits` (a request that exceeds its own limit is nonsensical).
86
+ *
87
+ * Throws on the first violation with a descriptive error.
88
+ */
89
+ export declare function validateResourceRequest(req: ResourceRequest): void;
90
+ //# sourceMappingURL=resource-types.d.ts.map
@@ -0,0 +1,99 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ import { z } from "zod";
3
+ //#region src/scaler/resource-types.ts
4
+ /**
5
+ * Resource request and limit types for jobs and scalers.
6
+ *
7
+ * Single source of truth — re-exported from the engine barrel and consumed by:
8
+ * - SDK (`Job` / `JobOptions` `resources` field)
9
+ * - compiler (compile-time validation + lockfile emission)
10
+ * - orchestrator (scaler accounting + backend enforcement)
11
+ * - dashboard (read-only display)
12
+ *
13
+ * Shape is K8s-style requests/limits split:
14
+ * - `requests` drive the scheduler's cap math (per-scaler / per-orch / per-machine).
15
+ * - `limits` drive kernel-side enforcement (Docker memory + nanoCpus, FC memSizeMib + vcpuCount,
16
+ * optional bare-metal systemd-run scope).
17
+ *
18
+ * Mirroring rule (applied at the orchestrator's resolve step):
19
+ * - request-only ⇒ limit = request
20
+ * - limit-only ⇒ request = limit
21
+ * - neither ⇒ scaler default
22
+ * - nothing anywhere ⇒ 0/0 (job counts toward agent-count cap only)
23
+ */
24
+ /**
25
+ * Zod schema for a single resource spec (cpus + memory).
26
+ */
27
+ const resourceSpecSchema = z.object({
28
+ cpus: z.number().positive().max(256).optional(),
29
+ memory: z.string().optional()
30
+ }).strict();
31
+ /**
32
+ * Zod schema for the nested request/limit form.
33
+ */
34
+ const resourceRequestNestedSchema = z.object({
35
+ requests: resourceSpecSchema.optional(),
36
+ limits: resourceSpecSchema.optional()
37
+ }).strict();
38
+ /**
39
+ * Memory string units supported across the codebase.
40
+ *
41
+ * Mirrors `parseMemoryString` in `packages/orchestrator/src/scaler/config.ts` —
42
+ * keep both in sync. Hoisted here so the compiler (browser-safe) can validate
43
+ * memory strings at compile time without depending on the orchestrator package.
44
+ */
45
+ const MEMORY_FORMAT_RE = /^(\d+(?:\.\d+)?)\s*([kmgKMG])$/;
46
+ /**
47
+ * Parse a memory string with unit suffix to bytes.
48
+ *
49
+ * Supported formats:
50
+ * - "512m" or "512M" -> 536870912 (512 * 1024^2)
51
+ * - "2g" or "2G" -> 2147483648 (2 * 1024^3)
52
+ * - "1024k" or "1024K" -> 1048576 (1024 * 1024)
53
+ *
54
+ * @throws Error if the format is invalid
55
+ */
56
+ function parseMemoryString(memory) {
57
+ const match = memory.match(MEMORY_FORMAT_RE);
58
+ if (!match) throw new Error(`Invalid memory format: "${memory}". Expected format like "512m", "2g", or "1024k".`);
59
+ const value = parseFloat(match[1]);
60
+ const unit = match[2].toLowerCase();
61
+ switch (unit) {
62
+ case "k": return Math.floor(value * 1024);
63
+ case "m": return Math.floor(value * 1024 * 1024);
64
+ case "g": return Math.floor(value * 1024 * 1024 * 1024);
65
+ default: throw new Error(`Unknown memory unit: "${unit}"`);
66
+ }
67
+ }
68
+ /**
69
+ * Validate a `ResourceRequest` literal (e.g., from compile-time SDK input).
70
+ *
71
+ * Checks:
72
+ * - `memory` strings parse via `parseMemoryString`.
73
+ * - `cpus` are positive numbers ≤ 256 (max practical scaler).
74
+ * - When both `requests` and `limits` are set on the same dimension,
75
+ * `requests <= limits` (a request that exceeds its own limit is nonsensical).
76
+ *
77
+ * Throws on the first violation with a descriptive error.
78
+ */
79
+ function validateResourceRequest(req) {
80
+ resourceRequestNestedSchema.parse(req);
81
+ for (const side of ["requests", "limits"]) {
82
+ const spec = req[side];
83
+ if (!spec) continue;
84
+ if (spec.memory !== void 0) parseMemoryString(spec.memory);
85
+ if (spec.cpus !== void 0 && spec.cpus <= 0) throw new Error(`resources.${side}.cpus must be > 0 (got ${spec.cpus})`);
86
+ }
87
+ const requests = req.requests;
88
+ const limits = req.limits;
89
+ if (requests && limits) {
90
+ if (requests.cpus !== void 0 && limits.cpus !== void 0 && requests.cpus > limits.cpus) throw new Error(`resources.requests.cpus (${requests.cpus}) must not exceed resources.limits.cpus (${limits.cpus})`);
91
+ if (requests.memory !== void 0 && limits.memory !== void 0) {
92
+ if (parseMemoryString(requests.memory) > parseMemoryString(limits.memory)) throw new Error(`resources.requests.memory (${requests.memory}) must not exceed resources.limits.memory (${limits.memory})`);
93
+ }
94
+ }
95
+ }
96
+ //#endregion
97
+ export { parseMemoryString, resourceRequestNestedSchema, resourceSpecSchema, validateResourceRequest };
98
+
99
+ //# sourceMappingURL=resource-types.js.map
@@ -0,0 +1,16 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Scaler backend type identifiers.
4
+ *
5
+ * Enumerates the agent provisioning backends supported by the orchestrator's
6
+ * auto-scaler module. Each backend implements the ScalerBackend interface.
7
+ * Access values: ScalerBackendType.enum.container, ScalerBackendType.enum.firecracker, etc.
8
+ */
9
+ export declare const ScalerBackendType: z.ZodEnum<{
10
+ container: "container";
11
+ "bare-metal": "bare-metal";
12
+ firecracker: "firecracker";
13
+ kubernetes: "kubernetes";
14
+ }>;
15
+ export type ScalerBackendType = z.infer<typeof ScalerBackendType>;
16
+ //# sourceMappingURL=scaler-backend-type.d.ts.map
@@ -0,0 +1,20 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ import { z } from "zod";
3
+ //#region src/scaler/scaler-backend-type.ts
4
+ /**
5
+ * Scaler backend type identifiers.
6
+ *
7
+ * Enumerates the agent provisioning backends supported by the orchestrator's
8
+ * auto-scaler module. Each backend implements the ScalerBackend interface.
9
+ * Access values: ScalerBackendType.enum.container, ScalerBackendType.enum.firecracker, etc.
10
+ */
11
+ const ScalerBackendType = z.enum([
12
+ "container",
13
+ "bare-metal",
14
+ "firecracker",
15
+ "kubernetes"
16
+ ]);
17
+ //#endregion
18
+ export { ScalerBackendType };
19
+
20
+ //# sourceMappingURL=scaler-backend-type.js.map
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Secrets management module.
3
+ *
4
+ * Re-exports scope-based secret store types and audit entry.
5
+ */
6
+ export type { SecretStore, AuditEntry, BackendType, BackendHealthStatus, BackendDescriptor, AddBackendParams, BackendManager, BackendSyncManager, } from './types.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ export {};
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Secrets management interfaces for KiCI.
3
+ *
4
+ * Defines the pluggable backend contract (SecretStore) and audit logging
5
+ * (AuditEntry) for the scoped secrets system.
6
+ *
7
+ * These interfaces are backend-agnostic -- implementations live in
8
+ * orchestrator (PG backend) or can be swapped for Vault, etc.
9
+ */
10
+ /**
11
+ * Scope-based secret store interface.
12
+ * Provides access to secrets organized by (orgId, scope, key).
13
+ */
14
+ export interface SecretStore {
15
+ /** Get all secrets for a scope as decrypted key-value pairs. */
16
+ getSecrets(orgId: string, scope: string): Promise<Record<string, string>>;
17
+ /** Set (create or update) a secret in a scope. */
18
+ setSecret(orgId: string, scope: string, key: string, value: string): Promise<void>;
19
+ /** Delete a secret from a scope. */
20
+ deleteSecret(orgId: string, scope: string, key: string): Promise<void>;
21
+ /** List all secret key names in a scope (no values returned). */
22
+ listKeys(orgId: string, scope: string): Promise<string[]>;
23
+ /** List all distinct scopes for an org. */
24
+ listScopes(orgId: string): Promise<string[]>;
25
+ /** Create an empty scope (implementation may use a sentinel row or metadata table). */
26
+ createScope?(orgId: string, scope: string): Promise<void>;
27
+ /** Rename a scope -- update all secret rows from oldScope to newScope. */
28
+ renameScope?(orgId: string, oldScope: string, newScope: string): Promise<void>;
29
+ /** Delete a scope and all its secrets. */
30
+ deleteScope?(orgId: string, scope: string): Promise<void>;
31
+ /** Get all secrets for an org (for resolver). Returns encrypted values. */
32
+ getAllSecrets(orgId: string): Promise<Array<{
33
+ scope: string;
34
+ key: string;
35
+ encryptedValue: string;
36
+ keyVersion: number;
37
+ }>>;
38
+ }
39
+ /** Supported secret backend types. */
40
+ export type BackendType = 'pg' | 'vault';
41
+ /** Health status of a secret backend. */
42
+ export type BackendHealthStatus = 'healthy' | 'degraded' | 'unreachable' | 'unknown';
43
+ /**
44
+ * Metadata descriptor for a registered secret backend.
45
+ * Does NOT include credentials — safe to expose via API.
46
+ */
47
+ export interface BackendDescriptor {
48
+ id: string;
49
+ name: string;
50
+ backendType: BackendType;
51
+ /** Comma-separated globs for scope filtering. Default '**'. */
52
+ scopeFilter: string;
53
+ /** Sync interval in milliseconds. Default 300000 (5 min). */
54
+ syncIntervalMs: number;
55
+ enabled: boolean;
56
+ healthStatus: BackendHealthStatus;
57
+ scopeCount: number;
58
+ lastSyncAt: Date | null;
59
+ lastSyncError: string | null;
60
+ lastHealthCheckAt: Date | null;
61
+ createdAt: Date;
62
+ updatedAt: Date;
63
+ }
64
+ /** Parameters for registering a new secret backend. */
65
+ export interface AddBackendParams {
66
+ name: string;
67
+ backendType: BackendType;
68
+ config: Record<string, unknown>;
69
+ scopeFilter?: string;
70
+ syncIntervalMs?: number;
71
+ }
72
+ /**
73
+ * Backend lifecycle manager interface.
74
+ * Provides CRUD, health checks, and connection testing for secret backends.
75
+ */
76
+ export interface BackendManager {
77
+ /** Check backend connectivity. Returns health status. */
78
+ checkHealth(name: string): Promise<BackendHealthStatus>;
79
+ /** Trigger scope discovery sync for a backend (or all if name omitted). */
80
+ syncScopes(name?: string): Promise<void>;
81
+ /** List all registered backends (no credentials). */
82
+ listBackends(): Promise<BackendDescriptor[]>;
83
+ /** Get a single backend by name. */
84
+ getBackend(name: string): Promise<BackendDescriptor | null>;
85
+ /** Register a new backend. Returns the descriptor. */
86
+ addBackend(params: AddBackendParams): Promise<BackendDescriptor>;
87
+ /** Remove a backend by name. Returns true if removed. */
88
+ removeBackend(name: string): Promise<boolean>;
89
+ /** Test connectivity without persisting. */
90
+ testConnection(params: AddBackendParams): Promise<{
91
+ ok: boolean;
92
+ error?: string;
93
+ latencyMs: number;
94
+ }>;
95
+ }
96
+ /**
97
+ * Periodic scope sync manager for secret backends.
98
+ */
99
+ export interface BackendSyncManager {
100
+ syncBackend(name: string): Promise<{
101
+ scopeCount: number;
102
+ error?: string;
103
+ }>;
104
+ syncAllBackends(): Promise<Array<{
105
+ name: string;
106
+ scopeCount: number;
107
+ error?: string;
108
+ }>>;
109
+ startPeriodicSync(): void;
110
+ stopPeriodicSync(): void;
111
+ }
112
+ /**
113
+ * Audit log entry for secrets operations.
114
+ * Used for tracking access patterns and security events.
115
+ */
116
+ export interface AuditEntry {
117
+ /** The action performed (e.g., 'getSecrets', 'setSecret', 'resolve'). */
118
+ action: string;
119
+ /** The scope or context name involved. */
120
+ contextName: string;
121
+ /** Routing key scope. */
122
+ routingKey: string | null;
123
+ /** Secret keys involved (null for scope-level ops). */
124
+ secretKeys: string[] | null;
125
+ /** Whether the operation was allowed or denied. */
126
+ outcome: 'allowed' | 'denied';
127
+ /** CI run ID if applicable. */
128
+ runId: string | null;
129
+ /** Job ID if applicable. */
130
+ jobId: string | null;
131
+ /** User ID if applicable. */
132
+ userId: string | null;
133
+ /** User role if applicable. */
134
+ role: string | null;
135
+ /** Additional metadata. */
136
+ metadata: Record<string, unknown> | null;
137
+ }
138
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,2 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ export {};
@@ -0,0 +1,2 @@
1
+ export { transition, isTerminal } from './machine.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ import { isTerminal, transition } from "./machine.js";
3
+ export { isTerminal, transition };