@kici-dev/orchestrator 0.1.15 → 0.1.17
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/agent/dispatcher.d.ts +18 -1
- package/dist/app.d.ts +25 -0
- package/dist/approvals/apply-decision.d.ts +70 -0
- package/dist/approvals/approval-resolver.d.ts +66 -0
- package/dist/approvals/step-approval-bridge.d.ts +72 -0
- package/dist/approvals/team-membership-lookup.d.ts +13 -0
- package/dist/cache/pending-inits.d.ts +5 -0
- package/dist/cache/user-cache.d.ts +1 -1
- package/dist/cli/api-client.d.ts +35 -0
- package/dist/cli/commands/firecracker/index.d.ts +11 -0
- package/dist/cli/commands/firecracker/provision.d.ts +13 -0
- package/dist/cli/commands/firecracker/teardown.d.ts +3 -0
- package/dist/cli/commands/firecracker/verify.d.ts +3 -0
- package/dist/cli/commands/local-hook.d.ts +15 -0
- package/dist/cli/commands/local-trigger.d.ts +24 -0
- package/dist/cli/commands/remote-source.d.ts +17 -0
- package/dist/cli/commands/scaler.d.ts +18 -0
- package/dist/cli/commands/shared/versioned-upgrade.d.ts +14 -0
- package/dist/cli/kici-admin.d.ts +23 -1
- package/dist/cli/service/image-digests.d.ts +21 -0
- package/dist/cli.js +4320 -490
- package/dist/cluster/peer-client.d.ts +23 -1
- package/dist/cluster/peer-handler.d.ts +9 -1
- package/dist/config.d.ts +0 -4
- package/dist/dashboard/handler.d.ts +26 -2
- package/dist/dashboard/needs-edges.d.ts +13 -0
- package/dist/db/migrations/033_org_settings_approval.d.ts +19 -0
- package/dist/db/migrations/034_held_runs_generalize.d.ts +24 -0
- package/dist/db/migrations/035_pending_workflow_contexts.d.ts +11 -0
- package/dist/db/migrations/036_attestations.d.ts +15 -0
- package/dist/db/migrations/037_generic_sources_provider_type_local.d.ts +19 -0
- package/dist/db/migrations/038_remote_sources.d.ts +14 -0
- package/dist/db/types.d.ts +135 -11
- package/dist/diagnostics/bundle-writer.d.ts +1 -17
- package/dist/diagnostics/checks/firecracker-network.d.ts +13 -0
- package/dist/diagnostics/checks/index.d.ts +2 -1
- package/dist/diagnostics/fleet-collector.d.ts +52 -0
- package/dist/diagnostics/fleet-constants.d.ts +8 -0
- package/dist/diagnostics/fleet-selection.d.ts +15 -0
- package/dist/diagnostics/fleet-topology.d.ts +47 -0
- package/dist/diagnostics/fleet-wiring.d.ts +60 -0
- package/dist/entry-helpers.d.ts +7 -29
- package/dist/environments/held-runs.d.ts +93 -1
- package/dist/firecracker/host-network.d.ts +83 -0
- package/dist/firecracker/persist.d.ts +14 -0
- package/dist/index.js +25 -6
- package/dist/metrics/prometheus.d.ts +4 -2
- package/dist/orchestrator-core.d.ts +57 -1
- package/dist/pipeline/dispatch-matched-workflow.d.ts +18 -1
- package/dist/pipeline/install-secrets-resolver.d.ts +32 -5
- package/dist/pipeline/needs-scheduler.d.ts +12 -10
- package/dist/pipeline/pending-workflow-context.d.ts +44 -0
- package/dist/pipeline/processor.d.ts +28 -4
- package/dist/pipeline/remote-source-store.d.ts +21 -0
- package/dist/pipeline/resume-workflow.d.ts +26 -0
- package/dist/providers/local/index.d.ts +33 -0
- package/dist/providers/local/local-source-config.d.ts +17 -0
- package/dist/providers/{internal → local}/lock-file-fetcher.d.ts +6 -6
- package/dist/providers/{internal → local}/normalizer.d.ts +28 -28
- package/dist/providers/{internal → local}/repo-url-builder.d.ts +6 -6
- package/dist/reporting/execution-tracker.d.ts +33 -0
- package/dist/routes/admin-events.d.ts +3 -4
- package/dist/routes/fleet.d.ts +20 -0
- package/dist/routes/uploads.d.ts +36 -26
- package/dist/scaler/config.d.ts +4 -2
- package/dist/scaler/disk-guard.d.ts +27 -0
- package/dist/scaler/firecracker-backend.d.ts +18 -0
- package/dist/scaler/manager.d.ts +6 -0
- package/dist/scaler/nftables.d.ts +4 -0
- package/dist/scaler/reap-orphans.d.ts +27 -0
- package/dist/scaler/types.d.ts +2 -0
- package/dist/server.js +26929 -23511
- package/dist/sources/build-platform-sources.d.ts +4 -2
- package/dist/stale-detector/stale-run-detector.d.ts +32 -1
- package/dist/standalone.js +16941 -15329
- package/dist/storage/filesystem.d.ts +2 -1
- package/dist/storage/s3.d.ts +2 -1
- package/dist/storage/types.d.ts +7 -0
- package/dist/webhook/generic-sources-listener.d.ts +4 -0
- package/dist/webhook/generic-sources.d.ts +37 -11
- package/dist/webhook/register-source-bundle.d.ts +14 -4
- package/dist/ws/agent-handler.d.ts +49 -0
- package/dist/ws/dashboard-dispatch-guard.d.ts +21 -0
- package/dist/ws/dashboard-env-handler.d.ts +47 -0
- package/dist/ws/fleet-agent-collector.d.ts +23 -0
- package/dist/ws/oidc-token-relay.d.ts +59 -0
- package/dist/ws/platform-client.d.ts +30 -1
- package/dist/ws/test-relay-handlers.d.ts +112 -0
- package/installer-image-digests.json +7 -0
- package/package.json +6 -5
- package/sbom.spdx.json +112 -57
- package/dist/providers/internal/index.d.ts +0 -32
- package/dist/routes/test-trigger.d.ts +0 -41
- package/dist/ws/observer-handler.d.ts +0 -42
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* data file is byte-identical to what the agent receives over HTTP. TTL is
|
|
14
14
|
* enforced lazily on access — same model as the S3 backend.
|
|
15
15
|
*/
|
|
16
|
-
import type { CacheStorage } from './types.js';
|
|
16
|
+
import type { CacheMetadata, CacheStorage } from './types.js';
|
|
17
17
|
export interface FilesystemCacheStorageOptions {
|
|
18
18
|
/** Absolute path to the cache root directory. Created on first write if missing. */
|
|
19
19
|
basePath: string;
|
|
@@ -55,6 +55,7 @@ export declare class FilesystemCacheStorage implements CacheStorage {
|
|
|
55
55
|
getInternalUploadUrl(key: string): Promise<string>;
|
|
56
56
|
initMeta(key: string): Promise<void>;
|
|
57
57
|
list(subPrefix: string): Promise<string[]>;
|
|
58
|
+
getMetadata(key: string): Promise<CacheMetadata | null>;
|
|
58
59
|
copy(srcKey: string, destKey: string): Promise<void>;
|
|
59
60
|
/**
|
|
60
61
|
* Recursively collect data files under `dir`, returning each as a cache key
|
package/dist/storage/s3.d.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* TTL is enforced lazily: expired items are deleted on access.
|
|
12
12
|
* Pre-signed URLs are generated for getUrl() with 15-minute expiry.
|
|
13
13
|
*/
|
|
14
|
-
import type { CacheStorage } from './types.js';
|
|
14
|
+
import type { CacheMetadata, CacheStorage } from './types.js';
|
|
15
15
|
export interface S3CacheStorageOptions {
|
|
16
16
|
bucket: string;
|
|
17
17
|
prefix: string;
|
|
@@ -74,6 +74,7 @@ export declare class S3CacheStorage implements CacheStorage {
|
|
|
74
74
|
getInternalUploadUrl(key: string): Promise<string>;
|
|
75
75
|
initMeta(key: string): Promise<void>;
|
|
76
76
|
list(subPrefix: string): Promise<string[]>;
|
|
77
|
+
getMetadata(key: string): Promise<CacheMetadata | null>;
|
|
77
78
|
copy(srcKey: string, destKey: string): Promise<void>;
|
|
78
79
|
/** Delete an S3 object. Idempotent (doesn't error if missing). */
|
|
79
80
|
private deleteObject;
|
package/dist/storage/types.d.ts
CHANGED
|
@@ -79,6 +79,13 @@ export interface CacheStorage {
|
|
|
79
79
|
list(subPrefix: string): Promise<string[]>;
|
|
80
80
|
/** Server-side copy from one cache key to another (used for atomic temp -> final commit). */
|
|
81
81
|
copy(srcKey: string, destKey: string): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Read the stored metadata (createdAt + lastAccessedAt) for a key WITHOUT
|
|
84
|
+
* refreshing lastAccessedAt. Returns null when the key is missing or carries
|
|
85
|
+
* no metadata. A pure read (no TTL-expiry side effect) — used by quota
|
|
86
|
+
* eviction to order candidates by access recency.
|
|
87
|
+
*/
|
|
88
|
+
getMetadata(key: string): Promise<CacheMetadata | null>;
|
|
82
89
|
}
|
|
83
90
|
import type { SharedS3Config } from '@kici-dev/shared';
|
|
84
91
|
/**
|
|
@@ -51,6 +51,10 @@ export interface GenericSourcesChangeListenerOptions {
|
|
|
51
51
|
/** Required for universal-git source rows; null is acceptable on
|
|
52
52
|
* peers that cannot serve them. */
|
|
53
53
|
secretResolver: SecretResolver | null;
|
|
54
|
+
/** Active scaler backend on this peer. Threaded into the warm-path
|
|
55
|
+
* registration so a local source added at runtime on a container /
|
|
56
|
+
* firecracker scaler emits the same reachability warning as a cold-boot one. */
|
|
57
|
+
scalerBackendType?: string;
|
|
54
58
|
/** Coalesce window for rapid NOTIFYs against the same row. Default 200 ms. */
|
|
55
59
|
debounceMs?: number;
|
|
56
60
|
/**
|
|
@@ -9,6 +9,7 @@ import { type Kysely } from 'kysely';
|
|
|
9
9
|
import type { Database, GenericWebhookSource } from '../db/types.js';
|
|
10
10
|
import type { VerificationMethod } from '../providers/generic/verification.js';
|
|
11
11
|
import { type UniversalGitConfig } from '../providers/universal-git/config.js';
|
|
12
|
+
import { type LocalSourceConfig } from '../providers/local/local-source-config.js';
|
|
12
13
|
/**
|
|
13
14
|
* Input for creating a new generic webhook source.
|
|
14
15
|
*/
|
|
@@ -26,22 +27,31 @@ interface CreateSourceInput {
|
|
|
26
27
|
allowedEvents?: string[];
|
|
27
28
|
stripHeaders?: string[];
|
|
28
29
|
rateLimitRpm?: number;
|
|
29
|
-
/** Provider implementation: 'generic' (default) or '
|
|
30
|
-
*
|
|
31
|
-
|
|
30
|
+
/** Provider implementation: 'generic' (default) or 'local' (a git repo on
|
|
31
|
+
* the agent filesystem cloned via file://, routed through
|
|
32
|
+
* LocalWebhookNormalizer). */
|
|
33
|
+
providerType?: 'generic' | 'local';
|
|
32
34
|
/** Universal-git configuration — when set, promotes this source from a
|
|
33
35
|
* payload-only generic webhook to a full git-aware source that can register
|
|
34
36
|
* workflows, fetch lock files, and be cloned by agents. Validated against
|
|
35
37
|
* `UniversalGitConfigSchema`; stored as JSONB in `generic_webhook_sources.git_config`. */
|
|
36
38
|
gitConfig?: UniversalGitConfig;
|
|
39
|
+
/** Local filesystem source config (`{ repoBasePath, cloneUrlBase? }`).
|
|
40
|
+
* Mutually exclusive with `gitConfig`. Stored as JSONB in the same
|
|
41
|
+
* `git_config` column, discriminated from universal-git by `providerType='local'`.
|
|
42
|
+
* Validated against `LocalSourceConfigSchema`. */
|
|
43
|
+
localConfig?: LocalSourceConfig;
|
|
37
44
|
}
|
|
38
45
|
/**
|
|
39
46
|
* Input for updating an existing generic webhook source. Use `gitConfig: null`
|
|
40
47
|
* to explicitly demote a universal-git source back to a plain generic webhook
|
|
41
48
|
* (omitting the field leaves the existing config untouched).
|
|
42
49
|
*/
|
|
43
|
-
type UpdateSourceInput = Partial<Omit<CreateSourceInput, 'orgId' | 'gitConfig'>> & {
|
|
50
|
+
type UpdateSourceInput = Partial<Omit<CreateSourceInput, 'orgId' | 'gitConfig' | 'localConfig'>> & {
|
|
44
51
|
gitConfig?: UniversalGitConfig | null;
|
|
52
|
+
/** `null` clears the local config; a validated object re-serializes it to
|
|
53
|
+
* `git_config`. Omit to leave the existing config untouched. */
|
|
54
|
+
localConfig?: LocalSourceConfig | null;
|
|
45
55
|
};
|
|
46
56
|
/**
|
|
47
57
|
* Generic webhook source manager.
|
|
@@ -77,19 +87,32 @@ export declare class GenericSourceManager {
|
|
|
77
87
|
* List all enabled, non-deleted sources matching a provider type.
|
|
78
88
|
*
|
|
79
89
|
* Used at orchestrator startup to register provider bundles per routing key
|
|
80
|
-
* (e.g. registering
|
|
81
|
-
* provider_type='
|
|
82
|
-
*
|
|
83
|
-
* generic endpoint without a real GitHub signature).
|
|
90
|
+
* (e.g. registering a LocalWebhookNormalizer bundle for every
|
|
91
|
+
* provider_type='local' source so local filesystem repos can dispatch real
|
|
92
|
+
* runs through the generic endpoint without a real GitHub signature).
|
|
84
93
|
*/
|
|
85
|
-
listByProviderType(providerType: 'generic' | '
|
|
94
|
+
listByProviderType(providerType: 'generic' | 'local'): Promise<GenericWebhookSource[]>;
|
|
86
95
|
/**
|
|
87
96
|
* List all enabled, non-deleted sources with a non-null `git_config`
|
|
88
97
|
* (universal-git sources). Used at orchestrator startup + config reload
|
|
89
98
|
* to register a universal-git `ProviderBundle` under each source's
|
|
90
99
|
* routing key.
|
|
100
|
+
*
|
|
101
|
+
* Local sources ALSO carry `git_config` (they store `{ repoBasePath }` there),
|
|
102
|
+
* so this query MUST exclude `provider_type='local'` — otherwise a local
|
|
103
|
+
* source would be mis-registered as a universal-git bundle. The matching
|
|
104
|
+
* discrimination lives in `genericProviderTypeToSubtype` (local branch first)
|
|
105
|
+
* and `registerProviderBundleForSource` (local branch before the universal-git
|
|
106
|
+
* branch).
|
|
91
107
|
*/
|
|
92
108
|
listUniversalGitSources(): Promise<GenericWebhookSource[]>;
|
|
109
|
+
/**
|
|
110
|
+
* List all enabled, non-deleted local filesystem sources
|
|
111
|
+
* (`provider_type='local'`). Used at orchestrator startup + config reload to
|
|
112
|
+
* register a `LocalWebhookNormalizer` bundle (built from each row's
|
|
113
|
+
* `git_config.repoBasePath`) under the source's routing key.
|
|
114
|
+
*/
|
|
115
|
+
listLocalSources(): Promise<GenericWebhookSource[]>;
|
|
93
116
|
/**
|
|
94
117
|
* Update a source's configuration.
|
|
95
118
|
*/
|
|
@@ -151,8 +174,8 @@ export declare class GenericSourceManager {
|
|
|
151
174
|
*
|
|
152
175
|
* Returns `provider_type` alongside the routing key so callers can decide
|
|
153
176
|
* whether the local orchestrator can actually serve each row. A peer that
|
|
154
|
-
* cannot serve a provider_type (e.g.
|
|
155
|
-
*
|
|
177
|
+
* cannot serve a provider_type (e.g. a `local` source whose `repoBasePath`
|
|
178
|
+
* does not exist on that peer) MUST NOT advertise that routing key
|
|
156
179
|
* to Platform — otherwise Platform's least-loaded relay may pick that peer
|
|
157
180
|
* and the webhook is silently dropped on a pipeline that has no working
|
|
158
181
|
* lock-file fetcher.
|
|
@@ -164,6 +187,9 @@ export declare function loadActiveGenericRoutingKeys(db: Kysely<Database>): Prom
|
|
|
164
187
|
name: string;
|
|
165
188
|
/** Whether the row has a non-null `git_config` (universal-git source). */
|
|
166
189
|
has_git_config: boolean;
|
|
190
|
+
/** Raw `git_config` JSONB. Carried so the caller can check a local source's
|
|
191
|
+
* per-row `repoBasePath` reachability via `canServeGenericProviderType`. */
|
|
192
|
+
git_config: string | Record<string, unknown> | null;
|
|
167
193
|
}>>;
|
|
168
194
|
export {};
|
|
169
195
|
//# sourceMappingURL=generic-sources.d.ts.map
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* the orchestrator's already-instantiated registry / config /
|
|
25
25
|
* secret-resolver and we do the right thing.
|
|
26
26
|
*
|
|
27
|
-
* Failure semantics match the startup behaviour:
|
|
27
|
+
* Failure semantics match the startup behaviour: local-only-but-
|
|
28
28
|
* unservable peers log + skip (no throw); universal-git config errors
|
|
29
29
|
* bump the per-row metric + log but never propagate. The caller can
|
|
30
30
|
* assume "returns normally" means "the right thing happened or we
|
|
@@ -40,13 +40,23 @@ export interface RegisterSourceBundleDeps {
|
|
|
40
40
|
/** Required for universal-git source rows. Null is allowed; rows that
|
|
41
41
|
* carry `git_config` will be skipped with a metric bump. */
|
|
42
42
|
secretResolver: SecretResolver | null;
|
|
43
|
+
/** Active scaler backend on this peer. When 'container' or 'firecracker', a
|
|
44
|
+
* local source registration emits a one-time reachability warning (the repo
|
|
45
|
+
* must exist inside the agent filesystem, not just on the orchestrator host). */
|
|
46
|
+
scalerBackendType?: string;
|
|
47
|
+
/** Sink for the scaler-coexistence warning. Defaults to the module logger;
|
|
48
|
+
* overridable in tests so the warning can be asserted without logger spying. */
|
|
49
|
+
onScalerWarning?: (message: string, ctx: Record<string, unknown>) => void;
|
|
43
50
|
}
|
|
44
51
|
/**
|
|
45
52
|
* Register the per-routing-key provider bundle a source row needs.
|
|
46
53
|
*
|
|
47
|
-
* - `provider_type='
|
|
48
|
-
*
|
|
49
|
-
*
|
|
54
|
+
* - `provider_type='local'`: registers a `LocalWebhookNormalizer` bundle
|
|
55
|
+
* built from the ROW's own `git_config.repoBasePath`, when that path
|
|
56
|
+
* exists as a directory on THIS peer. A peer that doesn't host the repo
|
|
57
|
+
* skips registration (and won't advertise the routing key — see
|
|
58
|
+
* `canServeGenericProviderType`). Checked BEFORE the universal-git branch
|
|
59
|
+
* because local sources also carry `git_config`.
|
|
50
60
|
* - `git_config IS NOT NULL`: registers a universal-git bundle.
|
|
51
61
|
* - everything else: no-op — the default `'generic'` bundle handles it.
|
|
52
62
|
*
|
|
@@ -31,6 +31,7 @@ import type { PendingDynamicTracker } from '../cache/pending-dynamics.js';
|
|
|
31
31
|
import type { CacheStorage } from '../storage/types.js';
|
|
32
32
|
import type { AgentMetricsAggregator } from '../metrics/agent-metrics-aggregator.js';
|
|
33
33
|
import type { AgentApiRegistry } from './agent-api-registry.js';
|
|
34
|
+
import type { FleetAgentCollector } from './fleet-agent-collector.js';
|
|
34
35
|
/**
|
|
35
36
|
* Run the three token-bound authorization gates against a wire-supplied
|
|
36
37
|
* `agent.register` payload. The gates are identical at first register
|
|
@@ -181,6 +182,23 @@ export interface AgentWsHandlerDeps {
|
|
|
181
182
|
dispatchCacheRefs?: DispatchCacheRefTracker;
|
|
182
183
|
/** Cache storage for setting metadata after upload completion. */
|
|
183
184
|
cacheStorage?: CacheStorage;
|
|
185
|
+
/**
|
|
186
|
+
* Storage used to mint presigned PUT URLs for provenance bundles. Distinct
|
|
187
|
+
* dep so a deployment can decide whether attestations share the cache bucket.
|
|
188
|
+
*/
|
|
189
|
+
provenanceStorage?: CacheStorage;
|
|
190
|
+
/**
|
|
191
|
+
* Record a completed provenance-bundle upload (writes an attestations row).
|
|
192
|
+
* `runId` is resolved server-side from the job's dispatch ref, never the wire.
|
|
193
|
+
*/
|
|
194
|
+
onProvenanceUpload?: (record: {
|
|
195
|
+
runId: string;
|
|
196
|
+
jobId: string;
|
|
197
|
+
subjectName: string;
|
|
198
|
+
subjectDigest: string;
|
|
199
|
+
storageKey: string;
|
|
200
|
+
mediaType: string;
|
|
201
|
+
}) => Promise<void>;
|
|
184
202
|
/** Optional rate limiter configuration. */
|
|
185
203
|
rateLimiterConfig?: RateLimiterConfig;
|
|
186
204
|
/** Optional ownership tracker for validating job-related messages. */
|
|
@@ -208,6 +226,30 @@ export interface AgentWsHandlerDeps {
|
|
|
208
226
|
action: 'proceed' | 'wait' | 'cancel';
|
|
209
227
|
reason?: string;
|
|
210
228
|
}>;
|
|
229
|
+
/**
|
|
230
|
+
* Optional callback when an agent blocks a `requireApproval` step. The server
|
|
231
|
+
* creates a step-scoped hold from the carried clauses and returns a promise
|
|
232
|
+
* that resolves when the hold is approved, rejected, or expired. The handler
|
|
233
|
+
* relays the resolution back to the originating agent as a
|
|
234
|
+
* `step.approval-resolved` message. The `agentId` lets the server drop the
|
|
235
|
+
* pending resolver when the agent disconnects.
|
|
236
|
+
*/
|
|
237
|
+
onStepApproval?: (agentId: string, msg: {
|
|
238
|
+
runId: string;
|
|
239
|
+
jobId: string;
|
|
240
|
+
stepIndex: number;
|
|
241
|
+
stepName: string;
|
|
242
|
+
clauses: Array<{
|
|
243
|
+
team: string;
|
|
244
|
+
} | {
|
|
245
|
+
user: string;
|
|
246
|
+
}>;
|
|
247
|
+
reason: string;
|
|
248
|
+
timeoutSeconds?: number;
|
|
249
|
+
}) => Promise<{
|
|
250
|
+
outcome: 'approved' | 'rejected' | 'expired';
|
|
251
|
+
reason?: string;
|
|
252
|
+
}>;
|
|
211
253
|
/**
|
|
212
254
|
* Optional callback fired when an agent's WS connection closes, after the
|
|
213
255
|
* dispatcher's own cleanup has run. Used by the long-poll concurrency
|
|
@@ -217,6 +259,13 @@ export interface AgentWsHandlerDeps {
|
|
|
217
259
|
onConcurrencyAgentDisconnect?: (agentId: string) => void | Promise<void>;
|
|
218
260
|
/** Agent private API registry for handling agent.api.request messages. */
|
|
219
261
|
agentApiRegistry?: AgentApiRegistry;
|
|
262
|
+
/**
|
|
263
|
+
* Orchestrator-scoped collector that correlates fleet.logs.request with the
|
|
264
|
+
* agent's chunked fleet.bundle.chunk / fleet.bundle.error response. Routed to
|
|
265
|
+
* from the incoming-message switch; pending requests for a given agent are
|
|
266
|
+
* rejected when that agent's WS closes.
|
|
267
|
+
*/
|
|
268
|
+
fleetAgentCollector?: FleetAgentCollector;
|
|
220
269
|
}
|
|
221
270
|
export declare function createAgentWsHandler(deps: AgentWsHandlerDeps): WSEvents;
|
|
222
271
|
//# sourceMappingURL=agent-handler.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Guarantees every forwarded dashboard request produces exactly one response
|
|
3
|
+
* frame keyed to its requestId. Wraps the per-type dispatch so a thrown handler
|
|
4
|
+
* or an unhandled message type returns a fast structured error instead of a
|
|
5
|
+
* silently dropped frame (which the Platform would surface as a 10s 504 at its
|
|
6
|
+
* forward window).
|
|
7
|
+
*/
|
|
8
|
+
export interface DashboardDispatchGuardDeps {
|
|
9
|
+
/** Sends a raw frame back over the Platform WS. */
|
|
10
|
+
sendRaw: (msg: unknown) => void;
|
|
11
|
+
/** Runs the real per-type dispatch; resolves true if a handler owned the type. */
|
|
12
|
+
dispatch: (msg: {
|
|
13
|
+
type: string;
|
|
14
|
+
requestId: string;
|
|
15
|
+
}) => Promise<boolean>;
|
|
16
|
+
}
|
|
17
|
+
export declare function guardedDashboardDispatch(deps: DashboardDispatchGuardDeps, msg: {
|
|
18
|
+
type: string;
|
|
19
|
+
requestId: string;
|
|
20
|
+
}): Promise<void>;
|
|
21
|
+
//# sourceMappingURL=dashboard-dispatch-guard.d.ts.map
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
* 3. Returns a response message with requestId and data (or error)
|
|
12
12
|
*/
|
|
13
13
|
import { type Kysely } from 'kysely';
|
|
14
|
+
import type { HeldRunStore, ReleaseSignal } from '../environments/held-runs.js';
|
|
15
|
+
import type { TeamMembershipLookup } from '../approvals/approval-resolver.js';
|
|
14
16
|
import type { DashboardPlatformToOrchMessage } from '@kici-dev/engine';
|
|
15
17
|
import type { EnvironmentStore } from '../environments/environment-store.js';
|
|
16
18
|
import type { VariableStore } from '../environments/variable-store.js';
|
|
@@ -44,6 +46,30 @@ export interface DashboardEnvHandlerDeps {
|
|
|
44
46
|
accessLog?: AccessLogWriter;
|
|
45
47
|
/** Routing key for access_log rows (null when not run-scoped). */
|
|
46
48
|
routingKey?: string | null;
|
|
49
|
+
/**
|
|
50
|
+
* Held-run store + resume hook for the approve/reject flow. When present, the
|
|
51
|
+
* approve/reject handlers route through the shared `applyDecision` applier
|
|
52
|
+
* (eligibility check, real attribution, multi-clause accumulation, and the
|
|
53
|
+
* resume-after-approval re-dispatch). When absent (legacy / tests), the
|
|
54
|
+
* handlers fall back to the direct status flip.
|
|
55
|
+
*/
|
|
56
|
+
approvals?: ApprovalHandlerDeps;
|
|
57
|
+
}
|
|
58
|
+
/** Dependencies enabling the resolver-backed approve/reject + resume path. */
|
|
59
|
+
export interface ApprovalHandlerDeps {
|
|
60
|
+
store: HeldRunStore;
|
|
61
|
+
/** Team name → member user ids (Plan-1 trust-policy cache). */
|
|
62
|
+
teamMembershipLookup: TeamMembershipLookup;
|
|
63
|
+
/** Re-dispatch a released job hold (consumes its pending context). */
|
|
64
|
+
resumeJob: (signal: ReleaseSignal) => Promise<void>;
|
|
65
|
+
/** Notify a waiting agent that a step hold released (step scope). */
|
|
66
|
+
resumeStep?: (signal: ReleaseSignal) => Promise<void>;
|
|
67
|
+
/** Notify a waiting agent that a step hold was rejected (step scope). */
|
|
68
|
+
rejectStep?: (heldRunId: string, reason?: string) => Promise<void> | void;
|
|
69
|
+
/** Resume a released workflow install-gate hold (workflow scope). */
|
|
70
|
+
resumeWorkflow?: (signal: ReleaseSignal) => Promise<void>;
|
|
71
|
+
/** Cancel a rejected workflow install-gate hold (workflow scope). */
|
|
72
|
+
rejectWorkflow?: (runId: string) => Promise<void>;
|
|
47
73
|
}
|
|
48
74
|
/**
|
|
49
75
|
* Handler for all dashboard environment and held run WS messages.
|
|
@@ -78,6 +104,14 @@ export declare class DashboardEnvHandler {
|
|
|
78
104
|
*/
|
|
79
105
|
handleMessage(msg: DashboardPlatformToOrchMessage): Promise<boolean>;
|
|
80
106
|
private handleEnvList;
|
|
107
|
+
/**
|
|
108
|
+
* Map each environment id to the distinct secret key names reachable through
|
|
109
|
+
* its scope bindings. Joins `environment_bindings` → `scoped_secrets` on the
|
|
110
|
+
* scope pattern, excluding the `__empty__` sentinel. Returns key names only —
|
|
111
|
+
* never values. Scoped to the caller-resolved org (the request's target org,
|
|
112
|
+
* or the connection-level org on the legacy path).
|
|
113
|
+
*/
|
|
114
|
+
private loadSecretKeysByEnv;
|
|
81
115
|
private handleEnvGet;
|
|
82
116
|
private handleEnvCreate;
|
|
83
117
|
private handleEnvUpdate;
|
|
@@ -107,6 +141,19 @@ export declare class DashboardEnvHandler {
|
|
|
107
141
|
private handleScopeDelete;
|
|
108
142
|
private handleEnvHistory;
|
|
109
143
|
private handleHeldRunsList;
|
|
144
|
+
/**
|
|
145
|
+
* Resolve the actor's Keycloak sub for approval attribution. Only `user` and
|
|
146
|
+
* `platform_operator` actors carry a `sub`; others fall back to a stable id.
|
|
147
|
+
*/
|
|
148
|
+
private actorSub;
|
|
149
|
+
/** Read org_settings.allow_self_approval (default true). */
|
|
150
|
+
private readAllowSelfApproval;
|
|
151
|
+
/**
|
|
152
|
+
* Route an approve/reject through the shared `applyDecision` applier:
|
|
153
|
+
* eligibility check, real attribution, multi-clause accumulation, and the
|
|
154
|
+
* resume-after-approval re-dispatch. Sends the matching response message.
|
|
155
|
+
*/
|
|
156
|
+
private applyApprovalDecision;
|
|
110
157
|
private handleHeldRunApprove;
|
|
111
158
|
private handleHeldRunReject;
|
|
112
159
|
private sendError;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface FleetAgentCollectorOptions {
|
|
2
|
+
timeoutMs: number;
|
|
3
|
+
}
|
|
4
|
+
export declare class FleetAgentCollector {
|
|
5
|
+
private readonly opts;
|
|
6
|
+
private readonly waiter;
|
|
7
|
+
/** requestId -> owning agentId, so a disconnect rejects only that agent's requests. */
|
|
8
|
+
private readonly requestAgent;
|
|
9
|
+
constructor(opts: FleetAgentCollectorOptions);
|
|
10
|
+
/**
|
|
11
|
+
* Register the pending request `requestId` (owned by `agentId`), invoke
|
|
12
|
+
* `send` to dispatch the fleet.logs.request envelope, and await the
|
|
13
|
+
* reassembled bundle Buffer.
|
|
14
|
+
*/
|
|
15
|
+
request(requestId: string, agentId: string, send: () => void): Promise<Buffer>;
|
|
16
|
+
onChunk(requestId: string, seq: number, dataB64: string, isLast: boolean): void;
|
|
17
|
+
onError(requestId: string, message: string): void;
|
|
18
|
+
/** Reject every pending request owned by `agentId` (called on its disconnect). */
|
|
19
|
+
rejectAgent(agentId: string, reason: string): void;
|
|
20
|
+
/** Reject every pending request regardless of owner (orchestrator shutdown). */
|
|
21
|
+
rejectAll(reason: string): void;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=fleet-agent-collector.d.ts.map
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provenance ID-token relay (orchestrator side).
|
|
3
|
+
*
|
|
4
|
+
* Backs the `oidc.token.request` agent.api method: an agent asks for a
|
|
5
|
+
* short-lived OIDC ID token for a job it is running; the orchestrator verifies
|
|
6
|
+
* the agent owns that job, resolves its runId from its own dispatch state, and
|
|
7
|
+
* relays a mint request to the Platform's token-mint endpoint over HTTPS using
|
|
8
|
+
* the orchestrator's own `KICI_PLATFORM_TOKEN`. The agent never holds Platform
|
|
9
|
+
* credentials and never asserts its own identity claims — the Platform derives
|
|
10
|
+
* every identity claim from its own run/job rows.
|
|
11
|
+
*/
|
|
12
|
+
import { type OidcTokenResult } from '@kici-dev/engine/protocol/messages/oidc-token-relay';
|
|
13
|
+
/** 404 / 409: the run/job is missing on the Platform or the job is terminal. */
|
|
14
|
+
export declare class MintRejectedError extends Error {
|
|
15
|
+
}
|
|
16
|
+
/** 503: provenance signing is not configured / the Platform is unavailable. */
|
|
17
|
+
export declare class MintUnavailableError extends Error {
|
|
18
|
+
}
|
|
19
|
+
/** Any other non-2xx from the mint endpoint. */
|
|
20
|
+
export declare class MintRelayError extends Error {
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Turn the Platform WS URL (`wss://host[/base]/ws`) into its HTTP base
|
|
24
|
+
* (`https://host[/base]`). Maps the scheme and strips a trailing `/ws` while
|
|
25
|
+
* preserving the host and any basePath in front of it.
|
|
26
|
+
*/
|
|
27
|
+
export declare function deriveHttpBaseFromWsUrl(wsUrl: string): string;
|
|
28
|
+
export interface RequestMintArgs {
|
|
29
|
+
httpBase: string;
|
|
30
|
+
token: string;
|
|
31
|
+
orchestratorId: string;
|
|
32
|
+
runId: string;
|
|
33
|
+
jobId: string;
|
|
34
|
+
audience: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Call the Platform token-mint endpoint over HTTPS using the orchestrator's
|
|
38
|
+
* Platform token. Maps non-2xx responses to typed errors so the agent always
|
|
39
|
+
* sees a clear message instead of a raw 5xx body.
|
|
40
|
+
*/
|
|
41
|
+
export declare function requestMint(args: RequestMintArgs): Promise<OidcTokenResult>;
|
|
42
|
+
export interface OidcTokenHandlerDeps {
|
|
43
|
+
dispatcher: {
|
|
44
|
+
resolveOwnedJob(agentId: string, jobId: string): {
|
|
45
|
+
runId: string;
|
|
46
|
+
} | undefined;
|
|
47
|
+
};
|
|
48
|
+
platformToken: string;
|
|
49
|
+
platformHttpBase: string;
|
|
50
|
+
orchestratorId: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Build the agent.api handler for `OIDC_TOKEN_REQUEST_METHOD`. Validates the
|
|
54
|
+
* params, verifies the agent owns the named job (resolving its runId from the
|
|
55
|
+
* dispatcher), and relays a mint request to the Platform. A job the agent does
|
|
56
|
+
* not own is rejected without ever contacting the Platform.
|
|
57
|
+
*/
|
|
58
|
+
export declare function createOidcTokenHandler(deps: OidcTokenHandlerDeps): (agentId: string, params: Record<string, unknown>) => Promise<OidcTokenResult>;
|
|
59
|
+
//# sourceMappingURL=oidc-token-relay.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type OrchestratorToPlatformMessage, type WebhookRelay, type WebhookRelayResult, type TrustPolicyUpdate, type StaleCheckrunCleanup, type DashboardRunDetailRequest, type DashboardRunsListRequest, type DashboardRunsFiltersRequest, type DashboardSourcesListRequest, type DashboardStepLogsRequest, type DashboardOrchLogsRequest, type RunRerunRequest, type ManualScheduleRequest, type RunCancelRequest, type DashboardPayloadRequest, type DashboardPlatformToOrchMessage, type DashboardDiagnosticsRequest, type DashboardScalerCapacityRequest, type DashboardScalerAgentsRequest, type JoinRequest, type JoinResponse, type OrchCapabilities, type OrchRole } from '@kici-dev/engine';
|
|
1
|
+
import { type OrchestratorToPlatformMessage, type WebhookRelay, type WebhookRelayResult, type TrustPolicyUpdate, type StaleCheckrunCleanup, type DashboardRunDetailRequest, type DashboardRunsListRequest, type DashboardRunsFiltersRequest, type DashboardSourcesListRequest, type DashboardStepLogsRequest, type DashboardAttestationsListRequest, type DashboardOrchLogsRequest, type RunRerunRequest, type ManualScheduleRequest, type RunCancelRequest, type DashboardPayloadRequest, type DashboardPlatformToOrchMessage, type TestRelayRequest, type DashboardDiagnosticsRequest, type DashboardScalerCapacityRequest, type DashboardScalerAgentsRequest, type JoinRequest, type JoinResponse, type OrchCapabilities, type OrchRole } from '@kici-dev/engine';
|
|
2
2
|
import { RelayBufferRegistry, type RelayStartMeta } from '../webhook/relay-buffer.js';
|
|
3
3
|
/**
|
|
4
4
|
* Verification + processing outcome returned by the chunked relay path's
|
|
@@ -87,6 +87,17 @@ export interface PlatformClientOptions {
|
|
|
87
87
|
}) => void;
|
|
88
88
|
/** Optional callback invoked after successful authentication and source registration. */
|
|
89
89
|
onAuthenticated?: () => void;
|
|
90
|
+
/**
|
|
91
|
+
* Optional callback invoked when the Platform surfaces the orchestrator's
|
|
92
|
+
* canonical org id on `auth.success`. Used to auto-provision the
|
|
93
|
+
* `remote_sources` anchor (`remote:<orgId>`) so Platform-relayed
|
|
94
|
+
* `kici run remote` resolves the real tenant. Fires on every (re)connect;
|
|
95
|
+
* provisioning is idempotent.
|
|
96
|
+
*/
|
|
97
|
+
onOrgIdentified?: (info: {
|
|
98
|
+
orgId: string;
|
|
99
|
+
clusterId: string | null;
|
|
100
|
+
}) => void;
|
|
90
101
|
/** Optional callback for dashboard run detail requests from Platform. */
|
|
91
102
|
onDashboardRunDetail?: (msg: DashboardRunDetailRequest) => void;
|
|
92
103
|
/** Optional callback for dashboard runs.list (operator console) requests from Platform. */
|
|
@@ -97,6 +108,8 @@ export interface PlatformClientOptions {
|
|
|
97
108
|
onDashboardSourcesList?: (msg: DashboardSourcesListRequest) => void;
|
|
98
109
|
/** Optional callback for dashboard step logs requests from Platform. */
|
|
99
110
|
onDashboardStepLogs?: (msg: DashboardStepLogsRequest) => void;
|
|
111
|
+
/** Optional callback for dashboard attestations-list requests from Platform. */
|
|
112
|
+
onDashboardAttestationsList?: (msg: DashboardAttestationsListRequest) => void;
|
|
100
113
|
/** Optional callback for run re-run requests from Platform (dashboard action). */
|
|
101
114
|
onRunRerun?: (msg: RunRerunRequest) => void;
|
|
102
115
|
/** Optional callback for manual schedule trigger requests from Platform (dashboard action). */
|
|
@@ -109,6 +122,12 @@ export interface PlatformClientOptions {
|
|
|
109
122
|
onDashboardOrchLogs?: (msg: DashboardOrchLogsRequest) => void;
|
|
110
123
|
/** Optional callback for dashboard environment/held-run messages from Platform. */
|
|
111
124
|
onDashboardEnvMessage?: (msg: DashboardPlatformToOrchMessage) => void;
|
|
125
|
+
/**
|
|
126
|
+
* Optional callback for Platform-first `kici run remote` control-plane relay
|
|
127
|
+
* requests (upload-init, trigger, status, logs, cancel). The handler performs
|
|
128
|
+
* the action and replies over the WS keyed by `requestId`.
|
|
129
|
+
*/
|
|
130
|
+
onTestRelay?: (msg: TestRelayRequest) => void;
|
|
112
131
|
/** Optional callback for dashboard diagnostics requests from Platform. */
|
|
113
132
|
onDashboardDiagnostics?: (msg: DashboardDiagnosticsRequest) => void;
|
|
114
133
|
/** Optional callback for dashboard scaler capacity requests from Platform. */
|
|
@@ -180,17 +199,20 @@ export declare class PlatformClient {
|
|
|
180
199
|
private readonly onLogPullRequest?;
|
|
181
200
|
private readonly onPeerDiscover?;
|
|
182
201
|
private readonly onAuthenticated?;
|
|
202
|
+
private readonly onOrgIdentified?;
|
|
183
203
|
private readonly onDashboardRunDetail?;
|
|
184
204
|
private readonly onDashboardRunsList?;
|
|
185
205
|
private readonly onDashboardRunsFilters?;
|
|
186
206
|
private readonly onDashboardSourcesList?;
|
|
187
207
|
private readonly onDashboardStepLogs?;
|
|
208
|
+
private readonly onDashboardAttestationsList?;
|
|
188
209
|
private readonly onRunRerun?;
|
|
189
210
|
private readonly onManualSchedule?;
|
|
190
211
|
private readonly onRunCancel?;
|
|
191
212
|
private readonly onDashboardPayload?;
|
|
192
213
|
private readonly onDashboardOrchLogs?;
|
|
193
214
|
private readonly onDashboardEnvMessage?;
|
|
215
|
+
private readonly onTestRelay?;
|
|
194
216
|
private readonly onDashboardDiagnostics?;
|
|
195
217
|
private readonly onDashboardScalerCapacity?;
|
|
196
218
|
private readonly onDashboardScalerAgents?;
|
|
@@ -306,6 +328,13 @@ export declare class PlatformClient {
|
|
|
306
328
|
* back to a structured warning if neither schema matches.
|
|
307
329
|
*/
|
|
308
330
|
private handleNonStandardMessage;
|
|
331
|
+
/**
|
|
332
|
+
* If `raw` looks like a dashboard request (a `dashboard.*` type with a
|
|
333
|
+
* requestId) that failed schema validation, send a structured error response
|
|
334
|
+
* keyed to its requestId and return true. Returns false when the message is
|
|
335
|
+
* not a recognisable dashboard request (let the caller log a warning).
|
|
336
|
+
*/
|
|
337
|
+
private respondToInvalidDashboardRequest;
|
|
309
338
|
/**
|
|
310
339
|
* Dispatch a parsed platform message to the appropriate per-area
|
|
311
340
|
* handler. Each `case` either inlines a tiny dispatch (for one-line
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrator-side handlers for the Platform-relayed `kici run remote` control
|
|
3
|
+
* plane. The Platform relays five `test.relay.*` requests over the authenticated
|
|
4
|
+
* dashboard-proxy WS connection; each handler here performs the action by
|
|
5
|
+
* reusing the existing test pipeline / upload / cancel internals (no
|
|
6
|
+
* duplication) and returns the response payload the caller sends back keyed by
|
|
7
|
+
* `requestId`.
|
|
8
|
+
*
|
|
9
|
+
* The control plane carries only small JSON. The overlay tarball never reaches
|
|
10
|
+
* the Platform — `handleTestUploadsInit` returns an external presigned URL the
|
|
11
|
+
* developer PUTs to directly.
|
|
12
|
+
*/
|
|
13
|
+
import type { Kysely } from 'kysely';
|
|
14
|
+
import type { TestRelayRequest, TestRelayUploadsInitRequest, TestRelayTriggerRequest, TestRelayRunStatusRequest, TestRelayRunLogsRequest, TestRelayCancelRequest } from '@kici-dev/engine';
|
|
15
|
+
import type { Database } from '../db/types.js';
|
|
16
|
+
import type { CacheStorage } from '../storage/types.js';
|
|
17
|
+
import type { LogStorage } from '../reporting/log-storage.js';
|
|
18
|
+
import type { AccessLogWriter } from '../audit/access-log.js';
|
|
19
|
+
import { type TestPipelineDeps } from '../pipeline/test-pipeline.js';
|
|
20
|
+
/** Dependencies shared by all five test-relay handlers. */
|
|
21
|
+
export interface TestRelayHandlerDeps extends TestPipelineDeps {
|
|
22
|
+
db: Kysely<Database>;
|
|
23
|
+
cacheStorage?: CacheStorage;
|
|
24
|
+
logStorage?: LogStorage;
|
|
25
|
+
accessLog?: AccessLogWriter;
|
|
26
|
+
/** Canonical org id this orchestrator is bound to (for access_log attribution). */
|
|
27
|
+
orgId?: string | null;
|
|
28
|
+
/** Routing key resolved for this orchestrator's bound org (for access_log attribution). */
|
|
29
|
+
routingKey?: string | null;
|
|
30
|
+
}
|
|
31
|
+
/** Response payload for `test.relay.uploads.init.response` (minus envelope fields). */
|
|
32
|
+
export interface TestUploadsInitPayload {
|
|
33
|
+
uploadId: string;
|
|
34
|
+
signedUrl: string;
|
|
35
|
+
publicKey: string;
|
|
36
|
+
expiresIn: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Mint an upload record + external presigned PUT URL. The developer's PAT
|
|
40
|
+
* identity (`msg.actor`) is recorded as the upload owner so the upload is
|
|
41
|
+
* attributable.
|
|
42
|
+
*/
|
|
43
|
+
export declare function handleTestUploadsInit(msg: TestRelayUploadsInitRequest, deps: TestRelayHandlerDeps): Promise<TestUploadsInitPayload>;
|
|
44
|
+
/** Response payload for `test.relay.trigger.response` (minus envelope fields). */
|
|
45
|
+
export interface TestTriggerPayload {
|
|
46
|
+
runId: string;
|
|
47
|
+
status: 'accepted' | 'rejected';
|
|
48
|
+
reason?: string;
|
|
49
|
+
jobIds: string[];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Resolve the overlay tarball URL + decryption keys from the upload record, then
|
|
53
|
+
* run the existing `processTestTrigger` pipeline with `routingKey = remote:<orgId>`.
|
|
54
|
+
* The developer's PAT identity is written to `access_log` (`run.trigger`).
|
|
55
|
+
*/
|
|
56
|
+
export declare function handleTestTrigger(msg: TestRelayTriggerRequest, deps: TestRelayHandlerDeps): Promise<TestTriggerPayload>;
|
|
57
|
+
/** Response payload for `test.relay.run.status.response` (minus envelope fields). */
|
|
58
|
+
export interface TestRunStatusPayload {
|
|
59
|
+
runId: string;
|
|
60
|
+
status: string;
|
|
61
|
+
jobs: Array<{
|
|
62
|
+
jobId: string;
|
|
63
|
+
jobName: string;
|
|
64
|
+
status: string;
|
|
65
|
+
errorMessage?: string | null;
|
|
66
|
+
}>;
|
|
67
|
+
done: boolean;
|
|
68
|
+
}
|
|
69
|
+
/** Snapshot a run's status + per-job status. `done` is true at a terminal run state. */
|
|
70
|
+
export declare function handleTestRunStatus(msg: TestRelayRunStatusRequest, deps: TestRelayHandlerDeps): Promise<TestRunStatusPayload | {
|
|
71
|
+
error: string;
|
|
72
|
+
}>;
|
|
73
|
+
/** Response payload for `test.relay.run.logs.response` (minus envelope fields). */
|
|
74
|
+
export interface TestRunLogsPayload {
|
|
75
|
+
lines: string[];
|
|
76
|
+
nextCursor: number;
|
|
77
|
+
done: boolean;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Return the next chunk of a run's logs from a monotonic line-offset cursor
|
|
81
|
+
* (spec §13a). The orchestrator concatenates every log line in a deterministic
|
|
82
|
+
* `(jobName ASC, stepIndex ASC, lineIndex ASC)` order; `cursor` is the count of
|
|
83
|
+
* lines already delivered. `done` is true only when the run is terminal AND the
|
|
84
|
+
* cursor has reached the end (the final tail-draining poll). A poll mid-step
|
|
85
|
+
* returns the lines available so far with `done: false`, so no line is ever
|
|
86
|
+
* dropped or skipped on a live run.
|
|
87
|
+
*/
|
|
88
|
+
export declare function handleTestRunLogs(msg: TestRelayRunLogsRequest, deps: TestRelayHandlerDeps): Promise<TestRunLogsPayload | {
|
|
89
|
+
error: string;
|
|
90
|
+
}>;
|
|
91
|
+
/** Response payload for `test.relay.cancel.response` (minus envelope fields). */
|
|
92
|
+
export interface TestCancelPayload {
|
|
93
|
+
cancelled: boolean;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Cancel a running test run: signal cancellation to every dispatched agent,
|
|
97
|
+
* mark still-pending dispatch queue entries cancelled, and mark the
|
|
98
|
+
* `execution_runs` row cancelled. Returns `{ cancelled }` — true when the run
|
|
99
|
+
* existed, was a test run, and was not already terminal.
|
|
100
|
+
*/
|
|
101
|
+
export declare function handleTestCancel(msg: TestRelayCancelRequest, deps: TestRelayHandlerDeps): Promise<TestCancelPayload | {
|
|
102
|
+
error: string;
|
|
103
|
+
}>;
|
|
104
|
+
/**
|
|
105
|
+
* Route a parsed `test.relay.*` request to its handler and build the full
|
|
106
|
+
* response envelope (`type` + `requestId` + payload) the caller relays back over
|
|
107
|
+
* the WS connection via `sendRaw`. Errors and `{ error }` results are surfaced
|
|
108
|
+
* on the response's `error` field; the wire stays a structured response so the
|
|
109
|
+
* Platform can map it to an HTTP status.
|
|
110
|
+
*/
|
|
111
|
+
export declare function dispatchTestRelay(msg: TestRelayRequest, deps: TestRelayHandlerDeps): Promise<Record<string, unknown>>;
|
|
112
|
+
//# sourceMappingURL=test-relay-handlers.d.ts.map
|