@agent-beam/beam 0.2.25 → 0.2.27
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.
- package/README.md +20 -3
- package/Skills/README.md +1 -1
- package/Skills/agentbeam-app-monitoring/SKILL.md +112 -0
- package/Skills/manifest.json +4 -0
- package/dist/auto-update.d.ts +52 -0
- package/dist/auto-update.js +173 -0
- package/dist/auto-update.js.map +1 -0
- package/dist/cli.js +25 -1
- package/dist/cli.js.map +1 -1
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/cve.js +3 -4
- package/dist/cve.js.map +1 -1
- package/dist/data-detectors.js +1 -1
- package/dist/data-detectors.js.map +1 -1
- package/dist/monitor-client.d.ts +12 -4
- package/dist/monitor-client.js +30 -1
- package/dist/monitor-client.js.map +1 -1
- package/dist/monitor-rules.js +2 -2
- package/dist/monitor-rules.js.map +1 -1
- package/dist/monitor.d.ts +2 -0
- package/dist/monitor.js +50 -8
- package/dist/monitor.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -54,6 +54,12 @@ beam cve check . # check an app's dependencies for known vulnerabiliti
|
|
|
54
54
|
|
|
55
55
|
Run `beam setup` again when adding an agent or repairing an installation. It preserves existing agent configuration.
|
|
56
56
|
|
|
57
|
+
**Updates.** Like Claude Code, Beam keeps itself current. At most once a day, an interactive `beam` command checks for a new release and installs it in the background, so the command you ran never waits. The next command tells you it's done and what to restart.
|
|
58
|
+
|
|
59
|
+
- It never runs inside agent hooks, `beam run`, `beam monitor`, CI or non-interactive shells, and never asks for sudo. If the install needs elevated rights, it tells you to run `beam update`.
|
|
60
|
+
- Turn it off per user with `beam update --auto off`, or fleet-wide with `BEAM_DISABLE_AUTOUPDATE=1` (for example through MDM).
|
|
61
|
+
- Standalone binaries show a download link instead.
|
|
62
|
+
|
|
57
63
|
## What AgentBeam protects
|
|
58
64
|
|
|
59
65
|
Depending on organization policy, AgentBeam can ask for approval, block, redact, or log:
|
|
@@ -169,16 +175,27 @@ Jev and `beam judge` can run together. Each adds its own wait to every eligible
|
|
|
169
175
|
Both need a connected workspace, and both stay off until a workspace owner or admin turns on App monitoring in the dashboard. Until then, `beam monitor` waits and captures nothing.
|
|
170
176
|
|
|
171
177
|
```bash
|
|
172
|
-
|
|
178
|
+
export BEAM_APP_TOKEN=beam_app_... # the app's token, from the dashboard (App monitoring > Apps)
|
|
173
179
|
beam monitor --file /var/log/nginx/access.log --file /var/log/app/app.log
|
|
174
180
|
beam monitor --file /var/log/app/app.log --app /srv/app # also check dependencies at start and daily
|
|
175
181
|
node server.js 2>&1 | beam monitor --stdin # or read piped output
|
|
176
|
-
beam monitor
|
|
182
|
+
beam monitor test # send one test finding to prove the setup
|
|
183
|
+
beam monitor status # app, on or off, level, and this month's usage
|
|
177
184
|
beam cve check . # one-off check; exits 2 when anything is found
|
|
178
185
|
beam cve check . --fail-on high --json # in CI: fail only on high and critical
|
|
179
186
|
```
|
|
180
187
|
|
|
181
|
-
|
|
188
|
+
**Apps and tokens.** Add each app (bgremover, explainx, ...) on the dashboard's App monitoring page to get its own token, shown once. With `BEAM_APP_TOKEN` set, `beam monitor` and `beam cve check` report as that app, and its findings, filters and webhook routing stay separate from your other apps. A laptop connected with `beam connect` works without a token. Tokens are least-privilege:
|
|
189
|
+
|
|
190
|
+
- They work only for App monitoring. Every other AgentBeam API rejects them.
|
|
191
|
+
- Only a hash is stored, and the CLI refuses to send one over plain HTTP.
|
|
192
|
+
- Beam redacts its own tokens from logs and evidence.
|
|
193
|
+
- Each app has a per-minute request limit.
|
|
194
|
+
- Rotating or removing a token takes effect immediately.
|
|
195
|
+
|
|
196
|
+
Run it under whatever keeps your app running: a systemd unit, a sidecar container that shares the log volume, or pm2. For an app on Railway, deploy the [Beam monitor service](deploy/railway-monitor/README.md) next to it. It streams the app's HTTP and app logs from Railway without changing the app.
|
|
197
|
+
|
|
198
|
+
**Let your coding agent do it:** `npx @agent-beam/beam add skill agentbeam-app-monitoring -g --all-agents`, then ask it to add AgentBeam monitoring to your app. It finds where the app runs, keeps the token out of the repository, and finishes with `beam monitor test`.
|
|
182
199
|
|
|
183
200
|
**What leaves the machine.** Log lines are matched on the server where `beam monitor` runs, and raw lines are never sent. A finding carries the rule, severity, file, a repeat count and a redacted excerpt of up to 600 characters. Redaction removes credentials, bearer tokens, URL userinfo, email addresses and your policy's custom detector matches. Query strings are kept, because in an access log the query is usually the attack. `beam cve check` sends package names and versions only.
|
|
184
201
|
|
package/Skills/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Start with `security-assessment` for an assessment spanning several surfaces. Fo
|
|
|
12
12
|
| Pre-install and discovery | [skill-scanner](skill-scanner/SKILL.md), [mcp-scanner](mcp-scanner/SKILL.md), [ai-asset-scanner](ai-asset-scanner/SKILL.md), [model-artifact-scanner](model-artifact-scanner/SKILL.md), [training-data-security](training-data-security/SKILL.md), [agent-plugin-marketplace-review](agent-plugin-marketplace-review/SKILL.md) |
|
|
13
13
|
| AI trust boundaries | [jev-action-judge](jev-action-judge/SKILL.md), [ai-security](ai-security/SKILL.md), [prompt-injection-review](prompt-injection-review/SKILL.md), [agent-permissions-review](agent-permissions-review/SKILL.md), [rag-memory-security](rag-memory-security/SKILL.md), [tool-schema-review](tool-schema-review/SKILL.md), [multi-agent-trust-review](multi-agent-trust-review/SKILL.md) |
|
|
14
14
|
| Application and supply chain | [api-auth-security](api-auth-security/SKILL.md), [agent-web-security](agent-web-security/SKILL.md), [agent-transport-security](agent-transport-security/SKILL.md), [secrets-egress-review](secrets-egress-review/SKILL.md), [dependency-supply-chain](dependency-supply-chain/SKILL.md), [cicd-agent-security](cicd-agent-security/SKILL.md), [browser-agent-security](browser-agent-security/SKILL.md), [llm-output-handling](llm-output-handling/SKILL.md), [webhook-callback-security](webhook-callback-security/SKILL.md) |
|
|
15
|
-
| Deployment and operations | [agentbeam-setup](agentbeam-setup/SKILL.md), [container-sandbox-security](container-sandbox-security/SKILL.md), [cloud-agent-security](cloud-agent-security/SKILL.md), [agent-monitoring-review](agent-monitoring-review/SKILL.md), [agent-incident-response](agent-incident-response/SKILL.md), [agent-cost-abuse-review](agent-cost-abuse-review/SKILL.md), [data-retention-privacy-review](data-retention-privacy-review/SKILL.md), [agent-network-segmentation](agent-network-segmentation/SKILL.md) |
|
|
15
|
+
| Deployment and operations | [agentbeam-setup](agentbeam-setup/SKILL.md), [agentbeam-app-monitoring](agentbeam-app-monitoring/SKILL.md), [container-sandbox-security](container-sandbox-security/SKILL.md), [cloud-agent-security](cloud-agent-security/SKILL.md), [agent-monitoring-review](agent-monitoring-review/SKILL.md), [agent-incident-response](agent-incident-response/SKILL.md), [agent-cost-abuse-review](agent-cost-abuse-review/SKILL.md), [data-retention-privacy-review](data-retention-privacy-review/SKILL.md), [agent-network-segmentation](agent-network-segmentation/SKILL.md) |
|
|
16
16
|
|
|
17
17
|
These are agent workflows, not new CLI subcommands, automatic installation gates, or a generic penetration-testing catalog. The static review skills work without Beam installed. The optional `jev-action-judge` workflow requires Beam CLI and authorized remote API use. Existing `beam scan` commands add offline text heuristics; they do not provide every capability described in the review workflows.
|
|
18
18
|
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentbeam-app-monitoring
|
|
3
|
+
description: Add AgentBeam app monitoring to an application - check its dependencies for known vulnerabilities with beam cve check, and watch its logs and traffic for attacks around the clock with beam monitor - without changing how the app runs. Use when the user asks to monitor an app, server or service with AgentBeam, add beam monitor, or check dependencies with beam cve check.
|
|
4
|
+
license: AGPL-3.0-only
|
|
5
|
+
metadata:
|
|
6
|
+
author: Beam
|
|
7
|
+
version: "1.0.0"
|
|
8
|
+
website: https://agentbeam.com
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Add AgentBeam app monitoring
|
|
12
|
+
|
|
13
|
+
You'll set up two things for the user's app:
|
|
14
|
+
|
|
15
|
+
- `beam cve check` checks its dependencies against AgentBeam's vulnerability database.
|
|
16
|
+
- `beam monitor` watches its logs and HTTP traffic and sends redacted findings to the user's AgentBeam workspace and webhooks. It only watches: it never blocks requests, changes the app, or sits in its request path.
|
|
17
|
+
|
|
18
|
+
## Rules while you do this
|
|
19
|
+
|
|
20
|
+
- Never change how the app starts, builds or deploys. Monitoring runs next to the app.
|
|
21
|
+
- The app token (`BEAM_APP_TOKEN`) is a credential. Don't print it, commit it, or write it into a Dockerfile, a compose file, CI config or any other file in the repository. It belongs in the platform's credential store (Railway variables, CI repository variables, a root-only systemd EnvironmentFile). Ask the user to paste it there themselves.
|
|
22
|
+
- Never send log contents anywhere yourself. `beam monitor` redacts on the machine and sends findings only.
|
|
23
|
+
- Ask before creating cloud resources (services, workflows, units) and before committing.
|
|
24
|
+
|
|
25
|
+
## 1. Check the prerequisites with the user
|
|
26
|
+
|
|
27
|
+
- App monitoring is turned on for their workspace at https://app.agentbeam.com/dashboard/monitoring (an owner or admin does this).
|
|
28
|
+
- The app has been added there under Apps (named after the app, for example `bgremover`), and its token is in the environment where you'll run commands. `beam monitor status` confirms the token works without printing it.
|
|
29
|
+
|
|
30
|
+
## 2. Install the CLI
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
npm i -g @agent-beam/beam
|
|
34
|
+
beam --version
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
It needs Node.js 20.17 or newer. `npx -y @agent-beam/beam <command>` works without a global install.
|
|
38
|
+
|
|
39
|
+
## 3. Check the dependencies
|
|
40
|
+
|
|
41
|
+
From the app's directory:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
beam cve check .
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Exit code 2 means known vulnerabilities were found. For each one, tell the user the package, the installed version, the fixed version and the advisory link. Propose upgrades, but don't apply them without asking. To keep checking on every push, offer a CI step that runs `npx -y @agent-beam/beam cve check . --fail-on high`. The user stores the token in the CI provider's encrypted repository variables (in GitHub, Settings > Secrets and variables > Actions, named `BEAM_APP_TOKEN`), and the step exposes it to the command as an environment variable. The step fails the build only on high or critical findings.
|
|
48
|
+
|
|
49
|
+
## 4. Find where the app runs and what it logs
|
|
50
|
+
|
|
51
|
+
Look at the repository: a Dockerfile, docker-compose file, Railway config, fly.toml, vercel.json, Procfile, systemd units, nginx or Apache config. Then pick the matching step below. Monitoring needs a stream of the app's logs; for serverless platforms without one (such as Vercel functions), stop after the dependency check and tell the user.
|
|
52
|
+
|
|
53
|
+
### 4a. Railway
|
|
54
|
+
|
|
55
|
+
Use the Beam monitor service from https://github.com/whyashthakker/beam-cli/tree/main/deploy/railway-monitor. It's a separate service in the same Railway project, which streams the app's HTTP and app logs into `beam monitor`. Walk the user through its README:
|
|
56
|
+
|
|
57
|
+
1. The user creates a Railway project token (project Settings, then Tokens).
|
|
58
|
+
2. Add a service whose source is that repository, with `RAILWAY_DOCKERFILE_PATH=deploy/railway-monitor/Dockerfile`.
|
|
59
|
+
3. The user sets sealed variables `BEAM_APP_TOKEN` and `RAILWAY_TOKEN`, plus `MONITOR_SERVICE` (the app's service name).
|
|
60
|
+
|
|
61
|
+
### 4b. Docker Compose or Kubernetes
|
|
62
|
+
|
|
63
|
+
Run `beam monitor` as a sidecar that reads the app's log files from a shared volume, read-only. In Compose, pass the token through from the host environment by name, never by value:
|
|
64
|
+
|
|
65
|
+
```yaml
|
|
66
|
+
beam-monitor:
|
|
67
|
+
image: node:24-slim
|
|
68
|
+
command: ["npx", "-y", "@agent-beam/beam", "monitor", "--file", "/logs/access.log", "--file", "/logs/app.log"]
|
|
69
|
+
environment:
|
|
70
|
+
- BEAM_APP_TOKEN
|
|
71
|
+
volumes:
|
|
72
|
+
- app-logs:/logs:ro
|
|
73
|
+
restart: unless-stopped
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
If the app only logs to stdout, run `docker logs -f <container> | beam monitor --stdin --no-echo` on the host instead.
|
|
77
|
+
|
|
78
|
+
### 4c. A server with systemd
|
|
79
|
+
|
|
80
|
+
Create a unit that runs next to the app. Put the token in a root-owned EnvironmentFile (for example `/etc/beam/app-monitor.conf`) with mode 600, and make sure the service user can read the log files (for example, membership in the `adm` group). Use the path that `command -v beam` prints in `ExecStart`:
|
|
81
|
+
|
|
82
|
+
```ini
|
|
83
|
+
[Unit]
|
|
84
|
+
Description=AgentBeam app monitoring
|
|
85
|
+
After=network-online.target
|
|
86
|
+
|
|
87
|
+
[Service]
|
|
88
|
+
EnvironmentFile=/etc/beam/app-monitor.conf
|
|
89
|
+
ExecStart=/usr/local/bin/beam monitor --file /var/log/nginx/access.log --file /var/log/myapp/app.log
|
|
90
|
+
Restart=always
|
|
91
|
+
User=beam-monitor
|
|
92
|
+
|
|
93
|
+
[Install]
|
|
94
|
+
WantedBy=multi-user.target
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## 5. Prove it works
|
|
98
|
+
|
|
99
|
+
From the same environment, with the token set:
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
beam monitor test
|
|
103
|
+
beam monitor status
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The test finding should appear within seconds on https://app.agentbeam.com/dashboard/monitoring, and at the webhooks set for that app. `beam monitor status` shows the app name, level and this month's usage.
|
|
107
|
+
|
|
108
|
+
## Optional extras
|
|
109
|
+
|
|
110
|
+
- **Review flagged lines with the user's own LLM:** set the `BEAM_LLM_*` variables (endpoint, model and, if the endpoint needs one, its key) where `beam monitor` runs.
|
|
111
|
+
- **Separate alert channels:** add webhooks on the dashboard and limit each one to particular apps.
|
|
112
|
+
- **Full guide:** https://docs.agentbeam.com/agent-cli/app-monitoring
|
package/Skills/manifest.json
CHANGED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export declare const WORKER_COMMAND = "__auto-update";
|
|
2
|
+
export interface UpdateState {
|
|
3
|
+
autoUpdate?: boolean;
|
|
4
|
+
checkedAt?: string;
|
|
5
|
+
latest?: string;
|
|
6
|
+
installing?: {
|
|
7
|
+
version: string;
|
|
8
|
+
pid: number;
|
|
9
|
+
startedAt: string;
|
|
10
|
+
};
|
|
11
|
+
installed?: {
|
|
12
|
+
version: string;
|
|
13
|
+
from: string;
|
|
14
|
+
at: string;
|
|
15
|
+
};
|
|
16
|
+
failed?: {
|
|
17
|
+
version: string;
|
|
18
|
+
at: string;
|
|
19
|
+
reason: string;
|
|
20
|
+
};
|
|
21
|
+
noticeShownAt?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare const updateStatePath: () => string;
|
|
24
|
+
export declare function readUpdateState(path?: string): Promise<UpdateState>;
|
|
25
|
+
export declare function writeUpdateState(state: UpdateState, path?: string): Promise<void>;
|
|
26
|
+
/** >0 when `a` is newer. Numeric major.minor.patch; prerelease suffixes are ignored. */
|
|
27
|
+
export declare function compareVersions(a: string, b: string): number;
|
|
28
|
+
export type InstallKind = "npm" | "binary" | "source";
|
|
29
|
+
/** npm package (global or local install), a standalone pkg binary, or a source checkout (dev). */
|
|
30
|
+
export declare function installKind(modulePath?: string): InstallKind;
|
|
31
|
+
export declare function autoUpdateAllowed(command: string | undefined, env?: NodeJS.ProcessEnv, interactive?: boolean): boolean;
|
|
32
|
+
export interface TickDeps {
|
|
33
|
+
now?: number;
|
|
34
|
+
kind?: InstallKind;
|
|
35
|
+
statePath?: string;
|
|
36
|
+
startWorker?: () => void;
|
|
37
|
+
fetchLatest?: () => Promise<string | null>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Runs on every eligible command: returns a one-line notice to print (or null), and starts the
|
|
41
|
+
* background worker when a check is due. Never throws and never waits on the network for npm
|
|
42
|
+
* installs; binaries do a short direct check because they can't install themselves.
|
|
43
|
+
*/
|
|
44
|
+
export declare function autoUpdateTick(current: string, deps?: TickDeps): Promise<string | null>;
|
|
45
|
+
export interface WorkerDeps {
|
|
46
|
+
current: string;
|
|
47
|
+
statePath?: string;
|
|
48
|
+
fetchLatest?: () => Promise<string | null>;
|
|
49
|
+
install?: (version: string) => Promise<void>;
|
|
50
|
+
}
|
|
51
|
+
/** The detached process: check, then install without prompting or escalating. */
|
|
52
|
+
export declare function runAutoUpdateWorker(deps: WorkerDeps): Promise<void>;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
// Background auto-update, the way Claude Code does it: at most once a day an interactive `beam`
|
|
2
|
+
// command starts a detached check against the npm registry and, when a newer release exists,
|
|
3
|
+
// installs it in the background. The command you ran never waits. The next command says the
|
|
4
|
+
// update is in, and what to restart.
|
|
5
|
+
//
|
|
6
|
+
// It never runs where it could slow down or surprise anything: agent hooks and `beam run` (they
|
|
7
|
+
// sit in the agent's tool path), long-running `beam monitor` / `beam start` / MCP processes, CI,
|
|
8
|
+
// non-interactive shells, or source checkouts. It never asks for sudo: if the global install
|
|
9
|
+
// isn't writable it falls back to telling you to run `beam update`. Administrators can turn it
|
|
10
|
+
// off with BEAM_DISABLE_AUTOUPDATE=1 (for example through MDM) or `beam update --auto off`.
|
|
11
|
+
import { spawn } from "node:child_process";
|
|
12
|
+
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
13
|
+
import { dirname, join } from "node:path";
|
|
14
|
+
import { fileURLToPath } from "node:url";
|
|
15
|
+
import { getBeamHome } from "./config.js";
|
|
16
|
+
const PACKAGE = "@agent-beam/beam";
|
|
17
|
+
const LATEST_URL = "https://registry.npmjs.org/@agent-beam%2fbeam/latest";
|
|
18
|
+
const CHECK_EVERY_MS = 24 * 60 * 60 * 1000;
|
|
19
|
+
const INSTALL_STALE_MS = 15 * 60 * 1000;
|
|
20
|
+
export const WORKER_COMMAND = "__auto-update";
|
|
21
|
+
// Commands that are in an agent's tool path, run unattended, or manage updates themselves.
|
|
22
|
+
const SKIP_COMMANDS = new Set(["hook", "run", "mcp", "start", "monitor", "update", "uninstall", "import", WORKER_COMMAND]);
|
|
23
|
+
export const updateStatePath = () => join(getBeamHome(), "update-state.json");
|
|
24
|
+
export async function readUpdateState(path = updateStatePath()) {
|
|
25
|
+
try {
|
|
26
|
+
return JSON.parse(await readFile(path, "utf8"));
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return {};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export async function writeUpdateState(state, path = updateStatePath()) {
|
|
33
|
+
await mkdir(dirname(path), { recursive: true, mode: 0o700 });
|
|
34
|
+
const tmp = `${path}.${process.pid}.tmp`;
|
|
35
|
+
await writeFile(tmp, `${JSON.stringify(state, null, 2)}\n`, { mode: 0o600 });
|
|
36
|
+
await rename(tmp, path);
|
|
37
|
+
}
|
|
38
|
+
/** >0 when `a` is newer. Numeric major.minor.patch; prerelease suffixes are ignored. */
|
|
39
|
+
export function compareVersions(a, b) {
|
|
40
|
+
const pa = a.split(/[.-]/).map(n => Number(n) || 0);
|
|
41
|
+
const pb = b.split(/[.-]/).map(n => Number(n) || 0);
|
|
42
|
+
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
43
|
+
const diff = (pa[i] ?? 0) - (pb[i] ?? 0);
|
|
44
|
+
if (diff !== 0)
|
|
45
|
+
return diff;
|
|
46
|
+
}
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
/** npm package (global or local install), a standalone pkg binary, or a source checkout (dev). */
|
|
50
|
+
export function installKind(modulePath = fileURLToPath(import.meta.url)) {
|
|
51
|
+
if (process.pkg)
|
|
52
|
+
return "binary";
|
|
53
|
+
return /[\\/]node_modules[\\/]@agent-beam[\\/]beam[\\/]/.test(modulePath) ? "npm" : "source";
|
|
54
|
+
}
|
|
55
|
+
export function autoUpdateAllowed(command, env = process.env, interactive = Boolean(process.stdout.isTTY && process.stderr.isTTY)) {
|
|
56
|
+
if (/^(1|true|yes)$/i.test(env.BEAM_DISABLE_AUTOUPDATE ?? ""))
|
|
57
|
+
return false;
|
|
58
|
+
if (env.CI || env.BEAM_AUTO_UPDATE_WORKER)
|
|
59
|
+
return false;
|
|
60
|
+
if (!interactive)
|
|
61
|
+
return false;
|
|
62
|
+
return !SKIP_COMMANDS.has(command ?? "");
|
|
63
|
+
}
|
|
64
|
+
const alive = (pid) => { try {
|
|
65
|
+
process.kill(pid, 0);
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return false;
|
|
70
|
+
} };
|
|
71
|
+
/**
|
|
72
|
+
* Runs on every eligible command: returns a one-line notice to print (or null), and starts the
|
|
73
|
+
* background worker when a check is due. Never throws and never waits on the network for npm
|
|
74
|
+
* installs; binaries do a short direct check because they can't install themselves.
|
|
75
|
+
*/
|
|
76
|
+
export async function autoUpdateTick(current, deps = {}) {
|
|
77
|
+
try {
|
|
78
|
+
const now = deps.now ?? Date.now();
|
|
79
|
+
const kind = deps.kind ?? installKind();
|
|
80
|
+
if (kind === "source")
|
|
81
|
+
return null;
|
|
82
|
+
const statePath = deps.statePath ?? updateStatePath();
|
|
83
|
+
const state = await readUpdateState(statePath);
|
|
84
|
+
if (state.autoUpdate === false)
|
|
85
|
+
return null;
|
|
86
|
+
// The background install finished and this process is the new version: say so, once.
|
|
87
|
+
if (state.installed && state.installed.version === current && !state.noticeShownAt) {
|
|
88
|
+
await writeUpdateState({ ...state, noticeShownAt: new Date(now).toISOString() }, statePath);
|
|
89
|
+
return `✔ Beam updated to v${current} (from v${state.installed.from}). If Beam's background service is running, restart it to use the new version: beam service stop && beam service start`;
|
|
90
|
+
}
|
|
91
|
+
const due = !state.checkedAt || now - Date.parse(state.checkedAt) >= CHECK_EVERY_MS;
|
|
92
|
+
const installing = state.installing && alive(state.installing.pid) && now - Date.parse(state.installing.startedAt) < INSTALL_STALE_MS;
|
|
93
|
+
if (kind === "binary") {
|
|
94
|
+
if (!due)
|
|
95
|
+
return null;
|
|
96
|
+
const latest = await (deps.fetchLatest ?? fetchLatest)();
|
|
97
|
+
await writeUpdateState({ ...state, checkedAt: new Date(now).toISOString(), latest: latest ?? state.latest }, statePath);
|
|
98
|
+
return latest && compareVersions(latest, current) > 0
|
|
99
|
+
? `Beam v${latest} is available (you have v${current}). Download it with: curl -fsSL https://agentbeam.com/install.sh | bash`
|
|
100
|
+
: null;
|
|
101
|
+
}
|
|
102
|
+
// An install that needed privileges we won't take: point to the explicit command, once a day.
|
|
103
|
+
if (state.failed && compareVersions(state.failed.version, current) > 0 && due) {
|
|
104
|
+
await writeUpdateState({ ...state, checkedAt: new Date(now).toISOString() }, statePath);
|
|
105
|
+
return `Beam v${state.failed.version} is available (you have v${current}). Run 'beam update' to install it.`;
|
|
106
|
+
}
|
|
107
|
+
if (due && !installing) {
|
|
108
|
+
await writeUpdateState({ ...state, checkedAt: new Date(now).toISOString() }, statePath);
|
|
109
|
+
(deps.startWorker ?? startWorker)();
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async function fetchLatest() {
|
|
118
|
+
try {
|
|
119
|
+
const response = await fetch(LATEST_URL, { signal: AbortSignal.timeout(3000), headers: { Accept: "application/json" } });
|
|
120
|
+
if (!response.ok)
|
|
121
|
+
return null;
|
|
122
|
+
const { version } = (await response.json());
|
|
123
|
+
return typeof version === "string" && /^\d+\.\d+\.\d+/.test(version) ? version : null;
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function startWorker() {
|
|
130
|
+
const cli = process.argv[1];
|
|
131
|
+
if (!cli)
|
|
132
|
+
return;
|
|
133
|
+
const child = spawn(process.execPath, [cli, WORKER_COMMAND], {
|
|
134
|
+
detached: true,
|
|
135
|
+
stdio: "ignore",
|
|
136
|
+
env: { ...process.env, BEAM_AUTO_UPDATE_WORKER: "1" },
|
|
137
|
+
});
|
|
138
|
+
child.unref();
|
|
139
|
+
}
|
|
140
|
+
/** The detached process: check, then install without prompting or escalating. */
|
|
141
|
+
export async function runAutoUpdateWorker(deps) {
|
|
142
|
+
const statePath = deps.statePath ?? updateStatePath();
|
|
143
|
+
const latest = await (deps.fetchLatest ?? fetchLatest)();
|
|
144
|
+
const state = await readUpdateState(statePath);
|
|
145
|
+
if (!latest || compareVersions(latest, deps.current) <= 0) {
|
|
146
|
+
await writeUpdateState({ ...state, latest: latest ?? state.latest, installing: undefined }, statePath);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
await writeUpdateState({ ...state, latest, installing: { version: latest, pid: process.pid, startedAt: new Date().toISOString() } }, statePath);
|
|
150
|
+
try {
|
|
151
|
+
await (deps.install ?? npmInstall)(latest);
|
|
152
|
+
const after = await readUpdateState(statePath);
|
|
153
|
+
await writeUpdateState({ ...after, installing: undefined, failed: undefined, noticeShownAt: undefined,
|
|
154
|
+
installed: { version: latest, from: deps.current, at: new Date().toISOString() } }, statePath);
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
const after = await readUpdateState(statePath);
|
|
158
|
+
await writeUpdateState({ ...after, installing: undefined,
|
|
159
|
+
failed: { version: latest, at: new Date().toISOString(), reason: (error instanceof Error ? error.message : String(error)).slice(0, 300) } }, statePath);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function npmInstall(version) {
|
|
163
|
+
return new Promise((resolve, reject) => {
|
|
164
|
+
const child = spawn("npm", ["install", "-g", `${PACKAGE}@${version}`, "--no-audit", "--no-fund", "--loglevel=error"], {
|
|
165
|
+
stdio: "ignore",
|
|
166
|
+
shell: process.platform === "win32",
|
|
167
|
+
});
|
|
168
|
+
const timer = setTimeout(() => { child.kill(); reject(new Error("npm install timed out")); }, 5 * 60 * 1000);
|
|
169
|
+
child.on("error", error => { clearTimeout(timer); reject(error); });
|
|
170
|
+
child.on("exit", code => { clearTimeout(timer); code === 0 ? resolve() : reject(new Error(`npm install exited with ${code}`)); });
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=auto-update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-update.js","sourceRoot":"","sources":["../src/auto-update.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -37,8 +37,9 @@ import { registerJudgeCommands } from "./judge-cli.js";
|
|
|
37
37
|
import { addTrustedPath, readTrustedPaths, removeTrustedPath, trustedPathsFile } from "./trusted-paths.js";
|
|
38
38
|
import { blockedTargetsFile, readBlockedTargets, removeBlockedTarget } from "./blocked-targets.js";
|
|
39
39
|
import { checkForUpdate, installUpdate } from "./update.js";
|
|
40
|
+
import { WORKER_COMMAND, autoUpdateAllowed, autoUpdateTick, readUpdateState, runAutoUpdateWorker, writeUpdateState } from "./auto-update.js";
|
|
40
41
|
import { recordExpectedHooks, reportControlEvent } from "./tamper.js";
|
|
41
|
-
import { monitorStatus, runMonitor } from "./monitor.js";
|
|
42
|
+
import { monitorStatus, monitorTest, runMonitor } from "./monitor.js";
|
|
42
43
|
import { CVE_SEVERITIES, runCveCheck } from "./cve.js";
|
|
43
44
|
// Lets 'BEAM_API_URL=... beam connect' style overrides live in a .env file instead of the
|
|
44
45
|
// shell profile. Checked in cwd first (handy when developing from the repo), then in
|
|
@@ -346,7 +347,17 @@ program.command("sync")
|
|
|
346
347
|
program.command("update")
|
|
347
348
|
.description("Update the globally installed beam CLI to the latest published version")
|
|
348
349
|
.option("--check", "only check for an update, don't install it")
|
|
350
|
+
.option("--auto <on|off>", "turn background auto-updates on or off for this user (BEAM_DISABLE_AUTOUPDATE=1 also turns them off)")
|
|
349
351
|
.action(async (options) => {
|
|
352
|
+
if (options.auto !== undefined) {
|
|
353
|
+
if (options.auto !== "on" && options.auto !== "off")
|
|
354
|
+
throw new Error("--auto must be on or off.");
|
|
355
|
+
await writeUpdateState({ ...(await readUpdateState()), autoUpdate: options.auto === "on" });
|
|
356
|
+
console.log(options.auto === "on"
|
|
357
|
+
? "✔ Background auto-updates are on. Beam checks once a day and installs new versions in the background."
|
|
358
|
+
: "✔ Background auto-updates are off. Run 'beam update' to update.");
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
350
361
|
let check;
|
|
351
362
|
try {
|
|
352
363
|
check = await checkForUpdate(packageJson.version);
|
|
@@ -369,6 +380,9 @@ program.command("update")
|
|
|
369
380
|
throw new Error(`Could not install the update automatically: ${e.message}\n Run manually: npm install -g @agent-beam/beam@${check.latest}`);
|
|
370
381
|
}
|
|
371
382
|
});
|
|
383
|
+
// The detached background worker started by autoUpdateTick(); not for direct use.
|
|
384
|
+
program.command(WORKER_COMMAND, { hidden: true })
|
|
385
|
+
.action(async () => { await runAutoUpdateWorker({ current: packageJson.version }); });
|
|
372
386
|
const shims = program.command("shims").description("Make agent CLIs (claude, codex, ...) sandboxed automatically, without typing 'beam run'");
|
|
373
387
|
shims.command("install")
|
|
374
388
|
.description("Install PATH shims for the given agents (default: all known agents found on this machine)")
|
|
@@ -611,6 +625,9 @@ monitor.command("start", { isDefault: true })
|
|
|
611
625
|
.action(async (options) => {
|
|
612
626
|
await runMonitor({ files: options.file, stdin: options.stdin, echo: options.echo, app: options.app, fromStart: options.fromStart, wait: options.wait });
|
|
613
627
|
});
|
|
628
|
+
monitor.command("test")
|
|
629
|
+
.description("Send one test finding to prove the integration: it appears on the dashboard and at the app's webhooks")
|
|
630
|
+
.action(async () => { process.exitCode = await monitorTest(); });
|
|
614
631
|
monitor.command("status")
|
|
615
632
|
.description("Show whether App monitoring is on for this workspace, its level, and this month's usage")
|
|
616
633
|
.action(async () => { process.exitCode = await monitorStatus(); });
|
|
@@ -802,6 +819,13 @@ block.command("list")
|
|
|
802
819
|
for (const t of targets)
|
|
803
820
|
console.log(t);
|
|
804
821
|
});
|
|
822
|
+
// Background auto-update (see auto-update.ts): a notice from a finished update, or a daily check
|
|
823
|
+
// started in a detached process. Never on hooks, agent wrappers, long-running or non-interactive runs.
|
|
824
|
+
if (autoUpdateAllowed(argv[0])) {
|
|
825
|
+
const notice = await autoUpdateTick(packageJson.version);
|
|
826
|
+
if (notice)
|
|
827
|
+
console.error(cyan(notice));
|
|
828
|
+
}
|
|
805
829
|
try {
|
|
806
830
|
await program.parseAsync();
|
|
807
831
|
}
|