@kici-dev/agent 0.1.27 → 0.2.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/bootstrap/ensure-init-runner.d.ts +23 -22
- package/dist/bootstrap/payload-source.d.ts +32 -0
- package/dist/bootstrap/probe-platform.d.ts +21 -0
- package/dist/bootstrap/restage-agent.d.ts +43 -0
- package/dist/bootstrap/run-restage.d.ts +12 -0
- package/dist/bootstrap/s3-payload-source.d.ts +35 -0
- package/dist/bootstrap/ssh-exec.d.ts +14 -0
- package/dist/bootstrap/stage-agent-payload.d.ts +41 -0
- package/dist/checkout/changed-files.d.ts +34 -0
- package/dist/config.d.ts +36 -14
- package/dist/container-ts-loader-hook.js +147710 -0
- package/dist/execution/artifacts/artifact-engine.d.ts +51 -0
- package/dist/execution/dep-installer.d.ts +3 -3
- package/dist/execution/job-runner.d.ts +24 -6
- package/dist/execution/log-streamer.d.ts +17 -2
- package/dist/execution/rule-evaluator.d.ts +1 -12
- package/dist/execution/sandbox/container-hardening.d.ts +80 -0
- package/dist/execution/sandbox/container-sandbox.d.ts +54 -0
- package/dist/execution/sandbox/container-ts-loader-hook.d.ts +26 -0
- package/dist/execution/sandbox/fork-runner.d.ts +14 -0
- package/dist/execution/sandbox/index.d.ts +2 -1
- package/dist/execution/sandbox/ipc-protocol.d.ts +79 -3
- package/dist/execution/sandbox/step-loop.d.ts +4 -0
- package/dist/execution/sandbox/types.d.ts +25 -4
- package/dist/execution/sandbox/workflow-runner.d.ts +111 -5
- package/dist/execution/streaming-zx-log.d.ts +11 -3
- package/dist/execution/tmp-gc.d.ts +22 -7
- package/dist/execution/workflow-loader.d.ts +32 -1
- package/dist/index.js +44 -45
- package/dist/provenance/statement-builder.d.ts +3 -2
- package/dist/server.d.ts +1 -1
- package/dist/server.js +1256 -171
- package/dist/workflow-runner-bundle.js +215393 -0
- package/dist/workflow-runner.js +886 -244
- package/dist/ws/orchestrator-client.d.ts +105 -1
- package/package.json +14 -12
- package/sbom.spdx.json +1090 -1721
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { type AgentToOrchestratorMessage, type JobDispatch, type JobCancel, type FleetLogsRequest } from '@kici-dev/engine';
|
|
2
|
-
import type { CacheRequestIpc, CacheResponseIpc, ProvenanceRequestIpc, ProvenanceResponseIpc, StepApprovalRequestIpc, StepApprovalResolvedIpc } from '../execution/sandbox/index.js';
|
|
2
|
+
import type { CacheRequestIpc, CacheResponseIpc, ProvenanceRequestIpc, ArtifactRequestIpc, ArtifactResponseIpc, ProvenanceResponseIpc, StepApprovalRequestIpc, StepApprovalResolvedIpc } from '../execution/sandbox/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* How many times an in-flight `artifacts.upload.complete` is re-sent across
|
|
5
|
+
* reconnects before the step is failed.
|
|
6
|
+
*
|
|
7
|
+
* Bounded so a flapping connection cannot loop forever. The overall wait is
|
|
8
|
+
* bounded independently by ARTIFACT_COMPLETE_ACK_TIMEOUT_MS, whose timer is
|
|
9
|
+
* never restarted across a hold or a resend.
|
|
10
|
+
*/
|
|
11
|
+
export declare const MAX_COMPLETE_RESEND_ATTEMPTS = 2;
|
|
3
12
|
export type ConnectionState = 'disconnected' | 'connecting' | 'authenticating' | 'registering' | 'registered';
|
|
4
13
|
export interface OrchestratorClientOptions {
|
|
5
14
|
/** WebSocket URL of the orchestrator. */
|
|
@@ -76,6 +85,13 @@ export declare class OrchestratorClient {
|
|
|
76
85
|
private reconnectTimer;
|
|
77
86
|
private reconnectAttempts;
|
|
78
87
|
private intentionalDisconnect;
|
|
88
|
+
/**
|
|
89
|
+
* Agent-facing capabilities advertised by the orchestrator on `register.ack`.
|
|
90
|
+
* Undefined until the first ack arrives, and on a pre-capability orchestrator
|
|
91
|
+
* that never advertises — both cases mean "assume unsupported" for every
|
|
92
|
+
* optional feature gated on it.
|
|
93
|
+
*/
|
|
94
|
+
private orchCapabilities;
|
|
79
95
|
private pendingLogBatch;
|
|
80
96
|
private logFlushTimer;
|
|
81
97
|
private static readonly LOG_BATCH_SIZE;
|
|
@@ -88,6 +104,26 @@ export declare class OrchestratorClient {
|
|
|
88
104
|
private readonly pendingApiRequests;
|
|
89
105
|
/** Pending user-cache restore/save requests awaiting orchestrator response. */
|
|
90
106
|
private readonly pendingUserCacheRequests;
|
|
107
|
+
/** Pending user-artifact upload/download requests awaiting orchestrator response. */
|
|
108
|
+
private readonly pendingUserArtifactRequests;
|
|
109
|
+
/**
|
|
110
|
+
* In-flight `artifacts.upload.complete` frames that are safe to re-send after a
|
|
111
|
+
* reconnect, keyed by their current `messageId`.
|
|
112
|
+
*
|
|
113
|
+
* The commit is idempotent server-side (the storage key is derived server-side,
|
|
114
|
+
* `initMeta` is a re-writable sidecar, and the DB insert is
|
|
115
|
+
* `onConflict.doNothing()`), so a dropped ack means "we did not hear the
|
|
116
|
+
* answer", not "it did not happen". `beginUpload` / `download` are deliberately
|
|
117
|
+
* absent: `beginUpload` mints a presigned PUT and is not idempotent the same
|
|
118
|
+
* way, and `download` is read-only and cheap to fail.
|
|
119
|
+
*/
|
|
120
|
+
private readonly resendableCompletes;
|
|
121
|
+
/**
|
|
122
|
+
* Completes taken off `pendingUserArtifactRequests` by the disconnect sweep and
|
|
123
|
+
* parked until the next `register.ack` re-sends them. Their ack timers keep
|
|
124
|
+
* running — parking does not extend the deadline.
|
|
125
|
+
*/
|
|
126
|
+
private readonly heldCompletes;
|
|
91
127
|
/**
|
|
92
128
|
* Pending step-approval requests awaiting the orchestrator's resolution.
|
|
93
129
|
* No client-side timeout: the orchestrator owns the (org-/SDK-configured)
|
|
@@ -243,6 +279,25 @@ export declare class OrchestratorClient {
|
|
|
243
279
|
* Times out after 30 seconds for the round-trip ops.
|
|
244
280
|
*/
|
|
245
281
|
requestUserCache(jobId: string, request: CacheRequestIpc): Promise<CacheResponseIpc>;
|
|
282
|
+
/**
|
|
283
|
+
* Relay a user-facing artifact request from the sandbox to the orchestrator.
|
|
284
|
+
*
|
|
285
|
+
* Translates the sandbox `artifacts.request` IPC into the matching
|
|
286
|
+
* `artifacts.*` WS message and resolves with the orchestrator's response
|
|
287
|
+
* mapped onto the IPC response shape:
|
|
288
|
+
*
|
|
289
|
+
* - `beginUpload` -> `artifacts.upload.request`, awaits `artifacts.upload.response`.
|
|
290
|
+
* - `completeUpload` -> `artifacts.upload.complete`, awaits
|
|
291
|
+
* `artifacts.upload.complete.ack` when the orchestrator advertises the
|
|
292
|
+
* `artifactCompleteAck` capability, and rejects when the commit failed so
|
|
293
|
+
* the workflow step fails instead of losing the artifact behind a green run.
|
|
294
|
+
* Against an orchestrator that never advertises it, the message stays
|
|
295
|
+
* fire-and-forget and resolves immediately.
|
|
296
|
+
* - `download` -> `artifacts.download.request`, awaits `artifacts.download.response`.
|
|
297
|
+
*
|
|
298
|
+
* Times out after 30 seconds for the round-trip ops.
|
|
299
|
+
*/
|
|
300
|
+
requestUserArtifact(jobId: string, request: ArtifactRequestIpc): Promise<ArtifactResponseIpc>;
|
|
246
301
|
/**
|
|
247
302
|
* Relay a provenance bundle upload operation to the orchestrator. Maps the
|
|
248
303
|
* IPC `provenance.request` onto `requestProvenanceUploadUrl` (returns the
|
|
@@ -314,6 +369,55 @@ export declare class OrchestratorClient {
|
|
|
314
369
|
}>;
|
|
315
370
|
getReconnectDelay(): number;
|
|
316
371
|
private doConnect;
|
|
372
|
+
/**
|
|
373
|
+
* Resolve a pending user-artifact request from an `artifacts.upload.response`
|
|
374
|
+
* / `artifacts.download.response` WS message, mapping the wire fields onto the
|
|
375
|
+
* IPC response shape. No-op when no request is pending for the requestId.
|
|
376
|
+
*/
|
|
377
|
+
private resolveArtifactResponse;
|
|
378
|
+
/**
|
|
379
|
+
* Resolve or reject a pending completeUpload from an
|
|
380
|
+
* `artifacts.upload.complete.ack`. `committed` resolves the relayed IPC
|
|
381
|
+
* request; `failed` rejects it (carrying the orchestrator's reason), which
|
|
382
|
+
* propagates through the relay's `response.error` and fails the workflow step
|
|
383
|
+
* rather than losing the artifact silently. No-op when nothing is pending for
|
|
384
|
+
* the requestId (an ack for an already-timed-out complete).
|
|
385
|
+
*/
|
|
386
|
+
private resolveArtifactCompleteAck;
|
|
387
|
+
/**
|
|
388
|
+
* Drop every trace of an in-flight upload-complete, whichever key it currently
|
|
389
|
+
* lives under and whether or not it is parked awaiting a resend.
|
|
390
|
+
*
|
|
391
|
+
* Called from the ack timer, which fires on the original schedule regardless of
|
|
392
|
+
* how many times the complete has been re-keyed since.
|
|
393
|
+
*/
|
|
394
|
+
private forgetComplete;
|
|
395
|
+
/**
|
|
396
|
+
* Fail every parked upload-complete closed, for the paths where the reconnect
|
|
397
|
+
* the park was betting on will never arrive (a deliberate shutdown, a
|
|
398
|
+
* permanently rejected token). Naming the ambiguity keeps the operator from
|
|
399
|
+
* hunting for an artifact that in fact landed.
|
|
400
|
+
*/
|
|
401
|
+
private rejectHeldCompletes;
|
|
402
|
+
/**
|
|
403
|
+
* Re-send every upload-complete parked by the disconnect sweep.
|
|
404
|
+
*
|
|
405
|
+
* Called from `register.ack`, once the new connection's capabilities are known.
|
|
406
|
+
* Each frame is re-keyed with a fresh `messageId` before it goes out: the id is
|
|
407
|
+
* the correlation key, so reusing it would let a late ack for the pre-disconnect
|
|
408
|
+
* send resolve the new pending.
|
|
409
|
+
*
|
|
410
|
+
* The ack timer created when the complete was first sent is deliberately left
|
|
411
|
+
* alone, so the hold plus every resend stays inside the original
|
|
412
|
+
* ARTIFACT_COMPLETE_ACK_TIMEOUT_MS budget.
|
|
413
|
+
*/
|
|
414
|
+
private resendHeldCompletes;
|
|
415
|
+
/**
|
|
416
|
+
* Route the orchestrator's replies to a relayed user-artifact request, which
|
|
417
|
+
* are dispatched off the raw frame rather than the parsed protocol union.
|
|
418
|
+
* Returns true when the message was consumed.
|
|
419
|
+
*/
|
|
420
|
+
private handleArtifactReply;
|
|
317
421
|
private handleMessage;
|
|
318
422
|
private flushBuffer;
|
|
319
423
|
/** Send the current pending log batch as an agent.log message. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kici-dev/agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Customer-deployable agent for the KiCI CI/CD stack. Connects to an orchestrator, clones the workflow repo, executes steps, and streams logs back.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ci",
|
|
@@ -49,25 +49,27 @@
|
|
|
49
49
|
"entries": {
|
|
50
50
|
"server.js": "src/server.ts",
|
|
51
51
|
"workflow-runner.js": "src/execution/sandbox/workflow-runner.ts",
|
|
52
|
+
"workflow-runner-bundle.js": "src/execution/sandbox/workflow-runner.ts",
|
|
53
|
+
"container-ts-loader-hook.js": "src/execution/sandbox/container-ts-loader-hook.ts",
|
|
52
54
|
"index.js": "src/index.ts"
|
|
53
55
|
}
|
|
54
56
|
},
|
|
55
57
|
"dependencies": {
|
|
56
|
-
"@hono/node-server": "^
|
|
58
|
+
"@hono/node-server": "^2.0.10",
|
|
57
59
|
"archiver": "^8.0.0",
|
|
58
|
-
"dockerode": "^5.0.
|
|
59
|
-
"hono": "^4.12.
|
|
60
|
+
"dockerode": "^5.0.1",
|
|
61
|
+
"hono": "^4.12.32",
|
|
60
62
|
"jose": "^6.1.0",
|
|
61
|
-
"tar": "^7.5.
|
|
63
|
+
"tar": "^7.5.20",
|
|
62
64
|
"winston": "^3.19.0",
|
|
63
|
-
"ws": "^8.21.
|
|
65
|
+
"ws": "^8.21.1",
|
|
64
66
|
"yaml": "^2.9.0",
|
|
65
67
|
"zod": "^4.4.3",
|
|
66
68
|
"zx": "^8.8.5",
|
|
67
|
-
"@kici-dev/core": "0.
|
|
68
|
-
"@kici-dev/engine": "0.
|
|
69
|
-
"@kici-dev/
|
|
70
|
-
"@kici-dev/
|
|
69
|
+
"@kici-dev/core": "0.2.0",
|
|
70
|
+
"@kici-dev/engine": "0.2.0",
|
|
71
|
+
"@kici-dev/shared": "0.2.0",
|
|
72
|
+
"@kici-dev/sdk": "0.2.0"
|
|
71
73
|
},
|
|
72
74
|
"kici": {
|
|
73
75
|
"metrics": {
|
|
@@ -80,8 +82,8 @@
|
|
|
80
82
|
"@types/dockerode": "^4.0.1"
|
|
81
83
|
},
|
|
82
84
|
"scripts": {
|
|
83
|
-
"build": "node ../../scripts/build-service.mjs &&
|
|
84
|
-
"typecheck": "
|
|
85
|
+
"build": "node ../../scripts/build-service.mjs && tsgo --emitDeclarationOnly",
|
|
86
|
+
"typecheck": "tsgo --noEmit",
|
|
85
87
|
"test": "vitest run"
|
|
86
88
|
}
|
|
87
89
|
}
|