@marcusrbrown/infra 0.25.0 → 0.25.1

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.
Files changed (2) hide show
  1. package/dist/cli.js +51 -11
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -6950,7 +6950,7 @@ import { goke } from "goke";
6950
6950
  // package.json
6951
6951
  var package_default = {
6952
6952
  name: "@marcusrbrown/infra",
6953
- version: "0.25.0",
6953
+ version: "0.25.1",
6954
6954
  description: "Infrastructure management CLI \u2014 deploy automation, health checks, and MCP bridge",
6955
6955
  keywords: [
6956
6956
  "infra",
@@ -8406,7 +8406,7 @@ var CONTENT_EVENTS = new Set([
8406
8406
  "discussion_comment"
8407
8407
  ]);
8408
8408
  var VERIFIED_ACTION_SHA_BY_LAYOUT = {
8409
- "fro-bot/agent@v0.118.2": "77f2bad7d68ac38279cd0fa28f38b26a0cd15dfb"
8409
+ "fro-bot/agent@v0.119.2": "83ed683da24111bd1474eb4bda39715ed5799bc2"
8410
8410
  };
8411
8411
  var REQUIRED_S3_INPUTS = {
8412
8412
  "s3-backup": undefined,
@@ -8917,7 +8917,7 @@ function formatStorageWorkflowSnippet() {
8917
8917
  with:
8918
8918
  role-to-assume: \${{ vars.FRO_BOT_S3_ROLE_TO_ASSUME }}
8919
8919
  aws-region: \${{ vars.FRO_BOT_S3_REGION }}
8920
- - uses: fro-bot/agent@77f2bad7d68ac38279cd0fa28f38b26a0cd15dfb
8920
+ - uses: fro-bot/agent@83ed683da24111bd1474eb4bda39715ed5799bc2
8921
8921
  with:
8922
8922
  s3-backup: true
8923
8923
  s3-bucket: \${{ vars.FRO_BOT_S3_BUCKET }}
@@ -9138,7 +9138,7 @@ var STORAGE_VARIABLE_NAMES = {
9138
9138
  prefix: "FRO_BOT_S3_PREFIX",
9139
9139
  expectedBucketOwner: "FRO_BOT_S3_EXPECTED_BUCKET_OWNER"
9140
9140
  };
9141
- var KNOWN_KEY_LAYOUT_VERSION = "fro-bot/agent@v0.118.2";
9141
+ var KNOWN_KEY_LAYOUT_VERSION = "fro-bot/agent@v0.119.2";
9142
9142
  var manifestSchema = z6.object({
9143
9143
  owner: z6.string().min(1),
9144
9144
  repo: z6.string().min(1),
@@ -11934,8 +11934,29 @@ function validateGatewayHost(host) {
11934
11934
  return host;
11935
11935
  }
11936
11936
 
11937
+ // src/commands/gateway/volume.ts
11938
+ var GATEWAY_COMPOSE_PROJECT_NAME = "fro-bot";
11939
+ var MITMPROXY_CERTS_VOLUME = `${GATEWAY_COMPOSE_PROJECT_NAME}_mitmproxy-certs`;
11940
+ var VOLUME_EXISTS_SENTINEL = "EXISTS";
11941
+ var VOLUME_MISSING_SENTINEL = "MISSING";
11942
+ function volumeProbeCommand(volume) {
11943
+ return `docker volume inspect ${volume} >/dev/null 2>&1 && echo ${VOLUME_EXISTS_SENTINEL} || echo ${VOLUME_MISSING_SENTINEL}`;
11944
+ }
11945
+ function checkVolumeProbeResult(volume, result) {
11946
+ if (result.exitCode !== 0) {
11947
+ return `Could not verify Docker volume ${volume} on the gateway host (exit ${result.exitCode}): ${result.stderr.trim() || "unknown error"}`;
11948
+ }
11949
+ const sentinel = result.stdout.trim();
11950
+ if (sentinel === VOLUME_EXISTS_SENTINEL) {
11951
+ return;
11952
+ }
11953
+ if (sentinel === VOLUME_MISSING_SENTINEL) {
11954
+ return `Docker volume ${volume} does not exist on the gateway host; refusing to continue (it would be created empty as a side effect).`;
11955
+ }
11956
+ return `Could not verify Docker volume ${volume} on the gateway host: unrecognized probe output`;
11957
+ }
11958
+
11937
11959
  // src/commands/gateway/backup.ts
11938
- var MITMPROXY_CERTS_VOLUME = "mitmproxy-certs";
11939
11960
  var CA_CERT_FILE = "mitmproxy-ca-cert.pem";
11940
11961
  var CA_KEY_FILE = "mitmproxy-ca.pem";
11941
11962
  var DEFAULT_OUTPUT = "apps/gateway/.local/mitmproxy-ca.tar";
@@ -11948,7 +11969,7 @@ async function backupGatewayCa(opts, spawn = defaultSpawn3, printErr) {
11948
11969
  return { ok: false, error: "Only CA backup is currently supported; --no-include-ca is not accepted" };
11949
11970
  }
11950
11971
  validateGatewayHost(opts.host);
11951
- const sshCmd = [
11972
+ const sshCommand = (remote) => [
11952
11973
  "ssh",
11953
11974
  "-o",
11954
11975
  "BatchMode=yes",
@@ -11956,13 +11977,28 @@ async function backupGatewayCa(opts, spawn = defaultSpawn3, printErr) {
11956
11977
  "StrictHostKeyChecking=yes",
11957
11978
  ...buildKnownHostsArgs(),
11958
11979
  `root@${opts.host}`,
11959
- `docker run --rm -v ${MITMPROXY_CERTS_VOLUME}:/src:ro alpine tar -cf - -C /src ${CA_CERT_FILE} ${CA_KEY_FILE}`
11980
+ remote
11960
11981
  ];
11961
11982
  const env = {
11962
11983
  PATH: process.env.PATH ?? "/usr/bin:/bin",
11963
11984
  HOME: process.env.HOME ?? "/tmp",
11964
11985
  ...process.env.SSH_AUTH_SOCK ? { SSH_AUTH_SOCK: process.env.SSH_AUTH_SOCK } : {}
11965
11986
  };
11987
+ const probe = spawn(sshCommand(volumeProbeCommand(MITMPROXY_CERTS_VOLUME)), { env, stdout: "pipe", stderr: "pipe" });
11988
+ const [probeStdout, probeStderr, probeExit] = await Promise.all([
11989
+ new Response(probe.stdout).text(),
11990
+ new Response(probe.stderr).text(),
11991
+ probe.exited
11992
+ ]);
11993
+ const probeError = checkVolumeProbeResult(MITMPROXY_CERTS_VOLUME, {
11994
+ stdout: probeStdout,
11995
+ stderr: probeStderr,
11996
+ exitCode: probeExit
11997
+ });
11998
+ if (probeError !== undefined) {
11999
+ return { ok: false, error: probeError };
12000
+ }
12001
+ const sshCmd = sshCommand(`docker run --rm -v ${MITMPROXY_CERTS_VOLUME}:/src:ro alpine tar -cf - -C /src ${CA_CERT_FILE} ${CA_KEY_FILE}`);
11966
12002
  const child = spawn(sshCmd, { env, stdout: "pipe", stderr: "pipe" });
11967
12003
  const [tarBytes, stderrText, exitCode] = await Promise.all([
11968
12004
  new Response(child.stdout).arrayBuffer(),
@@ -12231,7 +12267,6 @@ function registerGatewayLogs(cli) {
12231
12267
 
12232
12268
  // src/commands/gateway/restore.ts
12233
12269
  import { z as z25 } from "zod";
12234
- var MITMPROXY_CERTS_VOLUME2 = "mitmproxy-certs";
12235
12270
  var CA_CERT_FILE2 = "mitmproxy-ca-cert.pem";
12236
12271
  var CA_KEY_FILE2 = "mitmproxy-ca.pem";
12237
12272
  var COMPOSE_PROJECT_DIR4 = "/opt/gateway/deploy";
@@ -12300,6 +12335,11 @@ async function restoreGatewayCa(opts, spawn = defaultSpawn4) {
12300
12335
  if (archiveError !== undefined) {
12301
12336
  return { ok: false, error: archiveError };
12302
12337
  }
12338
+ const probeResult = await spawnText(spawn, sshCommand(opts.host, volumeProbeCommand(MITMPROXY_CERTS_VOLUME)), env);
12339
+ const probeError = checkVolumeProbeResult(MITMPROXY_CERTS_VOLUME, probeResult);
12340
+ if (probeError !== undefined) {
12341
+ return { ok: false, error: probeError };
12342
+ }
12303
12343
  const mktempResult = await spawnText(spawn, sshCommand(opts.host, "mktemp -t gateway-ca-restore-XXXXXX.tar"), env);
12304
12344
  if (mktempResult.exitCode !== 0) {
12305
12345
  return {
@@ -12336,7 +12376,7 @@ async function restoreGatewayCa(opts, spawn = defaultSpawn4) {
12336
12376
  };
12337
12377
  return primaryError;
12338
12378
  }
12339
- const extractResult = await spawnText(spawn, sshCommand(opts.host, `docker run --rm -v ${MITMPROXY_CERTS_VOLUME2}:/dst -v ${tmpRemote}:/src.tar:ro alpine sh -c 'tar -xf /src.tar -C /dst'`), env);
12379
+ const extractResult = await spawnText(spawn, sshCommand(opts.host, `docker run --rm -v ${MITMPROXY_CERTS_VOLUME}:/dst -v ${tmpRemote}:/src.tar:ro alpine sh -c 'tar -xf /src.tar -C /dst'`), env);
12340
12380
  if (extractResult.exitCode !== 0) {
12341
12381
  primaryError = {
12342
12382
  ok: false,
@@ -12353,8 +12393,8 @@ async function restoreGatewayCa(opts, spawn = defaultSpawn4) {
12353
12393
  return primaryError;
12354
12394
  }
12355
12395
  const [certResult, keyResult] = await Promise.all([
12356
- spawnText(spawn, sshCommand(opts.host, `docker run --rm -v ${MITMPROXY_CERTS_VOLUME2}:/src:ro alpine cat /src/${CA_CERT_FILE2}`), env),
12357
- spawnText(spawn, sshCommand(opts.host, `docker run --rm -v ${MITMPROXY_CERTS_VOLUME2}:/src:ro alpine cat /src/${CA_KEY_FILE2}`), env)
12396
+ spawnText(spawn, sshCommand(opts.host, `docker run --rm -v ${MITMPROXY_CERTS_VOLUME}:/src:ro alpine cat /src/${CA_CERT_FILE2}`), env),
12397
+ spawnText(spawn, sshCommand(opts.host, `docker run --rm -v ${MITMPROXY_CERTS_VOLUME}:/src:ro alpine cat /src/${CA_KEY_FILE2}`), env)
12358
12398
  ]);
12359
12399
  if (certResult.exitCode !== 0 || keyResult.exitCode !== 0) {
12360
12400
  primaryError = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marcusrbrown/infra",
3
- "version": "0.25.0",
3
+ "version": "0.25.1",
4
4
  "description": "Infrastructure management CLI — deploy automation, health checks, and MCP bridge",
5
5
  "keywords": [
6
6
  "infra",