@marcusrbrown/infra 0.23.0 → 0.25.0

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 (3) hide show
  1. package/README.md +88 -12
  2. package/dist/cli.js +14 -11
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -38,21 +38,40 @@ bunx @marcusrbrown/infra keeweb deploy --local --nginx # include nginx config
38
38
  bunx @marcusrbrown/infra keeweb open
39
39
  ```
40
40
 
41
+ ### Agent
42
+
43
+ Configure model credentials for the Fro Bot agent and wire the optional S3 durable-storage handoff.
44
+
45
+ | Subcommand | Description |
46
+ | --- | --- |
47
+ | `agent setup` | Interactive wizard to configure generalized agent model-credential secrets/variables |
48
+ | `agent storage --repo OWNER/REPO --manifest FILE` | Verify the provisioned S3 handoff and wire non-secret GitHub storage variables |
49
+ | `agent storage teardown --repo OWNER/REPO --manifest FILE` | Unwire S3 variables and remove the repo-scoped storage resources |
50
+
51
+ ```bash
52
+ bunx @marcusrbrown/infra agent setup
53
+ bunx @marcusrbrown/infra agent setup --repo owner/repo --harness opencode --key sk-existing --force
54
+ bunx @marcusrbrown/infra agent storage --repo owner/repo --manifest handoff.json
55
+ bunx @marcusrbrown/infra agent storage --repo owner/repo --manifest handoff.json --plan # report without mutating
56
+ bunx @marcusrbrown/infra agent storage teardown --repo owner/repo --manifest handoff.json
57
+ ```
58
+
41
59
  ### CLIProxyAPI
42
60
 
43
61
  Manage the CLIProxyAPI proxy on `cliproxy.fro.bot`.
44
62
 
45
- | Subcommand | Description |
46
- | ------------------ | ------------------------------------------------------------------------ |
47
- | `cliproxy status` | HTTP reachability, usage stats, version |
48
- | `cliproxy models` | List models served at /v1/models; optional `[provider]` filter |
49
- | `cliproxy deploy` | Trigger deployment (GitHub Actions by default; `--local` for direct SSH) |
50
- | `cliproxy config` | Get or set proxy configuration via the management API |
51
- | `cliproxy keys` | List, add, or remove API keys via the management API |
52
- | `cliproxy login` | Authenticate a provider (claude or codex) via SSH |
53
- | `cliproxy monitor` | Probe Anthropic auth and send issue/Discord transition alerts |
54
- | `cliproxy open` | Open an interactive TUI via SSH |
55
- | `cliproxy setup` | Interactive wizard to onboard a repo to CLIProxyAPI |
63
+ | Subcommand | Description |
64
+ | ---------------------- | ------------------------------------------------------------------------ |
65
+ | `cliproxy status` | HTTP reachability, usage stats, version |
66
+ | `cliproxy models` | List models served at /v1/models; optional `[provider]` filter |
67
+ | `cliproxy deploy` | Trigger deployment (GitHub Actions by default; `--local` for direct SSH) |
68
+ | `cliproxy config` | Get or set proxy configuration via the management API |
69
+ | `cliproxy keys` | List, add, or remove API keys via the management API |
70
+ | `cliproxy login` | Authenticate a provider (claude or codex) via SSH |
71
+ | `cliproxy monitor` | Probe Anthropic auth and send issue/Discord transition alerts |
72
+ | `cliproxy open` | Open an interactive TUI via SSH |
73
+ | `cliproxy reset-quota` | Reset quota for a CLIProxyAPI auth record |
74
+ | `cliproxy setup` | Interactive wizard to onboard a repo to CLIProxyAPI |
56
75
 
57
76
  ```bash
58
77
  bunx @marcusrbrown/infra cliproxy status
@@ -68,10 +87,27 @@ bunx @marcusrbrown/infra cliproxy login claude
68
87
  bunx @marcusrbrown/infra cliproxy login codex
69
88
  bunx @marcusrbrown/infra cliproxy monitor
70
89
  bunx @marcusrbrown/infra cliproxy open
90
+ bunx @marcusrbrown/infra cliproxy reset-quota
71
91
  bunx @marcusrbrown/infra cliproxy setup
72
92
  bunx @marcusrbrown/infra cliproxy setup --repo OWNER/REPO --harness opencode
73
93
  ```
74
94
 
95
+ ### Broker
96
+
97
+ Manage the OIDC credential broker on `broker.fro.bot`.
98
+
99
+ | Subcommand | Description |
100
+ | --------------- | ------------------------------------------------------------------------ |
101
+ | `broker status` | HTTP reachability via `/healthz` |
102
+ | `broker deploy` | Trigger deployment (GitHub Actions by default; `--local` for direct SSH) |
103
+ | `broker logs` | Stream broker service logs (`--tail N` to limit lines) |
104
+
105
+ ```bash
106
+ bunx @marcusrbrown/infra broker status
107
+ bunx @marcusrbrown/infra broker deploy
108
+ bunx @marcusrbrown/infra broker logs --tail 100
109
+ ```
110
+
75
111
  ### Gateway
76
112
 
77
113
  Manage the Fro Bot gateway on `gateway.fro.bot`.
@@ -108,6 +144,46 @@ bunx @marcusrbrown/infra umami deploy
108
144
  bunx @marcusrbrown/infra umami logs --tail 50
109
145
  ```
110
146
 
147
+ ### Dashboard
148
+
149
+ Manage the Fro Bot operator dashboard.
150
+
151
+ | Subcommand | Description |
152
+ | ------------------ | ------------------------------------------------------------------------ |
153
+ | `dashboard status` | SSH health check, `docker compose ps` service states |
154
+ | `dashboard deploy` | Trigger deployment (GitHub Actions by default; `--local` for direct SSH) |
155
+ | `dashboard logs` | Stream dashboard service logs (`--tail N` to limit lines) |
156
+
157
+ ```bash
158
+ bunx @marcusrbrown/infra dashboard status
159
+ bunx @marcusrbrown/infra dashboard deploy
160
+ bunx @marcusrbrown/infra dashboard deploy --image-version 2026.06.47 # pin a CalVer release
161
+ bunx @marcusrbrown/infra dashboard logs dashboard --tail 100
162
+ ```
163
+
164
+ ### VPN
165
+
166
+ Manage the WireGuard VPN egress box.
167
+
168
+ | Subcommand | Description |
169
+ | -------------------------- | ------------------------------------------------------------------------ |
170
+ | `vpn status` | SSH health check, `wg show wg0` interface state |
171
+ | `vpn deploy` | Trigger deployment (GitHub Actions by default; `--local` for direct SSH) |
172
+ | `vpn logs` | Stream WireGuard logs (`--tail N` to limit lines) |
173
+ | `vpn client add <name>` | Generate a keypair, assign a tunnel IP, write the client `.conf` |
174
+ | `vpn client list` | List peers (name, tunnel IP, public key) |
175
+ | `vpn client remove <name>` | Remove a peer |
176
+
177
+ ```bash
178
+ bunx @marcusrbrown/infra vpn status
179
+ bunx @marcusrbrown/infra vpn deploy
180
+ bunx @marcusrbrown/infra vpn deploy --force-server-key # rotates the server key, invalidates all client configs
181
+ bunx @marcusrbrown/infra vpn logs --tail 100
182
+ bunx @marcusrbrown/infra vpn client add laptop
183
+ bunx @marcusrbrown/infra vpn client list
184
+ bunx @marcusrbrown/infra vpn client remove laptop
185
+ ```
186
+
111
187
  ### Unified Status
112
188
 
113
189
  ```bash
@@ -117,7 +193,7 @@ bunx @marcusrbrown/infra status --json # machine-readable output
117
193
 
118
194
  ### MCP Bridge
119
195
 
120
- Exposes read-only status commands as MCP tools over stdio.
196
+ Starts a stdio MCP server exposing a read-only allowlist of exactly 9 status commands as tools: `gateway status`, `cliproxy status`, `cliproxy models`, `keeweb status`, `umami status`, `dashboard status`, `vpn status`, `broker status`, and unified `status`. Every mutating command is deliberately excluded from the allowlist.
121
197
 
122
198
  ```bash
123
199
  bunx @marcusrbrown/infra mcp
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.23.0",
6953
+ version: "0.25.0",
6954
6954
  description: "Infrastructure management CLI \u2014 deploy automation, health checks, and MCP bridge",
6955
6955
  keywords: [
6956
6956
  "infra",
@@ -6993,7 +6993,7 @@ var package_default = {
6993
6993
  },
6994
6994
  devDependencies: {
6995
6995
  "@marcusrbrown/infra-shared": "workspace:*",
6996
- "@modelcontextprotocol/sdk": "1.30.0",
6996
+ "@modelcontextprotocol/sdk": "1.32.1",
6997
6997
  yaml: "2.9.1"
6998
6998
  },
6999
6999
  engines: {
@@ -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.96.0": "c29ac295b8da06768b140c32e5bd0ae3aff45dc6"
8409
+ "fro-bot/agent@v0.118.2": "77f2bad7d68ac38279cd0fa28f38b26a0cd15dfb"
8410
8410
  };
8411
8411
  var REQUIRED_S3_INPUTS = {
8412
8412
  "s3-backup": undefined,
@@ -8849,9 +8849,16 @@ function hasHandoff(job) {
8849
8849
  const serialized = stringifyUnknown(job);
8850
8850
  return /needs\.[\w-]+\.outputs\./.test(serialized) || /actions\/(?:download-artifact|upload-artifact|cache|cache\/restore|cache\/save)@/.test(serialized);
8851
8851
  }
8852
+ var STATIC_AWS_CREDENTIAL_PATTERN = /AWS_ACCESS_KEY_ID|AWS_SECRET_ACCESS_KEY|aws-access-key-id|aws-secret-access-key/;
8853
+ function withoutBlankedCredentialKeys(value) {
8854
+ if (Array.isArray(value))
8855
+ return value.map(withoutBlankedCredentialKeys);
8856
+ if (!isMapping(value))
8857
+ return value;
8858
+ return Object.fromEntries(Object.entries(value).filter(([key, entry]) => !(entry === "" && STATIC_AWS_CREDENTIAL_PATTERN.test(key))).map(([key, entry]) => [key, withoutBlankedCredentialKeys(entry)]));
8859
+ }
8852
8860
  function hasStaticAwsCredentials(job) {
8853
- const serialized = stringifyUnknown(job);
8854
- return /AWS_ACCESS_KEY_ID|AWS_SECRET_ACCESS_KEY|aws-access-key-id|aws-secret-access-key/.test(serialized);
8861
+ return STATIC_AWS_CREDENTIAL_PATTERN.test(stringifyUnknown(withoutBlankedCredentialKeys(job)));
8855
8862
  }
8856
8863
  function ancestors(jobId, analyses) {
8857
8864
  const visited = new Set;
@@ -8910,7 +8917,7 @@ function formatStorageWorkflowSnippet() {
8910
8917
  with:
8911
8918
  role-to-assume: \${{ vars.FRO_BOT_S3_ROLE_TO_ASSUME }}
8912
8919
  aws-region: \${{ vars.FRO_BOT_S3_REGION }}
8913
- - uses: fro-bot/agent@c29ac295b8da06768b140c32e5bd0ae3aff45dc6
8920
+ - uses: fro-bot/agent@77f2bad7d68ac38279cd0fa28f38b26a0cd15dfb
8914
8921
  with:
8915
8922
  s3-backup: true
8916
8923
  s3-bucket: \${{ vars.FRO_BOT_S3_BUCKET }}
@@ -8946,10 +8953,6 @@ function environmentResult(environmentValue, branchPoliciesValue) {
8946
8953
  violations.push("GitHub Environment fro-bot-storage is missing or returned an invalid response.");
8947
8954
  return { verified: false, violations };
8948
8955
  }
8949
- const protectionRules = Array.isArray(environmentValue.protection_rules) ? environmentValue.protection_rules : [];
8950
- const hasReviewer = protectionRules.some((rule) => isMapping(rule) && rule.type === "required_reviewers" && Array.isArray(rule.reviewers) && rule.reviewers.length > 0);
8951
- if (!hasReviewer)
8952
- violations.push("GitHub Environment fro-bot-storage has no required reviewer protection rule.");
8953
8956
  const branchPolicy = environmentValue.deployment_branch_policy;
8954
8957
  if (!isMapping(branchPolicy) || branchPolicy.protected_branches !== false || branchPolicy.custom_branch_policies !== true) {
8955
8958
  violations.push("GitHub Environment fro-bot-storage does not use a custom deployment-branch policy.");
@@ -9135,7 +9138,7 @@ var STORAGE_VARIABLE_NAMES = {
9135
9138
  prefix: "FRO_BOT_S3_PREFIX",
9136
9139
  expectedBucketOwner: "FRO_BOT_S3_EXPECTED_BUCKET_OWNER"
9137
9140
  };
9138
- var KNOWN_KEY_LAYOUT_VERSION = "fro-bot/agent@v0.96.0";
9141
+ var KNOWN_KEY_LAYOUT_VERSION = "fro-bot/agent@v0.118.2";
9139
9142
  var manifestSchema = z6.object({
9140
9143
  owner: z6.string().min(1),
9141
9144
  repo: z6.string().min(1),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marcusrbrown/infra",
3
- "version": "0.23.0",
3
+ "version": "0.25.0",
4
4
  "description": "Infrastructure management CLI — deploy automation, health checks, and MCP bridge",
5
5
  "keywords": [
6
6
  "infra",
@@ -43,7 +43,7 @@
43
43
  },
44
44
  "devDependencies": {
45
45
  "@marcusrbrown/infra-shared": "workspace:*",
46
- "@modelcontextprotocol/sdk": "1.30.0",
46
+ "@modelcontextprotocol/sdk": "1.32.1",
47
47
  "yaml": "2.9.1"
48
48
  },
49
49
  "engines": {