@forgezero/agent 0.1.76 → 0.1.78

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.
@@ -750,7 +750,7 @@ async function postSignedNode(options, path, body) {
750
750
  }
751
751
 
752
752
  // src/version.ts
753
- var VERSION3 = "0.1.76";
753
+ var VERSION3 = "0.1.78";
754
754
 
755
755
  // src/agent-heartbeat.ts
756
756
  function readAgentHostMetrics() {
package/dist/bootstrap.js CHANGED
@@ -1416,7 +1416,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
1416
1416
  var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
1417
1417
 
1418
1418
  // src/version.ts
1419
- var VERSION = "0.1.76";
1419
+ var VERSION = "0.1.78";
1420
1420
 
1421
1421
  // src/software.ts
1422
1422
  var PINNED_BUN_VERSION = "1.3.14";
package/dist/fz-agent.js CHANGED
@@ -9193,7 +9193,7 @@ async function writeAndCloseProcessInput(input, value) {
9193
9193
  }
9194
9194
 
9195
9195
  // src/version.ts
9196
- var VERSION2 = "0.1.76";
9196
+ var VERSION2 = "0.1.78";
9197
9197
 
9198
9198
  // src/ssh-bootstrap.ts
9199
9199
  class SshBootstrapError extends Error {
@@ -16394,6 +16394,30 @@ async function runSupervisedApp(path2) {
16394
16394
  }
16395
16395
  }
16396
16396
 
16397
+ // src/stdin.ts
16398
+ async function readBoundedStdin(maxBytes) {
16399
+ if (!Number.isSafeInteger(maxBytes) || maxBytes < 1) {
16400
+ throw new Error("stdin byte limit must be a positive safe integer");
16401
+ }
16402
+ if (process.stdin.isTTY)
16403
+ throw new Error("stdin request pipe is required");
16404
+ const reader = Bun.spawn(["/usr/bin/head", "-c", String(maxBytes + 1)], {
16405
+ stdin: "inherit",
16406
+ stdout: "pipe",
16407
+ stderr: "pipe"
16408
+ });
16409
+ const [stdout, stderr, exitCode] = await Promise.all([
16410
+ new Response(reader.stdout).arrayBuffer(),
16411
+ new Response(reader.stderr).text(),
16412
+ reader.exited
16413
+ ]);
16414
+ if (exitCode !== 0)
16415
+ throw new Error(`stdin reader failed (${exitCode}): ${stderr.trim()}`);
16416
+ if (stdout.byteLength > maxBytes)
16417
+ throw new Error(`stdin request exceeds ${maxBytes} bytes`);
16418
+ return Buffer.from(stdout).toString("utf8");
16419
+ }
16420
+
16397
16421
  // src/index.ts
16398
16422
  function agentCommandArgs(args, command3) {
16399
16423
  const index = args.indexOf(command3);
@@ -16892,7 +16916,7 @@ if (import.meta.main) {
16892
16916
  if (claimArg !== "-" && !claimArg.startsWith("/")) {
16893
16917
  throw new Error("metal-apply claim path must be absolute");
16894
16918
  }
16895
- const raw = readFileSync20(claimArg === "-" ? "/dev/stdin" : claimArg, "utf8");
16919
+ const raw = claimArg === "-" ? await readBoundedStdin(32 * 1024) : readFileSync20(claimArg, "utf8");
16896
16920
  if (Buffer.byteLength(raw) > 32 * 1024)
16897
16921
  throw new Error("metal-apply claim exceeds 32 KiB");
16898
16922
  const claim = JSON.parse(raw);
@@ -16917,9 +16941,7 @@ if (import.meta.main) {
16917
16941
  if (commandArgs.length !== 1 || commandArgs[0] !== "--request=-") {
16918
16942
  throw new Error("community-rehearsal requires exactly --request=-");
16919
16943
  }
16920
- const raw = readFileSync20("/dev/stdin", "utf8");
16921
- if (Buffer.byteLength(raw) > 128 * 1024)
16922
- throw new Error("community rehearsal request exceeds 128 KiB");
16944
+ const raw = await readBoundedStdin(128 * 1024);
16923
16945
  const request = parseCommunityRehearsalHostRequest(JSON.parse(raw));
16924
16946
  console.log(JSON.stringify(await runCommunityRehearsalHost(request)));
16925
16947
  process.exit(0);
@@ -16928,9 +16950,7 @@ if (import.meta.main) {
16928
16950
  if (args.length !== 1 || args[0] !== "--request=-") {
16929
16951
  throw new Error("metal-admission-proof requires exactly --request=-");
16930
16952
  }
16931
- const raw = readFileSync20("/dev/stdin", "utf8");
16932
- if (Buffer.byteLength(raw) > 32 * 1024)
16933
- throw new Error("metal admission proof request exceeds 32 KiB");
16953
+ const raw = await readBoundedStdin(32 * 1024);
16934
16954
  const request = JSON.parse(raw);
16935
16955
  if (!/^[A-Za-z0-9_-]{1,64}$/.test(request.jobKey) || !/^[A-Za-z0-9_-]{1,64}$/.test(request.tenantKey) || !/^[A-Za-z0-9_-]{1,64}$/.test(request.projectKey) || !/^[a-z0-9][a-z0-9.-]{1,252}$/.test(request.hostname) || !/^[A-Za-z0-9_-]{32,128}$/.test(request.challenge) || !request.runnerNodeKey || !request.target?.host || !/^SHA256:[A-Za-z0-9+/]{43}$/.test(request.target.hostKeySha256)) {
16936
16956
  throw new Error("metal admission proof request is malformed");
package/dist/fz.js CHANGED
@@ -4837,7 +4837,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
4837
4837
  var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
4838
4838
 
4839
4839
  // src/version.ts
4840
- var VERSION2 = "0.1.76";
4840
+ var VERSION2 = "0.1.78";
4841
4841
 
4842
4842
  // src/software.ts
4843
4843
  var PINNED_BUN_VERSION = "1.3.14";
@@ -354,7 +354,7 @@ function systemdAgentEgressDirectives(loopbackTcpPorts = []) {
354
354
  }
355
355
 
356
356
  // src/version.ts
357
- var VERSION = "0.1.76";
357
+ var VERSION = "0.1.78";
358
358
 
359
359
  // src/otel-collector.ts
360
360
  var FORGEZERO_OTEL_COLLECTOR_UNIT = "forgezero-otel-collector.service";
@@ -1416,7 +1416,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
1416
1416
  var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
1417
1417
 
1418
1418
  // src/version.ts
1419
- var VERSION = "0.1.76";
1419
+ var VERSION = "0.1.78";
1420
1420
 
1421
1421
  // src/software.ts
1422
1422
  var PINNED_BUN_VERSION = "1.3.14";
@@ -2498,7 +2498,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
2498
2498
  }
2499
2499
 
2500
2500
  // src/version.ts
2501
- var VERSION3 = "0.1.76";
2501
+ var VERSION3 = "0.1.78";
2502
2502
 
2503
2503
  // src/egress-policy.ts
2504
2504
  import { realpathSync as realpathSync3 } from "node:fs";
package/dist/provision.js CHANGED
@@ -2498,7 +2498,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
2498
2498
  }
2499
2499
 
2500
2500
  // src/version.ts
2501
- var VERSION3 = "0.1.76";
2501
+ var VERSION3 = "0.1.78";
2502
2502
 
2503
2503
  // src/egress-policy.ts
2504
2504
  import { realpathSync as realpathSync3 } from "node:fs";
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Read one bounded request from stdin without using a synchronous `/dev/stdin`
3
+ * read. Bun can busy-loop while reading fd 0 from an SSH channel, both through
4
+ * synchronous fs calls and its JavaScript stream adapters. A fixed native
5
+ * `head` process owns that descriptor and returns at most limit + 1 bytes, so
6
+ * Bun handles only an already-bounded child stdout stream.
7
+ */
8
+ export declare function readBoundedStdin(maxBytes: number): Promise<string>;
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.76";
2
+ export declare const VERSION = "0.1.78";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgezero/agent",
3
- "version": "0.1.76",
3
+ "version": "0.1.78",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "check": "tsc --noEmit",