@forgezero/agent 0.1.35 → 0.1.37

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/index.d.ts CHANGED
@@ -15,6 +15,8 @@ export type { DeploymentPullOptions, RemoteDeploymentClaim, PullResult } from '.
15
15
  export { pullProvisioningOnce, startProvisioningPull } from './provisioning-pull';
16
16
  export type { CreateRemoteProvisionClaim, ProvisioningPullOptions, RemoteProvisionClaim, GuestAccess, ProvisionPullResult, ProvisionRunner, ProvisionResult } from './provisioning-pull';
17
17
  export { pullMigrationOnce, startMigrationPull } from './migration-pull';
18
+ export { executeSshBootstrap, pullSshBootstrapOnce, startSshBootstrapPull } from './ssh-bootstrap';
19
+ export type { RemoteSshBootstrapClaim, SshBootstrapPullOptions, SshBootstrapResult } from './ssh-bootstrap';
18
20
  export type { MigrationAction, MigrationEvidence, MigrationNetwork, MigrationPullOptions, MigrationPullResult, RemoteMigrationClaim } from './migration-pull';
19
21
  export { enrolGuestIdentity, loadGuestBinding } from './guest-enrolment';
20
22
  export type { GuestBinding, GuestEnrolmentOptions } from './guest-enrolment';
@@ -293,7 +293,7 @@ function systemdAgentEgressDirectives(loopbackTcpPorts = []) {
293
293
  }
294
294
 
295
295
  // src/version.ts
296
- var VERSION = "0.1.35";
296
+ var VERSION = "0.1.37";
297
297
 
298
298
  // src/metal-bootstrap.ts
299
299
  var PROFILE_PATH = "/etc/forgezero/metal.json";
@@ -100,6 +100,10 @@ export interface UnitOptions {
100
100
  runnerPublicTcpPorts?: readonly number[];
101
101
  /** Enable PQ-authenticated lifecycle claims through a constrained root helper. */
102
102
  pullMigrations?: boolean;
103
+ /** Claim API-owned SSH bootstrap jobs; the private key stays a systemd credential on this runner. */
104
+ pullBootstrap?: boolean;
105
+ bootstrapSshCredentialPath?: string;
106
+ bootstrapTargetTelemetryEndpoint?: string;
103
107
  /** Root-owned declarative lifecycle profile; never supplied by a migration claim. */
104
108
  lifecycleProfilePath?: string;
105
109
  lifecycleHelperSocketPath?: string;
package/dist/provision.js CHANGED
@@ -673,6 +673,7 @@ function requestAgentUpdate(request, socketPath = DEFAULT_AGENT_UPDATE_SOCKET, t
673
673
 
674
674
  // src/software.ts
675
675
  import { readFileSync as readFileSync3 } from "node:fs";
676
+ var PINNED_BUN_VERSION = "1.3.14";
676
677
  var BUN_INSTALLER_SHA256 = "bab8acfb046aac8c72407bdcce903957665d655d7acaa3e11c7c4616beae68dd";
677
678
  var ARANGO_SHA256 = "b5a9197b4343f2ed554e1ebc1ef8e6529c7c39cde0035cdc311a4747a3355066";
678
679
  var CLOUDFLARED_SHA256 = "9d71c677db00134c1bd4144b7783486b654ad281b1ea62b4972098d19f770f17";
@@ -684,7 +685,8 @@ var SOFTWARE_CATALOG = [
684
685
  { id: "nginx", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
685
686
  { id: "arangodb", version: "3.11.14", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
686
687
  { id: "cloudflared", version: "2026.7.3", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
687
- { id: "ufw", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
688
+ { id: "ufw", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
689
+ { id: "openssh-client", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
688
690
  ];
689
691
  var UBUNTU_2604_X64 = [
690
692
  {
@@ -711,6 +713,11 @@ var UBUNTU_2604_X64 = [
711
713
  requirement: { id: "ufw", version: "ubuntu-26.04" },
712
714
  check: "command -v ufw >/dev/null",
713
715
  install: "DEBIAN_FRONTEND=noninteractive apt-get update -qq && apt-get install -y ufw"
716
+ },
717
+ {
718
+ requirement: { id: "openssh-client", version: "ubuntu-26.04" },
719
+ check: "command -v ssh >/dev/null && command -v scp >/dev/null && command -v ssh-keyscan >/dev/null && command -v ssh-keygen >/dev/null",
720
+ install: "DEBIAN_FRONTEND=noninteractive apt-get update -qq && apt-get install -y openssh-client"
714
721
  }
715
722
  ];
716
723
  function observeSoftwareHost(osRelease = readFileSync3("/etc/os-release", "utf8"), architecture = process.arch) {
@@ -735,7 +742,7 @@ function validateSoftwareRequirements(value, _options = {}) {
735
742
  if (Object.keys(row).some((key) => key !== "id" && key !== "version")) {
736
743
  throw new Error("software requirement contains an unknown field");
737
744
  }
738
- if (!["bun", "nginx", "arangodb", "cloudflared", "ufw"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
745
+ if (!["bun", "nginx", "arangodb", "cloudflared", "ufw", "openssh-client"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
739
746
  throw new Error("software requirement coordinate is invalid");
740
747
  }
741
748
  const requirement = { id: row.id, version: row.version };
@@ -884,7 +891,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
884
891
  }
885
892
 
886
893
  // src/version.ts
887
- var VERSION3 = "0.1.35";
894
+ var VERSION3 = "0.1.37";
888
895
 
889
896
  // src/egress-policy.ts
890
897
  import { realpathSync } from "node:fs";
@@ -1419,7 +1426,12 @@ function agentUnit(options) {
1419
1426
  if (Boolean(options.pullMigrations) !== Boolean(options.lifecycleProfilePath)) {
1420
1427
  throw new Error("migration pull and lifecycle profile must be supplied together");
1421
1428
  }
1429
+ const bootstrapEnabled = Boolean(options.pullBootstrap && options.bootstrapSshCredentialPath && options.bootstrapTargetTelemetryEndpoint);
1430
+ if ([options.pullBootstrap, options.bootstrapSshCredentialPath, options.bootstrapTargetTelemetryEndpoint].some(Boolean) && !bootstrapEnabled) {
1431
+ throw new Error("bootstrap pull, SSH credential and target telemetry endpoint must be supplied together");
1432
+ }
1422
1433
  const lifecycleHelperSocketPath = lifecycleEnabled ? systemdPath(options.lifecycleHelperSocketPath ?? LIFECYCLE_HELPER_SOCKET, "lifecycle helper socket") : undefined;
1434
+ const bootstrapSshCredentialPath = bootstrapEnabled ? systemdPath(options.bootstrapSshCredentialPath, "bootstrap SSH credential") : undefined;
1423
1435
  const warpValues = [
1424
1436
  options.warpOrganization,
1425
1437
  options.warpClientIdCredentialPath,
@@ -1485,6 +1497,9 @@ function agentUnit(options) {
1485
1497
  options.publicApiUrl ? `FZ_PUBLIC_API_URL=${options.publicApiUrl}` : null,
1486
1498
  options.pullDeployments ? "FZ_DEPLOY_PULL=true" : null,
1487
1499
  options.pullMigrations ? "FZ_MIGRATION_PULL=true" : null,
1500
+ options.pullBootstrap ? "FZ_BOOTSTRAP_PULL=true" : null,
1501
+ options.pullBootstrap ? "FZ_BOOTSTRAP_SSH_KEY_CREDENTIAL=bootstrap-ssh-key" : null,
1502
+ options.pullBootstrap ? `FZ_BOOTSTRAP_TARGET_OTLP_ENDPOINT=${options.bootstrapTargetTelemetryEndpoint}` : null,
1488
1503
  `FZ_AGENT_UPDATE_SOCKET=${DEFAULT_AGENT_UPDATE_SOCKET}`,
1489
1504
  options.pullMigrations ? `FZ_LIFECYCLE_HELPER_SOCKET=${lifecycleHelperSocketPath}` : null
1490
1505
  ].filter((line) => line !== null);
@@ -1492,6 +1507,8 @@ function agentUnit(options) {
1492
1507
  environment.push(`HOME=${deployRoot}/agent-home`, `XDG_CACHE_HOME=${deployRoot}/cache`);
1493
1508
  }
1494
1509
  const gitCredential = options.gitCredentialPath ? `LoadCredentialEncrypted=git-deploy-key:${options.gitCredentialPath}
1510
+ ` : "";
1511
+ const bootstrapCredential = bootstrapEnabled ? `LoadCredentialEncrypted=bootstrap-ssh-key:${bootstrapSshCredentialPath}
1495
1512
  ` : "";
1496
1513
  const projectCredentials = Object.entries(deploymentCredentials).map(([name, path]) => `LoadCredentialEncrypted=${name}:${path}`).join(`
1497
1514
  `);
@@ -1546,7 +1563,7 @@ User=${user}
1546
1563
  Group=${VAULT_GROUP}
1547
1564
  ${deploymentGroup}
1548
1565
  LoadCredentialEncrypted=agent-seed:${seedCredentialPath}
1549
- ${gitCredential}${projectCredentials}${projectCredentials ? `
1566
+ ${gitCredential}${bootstrapCredential}${projectCredentials}${projectCredentials ? `
1550
1567
  ` : ""}${snpPrepare}ExecStart=${bin}
1551
1568
  Restart=always
1552
1569
  RestartSec=2
@@ -1601,6 +1618,10 @@ function planProvision(options) {
1601
1618
  if (Boolean(options.pullMigrations) !== Boolean(options.lifecycleProfilePath)) {
1602
1619
  throw new Error("migration pull and lifecycle profile must be supplied together");
1603
1620
  }
1621
+ const bootstrapEnabled = Boolean(options.pullBootstrap && options.bootstrapSshCredentialPath && options.bootstrapTargetTelemetryEndpoint);
1622
+ if ([options.pullBootstrap, options.bootstrapSshCredentialPath, options.bootstrapTargetTelemetryEndpoint].some(Boolean) && !bootstrapEnabled) {
1623
+ throw new Error("bootstrap pull, SSH credential and target telemetry endpoint must be supplied together");
1624
+ }
1604
1625
  const warpValues = [
1605
1626
  options.warpOrganization,
1606
1627
  options.warpClientIdCredentialPath,
@@ -1626,13 +1647,20 @@ function planProvision(options) {
1626
1647
  const gitPublicKeyDir = gitPublicKeyPath?.replace(/\/[^/]+$/, "");
1627
1648
  const lifecycleProfilePath = lifecycleEnabled ? systemdPath(options.lifecycleProfilePath, "lifecycle profile") : undefined;
1628
1649
  const lifecycleHelperSocketPath = lifecycleEnabled ? systemdPath(options.lifecycleHelperSocketPath ?? LIFECYCLE_HELPER_SOCKET, "lifecycle helper socket") : undefined;
1650
+ const bootstrapSshCredentialPath = bootstrapEnabled ? systemdPath(options.bootstrapSshCredentialPath, "bootstrap SSH credential") : undefined;
1629
1651
  const warpClientIdCredentialPath = warpEnabled ? systemdPath(options.warpClientIdCredentialPath, "WARP client-id credential") : undefined;
1630
1652
  const warpClientSecretCredentialPath = warpEnabled ? systemdPath(options.warpClientSecretCredentialPath, "WARP client-secret credential") : undefined;
1631
1653
  return {
1632
1654
  mode,
1633
1655
  reason: reasonFor(mode),
1634
1656
  unitPath: UNIT_PATH,
1635
- unit: agentUnit({ ...options, mode, lifecycleProfilePath, lifecycleHelperSocketPath }),
1657
+ unit: agentUnit({
1658
+ ...options,
1659
+ mode,
1660
+ lifecycleProfilePath,
1661
+ lifecycleHelperSocketPath,
1662
+ bootstrapSshCredentialPath
1663
+ }),
1636
1664
  auxiliaryUnits: [
1637
1665
  { path: AGENT_SOCKET_UNIT_PATH, unit: agentSocketUnit(options) },
1638
1666
  { path: AGENT_SOCKET_PROXY_UNIT_PATH, unit: agentSocketProxyUnit(options) },
@@ -1,5 +1,6 @@
1
1
  // src/software.ts
2
2
  import { readFileSync } from "node:fs";
3
+ var PINNED_BUN_VERSION = "1.3.14";
3
4
  var BUN_INSTALLER_SHA256 = "bab8acfb046aac8c72407bdcce903957665d655d7acaa3e11c7c4616beae68dd";
4
5
  var ARANGO_SHA256 = "b5a9197b4343f2ed554e1ebc1ef8e6529c7c39cde0035cdc311a4747a3355066";
5
6
  var CLOUDFLARED_SHA256 = "9d71c677db00134c1bd4144b7783486b654ad281b1ea62b4972098d19f770f17";
@@ -11,7 +12,8 @@ var SOFTWARE_CATALOG = [
11
12
  { id: "nginx", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
12
13
  { id: "arangodb", version: "3.11.14", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
13
14
  { id: "cloudflared", version: "2026.7.3", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
14
- { id: "ufw", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
15
+ { id: "ufw", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
16
+ { id: "openssh-client", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
15
17
  ];
16
18
  var UBUNTU_2604_X64 = [
17
19
  {
@@ -38,6 +40,11 @@ var UBUNTU_2604_X64 = [
38
40
  requirement: { id: "ufw", version: "ubuntu-26.04" },
39
41
  check: "command -v ufw >/dev/null",
40
42
  install: "DEBIAN_FRONTEND=noninteractive apt-get update -qq && apt-get install -y ufw"
43
+ },
44
+ {
45
+ requirement: { id: "openssh-client", version: "ubuntu-26.04" },
46
+ check: "command -v ssh >/dev/null && command -v scp >/dev/null && command -v ssh-keyscan >/dev/null && command -v ssh-keygen >/dev/null",
47
+ install: "DEBIAN_FRONTEND=noninteractive apt-get update -qq && apt-get install -y openssh-client"
41
48
  }
42
49
  ];
43
50
  function observeSoftwareHost(osRelease = readFileSync("/etc/os-release", "utf8"), architecture = process.arch) {
@@ -62,7 +69,7 @@ function validateSoftwareRequirements(value, _options = {}) {
62
69
  if (Object.keys(row).some((key) => key !== "id" && key !== "version")) {
63
70
  throw new Error("software requirement contains an unknown field");
64
71
  }
65
- if (!["bun", "nginx", "arangodb", "cloudflared", "ufw"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
72
+ if (!["bun", "nginx", "arangodb", "cloudflared", "ufw", "openssh-client"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
66
73
  throw new Error("software requirement coordinate is invalid");
67
74
  }
68
75
  const requirement = { id: row.id, version: row.version };
@@ -1,6 +1,6 @@
1
1
  export type CatalogStatus = 'testing' | 'active' | 'retired';
2
2
  export type DeploymentChannel = 'development' | 'production';
3
- export type SoftwareId = 'bun' | 'nginx' | 'arangodb' | 'cloudflared' | 'ufw';
3
+ export type SoftwareId = 'bun' | 'nginx' | 'arangodb' | 'cloudflared' | 'ufw' | 'openssh-client';
4
4
  /** Repository input is a catalogue coordinate, never a root command. */
5
5
  export interface SoftwareRequirement {
6
6
  id: SoftwareId;
@@ -32,6 +32,8 @@ export interface SoftwareCommandResult {
32
32
  output: string;
33
33
  }
34
34
  export type SoftwareExec = (command: string) => Promise<SoftwareCommandResult>;
35
+ export declare const PINNED_BUN_VERSION = "1.3.14";
36
+ export declare const BUN_INSTALLER_SHA256 = "bab8acfb046aac8c72407bdcce903957665d655d7acaa3e11c7c4616beae68dd";
35
37
  /** Public, command-free catalog. Root strategies remain private below. */
36
38
  export declare const OS_CATALOG: readonly OsCatalogEntry[];
37
39
  export declare const SOFTWARE_CATALOG: readonly SoftwareCatalogEntry[];
package/dist/software.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // src/software.ts
2
2
  import { readFileSync } from "node:fs";
3
+ var PINNED_BUN_VERSION = "1.3.14";
3
4
  var BUN_INSTALLER_SHA256 = "bab8acfb046aac8c72407bdcce903957665d655d7acaa3e11c7c4616beae68dd";
4
5
  var ARANGO_SHA256 = "b5a9197b4343f2ed554e1ebc1ef8e6529c7c39cde0035cdc311a4747a3355066";
5
6
  var CLOUDFLARED_SHA256 = "9d71c677db00134c1bd4144b7783486b654ad281b1ea62b4972098d19f770f17";
@@ -11,7 +12,8 @@ var SOFTWARE_CATALOG = [
11
12
  { id: "nginx", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
12
13
  { id: "arangodb", version: "3.11.14", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
13
14
  { id: "cloudflared", version: "2026.7.3", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
14
- { id: "ufw", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
15
+ { id: "ufw", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
16
+ { id: "openssh-client", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
15
17
  ];
16
18
  var UBUNTU_2604_X64 = [
17
19
  {
@@ -38,6 +40,11 @@ var UBUNTU_2604_X64 = [
38
40
  requirement: { id: "ufw", version: "ubuntu-26.04" },
39
41
  check: "command -v ufw >/dev/null",
40
42
  install: "DEBIAN_FRONTEND=noninteractive apt-get update -qq && apt-get install -y ufw"
43
+ },
44
+ {
45
+ requirement: { id: "openssh-client", version: "ubuntu-26.04" },
46
+ check: "command -v ssh >/dev/null && command -v scp >/dev/null && command -v ssh-keyscan >/dev/null && command -v ssh-keygen >/dev/null",
47
+ install: "DEBIAN_FRONTEND=noninteractive apt-get update -qq && apt-get install -y openssh-client"
41
48
  }
42
49
  ];
43
50
  function observeSoftwareHost(osRelease = readFileSync("/etc/os-release", "utf8"), architecture = process.arch) {
@@ -62,7 +69,7 @@ function validateSoftwareRequirements(value, _options = {}) {
62
69
  if (Object.keys(row).some((key) => key !== "id" && key !== "version")) {
63
70
  throw new Error("software requirement contains an unknown field");
64
71
  }
65
- if (!["bun", "nginx", "arangodb", "cloudflared", "ufw"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
72
+ if (!["bun", "nginx", "arangodb", "cloudflared", "ufw", "openssh-client"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
66
73
  throw new Error("software requirement coordinate is invalid");
67
74
  }
68
75
  const requirement = { id: row.id, version: row.version };
@@ -108,5 +115,7 @@ export {
108
115
  observeSoftwareHost,
109
116
  ensureSoftwareRequirements,
110
117
  SOFTWARE_CATALOG,
111
- OS_CATALOG
118
+ PINNED_BUN_VERSION,
119
+ OS_CATALOG,
120
+ BUN_INSTALLER_SHA256
112
121
  };
@@ -0,0 +1,72 @@
1
+ import type { NodeKeyPair } from '@forgezero/runtime/identity';
2
+ import type { AgentOperationTelemetry } from './telemetry-runtime';
3
+ import { type GitHostResolver } from './git-egress';
4
+ export interface RemoteSshBootstrapClaim {
5
+ computeKey: string;
6
+ computeReference: string;
7
+ claimToken: string;
8
+ claimExpiresAtTs: number;
9
+ attempt: number;
10
+ realm: string;
11
+ projectKey: string;
12
+ environmentKey: string;
13
+ target: {
14
+ host: string;
15
+ port: number;
16
+ user: string;
17
+ hostKeySha256: string;
18
+ nodeHostname: string;
19
+ };
20
+ enrolmentToken: string;
21
+ }
22
+ export interface BootstrapCommandResult {
23
+ exitCode: number;
24
+ output: string;
25
+ }
26
+ export type BootstrapCommand = (argv: readonly string[], options?: {
27
+ stdin?: string;
28
+ secret?: boolean;
29
+ }) => Promise<BootstrapCommandResult>;
30
+ export interface SshBootstrapPullOptions {
31
+ apiUrl: string;
32
+ platformApiUrl: string;
33
+ nodeKey: string;
34
+ keys: NodeKeyPair;
35
+ sshKeyPath: string;
36
+ targetTelemetryEndpoint: string;
37
+ fzCliPath?: string;
38
+ fzAgentPath?: string;
39
+ exec?: BootstrapCommand;
40
+ fetch?: (input: URL, init: RequestInit) => Promise<Response>;
41
+ intervalMs?: number;
42
+ requestTimeoutMs?: number;
43
+ now?: () => number;
44
+ setTimer?: (callback: () => void, ms: number) => unknown;
45
+ clearTimer?: (handle: unknown) => void;
46
+ onEvent?: (event: string, detail?: unknown) => void;
47
+ telemetry?: AgentOperationTelemetry;
48
+ resolveHost?: GitHostResolver;
49
+ }
50
+ export type SshBootstrapResult = {
51
+ status: 'idle';
52
+ } | {
53
+ status: 'completed';
54
+ computeKey: string;
55
+ attempt: number;
56
+ } | {
57
+ status: 'failed';
58
+ computeKey: string;
59
+ attempt: number;
60
+ failureCode: string;
61
+ };
62
+ export declare class SshBootstrapError extends Error {
63
+ readonly code: string;
64
+ constructor(code: string, message?: string);
65
+ }
66
+ /** Execute one job without ever putting the enrolment token or SSH key in argv. */
67
+ export declare function executeSshBootstrap(claim: RemoteSshBootstrapClaim, options: Pick<SshBootstrapPullOptions, 'platformApiUrl' | 'sshKeyPath' | 'targetTelemetryEndpoint' | 'fzCliPath' | 'fzAgentPath' | 'exec' | 'resolveHost'>): Promise<void>;
68
+ export declare function pullSshBootstrapOnce(options: SshBootstrapPullOptions): Promise<SshBootstrapResult>;
69
+ export declare function startSshBootstrapPull(options: SshBootstrapPullOptions): {
70
+ stop(): Promise<void>;
71
+ readonly active: boolean;
72
+ };
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** One package version shared by both public binaries. Pinned to package.json by tests. */
2
- export declare const VERSION = "0.1.35";
2
+ export declare const VERSION = "0.1.37";
package/package.json CHANGED
@@ -1,15 +1,14 @@
1
1
  {
2
2
  "name": "@forgezero/agent",
3
- "version": "0.1.35",
3
+ "version": "0.1.37",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "check": "tsc --noEmit",
7
7
  "prebuild": "rm -rf dist",
8
- "build": "bun build src/index.ts --outfile dist/fz-agent.js --target bun --format esm && bun build src/cli/index.ts --outfile dist/fz.js --target bun --format esm && bun build src/compute.ts src/provision.ts src/subscribe.ts src/pipeline.ts src/definition.ts src/deploy-file.ts src/ssh-server.ts src/ssh-listen.ts src/provisioning-pull.ts src/migration-pull.ts src/guest-enrolment.ts src/node-vault.ts src/metal-provision.ts src/metal-helper-socket.ts src/lifecycle-helper.ts src/deployment-runner.ts src/agent-update.ts src/agent-update-helper.ts src/agent-heartbeat.ts src/software.ts src/software-helper.ts src/ubuntu.ts src/capacity-calibration.ts src/platform-bootstrap-runtime.ts --root src --outdir dist --target browser --format esm --packages external && bun build src/project-context.ts src/bootstrap.ts src/metal-bootstrap.ts src/cloudflare-bootstrap.ts src/cloudflare-edge.ts --root src --outdir dist --target bun --format esm --packages external && tsc --emitDeclarationOnly --declaration --noEmit false --outDir dist",
8
+ "build": "bun build src/index.ts --outfile dist/fz-agent.js --target bun --format esm --external '@forgezero/access' --external '@forgezero/access/*' --external '@forgezero/runtime' --external '@forgezero/runtime/*' --external '@forgezero/vault' --external '@forgezero/vault/*' && bun build src/cli/index.ts --outfile dist/fz.js --target bun --format esm --external '@forgezero/access' --external '@forgezero/access/*' --external '@forgezero/runtime' --external '@forgezero/runtime/*' --external '@forgezero/vault' --external '@forgezero/vault/*' && bun build src/compute.ts src/provision.ts src/subscribe.ts src/pipeline.ts src/definition.ts src/deploy-file.ts src/ssh-server.ts src/ssh-listen.ts src/provisioning-pull.ts src/migration-pull.ts src/guest-enrolment.ts src/node-vault.ts src/metal-provision.ts src/metal-helper-socket.ts src/lifecycle-helper.ts src/deployment-runner.ts src/agent-update.ts src/agent-update-helper.ts src/agent-heartbeat.ts src/software.ts src/software-helper.ts src/ubuntu.ts src/capacity-calibration.ts src/platform-bootstrap-runtime.ts --root src --outdir dist --target browser --format esm --packages external && bun build src/project-context.ts src/bootstrap.ts src/metal-bootstrap.ts src/cloudflare-bootstrap.ts src/cloudflare-edge.ts --root src --outdir dist --target bun --format esm --packages external && tsc --emitDeclarationOnly --declaration --noEmit false --outDir dist",
9
9
  "prepublishOnly": "bun run check && bun run build"
10
10
  },
11
11
  "devDependencies": {
12
- "@forgezero/access": "^0.1.0",
13
12
  "typescript": "^5.6.0",
14
13
  "@types/bun": "latest",
15
14
  "@types/node": "^22.0.0",
@@ -17,6 +16,7 @@
17
16
  "@noble/post-quantum": "^0.6.1"
18
17
  },
19
18
  "dependencies": {
19
+ "@forgezero/access": "0.1.1",
20
20
  "@forgezero/runtime": "0.1.5",
21
21
  "@forgezero/vault": "0.1.8",
22
22
  "@noble/curves": "2.2.0",
@@ -28,7 +28,7 @@
28
28
  "additionalProperties": false,
29
29
  "required": ["id", "version"],
30
30
  "properties": {
31
- "id": { "enum": ["bun", "nginx", "arangodb", "cloudflared", "ufw"] },
31
+ "id": { "enum": ["bun", "nginx", "arangodb", "cloudflared", "ufw", "openssh-client"] },
32
32
  "version": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$" }
33
33
  }
34
34
  }