@forgezero/agent 0.1.56 → 0.1.57

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.
@@ -749,7 +749,7 @@ async function postSignedNode(options, path, body) {
749
749
  }
750
750
 
751
751
  // src/version.ts
752
- var VERSION3 = "0.1.56";
752
+ var VERSION3 = "0.1.57";
753
753
 
754
754
  // src/agent-heartbeat.ts
755
755
  var unquote = (value) => value.replace(/^['"]|['"]$/g, "");
package/dist/bootstrap.js CHANGED
@@ -1207,7 +1207,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
1207
1207
  var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
1208
1208
 
1209
1209
  // src/version.ts
1210
- var VERSION = "0.1.56";
1210
+ var VERSION = "0.1.57";
1211
1211
 
1212
1212
  // src/software.ts
1213
1213
  var PINNED_BUN_VERSION = "1.3.14";
@@ -1,4 +1,11 @@
1
- import { finalizeCloudflareBootstrapAcceptance, verifyCloudflareBootstrapAcceptance, type AttendedCloudflareBootstrapRequest, type CloudflareBootstrapEvidence, type CloudflareBootstrapAcceptanceEvidence, type CloudflareBootstrapFinalizeRequest, type CloudflareBootstrapPhaseRunner } from '../cloudflare-bootstrap';
1
+ import { finalizeCloudflareBootstrapAcceptance, verifyCloudflareBootstrapAcceptance, type AttendedCloudflareBootstrapRequest, type CloudflareBootstrapEvidence, type CloudflareBootstrapAcceptanceEvidence, type CloudflareBootstrapFinalizeRequest, type CloudflareBootstrapPhaseRunner, type CloudflareBootstrapTokenFiles } from '../cloudflare-bootstrap';
2
+ export interface CloudflareBootstrapCommandConfig {
3
+ format: 1;
4
+ kind: 'forgezero-cloudflare-bootstrap-request';
5
+ checkpointPath: string;
6
+ coordinates: AttendedCloudflareBootstrapRequest['coordinates'];
7
+ tokenFiles: CloudflareBootstrapTokenFiles;
8
+ }
2
9
  export interface CloudflareBootstrapCommandDependencies {
3
10
  run?: CloudflareBootstrapPhaseRunner;
4
11
  write?: (text: string) => void;
@@ -9,6 +16,15 @@ export interface CloudflareBootstrapFinalizeConfig {
9
16
  checkpointPath: string;
10
17
  acceptancePath: string;
11
18
  }
19
+ /**
20
+ * Construct the exact reviewed JSON shape used by both the interactive CLI and
21
+ * the strict file reader. Token values are deliberately not accepted here.
22
+ */
23
+ export declare function createCloudflareBootstrapCommandConfig(input: {
24
+ checkpointPath: string;
25
+ coordinates: AttendedCloudflareBootstrapRequest['coordinates'];
26
+ tokenFiles: CloudflareBootstrapTokenFiles;
27
+ }): CloudflareBootstrapCommandConfig;
12
28
  /**
13
29
  * Read reviewed non-secret coordinates and token-file paths for the attended
14
30
  * operator phase. Raw token values and a persisted mode are not schema fields.
package/dist/fz-agent.js CHANGED
@@ -8448,7 +8448,7 @@ function assertSupportedGuestImage(imageKey) {
8448
8448
  }
8449
8449
 
8450
8450
  // src/version.ts
8451
- var VERSION2 = "0.1.56";
8451
+ var VERSION2 = "0.1.57";
8452
8452
 
8453
8453
  // src/ssh-bootstrap.ts
8454
8454
  class SshBootstrapError extends Error {
package/dist/fz.js CHANGED
@@ -4830,7 +4830,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
4830
4830
  var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
4831
4831
 
4832
4832
  // src/version.ts
4833
- var VERSION2 = "0.1.56";
4833
+ var VERSION2 = "0.1.57";
4834
4834
 
4835
4835
  // src/software.ts
4836
4836
  var PINNED_BUN_VERSION = "1.3.14";
@@ -14347,6 +14347,26 @@ var record2 = (value, label) => {
14347
14347
  throw new Error(`${label} must be an object`);
14348
14348
  return value;
14349
14349
  };
14350
+ function createCloudflareBootstrapCommandConfig(input) {
14351
+ if (typeof input.checkpointPath !== "string" || !input.checkpointPath.trim()) {
14352
+ throw new Error("Cloudflare bootstrap checkpointPath is required");
14353
+ }
14354
+ for (const key of ["tunnelTokenFile", "apiTokenFile"]) {
14355
+ if (typeof input.tokenFiles?.[key] !== "string" || !input.tokenFiles[key].trim()) {
14356
+ throw new Error(`Cloudflare bootstrap tokenFiles.${key} is required and must be a non-empty file path`);
14357
+ }
14358
+ }
14359
+ return {
14360
+ format: 1,
14361
+ kind: "forgezero-cloudflare-bootstrap-request",
14362
+ checkpointPath: input.checkpointPath.trim(),
14363
+ coordinates: validateCloudflareBootstrapCoordinates(input.coordinates),
14364
+ tokenFiles: {
14365
+ tunnelTokenFile: input.tokenFiles.tunnelTokenFile.trim(),
14366
+ apiTokenFile: input.tokenFiles.apiTokenFile.trim()
14367
+ }
14368
+ };
14369
+ }
14350
14370
  function readOwnerConfig(path) {
14351
14371
  const absolute2 = resolve6(path);
14352
14372
  let descriptor;
@@ -17118,6 +17138,55 @@ function writeBootstrapConfig(path, config) {
17118
17138
  `, { mode: 384, flag: "wx" });
17119
17139
  return path;
17120
17140
  }
17141
+ function interactiveCloudflareBootstrap() {
17142
+ if (!process.stdin.isTTY)
17143
+ throw new Error("interactive Cloudflare config generation requires a terminal");
17144
+ const nodeCount = bootstrapNumber("Number of public API nodes", "3");
17145
+ if (nodeCount < 1 || nodeCount > 32)
17146
+ throw new Error("Number of public API nodes must be between 1 and 32");
17147
+ const realtimeEnabled = bootstrapAnswer("Configure existing Worker realtime fan-out? (yes/no)", "yes") === "yes";
17148
+ const meshEnabled = bootstrapAnswer("Configure private Mesh/WARP routes? (yes/no)", "no") === "yes";
17149
+ const meshDevicePolicyId = meshEnabled ? bootstrapAnswer("Existing Mesh device policy id") : undefined;
17150
+ const nodes = Array.from({ length: nodeCount }, (_, index) => {
17151
+ const ordinal = index + 1;
17152
+ const nodeName = bootstrapAnswer(`Node ${ordinal} inventory name`);
17153
+ const nodeMesh = meshEnabled && bootstrapAnswer(`Configure Mesh routes for ${nodeName}? (yes/no)`, "yes") === "yes";
17154
+ return {
17155
+ nodeName,
17156
+ hostname: bootstrapAnswer(`${nodeName} public hostname`),
17157
+ service: bootstrapAnswer(`${nodeName} loopback API service`, "http://127.0.0.1:3000"),
17158
+ tunnelName: bootstrapAnswer(`${nodeName} Tunnel name`, nodeName),
17159
+ ...nodeMesh ? {
17160
+ mesh: {
17161
+ connectorName: bootstrapAnswer(`${nodeName} Mesh connector name`, `${nodeName}-mesh`),
17162
+ routes: bootstrapList(`${nodeName} private CIDR routes`),
17163
+ highAvailability: bootstrapAnswer(`${nodeName} shares a highly available Mesh connector? (yes/no)`, "no") === "yes"
17164
+ }
17165
+ } : {}
17166
+ };
17167
+ });
17168
+ return createCloudflareBootstrapCommandConfig({
17169
+ checkpointPath: bootstrapAnswer("Owner-only resumable checkpoint path", "./cloudflare-handoff.json"),
17170
+ coordinates: {
17171
+ accountId: bootstrapAnswer("Cloudflare account id"),
17172
+ zoneId: bootstrapAnswer("Cloudflare zone id"),
17173
+ kvNamespaceId: bootstrapAnswer("Existing Worker-bound KV namespace id"),
17174
+ ...meshDevicePolicyId ? { meshDevicePolicyId } : {},
17175
+ ...realtimeEnabled ? {
17176
+ realtime: {
17177
+ workerScriptName: bootstrapAnswer("Existing Worker script name"),
17178
+ endpoint: bootstrapAnswer("Stable public Worker HTTPS endpoint"),
17179
+ producer: bootstrapAnswer("Realtime producer identity", "platform-api")
17180
+ }
17181
+ } : {},
17182
+ nodes
17183
+ },
17184
+ tokenFiles: {
17185
+ tunnelTokenFile: bootstrapAnswer("Owner-only CF_TUNNEL_TOKEN file", "./CF_TUNNEL_TOKEN"),
17186
+ apiTokenFile: bootstrapAnswer("Owner-only CF_API_TOKEN file", "./CF_API_TOKEN")
17187
+ }
17188
+ });
17189
+ }
17121
17190
  function genesisOutputDirectory(path) {
17122
17191
  if (!isAbsolute5(path) || resolve9(path) !== path)
17123
17192
  throw new Error("--output must be a canonical absolute directory");
@@ -17290,13 +17359,19 @@ async function cmdBootstrap(options, args) {
17290
17359
  const operation = args[0] ?? "status";
17291
17360
  if (operation === "config") {
17292
17361
  const kind = args[1];
17293
- if (kind !== "metal" && kind !== "platform" || args[2] !== undefined || !options.outputPath) {
17294
- throw new Error("Usage: fz bootstrap config metal --output <absolute-file> | fz bootstrap config platform --output <absolute-owner-only-directory>");
17362
+ if (kind !== "metal" && kind !== "platform" && kind !== "cloudflare" || args[2] !== undefined || !options.outputPath) {
17363
+ throw new Error("Usage: fz bootstrap config metal|cloudflare --output <absolute-file> | fz bootstrap config platform --output <absolute-owner-only-directory>");
17295
17364
  }
17296
17365
  if (kind === "platform") {
17297
17366
  out.line(JSON.stringify({ kind, ...writePlatformGenesisFleet(options.outputPath), mode: "0600" }, null, 2));
17298
17367
  return 0;
17299
17368
  }
17369
+ if (kind === "cloudflare") {
17370
+ const path = writeBootstrapConfig(options.outputPath, interactiveCloudflareBootstrap());
17371
+ readCloudflareBootstrapCommandConfig(path, "plan");
17372
+ out.line(JSON.stringify({ kind, path, mode: "0600" }, null, 2));
17373
+ return 0;
17374
+ }
17300
17375
  const config2 = interactiveMetalBootstrap();
17301
17376
  out.line(JSON.stringify({ kind, path: writeBootstrapConfig(options.outputPath, config2), mode: "0600" }, null, 2));
17302
17377
  return 0;
@@ -17432,7 +17507,7 @@ async function cmdBootstrap(options, args) {
17432
17507
  return 0;
17433
17508
  }
17434
17509
  if (!["platform", "repair"].includes(operation)) {
17435
- throw new Error("Usage: fz bootstrap config <metal|platform>|platform [prepare|remote <prepare|apply|status>|cloudflare [verify|finalize]]|metal [remote <apply|genesis|status>]|status|repair [--bootstrap-config <path>] [--apply]");
17510
+ throw new Error("Usage: fz bootstrap config <metal|platform|cloudflare>|platform [prepare|remote <prepare|apply|status>|cloudflare [verify|finalize]]|metal [remote <apply|genesis|rehearsal|status>]|status|repair [--bootstrap-config <path>] [--apply]");
17436
17511
  }
17437
17512
  const config = options.bootstrapConfigPath ? readBootstrapConfig(options.bootstrapConfigPath) : operation === "repair" ? (() => {
17438
17513
  throw new Error("repair requires --bootstrap-config so immutable coordinates are revalidated");
@@ -17997,9 +18072,9 @@ function usage() {
17997
18072
  Run typed bootstrap from the operator laptop through
17998
18073
  a pinned host and caller-approved SSH agent
17999
18074
  fz bootstrap platform Install/repair a typed elastic platform compute
18000
- fz bootstrap config <metal|platform>
18001
- Write a validated owner-only metal file or strict
18002
- three-node platform genesis directory; never apply locally
18075
+ fz bootstrap config <metal|platform|cloudflare>
18076
+ Write a validated owner-only metal/Cloudflare file or
18077
+ strict three-node platform genesis directory; never apply locally
18003
18078
  fz bootstrap platform cloudflare
18004
18079
  Plan/apply attended Tunnel and DNS reconciliation
18005
18080
  using supplied management and KV/Worker runtime token files
@@ -292,7 +292,7 @@ function systemdAgentEgressDirectives(loopbackTcpPorts = []) {
292
292
  }
293
293
 
294
294
  // src/version.ts
295
- var VERSION = "0.1.56";
295
+ var VERSION = "0.1.57";
296
296
 
297
297
  // src/otel-collector.ts
298
298
  var FORGEZERO_OTEL_COLLECTOR_UNIT = "forgezero-otel-collector.service";
@@ -1207,7 +1207,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
1207
1207
  var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
1208
1208
 
1209
1209
  // src/version.ts
1210
- var VERSION = "0.1.56";
1210
+ var VERSION = "0.1.57";
1211
1211
 
1212
1212
  // src/software.ts
1213
1213
  var PINNED_BUN_VERSION = "1.3.14";
@@ -2086,7 +2086,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
2086
2086
  }
2087
2087
 
2088
2088
  // src/version.ts
2089
- var VERSION3 = "0.1.56";
2089
+ var VERSION3 = "0.1.57";
2090
2090
 
2091
2091
  // src/egress-policy.ts
2092
2092
  import { realpathSync as realpathSync3 } from "node:fs";
package/dist/provision.js CHANGED
@@ -2086,7 +2086,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
2086
2086
  }
2087
2087
 
2088
2088
  // src/version.ts
2089
- var VERSION3 = "0.1.56";
2089
+ var VERSION3 = "0.1.57";
2090
2090
 
2091
2091
  // src/egress-policy.ts
2092
2092
  import { realpathSync as realpathSync3 } from "node:fs";
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.56";
2
+ export declare const VERSION = "0.1.57";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgezero/agent",
3
- "version": "0.1.56",
3
+ "version": "0.1.57",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "check": "tsc --noEmit",