@kici-dev/agent 0.8.0 → 0.9.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.
@@ -1360,10 +1360,10 @@ function createArtifactsApi(workDir, transport, roots) {
1360
1360
  if (paths.length === 0) throw new Error(`artifact "${name}" upload requires at least one path`);
1361
1361
  const { tarball, hash } = await packCachePaths(workDir, paths, roots);
1362
1362
  const grant = await transport.beginUpload(name, tarball.length);
1363
- if (grant.outcome === "rejected" || !grant.uploadUrl || !grant.storageKey) throw new Error(rejectionMessage(name, grant.reason, grant.error));
1363
+ if (grant.outcome === "rejected" || !grant.uploadUrl) throw new Error(rejectionMessage(name, grant.reason, grant.error));
1364
1364
  const { uploadToPresignedUrl } = await Promise.resolve().then(() => (init_download(), download_exports));
1365
1365
  await uploadToPresignedUrl(grant.uploadUrl, tarball);
1366
- await transport.completeUpload(name, tarball.length, hash, grant.storageKey);
1366
+ await transport.completeUpload(name, hash);
1367
1367
  logger$3.info("artifact uploaded", {
1368
1368
  name,
1369
1369
  sizeBytes: tarball.length,
@@ -4272,32 +4272,29 @@ function buildGeneratorContext(input) {
4272
4272
  * ESM modules by resolved URL, so importing that path yields the workflow's live
4273
4273
  * singleton, not a fresh copy.
4274
4274
  *
4275
- * Both specifiers resolve to the same module-global maps `internal.ts` and the
4276
- * root barrel re-export the same `outputs.js` bindings so the fallback below
4277
- * changes which entry is imported, never which singleton is mutated.
4278
- *
4279
- * Falls back to the agent's bundled setters when neither resolves (mirrors
4280
- * `resolveSdkSetters` in the compiler's test runner).
4275
+ * The setters live only on `@kici-dev/sdk/internal`. A tree whose SDK does not
4276
+ * publish that subpath cannot be wired to this agent, and the agent's own
4277
+ * bundled setters would mutate a map the workflow's proxies never read so the
4278
+ * mismatch is refused here rather than surfacing later as an empty `.result`.
4281
4279
  */
4282
4280
  async function resolveWorkflowSdkSetters(workflowFilePath) {
4283
4281
  const req = createRequire(workflowFilePath);
4284
- for (const specifier of ["@kici-dev/sdk/internal", "@kici-dev/sdk"]) try {
4285
- const sdkEntry = req.resolve(specifier);
4286
- const sdk = await import(pathToFileURL(sdkEntry).href);
4287
- if (typeof sdk.setStepOutputsMap === "function" && typeof sdk.setStepRefMap === "function" && typeof sdk.setJobOutputsMap === "function") return {
4288
- setStepOutputsMap: sdk.setStepOutputsMap,
4289
- setStepRefMap: sdk.setStepRefMap,
4290
- setJobOutputsMap: sdk.setJobOutputsMap
4291
- };
4292
- } catch {}
4282
+ let sdk;
4283
+ try {
4284
+ const sdkEntry = req.resolve("@kici-dev/sdk/internal");
4285
+ sdk = await import(pathToFileURL(sdkEntry).href);
4286
+ } catch (err) {
4287
+ throw new Error(`Could not resolve @kici-dev/sdk/internal from ${workflowFilePath}: the workflow tree must depend on @kici-dev/sdk@>=0.8.0 to run on this agent (agent baked @kici-dev/sdk@${AGENT_SDK_VERSION}). Upgrade the repository's @kici-dev/sdk and recompile: ${toErrorMessage(err)}`);
4288
+ }
4289
+ if (typeof sdk.setStepOutputsMap !== "function" || typeof sdk.setStepRefMap !== "function" || typeof sdk.setJobOutputsMap !== "function") throw new Error(`@kici-dev/sdk/internal resolved from ${workflowFilePath} carries no output-map setters; the workflow tree must depend on @kici-dev/sdk@>=0.8.0 to run on this agent (agent baked @kici-dev/sdk@${AGENT_SDK_VERSION}).`);
4293
4290
  return {
4294
- setStepOutputsMap,
4295
- setStepRefMap,
4296
- setJobOutputsMap
4291
+ setStepOutputsMap: sdk.setStepOutputsMap,
4292
+ setStepRefMap: sdk.setStepRefMap,
4293
+ setJobOutputsMap: sdk.setJobOutputsMap
4297
4294
  };
4298
4295
  }
4299
- const AGENT_SDK_VERSION = "0.8.0";
4300
- const AGENT_SDK_BUNDLE_HASH = "065963c7765dc8d87e04d45f57d7e15be1613da705e4ff3ec3742fd1408b7bf5";
4296
+ const AGENT_SDK_VERSION = "0.9.0";
4297
+ const AGENT_SDK_BUNDLE_HASH = "b012bd8bace3df9e574252bf290c652bc39766da617acf51729a08586756266d";
4301
4298
  /**
4302
4299
  * Register the ESM loader hook that transforms `.ts` / `.tsx` files on the fly
4303
4300
  * for subsequent dynamic `import()` calls. Idempotent at our level via the
@@ -4490,7 +4487,7 @@ async function extractStepsFromDynamicJob(workflow, dynamicIndex, jobName, event
4490
4487
  const dynamicFn = extractDynamicJobFn(workflow, dynamicIndex);
4491
4488
  const { $ } = await import("zx");
4492
4489
  const { createLogger } = await import("@kici-dev/shared");
4493
- const { buildKiciApi, buildNeedsContext } = await import("@kici-dev/sdk");
4490
+ const { buildKiciApi, buildNeedsContext } = await import("@kici-dev/sdk/internal");
4494
4491
  const log = createLogger({ prefix: `dynamic-job-fn:${workflow.name}` });
4495
4492
  const kici = buildKiciApi(apiTransport ?? (() => Promise.reject(/* @__PURE__ */ new Error("Agent API not available during re-evaluation"))));
4496
4493
  const needs = upstreamSnapshot ? buildNeedsContext(upstreamSnapshot, declaredNeeds ?? []) : void 0;
@@ -4592,18 +4589,13 @@ function applyGlobalWorkflowEnv(repos) {
4592
4589
  * optimization — source tarballs are tiny (kilobytes, not the hundreds of
4593
4590
  * megabytes a `node_modules/` tarball carries).
4594
4591
  *
4595
- * Two properties this path is responsible for, both of which it previously
4596
- * lacked:
4592
+ * Two properties this path is responsible for:
4597
4593
  *
4598
4594
  * **Verification.** `dispatch.sourceTarDigest` is the SHA-256 of the tarball's
4599
4595
  * own bytes, so the download is checked before anything is extracted — the same
4600
- * contract `restoreDeps` has always had via `depsHash`. The older
4601
- * `dispatch.sourceTarHash` field carries the workflow `contentHash` instead, so
4602
- * it never could serve this purpose; it stays on the wire for older peers and
4603
- * is deliberately not used as a verification input here. When no digest is
4604
- * dispatched (an older orchestrator, or a source that did not come from the
4605
- * content-addressed cache) the restore proceeds unverified rather than failing,
4606
- * so a mixed-version rollout still runs.
4596
+ * contract `restoreDeps` has via `depsHash`. When no digest is dispatched (a
4597
+ * source that did not come from the content-addressed cache) the restore
4598
+ * proceeds unverified rather than failing.
4607
4599
  *
4608
4600
  * **Replacement, not overlay.** Extraction lands in a scratch directory and the
4609
4601
  * result REPLACES `workDir/.kici` wholesale, save for `node_modules/` — the one
@@ -4817,7 +4809,7 @@ async function applyOverlay(config) {
4817
4809
  */
4818
4810
  init_download();
4819
4811
  init_dep_restore();
4820
- const AGENT_VERSION = "0.8.0";
4812
+ const AGENT_VERSION = "0.9.0";
4821
4813
  process.on("uncaughtException", (err) => {
4822
4814
  process.stderr.write(`[workflow-runner] UNCAUGHT EXCEPTION: ${err.message}\n`);
4823
4815
  if (err.stack) process.stderr.write(`[workflow-runner] Stack: ${err.stack}\n`);
@@ -5422,16 +5414,14 @@ function buildArtifactTransport() {
5422
5414
  ...response.rejectionDetail && { error: response.rejectionDetail }
5423
5415
  };
5424
5416
  },
5425
- async completeUpload(name, sizeBytes, sha256, storageKey) {
5417
+ async completeUpload(name, sha256) {
5426
5418
  const requestId = randomUUID();
5427
5419
  sendMessage({
5428
5420
  type: "artifacts.request",
5429
5421
  requestId,
5430
5422
  op: "completeUpload",
5431
5423
  name,
5432
- sizeBytes,
5433
- sha256,
5434
- storageKey
5424
+ sha256
5435
5425
  });
5436
5426
  const response = await waitForArtifactResponse(requestId);
5437
5427
  if (response.error) throw new Error(`Artifact upload-complete failed: ${response.error}`);
@@ -189,6 +189,18 @@ export declare class OrchestratorClient {
189
189
  * GitHub Actions run hangs until the job timeout.
190
190
  */
191
191
  onClaimFailedPermanently: ((reason: string) => void) | null;
192
+ /**
193
+ * Fired once when authentication fails permanently — an `auth.failure` frame,
194
+ * or the orchestrator closing with WS_CLOSE_AGENT_AUTH_FAILED (a revoked token,
195
+ * or a protocol version below the orchestrator's floor). The client never
196
+ * reconnects after this, so server.ts wires it to a non-zero graceful
197
+ * shutdown; without it the health HTTP server keeps a process alive that can
198
+ * never register again, and a one-shot GitHub Actions agent holds its runner
199
+ * until the job timeout.
200
+ */
201
+ onAuthFailedPermanently: ((reason: string) => void) | null;
202
+ /** Marks the auth failure permanent and fires onAuthFailedPermanently exactly once. */
203
+ private failAuthPermanently;
192
204
  constructor(options: OrchestratorClientOptions);
193
205
  /** Current connection state. */
194
206
  get state(): ConnectionState;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kici-dev/agent",
3
- "version": "0.8.0",
3
+ "version": "0.9.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",
@@ -59,18 +59,18 @@
59
59
  "@hono/node-server": "^2.1.1",
60
60
  "archiver": "^8.0.0",
61
61
  "dockerode": "^5.0.1",
62
- "hono": "^4.13.2",
63
- "jose": "^6.2.10",
62
+ "hono": "^4.13.7",
63
+ "jose": "^6.2.12",
64
64
  "tar": "^7.5.22",
65
65
  "winston": "^3.19.0",
66
66
  "ws": "^8.21.3",
67
- "yaml": "^2.9.0",
68
- "zod": "^4.4.3",
67
+ "yaml": "^2.9.1",
68
+ "zod": "^4.6.5",
69
69
  "zx": "^8.8.5",
70
- "@kici-dev/core": "0.8.0",
71
- "@kici-dev/engine": "0.8.0",
72
- "@kici-dev/sdk": "0.8.0",
73
- "@kici-dev/shared": "0.8.0"
70
+ "@kici-dev/core": "0.9.0",
71
+ "@kici-dev/engine": "0.9.0",
72
+ "@kici-dev/sdk": "0.9.0",
73
+ "@kici-dev/shared": "0.9.0"
74
74
  },
75
75
  "kici": {
76
76
  "metrics": {
@@ -83,8 +83,8 @@
83
83
  "@types/dockerode": "^4.0.1"
84
84
  },
85
85
  "scripts": {
86
- "build": "node ../../scripts/build-service.mjs && tsgo --emitDeclarationOnly",
87
- "typecheck": "tsgo --noEmit",
86
+ "build": "node ../../scripts/build-service.mjs && tsc --emitDeclarationOnly",
87
+ "typecheck": "tsc --noEmit",
88
88
  "test": "vitest run"
89
89
  }
90
90
  }