@forgezero/agent 0.1.121 → 0.1.123

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.
@@ -917,7 +917,7 @@ async function postSignedNode(options, path, body) {
917
917
  }
918
918
 
919
919
  // src/version.ts
920
- var VERSION3 = "0.1.121";
920
+ var VERSION3 = "0.1.123";
921
921
 
922
922
  // src/agent-heartbeat.ts
923
923
  function readAgentHostMetrics() {
package/dist/bootstrap.js CHANGED
@@ -1460,7 +1460,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
1460
1460
  var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
1461
1461
 
1462
1462
  // src/version.ts
1463
- var VERSION = "0.1.121";
1463
+ var VERSION = "0.1.123";
1464
1464
 
1465
1465
  // src/software.ts
1466
1466
  var PINNED_BUN_VERSION = "1.3.14";
@@ -6,6 +6,11 @@ export type RepositoryOperation = 'dev-reset' | 'db-backup' | 'db-recover' | 'db
6
6
  * error instead of a silently ignored mutation bypass such as --force.
7
7
  */
8
8
  export declare function unsupportedRepositoryCliOption(argv: readonly string[]): string | undefined;
9
+ export declare function forwardedRepositoryOperationArguments(options: {
10
+ apply: boolean;
11
+ json: boolean;
12
+ disposableFleetConfirmation?: string;
13
+ }, args: readonly string[]): string[];
9
14
  export interface ResolvedRepositoryOperation {
10
15
  operation: RepositoryOperation;
11
16
  root: string;
@@ -4,6 +4,11 @@ export declare const COMMUNITY_REHEARSAL_ROOT = "/opt/forgezero-rehearsals/commu
4
4
  export declare const COMMUNITY_DATABASE_ROOT = "/var/lib/forgezero-rehearsal-cluster";
5
5
  export declare const COMMUNITY_CREDENTIAL_PARENT = "/etc/forgezero-rehearsal";
6
6
  export declare const COMMUNITY_CREDENTIAL_ROOT = "/etc/forgezero-rehearsal/creds";
7
+ export declare const COMMUNITY_REHEARSAL_STARTER_PORT = 18528;
8
+ export declare const COMMUNITY_REHEARSAL_COORDINATOR_PORT = 18529;
9
+ export declare const COMMUNITY_REHEARSAL_DATABASE_PORT_RANGE = "18528:18539";
10
+ export declare const COMMUNITY_REHEARSAL_API_PORT = 18787;
11
+ export declare const COMMUNITY_REHEARSAL_FIREWALL_COMMENT = "fz-community-rehearsal";
7
12
  export interface CommunityRehearsalNode {
8
13
  name: string;
9
14
  address: string;
@@ -41,6 +46,8 @@ export type CommunityRehearsalHostRequest = {
41
46
  export type CommunityHostOperation = {
42
47
  kind: 'remove-tree';
43
48
  path: typeof COMMUNITY_DATABASE_ROOT | typeof COMMUNITY_REHEARSAL_ROOT | typeof COMMUNITY_CREDENTIAL_PARENT;
49
+ } | {
50
+ kind: 'clear-firewall';
44
51
  } | {
45
52
  kind: 'write';
46
53
  path: string;
@@ -67,5 +74,6 @@ export declare function planCommunityRehearsalPrepare(request: Extract<Community
67
74
  }>): CommunityHostOperation[];
68
75
  /** Remove only the dedicated rehearsal units, credentials, release and data. */
69
76
  export declare function planCommunityRehearsalCleanup(): CommunityHostOperation[];
77
+ export declare function communityRehearsalFirewallRuleNumbers(status: string): number[];
70
78
  /** Execute only the dedicated four-node rehearsal operation selected by a typed request. */
71
79
  export declare function runCommunityRehearsalHost(request: CommunityRehearsalHostRequest): Promise<Record<string, unknown>>;
@@ -572,6 +572,11 @@ var COMMUNITY_REHEARSAL_ROOT = "/opt/forgezero-rehearsals/community-cluster-api"
572
572
  var COMMUNITY_DATABASE_ROOT = "/var/lib/forgezero-rehearsal-cluster";
573
573
  var COMMUNITY_CREDENTIAL_PARENT = "/etc/forgezero-rehearsal";
574
574
  var COMMUNITY_CREDENTIAL_ROOT = "/etc/forgezero-rehearsal/creds";
575
+ var COMMUNITY_REHEARSAL_STARTER_PORT = 18528;
576
+ var COMMUNITY_REHEARSAL_COORDINATOR_PORT = 18529;
577
+ var COMMUNITY_REHEARSAL_DATABASE_PORT_RANGE = "18528:18539";
578
+ var COMMUNITY_REHEARSAL_API_PORT = 18787;
579
+ var COMMUNITY_REHEARSAL_FIREWALL_COMMENT = "fz-community-rehearsal";
575
580
  var RELEASE = /^[a-f0-9]{64}$/;
576
581
  var SAFE_NAME = /^[a-z][a-z0-9-]{0,62}$/;
577
582
  async function ensureCommunityRehearsalArango(execute = executeSoftwareOperation) {
@@ -651,7 +656,7 @@ function parseCommunityRehearsalHostRequest(value) {
651
656
  }
652
657
  var databaseUnit = (node, topology) => {
653
658
  const starter = topology.find((entry) => entry.starter);
654
- const join2 = node.starter ? "" : ` --starter.join=${starter.address}`;
659
+ const join2 = node.starter ? "" : ` --starter.join=${starter.address}:${COMMUNITY_REHEARSAL_STARTER_PORT}`;
655
660
  const role = node.agency ? "" : " --cluster.start-agent=false --cluster.start-coordinator=true --cluster.start-dbserver=true";
656
661
  return `[Unit]
657
662
  Description=ForgeZero isolated Community ${COMMUNITY_REHEARSAL_VERSION} rehearsal cluster
@@ -663,7 +668,7 @@ Type=simple
663
668
  User=arangodb
664
669
  Group=arangodb
665
670
  LoadCredentialEncrypted=arangodb-jwt:${COMMUNITY_CREDENTIAL_ROOT}/arangodb-jwt.cred
666
- ExecStart=/usr/bin/arangodb --starter.mode=cluster --starter.address=${node.address} --starter.host=${node.address} --starter.data-dir=${COMMUNITY_DATABASE_ROOT} --starter.disable-ipv6 --auth.jwt-secret=%d/arangodb-jwt${join2}${role}
671
+ ExecStart=/usr/bin/arangodb --starter.mode=cluster --starter.address=${node.address} --starter.host=${node.address} --starter.port=${COMMUNITY_REHEARSAL_STARTER_PORT} --starter.data-dir=${COMMUNITY_DATABASE_ROOT} --starter.disable-ipv6 --auth.jwt-secret=%d/arangodb-jwt${join2}${role}
667
672
  Restart=always
668
673
  RestartSec=5
669
674
  LimitNOFILE=100000
@@ -687,8 +692,8 @@ WantedBy=multi-user.target
687
692
  `;
688
693
  };
689
694
  var apiUnit = (node, topology) => {
690
- const urls = topology.map(({ address }) => `http://${address}:8529`).join(",");
691
- const readPreferred = topology.filter(({ readPreferred: readPreferred2 }) => readPreferred2).map(({ address }) => `http://${address}:8529`).join(",");
695
+ const urls = topology.map(({ address }) => `http://${address}:${COMMUNITY_REHEARSAL_COORDINATOR_PORT}`).join(",");
696
+ const readPreferred = topology.filter(({ readPreferred: readPreferred2 }) => readPreferred2).map(({ address }) => `http://${address}:${COMMUNITY_REHEARSAL_COORDINATOR_PORT}`).join(",");
692
697
  return `[Unit]
693
698
  Description=ForgeZero typed Community cluster rehearsal API
694
699
  After=forgezero-rehearsal-db.service network-online.target
@@ -701,9 +706,9 @@ Group=forgezero
701
706
  WorkingDirectory=${COMMUNITY_REHEARSAL_ROOT}/current
702
707
  LoadCredentialEncrypted=arangodb-jwt:${COMMUNITY_CREDENTIAL_ROOT}/arangodb-jwt.cred
703
708
  Environment=HOST=127.0.0.1
704
- Environment=PORT=8787
709
+ Environment=PORT=${COMMUNITY_REHEARSAL_API_PORT}
705
710
  Environment=NODE_NAME=${node.name}
706
- Environment=ARANGO_URL=http://127.0.0.1:8529
711
+ Environment=ARANGO_URL=http://127.0.0.1:${COMMUNITY_REHEARSAL_COORDINATOR_PORT}
707
712
  Environment=ARANGO_URLS=${urls}
708
713
  Environment=ARANGO_READ_PREFERRED_URLS=${readPreferred}
709
714
  Environment=ARANGO_READ_PREFERRED_FALLBACK=error
@@ -734,6 +739,24 @@ function planCommunityRehearsalPrepare(request) {
734
739
  { kind: "exec", argv: ["/usr/sbin/arangod", "--version"] },
735
740
  { kind: "exec", argv: ["/usr/bin/systemctl", "stop", "forgezero-community-api.service"], accepted: [0, 5] },
736
741
  { kind: "exec", argv: ["/usr/bin/systemctl", "stop", "forgezero-rehearsal-db.service"], accepted: [0, 5] },
742
+ { kind: "clear-firewall" },
743
+ ...topology.map(({ address }) => ({
744
+ kind: "exec",
745
+ argv: [
746
+ "/usr/sbin/ufw",
747
+ "allow",
748
+ "from",
749
+ address,
750
+ "to",
751
+ "any",
752
+ "port",
753
+ COMMUNITY_REHEARSAL_DATABASE_PORT_RANGE,
754
+ "proto",
755
+ "tcp",
756
+ "comment",
757
+ COMMUNITY_REHEARSAL_FIREWALL_COMMENT
758
+ ]
759
+ })),
737
760
  { kind: "remove-tree", path: COMMUNITY_DATABASE_ROOT },
738
761
  { kind: "exec", argv: ["/usr/bin/install", "-d", "-m", "0700", "-o", "root", "-g", "root", COMMUNITY_CREDENTIAL_ROOT] },
739
762
  { kind: "exec", argv: ["/usr/bin/install", "-d", "-m", "0700", "-o", "arangodb", "-g", "arangodb", COMMUNITY_DATABASE_ROOT] },
@@ -762,6 +785,7 @@ function planCommunityRehearsalCleanup() {
762
785
  { kind: "remove-tree", path: COMMUNITY_DATABASE_ROOT },
763
786
  { kind: "remove-tree", path: COMMUNITY_REHEARSAL_ROOT },
764
787
  { kind: "remove-tree", path: COMMUNITY_CREDENTIAL_PARENT },
788
+ { kind: "clear-firewall" },
765
789
  { kind: "exec", argv: ["/usr/bin/systemctl", "daemon-reload"] },
766
790
  { kind: "exec", argv: ["/usr/bin/systemctl", "reset-failed", "forgezero-community-api.service", "forgezero-rehearsal-db.service"], accepted: [0, 1, 5] }
767
791
  ];
@@ -781,6 +805,8 @@ async function applyOperations(operations) {
781
805
  for (const operation of operations) {
782
806
  if (operation.kind === "remove-tree")
783
807
  rmSync2(operation.path, { recursive: true, force: true });
808
+ else if (operation.kind === "clear-firewall")
809
+ await clearCommunityRehearsalFirewall();
784
810
  else if (operation.kind === "write") {
785
811
  mkdirSync2(dirname2(operation.path), { recursive: true });
786
812
  writeFileSync2(operation.path, operation.content, { mode: operation.mode });
@@ -803,8 +829,27 @@ async function applyOperations(operations) {
803
829
  }
804
830
  }
805
831
  }
832
+ function communityRehearsalFirewallRuleNumbers(status) {
833
+ return status.split(/\r?\n/).flatMap((line) => {
834
+ if (!line.includes(`# ${COMMUNITY_REHEARSAL_FIREWALL_COMMENT}`))
835
+ return [];
836
+ const match = line.match(/^\[\s*(\d+)\]/);
837
+ return match ? [Number(match[1])] : [];
838
+ }).filter((number) => Number.isSafeInteger(number) && number > 0).sort((left, right) => right - left);
839
+ }
840
+ async function clearCommunityRehearsalFirewall() {
841
+ const status = await exec(["/usr/sbin/ufw", "status", "numbered"]);
842
+ if (status.exitCode !== 0)
843
+ throw new Error(`unable to inspect rehearsal firewall rules: ${status.output.trim()}`);
844
+ for (const number of communityRehearsalFirewallRuleNumbers(status.output)) {
845
+ const removed = await exec(["/usr/sbin/ufw", "--force", "delete", String(number)]);
846
+ if (removed.exitCode !== 0) {
847
+ throw new Error(`unable to remove rehearsal firewall rule ${number}: ${removed.output.trim()}`);
848
+ }
849
+ }
850
+ }
806
851
  var responseFor = async (request) => {
807
- const base = "http://127.0.0.1:8787";
852
+ const base = `http://127.0.0.1:${COMMUNITY_REHEARSAL_API_PORT}`;
808
853
  if (request.operation === "health")
809
854
  return fetch(`${base}/health`, { signal: AbortSignal.timeout(15000) });
810
855
  if (request.operation === "init")
@@ -866,7 +911,7 @@ async function runCommunityRehearsalHost(request) {
866
911
  }
867
912
  if (request.action === "database-ready" || request.action === "starter-ready" || request.action === "api-ready") {
868
913
  const starter = topology.find((entry) => entry.starter);
869
- const url = request.action === "database-ready" ? "http://127.0.0.1:8529/_api/version" : request.action === "starter-ready" ? `http://${starter.address}:8528/version` : "http://127.0.0.1:8787/health";
914
+ const url = request.action === "database-ready" ? `http://127.0.0.1:${COMMUNITY_REHEARSAL_COORDINATOR_PORT}/_api/version` : request.action === "starter-ready" ? `http://${starter.address}:${COMMUNITY_REHEARSAL_STARTER_PORT}/version` : `http://127.0.0.1:${COMMUNITY_REHEARSAL_API_PORT}/health`;
870
915
  const response2 = await fetch(url, { signal: AbortSignal.timeout(2000) }).catch(() => {
871
916
  return;
872
917
  });
@@ -889,8 +934,14 @@ export {
889
934
  planCommunityRehearsalCleanup,
890
935
  parseCommunityRehearsalHostRequest,
891
936
  ensureCommunityRehearsalArango,
937
+ communityRehearsalFirewallRuleNumbers,
892
938
  COMMUNITY_REHEARSAL_VERSION,
939
+ COMMUNITY_REHEARSAL_STARTER_PORT,
893
940
  COMMUNITY_REHEARSAL_ROOT,
941
+ COMMUNITY_REHEARSAL_FIREWALL_COMMENT,
942
+ COMMUNITY_REHEARSAL_DATABASE_PORT_RANGE,
943
+ COMMUNITY_REHEARSAL_COORDINATOR_PORT,
944
+ COMMUNITY_REHEARSAL_API_PORT,
894
945
  COMMUNITY_DATABASE_ROOT,
895
946
  COMMUNITY_CREDENTIAL_ROOT,
896
947
  COMMUNITY_CREDENTIAL_PARENT
package/dist/fz-agent.js CHANGED
@@ -9640,7 +9640,7 @@ async function writeAndCloseProcessInput(input, value) {
9640
9640
  }
9641
9641
 
9642
9642
  // src/version.ts
9643
- var VERSION2 = "0.1.121";
9643
+ var VERSION2 = "0.1.123";
9644
9644
 
9645
9645
  // src/ssh-bootstrap.ts
9646
9646
  class SshBootstrapError extends Error {
@@ -17120,6 +17120,11 @@ var COMMUNITY_REHEARSAL_ROOT = "/opt/forgezero-rehearsals/community-cluster-api"
17120
17120
  var COMMUNITY_DATABASE_ROOT = "/var/lib/forgezero-rehearsal-cluster";
17121
17121
  var COMMUNITY_CREDENTIAL_PARENT = "/etc/forgezero-rehearsal";
17122
17122
  var COMMUNITY_CREDENTIAL_ROOT = "/etc/forgezero-rehearsal/creds";
17123
+ var COMMUNITY_REHEARSAL_STARTER_PORT = 18528;
17124
+ var COMMUNITY_REHEARSAL_COORDINATOR_PORT = 18529;
17125
+ var COMMUNITY_REHEARSAL_DATABASE_PORT_RANGE = "18528:18539";
17126
+ var COMMUNITY_REHEARSAL_API_PORT = 18787;
17127
+ var COMMUNITY_REHEARSAL_FIREWALL_COMMENT = "fz-community-rehearsal";
17123
17128
  var RELEASE = /^[a-f0-9]{64}$/;
17124
17129
  var SAFE_NAME2 = /^[a-z][a-z0-9-]{0,62}$/;
17125
17130
  async function ensureCommunityRehearsalArango(execute3 = executeSoftwareOperation) {
@@ -17199,7 +17204,7 @@ function parseCommunityRehearsalHostRequest(value) {
17199
17204
  }
17200
17205
  var databaseUnit = (node, topology) => {
17201
17206
  const starter = topology.find((entry) => entry.starter);
17202
- const join12 = node.starter ? "" : ` --starter.join=${starter.address}`;
17207
+ const join12 = node.starter ? "" : ` --starter.join=${starter.address}:${COMMUNITY_REHEARSAL_STARTER_PORT}`;
17203
17208
  const role = node.agency ? "" : " --cluster.start-agent=false --cluster.start-coordinator=true --cluster.start-dbserver=true";
17204
17209
  return `[Unit]
17205
17210
  Description=ForgeZero isolated Community ${COMMUNITY_REHEARSAL_VERSION} rehearsal cluster
@@ -17211,7 +17216,7 @@ Type=simple
17211
17216
  User=arangodb
17212
17217
  Group=arangodb
17213
17218
  LoadCredentialEncrypted=arangodb-jwt:${COMMUNITY_CREDENTIAL_ROOT}/arangodb-jwt.cred
17214
- ExecStart=/usr/bin/arangodb --starter.mode=cluster --starter.address=${node.address} --starter.host=${node.address} --starter.data-dir=${COMMUNITY_DATABASE_ROOT} --starter.disable-ipv6 --auth.jwt-secret=%d/arangodb-jwt${join12}${role}
17219
+ ExecStart=/usr/bin/arangodb --starter.mode=cluster --starter.address=${node.address} --starter.host=${node.address} --starter.port=${COMMUNITY_REHEARSAL_STARTER_PORT} --starter.data-dir=${COMMUNITY_DATABASE_ROOT} --starter.disable-ipv6 --auth.jwt-secret=%d/arangodb-jwt${join12}${role}
17215
17220
  Restart=always
17216
17221
  RestartSec=5
17217
17222
  LimitNOFILE=100000
@@ -17235,8 +17240,8 @@ WantedBy=multi-user.target
17235
17240
  `;
17236
17241
  };
17237
17242
  var apiUnit = (node, topology) => {
17238
- const urls = topology.map(({ address }) => `http://${address}:8529`).join(",");
17239
- const readPreferred = topology.filter(({ readPreferred: readPreferred2 }) => readPreferred2).map(({ address }) => `http://${address}:8529`).join(",");
17243
+ const urls = topology.map(({ address }) => `http://${address}:${COMMUNITY_REHEARSAL_COORDINATOR_PORT}`).join(",");
17244
+ const readPreferred = topology.filter(({ readPreferred: readPreferred2 }) => readPreferred2).map(({ address }) => `http://${address}:${COMMUNITY_REHEARSAL_COORDINATOR_PORT}`).join(",");
17240
17245
  return `[Unit]
17241
17246
  Description=ForgeZero typed Community cluster rehearsal API
17242
17247
  After=forgezero-rehearsal-db.service network-online.target
@@ -17249,9 +17254,9 @@ Group=forgezero
17249
17254
  WorkingDirectory=${COMMUNITY_REHEARSAL_ROOT}/current
17250
17255
  LoadCredentialEncrypted=arangodb-jwt:${COMMUNITY_CREDENTIAL_ROOT}/arangodb-jwt.cred
17251
17256
  Environment=HOST=127.0.0.1
17252
- Environment=PORT=8787
17257
+ Environment=PORT=${COMMUNITY_REHEARSAL_API_PORT}
17253
17258
  Environment=NODE_NAME=${node.name}
17254
- Environment=ARANGO_URL=http://127.0.0.1:8529
17259
+ Environment=ARANGO_URL=http://127.0.0.1:${COMMUNITY_REHEARSAL_COORDINATOR_PORT}
17255
17260
  Environment=ARANGO_URLS=${urls}
17256
17261
  Environment=ARANGO_READ_PREFERRED_URLS=${readPreferred}
17257
17262
  Environment=ARANGO_READ_PREFERRED_FALLBACK=error
@@ -17282,6 +17287,24 @@ function planCommunityRehearsalPrepare(request) {
17282
17287
  { kind: "exec", argv: ["/usr/sbin/arangod", "--version"] },
17283
17288
  { kind: "exec", argv: ["/usr/bin/systemctl", "stop", "forgezero-community-api.service"], accepted: [0, 5] },
17284
17289
  { kind: "exec", argv: ["/usr/bin/systemctl", "stop", "forgezero-rehearsal-db.service"], accepted: [0, 5] },
17290
+ { kind: "clear-firewall" },
17291
+ ...topology.map(({ address }) => ({
17292
+ kind: "exec",
17293
+ argv: [
17294
+ "/usr/sbin/ufw",
17295
+ "allow",
17296
+ "from",
17297
+ address,
17298
+ "to",
17299
+ "any",
17300
+ "port",
17301
+ COMMUNITY_REHEARSAL_DATABASE_PORT_RANGE,
17302
+ "proto",
17303
+ "tcp",
17304
+ "comment",
17305
+ COMMUNITY_REHEARSAL_FIREWALL_COMMENT
17306
+ ]
17307
+ })),
17285
17308
  { kind: "remove-tree", path: COMMUNITY_DATABASE_ROOT },
17286
17309
  { kind: "exec", argv: ["/usr/bin/install", "-d", "-m", "0700", "-o", "root", "-g", "root", COMMUNITY_CREDENTIAL_ROOT] },
17287
17310
  { kind: "exec", argv: ["/usr/bin/install", "-d", "-m", "0700", "-o", "arangodb", "-g", "arangodb", COMMUNITY_DATABASE_ROOT] },
@@ -17310,6 +17333,7 @@ function planCommunityRehearsalCleanup() {
17310
17333
  { kind: "remove-tree", path: COMMUNITY_DATABASE_ROOT },
17311
17334
  { kind: "remove-tree", path: COMMUNITY_REHEARSAL_ROOT },
17312
17335
  { kind: "remove-tree", path: COMMUNITY_CREDENTIAL_PARENT },
17336
+ { kind: "clear-firewall" },
17313
17337
  { kind: "exec", argv: ["/usr/bin/systemctl", "daemon-reload"] },
17314
17338
  { kind: "exec", argv: ["/usr/bin/systemctl", "reset-failed", "forgezero-community-api.service", "forgezero-rehearsal-db.service"], accepted: [0, 1, 5] }
17315
17339
  ];
@@ -17329,6 +17353,8 @@ async function applyOperations(operations) {
17329
17353
  for (const operation of operations) {
17330
17354
  if (operation.kind === "remove-tree")
17331
17355
  rmSync13(operation.path, { recursive: true, force: true });
17356
+ else if (operation.kind === "clear-firewall")
17357
+ await clearCommunityRehearsalFirewall();
17332
17358
  else if (operation.kind === "write") {
17333
17359
  mkdirSync17(dirname15(operation.path), { recursive: true });
17334
17360
  writeFileSync17(operation.path, operation.content, { mode: operation.mode });
@@ -17351,8 +17377,27 @@ async function applyOperations(operations) {
17351
17377
  }
17352
17378
  }
17353
17379
  }
17380
+ function communityRehearsalFirewallRuleNumbers(status) {
17381
+ return status.split(/\r?\n/).flatMap((line) => {
17382
+ if (!line.includes(`# ${COMMUNITY_REHEARSAL_FIREWALL_COMMENT}`))
17383
+ return [];
17384
+ const match = line.match(/^\[\s*(\d+)\]/);
17385
+ return match ? [Number(match[1])] : [];
17386
+ }).filter((number2) => Number.isSafeInteger(number2) && number2 > 0).sort((left, right) => right - left);
17387
+ }
17388
+ async function clearCommunityRehearsalFirewall() {
17389
+ const status = await exec(["/usr/sbin/ufw", "status", "numbered"]);
17390
+ if (status.exitCode !== 0)
17391
+ throw new Error(`unable to inspect rehearsal firewall rules: ${status.output.trim()}`);
17392
+ for (const number2 of communityRehearsalFirewallRuleNumbers(status.output)) {
17393
+ const removed = await exec(["/usr/sbin/ufw", "--force", "delete", String(number2)]);
17394
+ if (removed.exitCode !== 0) {
17395
+ throw new Error(`unable to remove rehearsal firewall rule ${number2}: ${removed.output.trim()}`);
17396
+ }
17397
+ }
17398
+ }
17354
17399
  var responseFor = async (request) => {
17355
- const base = "http://127.0.0.1:8787";
17400
+ const base = `http://127.0.0.1:${COMMUNITY_REHEARSAL_API_PORT}`;
17356
17401
  if (request.operation === "health")
17357
17402
  return fetch(`${base}/health`, { signal: AbortSignal.timeout(15000) });
17358
17403
  if (request.operation === "init")
@@ -17414,7 +17459,7 @@ async function runCommunityRehearsalHost(request) {
17414
17459
  }
17415
17460
  if (request.action === "database-ready" || request.action === "starter-ready" || request.action === "api-ready") {
17416
17461
  const starter = topology.find((entry) => entry.starter);
17417
- const url = request.action === "database-ready" ? "http://127.0.0.1:8529/_api/version" : request.action === "starter-ready" ? `http://${starter.address}:8528/version` : "http://127.0.0.1:8787/health";
17462
+ const url = request.action === "database-ready" ? `http://127.0.0.1:${COMMUNITY_REHEARSAL_COORDINATOR_PORT}/_api/version` : request.action === "starter-ready" ? `http://${starter.address}:${COMMUNITY_REHEARSAL_STARTER_PORT}/version` : `http://127.0.0.1:${COMMUNITY_REHEARSAL_API_PORT}/health`;
17418
17463
  const response2 = await fetch(url, { signal: AbortSignal.timeout(2000) }).catch(() => {
17419
17464
  return;
17420
17465
  });
package/dist/fz.js CHANGED
@@ -4844,7 +4844,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
4844
4844
  var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
4845
4845
 
4846
4846
  // src/version.ts
4847
- var VERSION2 = "0.1.121";
4847
+ var VERSION2 = "0.1.123";
4848
4848
 
4849
4849
  // src/software.ts
4850
4850
  var PINNED_BUN_VERSION = "1.3.14";
@@ -18488,6 +18488,14 @@ function unsupportedRepositoryCliOption(argv2) {
18488
18488
  }
18489
18489
  return;
18490
18490
  }
18491
+ function forwardedRepositoryOperationArguments(options, args) {
18492
+ return [
18493
+ ...options.apply ? ["--apply"] : [],
18494
+ ...options.json ? ["--json"] : [],
18495
+ ...options.disposableFleetConfirmation ? [`--confirm-disposable-fleet=${options.disposableFleetConfirmation}`] : [],
18496
+ ...args
18497
+ ];
18498
+ }
18491
18499
  function manifestName(root) {
18492
18500
  const manifestPath = join12(root, "package.json");
18493
18501
  if (!existsSync12(manifestPath)) {
@@ -20436,11 +20444,7 @@ function repositoryOperationArguments(options, args) {
20436
20444
  throw new Error("--root requires a repository path.");
20437
20445
  if (unsupported)
20438
20446
  throw new Error(`${unsupported} is not valid for repository maintenance commands.`);
20439
- return [
20440
- ...options.apply ? ["--apply"] : [],
20441
- ...options.json ? ["--json"] : [],
20442
- ...args
20443
- ];
20447
+ return forwardedRepositoryOperationArguments(options, args);
20444
20448
  }
20445
20449
  async function cmdDev(options, args) {
20446
20450
  if ((args[0] ?? "") !== "reset" || args.length !== 1) {
@@ -366,7 +366,7 @@ function systemdAgentEgressDirectives(loopbackTcpPorts = []) {
366
366
  }
367
367
 
368
368
  // src/version.ts
369
- var VERSION = "0.1.121";
369
+ var VERSION = "0.1.123";
370
370
 
371
371
  // src/otel-collector.ts
372
372
  var FORGEZERO_OTEL_COLLECTOR_UNIT = "forgezero-otel-collector.service";
@@ -1460,7 +1460,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
1460
1460
  var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
1461
1461
 
1462
1462
  // src/version.ts
1463
- var VERSION = "0.1.121";
1463
+ var VERSION = "0.1.123";
1464
1464
 
1465
1465
  // src/software.ts
1466
1466
  var PINNED_BUN_VERSION = "1.3.14";
@@ -3020,7 +3020,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
3020
3020
  }
3021
3021
 
3022
3022
  // src/version.ts
3023
- var VERSION3 = "0.1.121";
3023
+ var VERSION3 = "0.1.123";
3024
3024
 
3025
3025
  // src/egress-policy.ts
3026
3026
  import { realpathSync as realpathSync3 } from "node:fs";
package/dist/provision.js CHANGED
@@ -3020,7 +3020,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
3020
3020
  }
3021
3021
 
3022
3022
  // src/version.ts
3023
- var VERSION3 = "0.1.121";
3023
+ var VERSION3 = "0.1.123";
3024
3024
 
3025
3025
  // src/egress-policy.ts
3026
3026
  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.121";
2
+ export declare const VERSION = "0.1.123";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgezero/agent",
3
- "version": "0.1.121",
3
+ "version": "0.1.123",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "check": "tsc --noEmit",