@kici-dev/agent 0.1.27 → 0.3.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.
Files changed (37) hide show
  1. package/dist/bootstrap/ensure-init-runner.d.ts +23 -22
  2. package/dist/bootstrap/payload-source.d.ts +32 -0
  3. package/dist/bootstrap/probe-platform.d.ts +21 -0
  4. package/dist/bootstrap/restage-agent.d.ts +43 -0
  5. package/dist/bootstrap/run-restage.d.ts +12 -0
  6. package/dist/bootstrap/s3-payload-source.d.ts +35 -0
  7. package/dist/bootstrap/ssh-exec.d.ts +14 -0
  8. package/dist/bootstrap/stage-agent-payload.d.ts +41 -0
  9. package/dist/checkout/changed-files.d.ts +34 -0
  10. package/dist/config.d.ts +36 -14
  11. package/dist/container-ts-loader-hook.js +147710 -0
  12. package/dist/execution/artifacts/artifact-engine.d.ts +51 -0
  13. package/dist/execution/dep-installer.d.ts +3 -3
  14. package/dist/execution/job-runner.d.ts +24 -6
  15. package/dist/execution/log-streamer.d.ts +17 -2
  16. package/dist/execution/rule-evaluator.d.ts +1 -12
  17. package/dist/execution/sandbox/container-hardening.d.ts +80 -0
  18. package/dist/execution/sandbox/container-sandbox.d.ts +54 -0
  19. package/dist/execution/sandbox/container-ts-loader-hook.d.ts +26 -0
  20. package/dist/execution/sandbox/fork-runner.d.ts +14 -0
  21. package/dist/execution/sandbox/index.d.ts +2 -1
  22. package/dist/execution/sandbox/ipc-protocol.d.ts +79 -3
  23. package/dist/execution/sandbox/step-loop.d.ts +4 -0
  24. package/dist/execution/sandbox/types.d.ts +25 -4
  25. package/dist/execution/sandbox/workflow-runner.d.ts +111 -5
  26. package/dist/execution/streaming-zx-log.d.ts +11 -3
  27. package/dist/execution/tmp-gc.d.ts +22 -7
  28. package/dist/execution/workflow-loader.d.ts +32 -1
  29. package/dist/index.js +44 -45
  30. package/dist/provenance/statement-builder.d.ts +3 -2
  31. package/dist/server.d.ts +1 -1
  32. package/dist/server.js +1256 -171
  33. package/dist/workflow-runner-bundle.js +215403 -0
  34. package/dist/workflow-runner.js +886 -244
  35. package/dist/ws/orchestrator-client.d.ts +105 -1
  36. package/package.json +14 -12
  37. 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.1.27",
3
+ "version": "0.3.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": "^1.19.14",
58
+ "@hono/node-server": "^2.0.10",
57
59
  "archiver": "^8.0.0",
58
- "dockerode": "^5.0.0",
59
- "hono": "^4.12.25",
60
+ "dockerode": "^5.0.1",
61
+ "hono": "^4.12.32",
60
62
  "jose": "^6.1.0",
61
- "tar": "^7.5.16",
63
+ "tar": "^7.5.20",
62
64
  "winston": "^3.19.0",
63
- "ws": "^8.21.0",
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.1.27",
68
- "@kici-dev/engine": "0.1.27",
69
- "@kici-dev/sdk": "0.1.27",
70
- "@kici-dev/shared": "0.1.27"
69
+ "@kici-dev/engine": "0.3.0",
70
+ "@kici-dev/sdk": "0.3.0",
71
+ "@kici-dev/shared": "0.3.0",
72
+ "@kici-dev/core": "0.3.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 && tsc --emitDeclarationOnly",
84
- "typecheck": "tsc --noEmit",
85
+ "build": "node ../../scripts/build-service.mjs && tsgo --emitDeclarationOnly",
86
+ "typecheck": "tsgo --noEmit",
85
87
  "test": "vitest run"
86
88
  }
87
89
  }