@forgezero/agent 0.1.28 → 0.1.30

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/fz-agent.js CHANGED
@@ -4886,6 +4886,16 @@ import { readFileSync } from "fs";
4886
4886
  var BUN_INSTALLER_SHA256 = "bab8acfb046aac8c72407bdcce903957665d655d7acaa3e11c7c4616beae68dd";
4887
4887
  var ARANGO_SHA256 = "b5a9197b4343f2ed554e1ebc1ef8e6529c7c39cde0035cdc311a4747a3355066";
4888
4888
  var CLOUDFLARED_SHA256 = "9d71c677db00134c1bd4144b7783486b654ad281b1ea62b4972098d19f770f17";
4889
+ var OS_CATALOG = [
4890
+ { id: "ubuntu", version: "26.04", architecture: "x64", status: "active" }
4891
+ ];
4892
+ var SOFTWARE_CATALOG = [
4893
+ { id: "bun", version: "1.3.14", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
4894
+ { id: "nginx", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
4895
+ { id: "arangodb", version: "3.11.14", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
4896
+ { id: "cloudflared", version: "2026.7.3", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
4897
+ { id: "ufw", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
4898
+ ];
4889
4899
  var UBUNTU_2604_X64 = [
4890
4900
  {
4891
4901
  requirement: { id: "bun", version: "1.3.14" },
@@ -4924,7 +4934,7 @@ function observeSoftwareHost(osRelease = readFileSync("/etc/os-release", "utf8")
4924
4934
  architecture
4925
4935
  };
4926
4936
  }
4927
- function validateSoftwareRequirements(value) {
4937
+ function validateSoftwareRequirements(value, options = {}) {
4928
4938
  if (!Array.isArray(value) || value.length > 32)
4929
4939
  throw new Error("software requirements must be an array of at most 32 entries");
4930
4940
  const seen = new Set;
@@ -4942,13 +4952,18 @@ function validateSoftwareRequirements(value) {
4942
4952
  if (seen.has(requirement.id))
4943
4953
  throw new Error(`duplicate software requirement: ${requirement.id}`);
4944
4954
  seen.add(requirement.id);
4955
+ const catalog = SOFTWARE_CATALOG.find((candidate) => candidate.id === requirement.id && candidate.version === requirement.version);
4956
+ if (!catalog || catalog.status === "retired" || options.channel !== "development" && catalog.status !== "active") {
4957
+ throw new Error(`software requirement is not available for ${options.channel ?? "production"}: ${requirement.id}@${requirement.version}`);
4958
+ }
4945
4959
  return requirement;
4946
4960
  });
4947
4961
  }
4948
4962
  async function ensureSoftwareRequirements(requirementsInput, options) {
4949
4963
  const requirements = validateSoftwareRequirements(requirementsInput);
4950
4964
  const observation = options.observation ?? observeSoftwareHost();
4951
- if (observation.os.id !== "ubuntu" || observation.os.versionId !== "26.04" || observation.architecture !== "x64") {
4965
+ const os = OS_CATALOG.find((candidate) => candidate.id === observation.os.id && candidate.version === observation.os.versionId && candidate.architecture === observation.architecture);
4966
+ if (!os || os.status !== "active") {
4952
4967
  throw new Error(`unsupported software strategy: ${observation.os.id} ${observation.os.versionId} ${observation.architecture}`);
4953
4968
  }
4954
4969
  const results = [];
@@ -4973,7 +4988,7 @@ async function ensureSoftwareRequirements(requirementsInput, options) {
4973
4988
  }
4974
4989
 
4975
4990
  // src/definition.ts
4976
- var PIPELINE_VERSION = 1;
4991
+ var PIPELINE_VERSION = 2;
4977
4992
 
4978
4993
  class DefinitionError extends Error {
4979
4994
  constructor(message) {
@@ -4998,6 +5013,7 @@ var exactKeys = (value, allowed, where) => {
4998
5013
  if (unknown.length > 0)
4999
5014
  throw new DefinitionError(`${where} contains unknown field(s): ${unknown.join(", ")}.`);
5000
5015
  };
5016
+ var NAME = /^[a-z][a-z0-9-]{0,62}$/;
5001
5017
  var RESERVED_STEP_ENV = new Set([
5002
5018
  "PATH",
5003
5019
  "HOME",
@@ -5012,37 +5028,52 @@ var RESERVED_STEP_ENV = new Set([
5012
5028
  ]);
5013
5029
  function parseDeployDefinition(value) {
5014
5030
  const root = record(value, "pipeline");
5015
- exactKeys(root, ["version", "name", "requireAttestation", "roles", "steps"], "pipeline");
5031
+ exactKeys(root, ["$schema", "version", "name", "requireAttestation", "profiles", "steps"], "pipeline");
5032
+ if (root.$schema !== undefined && (typeof root.$schema !== "string" || !root.$schema.startsWith("https://"))) {
5033
+ throw new DefinitionError("pipeline.$schema must be an HTTPS URL.");
5034
+ }
5016
5035
  if (root.version !== PIPELINE_VERSION) {
5017
5036
  throw new DefinitionError(`pipeline.version must be ${PIPELINE_VERSION}.`);
5018
5037
  }
5019
- if (!Array.isArray(root.roles) || root.roles.length === 0) {
5020
- throw new DefinitionError("pipeline.roles must contain at least one role.");
5038
+ const rawProfiles = record(root.profiles, "pipeline.profiles");
5039
+ const profileEntries = Object.entries(rawProfiles);
5040
+ if (profileEntries.length === 0 || profileEntries.length > 32) {
5041
+ throw new DefinitionError("pipeline.profiles must contain from 1 to 32 named profiles.");
5021
5042
  }
5022
5043
  if (!Array.isArray(root.steps) || root.steps.length === 0) {
5023
5044
  throw new DefinitionError("pipeline.steps must contain at least one step.");
5024
5045
  }
5025
- const roles = root.roles.map((raw, index) => {
5026
- const role = record(raw, `roles[${index}]`);
5027
- exactKeys(role, ["name", "software"], `roles[${index}]`);
5028
- if (!Array.isArray(role.software)) {
5029
- throw new DefinitionError(`roles[${index}].software must be an array.`);
5046
+ const profiles = {};
5047
+ for (const [name, raw] of profileEntries) {
5048
+ if (!NAME.test(name))
5049
+ throw new DefinitionError(`pipeline profile name is invalid: ${name}.`);
5050
+ const profile = record(raw, `profiles.${name}`);
5051
+ exactKeys(profile, ["software"], `profiles.${name}`);
5052
+ if (!Array.isArray(profile.software)) {
5053
+ throw new DefinitionError(`profiles.${name}.software must be an array.`);
5030
5054
  }
5031
- return {
5032
- name: text(role.name, `roles[${index}].name`),
5033
- software: validateSoftwareRequirements(role.software)
5034
- };
5035
- });
5036
- if (new Set(roles.map((role) => role.name)).size !== roles.length) {
5037
- throw new DefinitionError("pipeline.roles must have unique names.");
5055
+ profiles[name] = { software: validateSoftwareRequirements(profile.software) };
5038
5056
  }
5039
5057
  const phases = new Set(["build", "release", "migrate", "health"]);
5040
5058
  const steps = root.steps.map((raw, index) => {
5041
5059
  const step = record(raw, `steps[${index}]`);
5042
- exactKeys(step, ["name", "run", "phase", "secrets", "once", "always", "timeoutMs", "when"], `steps[${index}]`);
5060
+ exactKeys(step, ["name", "run", "phase", "scope", "profiles", "secrets", "always", "timeoutMs", "when"], `steps[${index}]`);
5043
5061
  const phase = text(step.phase, `steps[${index}].phase`);
5044
5062
  if (!phases.has(phase))
5045
5063
  throw new DefinitionError(`steps[${index}].phase is not supported.`);
5064
+ if (step.scope !== "target" && step.scope !== "release") {
5065
+ throw new DefinitionError(`steps[${index}].scope must be target or release.`);
5066
+ }
5067
+ let selectedProfiles;
5068
+ if (step.profiles !== undefined) {
5069
+ if (!Array.isArray(step.profiles) || step.profiles.length === 0 || step.profiles.some((name) => typeof name !== "string" || !Object.hasOwn(profiles, name))) {
5070
+ throw new DefinitionError(`steps[${index}].profiles must name existing profiles.`);
5071
+ }
5072
+ selectedProfiles = [...step.profiles];
5073
+ if (new Set(selectedProfiles).size !== selectedProfiles.length) {
5074
+ throw new DefinitionError(`steps[${index}].profiles must not contain duplicates.`);
5075
+ }
5076
+ }
5046
5077
  if (step.secrets !== undefined && (!Array.isArray(step.secrets) || step.secrets.some((name) => typeof name !== "string" || !/^[A-Z_][A-Z0-9_]*$/.test(name)))) {
5047
5078
  throw new DefinitionError(`steps[${index}].secrets must contain names only.`);
5048
5079
  }
@@ -5073,8 +5104,9 @@ function parseDeployDefinition(value) {
5073
5104
  name: text(step.name, `steps[${index}].name`),
5074
5105
  run: text(step.run, `steps[${index}].run`),
5075
5106
  phase,
5107
+ scope: step.scope,
5108
+ profiles: selectedProfiles,
5076
5109
  secrets: step.secrets,
5077
- once: step.once === true,
5078
5110
  always: step.always === true,
5079
5111
  timeoutMs,
5080
5112
  when
@@ -5087,7 +5119,7 @@ function parseDeployDefinition(value) {
5087
5119
  version: PIPELINE_VERSION,
5088
5120
  name: text(root.name, "pipeline.name"),
5089
5121
  requireAttestation: root.requireAttestation === true,
5090
- roles,
5122
+ profiles,
5091
5123
  steps
5092
5124
  };
5093
5125
  }
@@ -5217,7 +5249,7 @@ function createDeploymentManager(options) {
5217
5249
  const exec = options.exec ?? shell;
5218
5250
  const projectExec = options.projectExec ?? exec;
5219
5251
  const now = options.now ?? Date.now;
5220
- const readDefinition = options.readDefinition ?? ((path) => Bun.YAML.parse(readFileSync2(path, "utf8")));
5252
+ const readDefinition = options.readDefinition ?? ((path) => JSON.parse(readFileSync2(path, "utf8")));
5221
5253
  const credentialsDirectory = process.env.CREDENTIALS_DIRECTORY;
5222
5254
  const gitCredentialPath = options.gitCredentialPath ?? (credentialsDirectory ? join(credentialsDirectory, "git-deploy-key") : undefined);
5223
5255
  const knownHostsPath = options.knownHostsPath ?? "/etc/forgezero/git/known_hosts";
@@ -5332,22 +5364,22 @@ function createDeploymentManager(options) {
5332
5364
  if (request.revision && head !== request.revision) {
5333
5365
  throw new DeploymentError("SOURCE_FAILED", `Git checked out ${head}, not requested ${request.revision}.`);
5334
5366
  }
5335
- const definition = parseDeployDefinition(readDefinition(join(release, ".fz", "deploy.yaml")));
5336
- const selectedRole = definition.roles.find((candidate) => candidate.name === options.role);
5337
- if (!selectedRole)
5338
- throw new DeploymentError("PIPELINE_FAILED", `pipeline role does not exist: ${options.role}.`);
5339
- if (selectedRole.software.length > 0) {
5367
+ const definition = parseDeployDefinition(readDefinition(join(release, ".fz", "deploy.json")));
5368
+ const selectedProfile = definition.profiles[options.profile];
5369
+ if (!selectedProfile)
5370
+ throw new DeploymentError("PIPELINE_FAILED", `pipeline profile does not exist: ${options.profile}.`);
5371
+ if (selectedProfile.software.length > 0) {
5340
5372
  if (!options.ensureSoftware) {
5341
5373
  throw new DeploymentError("PIPELINE_FAILED", "the supervised software helper is unavailable");
5342
5374
  }
5343
- await options.ensureSoftware(selectedRole.software);
5375
+ await options.ensureSoftware(selectedProfile.software);
5344
5376
  }
5345
5377
  const phaseEnvironment = {
5346
5378
  ...options.environment ?? {},
5347
5379
  FZ_RELEASE: release,
5348
5380
  FZ_DEPLOY_REVISION: head,
5349
5381
  FZ_DEPLOY_BRANCH: options.branch,
5350
- FZ_DEPLOY_ROLE: options.role,
5382
+ FZ_DEPLOY_PROFILE: options.profile,
5351
5383
  ...options.publicApiUrl ? { PUBLIC_API_URL: options.publicApiUrl } : {}
5352
5384
  };
5353
5385
  const phaseExec = ({ command, env: secrets, timeoutMs }) => projectExec({ command, cwd: release, env: { ...phaseEnvironment, ...secrets }, timeoutMs });
@@ -5363,7 +5395,7 @@ function createDeploymentManager(options) {
5363
5395
  return {
5364
5396
  name: `${definition.name}:${phase}`,
5365
5397
  requireAttestation: definition.requireAttestation,
5366
- steps: definition.steps.filter((step) => step.phase === phase && (!step.once || request.coordinator === true) && (!step.when || Object.entries(step.when).every(([name, expected]) => phaseEnvironment[name] === expected)))
5398
+ steps: definition.steps.filter((step) => step.phase === phase && (!step.profiles || step.profiles.includes(options.profile)) && (step.scope === "target" || request.releaseExecutor === true) && (!step.when || Object.entries(step.when).every(([name, expected]) => phaseEnvironment[name] === expected)))
5367
5399
  };
5368
5400
  })
5369
5401
  ].filter((pipeline) => pipeline.steps.length > 0);
@@ -5400,7 +5432,7 @@ function createDeploymentManager(options) {
5400
5432
  return revision.toLowerCase();
5401
5433
  },
5402
5434
  deploy(request = {}) {
5403
- const revisionKey = request.revision ? `${request.revision.toLowerCase()}:${request.coordinator === true ? "coordinator" : "node"}` : undefined;
5435
+ const revisionKey = request.revision ? `${request.revision.toLowerCase()}:${request.releaseExecutor === true ? "release" : "target"}` : undefined;
5404
5436
  if (revisionKey) {
5405
5437
  const existing = activeRevisions.get(revisionKey);
5406
5438
  if (existing)
@@ -5592,7 +5624,7 @@ async function deployClaim(options, claim) {
5592
5624
  schedule();
5593
5625
  let result;
5594
5626
  try {
5595
- result = await manager.deploy({ revision: claim.revision, coordinator: claim.coordinator }).result;
5627
+ result = await manager.deploy({ revision: claim.revision, releaseExecutor: claim.releaseExecutor }).result;
5596
5628
  } finally {
5597
5629
  stopped = true;
5598
5630
  clearTimer(timer);
@@ -6377,11 +6409,10 @@ ${attestationSetup}if [[ ! -x /usr/local/bin/bun ]]; then
6377
6409
  install -m 0755 ${agentBun}/bin/bun /usr/local/bin/bun
6378
6410
  rm -f /run/fz-bun-install
6379
6411
  fi
6380
- if [[ ! -x /usr/local/bin/fz-agent ]] || [[ "$(/usr/local/bin/fz-agent --version 2>/dev/null || true)" != "${profile.agentVersion}" ]]; then
6412
+ if [[ ! -x /usr/local/lib/forgezero/agent/fz-agent ]] || [[ "$(/usr/local/lib/forgezero/agent/fz-agent --version 2>/dev/null || true)" != "${profile.agentVersion}" ]]; then
6381
6413
  env BUN_INSTALL=${agentBun} /usr/local/bin/bun add -g --no-cache --force @forgezero/agent@${profile.agentVersion}
6382
- ln -sfn ${agentBun}/bin/fz-agent /usr/local/bin/fz-agent
6383
6414
  fi
6384
- env FZ_API=${profile.apiUrl} FZ_AGENT_BIN=/usr/local/bin/fz-agent FZ_AGENT_USER=forgezero-agent FZ_SOCKET_PATH=/run/forgezero/vault.sock FZ_SEED_CREDENTIAL_PATH=/etc/forgezero/creds/agent-seed.cred FZ_GIT_CREDENTIAL_PATH=/etc/forgezero/creds/git-deploy-key.cred FZ_GIT_PUBLIC_KEY_PATH=/etc/forgezero/git/deploy.pub FZ_DEPLOY_ROOT=/opt/forgezero FZ_DEPLOY_PULL=${hasEnrolment ? "true" : "false"} FZ_NODE_LABEL=${nodeLabel} ${agentBun}/bin/fz agent install --apply${hasEnrolment ? " --enrol" : ""}
6415
+ env FZ_API=${profile.apiUrl} FZ_AGENT_BIN=/usr/local/lib/forgezero/agent/fz-agent FZ_AGENT_USER=forgezero-agent FZ_SOCKET_PATH=/run/forgezero/vault.sock FZ_SEED_CREDENTIAL_PATH=/etc/forgezero/creds/agent-seed.cred FZ_GIT_CREDENTIAL_PATH=/etc/forgezero/creds/git-deploy-key.cred FZ_GIT_PUBLIC_KEY_PATH=/etc/forgezero/git/deploy.pub FZ_DEPLOY_ROOT=/opt/forgezero FZ_DEPLOY_PULL=${hasEnrolment ? "true" : "false"} FZ_NODE_LABEL=${nodeLabel} ${agentBun}/bin/fz agent install --apply${hasEnrolment ? " --enrol" : ""}
6385
6416
  `;
6386
6417
  }
6387
6418
  function cloudInit(profile, claim, manifest) {
@@ -7876,7 +7907,7 @@ function requestAgentUpdate(request, socketPath = DEFAULT_AGENT_UPDATE_SOCKET, t
7876
7907
  import { readFileSync as readFileSync7 } from "fs";
7877
7908
 
7878
7909
  // src/version.ts
7879
- var VERSION2 = "0.1.28";
7910
+ var VERSION2 = "0.1.30";
7880
7911
 
7881
7912
  // src/agent-heartbeat.ts
7882
7913
  var unquote = (value) => value.replace(/^['"]|['"]$/g, "");
@@ -8165,7 +8196,7 @@ if (import.meta.main) {
8165
8196
  " FZ_SEED_PATH legacy/dev seed file (default: " + DEFAULT_SEED_PATH + ")",
8166
8197
  " FZ_NODE_KEY override the node key (default: derived from the seed)",
8167
8198
  "",
8168
- " deploy [--revision=<full-sha>] [--coordinator]",
8199
+ " deploy [--revision=<full-sha>] [--release-executor]",
8169
8200
  " identity print this sealed seed's public identity",
8170
8201
  " enrol consume a systemd-loaded compute capability",
8171
8202
  " metal-helper --profile=/etc/forgezero/metal.json",
@@ -8222,9 +8253,9 @@ if (import.meta.main) {
8222
8253
  const profilePath = args.find((arg) => arg.startsWith("--profile="))?.slice("--profile=".length);
8223
8254
  if (!profilePath)
8224
8255
  throw new Error("metal-helper requires --profile=/absolute/path.json");
8225
- const profile = JSON.parse(readFileSync8(profilePath, "utf8"));
8256
+ const profile2 = JSON.parse(readFileSync8(profilePath, "utf8"));
8226
8257
  const helper = startMetalHelper({
8227
- profile,
8258
+ profile: profile2,
8228
8259
  socketPath: process.env.FZ_METAL_HELPER_SOCKET ?? DEFAULT_METAL_HELPER_SOCKET
8229
8260
  });
8230
8261
  console.log(`[metal-helper] listening on ${process.env.FZ_METAL_HELPER_SOCKET ?? DEFAULT_METAL_HELPER_SOCKET}`);
@@ -8340,8 +8371,8 @@ if (import.meta.main) {
8340
8371
  const profilePath = args.find((arg) => arg.startsWith("--profile="))?.slice("--profile=".length);
8341
8372
  if (!profilePath)
8342
8373
  throw new Error("metal-isolation requires --profile=/absolute/path.json");
8343
- const profile = JSON.parse(readFileSync8(profilePath, "utf8"));
8344
- await applyMetalIsolation(profile);
8374
+ const profile2 = JSON.parse(readFileSync8(profilePath, "utf8"));
8375
+ await applyMetalIsolation(profile2);
8345
8376
  console.log("[metal-isolation] host and guest cgroup boundaries active");
8346
8377
  process.exit(0);
8347
8378
  }
@@ -8469,7 +8500,7 @@ if (import.meta.main) {
8469
8500
  op: "deploy",
8470
8501
  request: {
8471
8502
  revision: revisionArg?.slice("--revision=".length),
8472
- coordinator: args.includes("--coordinator")
8503
+ releaseExecutor: args.includes("--release-executor")
8473
8504
  }
8474
8505
  } : command2 === "cancel" ? { op: "cancel", id: idArg?.slice("--id=".length) ?? "" } : ["pause-key", "resume-key", "stop-key", "start-key"].includes(command2) ? {
8475
8506
  op: command2,
@@ -8487,7 +8518,6 @@ if (import.meta.main) {
8487
8518
  const attestationSource = existsSync13("/dev/sev-guest") ? createSnpAttestationSource() : undefined;
8488
8519
  const running = runAgent({
8489
8520
  socketPath: process.env.FZ_SOCKET_PATH ?? DEFAULT_SOCKET_PATH,
8490
- listenFd: systemdListenFd(),
8491
8521
  seedCredential: process.env.FZ_SEED_CREDENTIAL,
8492
8522
  seedPath: process.env.FZ_SEED_PATH ?? DEFAULT_SEED_PATH,
8493
8523
  nodeKey: process.env.FZ_NODE_KEY,
@@ -8577,19 +8607,19 @@ if (import.meta.main) {
8577
8607
  } : systemdDeploymentSecrets;
8578
8608
  const repository = process.env.FZ_DEPLOY_REPO;
8579
8609
  const branch = process.env.FZ_DEPLOY_BRANCH;
8580
- const role = process.env.FZ_DEPLOY_ROLE;
8610
+ const profile = process.env.FZ_DEPLOY_PROFILE;
8581
8611
  const root = process.env.FZ_DEPLOY_ROOT;
8582
8612
  const pullEnabled = process.env.FZ_DEPLOY_PULL === "true" && Boolean(process.env.FZ_API);
8583
8613
  if (pullEnabled && !binding) {
8584
8614
  throw new Error("agent: outbound guest deployment requires a persisted tenant enrolment binding");
8585
8615
  }
8586
- if (root && (repository && branch && role || pullEnabled)) {
8616
+ if (root && (repository && branch && profile || pullEnabled)) {
8587
8617
  const managers = new Map;
8588
8618
  const managerOptions = (source, key) => ({
8589
8619
  key,
8590
8620
  repository: source.repository,
8591
8621
  branch: source.branch,
8592
- role: source.role,
8622
+ profile: source.profile,
8593
8623
  sourceAuth: source.auth,
8594
8624
  root,
8595
8625
  publicApiUrl: process.env.FZ_PUBLIC_API_URL,
@@ -8606,7 +8636,7 @@ if (import.meta.main) {
8606
8636
  ensureSoftware: (requirements) => requestSoftware(requirements, process.env.FZ_SOFTWARE_HELPER_SOCKET ?? DEFAULT_SOFTWARE_HELPER_SOCKET),
8607
8637
  projectExec: process.env.FZ_DEPLOY_RUNNER_SOCKET ? (input) => requestDeploymentCommand(input, process.env.FZ_DEPLOY_RUNNER_SOCKET) : undefined
8608
8638
  });
8609
- const staticManager = repository && branch && role ? createDeploymentManager(managerOptions({ repository, branch, role }, process.env.FZ_DEPLOY_KEY ?? `${repository}:${branch}:${role}`)) : undefined;
8639
+ const staticManager = repository && branch && profile ? createDeploymentManager(managerOptions({ repository, branch, profile }, process.env.FZ_DEPLOY_KEY ?? `${repository}:${branch}:${profile}`)) : undefined;
8610
8640
  if (staticManager)
8611
8641
  managers.set("__static__", staticManager);
8612
8642
  const control = staticManager ? startControlServer(staticManager, process.env.FZ_CONTROL_SOCKET ?? DEFAULT_CONTROL_SOCKET) : undefined;
@@ -8622,7 +8652,7 @@ if (import.meta.main) {
8622
8652
  claim.pipelineKey,
8623
8653
  claim.source.repository,
8624
8654
  claim.source.branch,
8625
- claim.source.role,
8655
+ claim.source.profile,
8626
8656
  JSON.stringify(claim.source.auth ?? null)
8627
8657
  ].join("\x00");
8628
8658
  const existing = managers.get(cacheKey);
@@ -8820,6 +8850,8 @@ export {
8820
8850
  SUPPORTED_GUEST_IMAGE,
8821
8851
  SOFTWARE_HELPER_UNIT_PATH,
8822
8852
  SOFTWARE_HELPER_GROUP,
8853
+ SOFTWARE_CATALOG,
8854
+ OS_CATALOG,
8823
8855
  MAX_AGENT_TARBALL_BYTES,
8824
8856
  DeploymentError,
8825
8857
  DEFAULT_SOFTWARE_HELPER_SOCKET,