@agent-beam/beam 0.2.18 → 0.2.21

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 (50) hide show
  1. package/README.md +19 -0
  2. package/dist/account.js +1 -1
  3. package/dist/account.js.map +1 -1
  4. package/dist/agents.d.ts +8 -2
  5. package/dist/agents.js +7 -7
  6. package/dist/agents.js.map +1 -1
  7. package/dist/blocked-targets.d.ts +8 -0
  8. package/dist/blocked-targets.js +83 -0
  9. package/dist/blocked-targets.js.map +1 -0
  10. package/dist/cli.js +208 -42
  11. package/dist/cli.js.map +1 -1
  12. package/dist/client.js +67 -11
  13. package/dist/client.js.map +1 -1
  14. package/dist/collector-health.d.ts +1 -0
  15. package/dist/collector-health.js +20 -0
  16. package/dist/collector-health.js.map +1 -0
  17. package/dist/connect.js +8 -4
  18. package/dist/connect.js.map +1 -1
  19. package/dist/enroll.d.ts +0 -4
  20. package/dist/enroll.js +2 -60
  21. package/dist/enroll.js.map +1 -1
  22. package/dist/forward.d.ts +5 -1
  23. package/dist/forward.js +23 -7
  24. package/dist/forward.js.map +1 -1
  25. package/dist/install.d.ts +2 -0
  26. package/dist/install.js +58 -6
  27. package/dist/install.js.map +1 -1
  28. package/dist/policy.d.ts +1 -0
  29. package/dist/policy.js +11 -3
  30. package/dist/policy.js.map +1 -1
  31. package/dist/serve.js +25 -2
  32. package/dist/serve.js.map +1 -1
  33. package/dist/service.d.ts +2 -0
  34. package/dist/service.js +16 -4
  35. package/dist/service.js.map +1 -1
  36. package/dist/setup.js +9 -4
  37. package/dist/setup.js.map +1 -1
  38. package/dist/tamper.d.ts +9 -0
  39. package/dist/tamper.js +116 -0
  40. package/dist/tamper.js.map +1 -0
  41. package/dist/trusted-paths.d.ts +5 -0
  42. package/dist/trusted-paths.js +59 -0
  43. package/dist/trusted-paths.js.map +1 -0
  44. package/dist/tty-prompt.d.ts +5 -0
  45. package/dist/tty-prompt.js +55 -0
  46. package/dist/tty-prompt.js.map +1 -0
  47. package/dist/update.d.ts +7 -0
  48. package/dist/update.js +31 -0
  49. package/dist/update.js.map +1 -0
  50. package/package.json +8 -1
package/README.md CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
  AgentBeam is a local security layer for AI agents. `beam` is the AgentBeam CLI. It installs hooks for the agents detected on your machine, captures agent and MCP activity, applies your AgentBeam policy locally, and sends approved telemetry to the AgentBeam dashboard.
4
4
 
5
+ ## WipeBench: coding agent safety benchmark
6
+
7
+ [WipeBench](https://github.com/whyashthakker/WipeBench) gives coding agents an
8
+ objective, captures the commands they choose, and evaluates task completion and
9
+ harmful effects in Docker. A benchmark by [AgentBeam](https://agentbeam.com), in
10
+ collaboration with [ExplainX.ai](https://explainx.ai).
11
+
12
+ The [local snapshot](safety-bench/README.md) includes 112 scored scenarios across
13
+ 12 categories and a no-key smoke test:
14
+
15
+ ```sh
16
+ python3 safety-bench/bench.py selftest --scenarios smoke-hello
17
+ ```
18
+
19
+ Requires Python 3.11+ and a running Docker daemon. Scripted self-tests validate
20
+ the harness; they are not model rankings. The benchmark snapshot uses its own
21
+ [Apache-2.0 license](safety-bench/LICENSE). See the
22
+ [benchmark page](https://agentbeam.com/benchmarks/wipebench) for scope and usage.
23
+
5
24
  ## Install and setup
6
25
 
7
26
  ```bash
package/dist/account.js CHANGED
@@ -21,7 +21,7 @@ export async function fetchAccount(identity) {
21
21
  }
22
22
  catch { /* keep the status-only message */ }
23
23
  if (response.status === 401)
24
- message = "This device's credentials were revoked. Run 'beam enroll' or 'beam connect' again.";
24
+ message = "This device's credentials were revoked. Run 'beam setup' again.";
25
25
  throw new Error(message);
26
26
  }
27
27
  return (await response.json());
@@ -1 +1 @@
1
- {"version":3,"file":"account.js","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"AAQA,+FAA+F;AAC/F,4FAA4F;AAC5F,yDAAyD;AACzD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAkB;IACnD,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,CAAC,OAAO,aAAa,EAAE;YACvD,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,QAAQ,CAAC,YAAY,EAAE,EAAE;YAC7D,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;SACpC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,IAAI,OAAO,GAAG,oCAAoC,QAAQ,CAAC,MAAM,IAAI,CAAC;QACtE,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAuB,CAAC;YAC3D,IAAI,IAAI,CAAC,KAAK;gBAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC,CAAC,kCAAkC,CAAC,CAAC;QAC9C,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,GAAG,oFAAoF,CAAC;QAC5H,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAY,CAAC;AAC5C,CAAC;AAED,+FAA+F;AAC/F,gGAAgG;AAChG,gGAAgG;AAChG,uEAAuE;AACvE,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAkB;IACnD,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,CAAC,OAAO,YAAY,EAAE;YACtD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,QAAQ,CAAC,YAAY,EAAE,EAAE;YAC7D,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;SACpC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC;IAC1D,CAAC;IAED,6EAA6E;IAC7E,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;QAAE,OAAO;IAEpC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,IAAI,OAAO,GAAG,iCAAiC,QAAQ,CAAC,MAAM,IAAI,CAAC;QACnE,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAuB,CAAC;YAC3D,IAAI,IAAI,CAAC,KAAK;gBAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC,CAAC,kCAAkC,CAAC,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"account.js","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"AAQA,+FAA+F;AAC/F,4FAA4F;AAC5F,yDAAyD;AACzD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAkB;IACnD,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,CAAC,OAAO,aAAa,EAAE;YACvD,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,QAAQ,CAAC,YAAY,EAAE,EAAE;YAC7D,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;SACpC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,IAAI,OAAO,GAAG,oCAAoC,QAAQ,CAAC,MAAM,IAAI,CAAC;QACtE,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAuB,CAAC;YAC3D,IAAI,IAAI,CAAC,KAAK;gBAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC,CAAC,kCAAkC,CAAC,CAAC;QAC9C,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,GAAG,iEAAiE,CAAC;QACzG,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAY,CAAC;AAC5C,CAAC;AAED,+FAA+F;AAC/F,gGAAgG;AAChG,gGAAgG;AAChG,uEAAuE;AACvE,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAkB;IACnD,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,CAAC,OAAO,YAAY,EAAE;YACtD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,QAAQ,CAAC,YAAY,EAAE,EAAE;YAC7D,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;SACpC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC;IAC1D,CAAC;IAED,6EAA6E;IAC7E,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;QAAE,OAAO;IAEpC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,IAAI,OAAO,GAAG,iCAAiC,QAAQ,CAAC,MAAM,IAAI,CAAC;QACnE,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAuB,CAAC;YAC3D,IAAI,IAAI,CAAC,KAAK;gBAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC,CAAC,kCAAkC,CAAC,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC"}
package/dist/agents.d.ts CHANGED
@@ -19,9 +19,15 @@ export interface AgentDefinition {
19
19
  /**
20
20
  * Reverse of mergeHookConfig — strips beam's hook entry back out, leaving any other hooks the
21
21
  * agent or the user configured untouched. Must be idempotent — safe to call on a config that
22
- * never had beam installed (a no-op).
22
+ * never had beam installed (a no-op). Takes a predicate rather than an exact command string:
23
+ * a hook's command embeds the absolute path to whichever beam install wrote it (see
24
+ * resolveHookCommand in install.ts), which differs between a global npm install, a local dev
25
+ * checkout, or the same install after 'beam update' changes its resolved path. An uninstall
26
+ * running from a *different* beam install than the one that wrote the entry must still
27
+ * recognize and remove it -- matching only one exact string silently leaves it in place (and
28
+ * beam fully monitoring/enforcing) instead. See isOwnHookCommand in install.ts.
23
29
  */
24
- unmergeHookConfig: ((existing: Obj, command: string) => Obj) | null;
30
+ unmergeHookConfig: ((existing: Obj, isOwnCommand: (command: string) => boolean) => Obj) | null;
25
31
  /** Payload adapter id used by src/hook-adapters.ts to normalize this agent's stdin JSON. */
26
32
  adapter: "passthrough" | "copilot-camel" | "generic" | "gemini";
27
33
  /** Whether the AGENT ITSELF (not just this entry's payload verification) is unverified — the
package/dist/agents.js CHANGED
@@ -43,33 +43,33 @@ function mergeCopilotHooks(event) {
43
43
  // Reverse of mergeClaudeStyleHooks: drops beam's command out of each entry's inner hooks array
44
44
  // (rather than the whole entry), so a user-added hook sharing the same matcher is left alone.
45
45
  function unmergeClaudeStyleHooks(event) {
46
- return (existing, command) => {
46
+ return (existing, isOwnCommand) => {
47
47
  const hooks = obj(existing.hooks);
48
48
  if (!(event in hooks))
49
49
  return existing;
50
50
  const list = arr(hooks[event]).map(obj)
51
- .map(entry => ({ ...entry, hooks: arr(entry.hooks).map(obj).filter(h => h.command !== command) }))
51
+ .map(entry => ({ ...entry, hooks: arr(entry.hooks).map(obj).filter(h => !isOwnCommand(String(h.command ?? ""))) }))
52
52
  .filter(entry => arr(entry.hooks).length > 0);
53
53
  return { ...existing, hooks: { ...hooks, [event]: list } };
54
54
  };
55
55
  }
56
56
  // Reverse of mergeCursorHooks.
57
57
  function unmergeCursorHooks(event) {
58
- return (existing, command) => {
58
+ return (existing, isOwnCommand) => {
59
59
  const hooks = obj(existing.hooks);
60
60
  if (!(event in hooks))
61
61
  return existing;
62
- const list = arr(hooks[event]).map(obj).filter(entry => entry.command !== command);
62
+ const list = arr(hooks[event]).map(obj).filter(entry => !isOwnCommand(String(entry.command ?? "")));
63
63
  return { ...existing, hooks: { ...hooks, [event]: list } };
64
64
  };
65
65
  }
66
66
  // Reverse of mergeCopilotHooks.
67
67
  function unmergeCopilotHooks(event) {
68
- return (existing, command) => {
68
+ return (existing, isOwnCommand) => {
69
69
  const hooks = obj(existing.hooks);
70
70
  if (!(event in hooks))
71
71
  return existing;
72
- const list = arr(hooks[event]).map(obj).filter(entry => entry.bash !== command);
72
+ const list = arr(hooks[event]).map(obj).filter(entry => !isOwnCommand(String(entry.bash ?? "")));
73
73
  return { ...existing, hooks: { ...hooks, [event]: list } };
74
74
  };
75
75
  }
@@ -83,7 +83,7 @@ function mergeAll(mergers) {
83
83
  return (existing, command) => mergers.reduce((acc, merge) => merge(acc, command), existing);
84
84
  }
85
85
  function unmergeAll(unmergers) {
86
- return (existing, command) => unmergers.reduce((acc, unmerge) => unmerge(acc, command), existing);
86
+ return (existing, isOwnCommand) => unmergers.reduce((acc, unmerge) => unmerge(acc, isOwnCommand), existing);
87
87
  }
88
88
  export const AGENTS = [
89
89
  {
@@ -1 +1 @@
1
- {"version":3,"file":"agents.js","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare function blockedTargetsFile(): string;
2
+ export declare function readBlockedTargets(): Promise<string[]>;
3
+ export declare function addBlockedTarget(target: string): Promise<string[]>;
4
+ export declare function removeBlockedTarget(target: string): Promise<string[]>;
5
+ export declare function isTargetBlocked(ctx: {
6
+ path?: string;
7
+ command?: string;
8
+ }, blocked: string[]): boolean;
@@ -0,0 +1,83 @@
1
+ import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
2
+ import { isAbsolute, join, relative, resolve } from "node:path";
3
+ import { getDataDirectory } from "./config.js";
4
+ // A global, human-maintained denylist -- the "Block always" choice on a warn prompt writes here.
5
+ // Lives under the data directory, same as trusted-paths.json: isBeamSelfProtectionTarget() already
6
+ // blocks an agent from writing to this directory, so only a human choosing it interactively (or
7
+ // running the CLI) can add an entry, never the agent whose own action got blocked.
8
+ export function blockedTargetsFile() { return join(getDataDirectory(), "blocked-targets.json"); }
9
+ export async function readBlockedTargets() {
10
+ try {
11
+ const parsed = JSON.parse(await readFile(blockedTargetsFile(), "utf8"));
12
+ return Array.isArray(parsed) ? parsed.filter((p) => typeof p === "string" && p.trim().length > 0) : [];
13
+ }
14
+ catch {
15
+ return [];
16
+ }
17
+ }
18
+ async function writeBlockedTargets(targets) {
19
+ const dir = getDataDirectory();
20
+ await mkdir(dir, { recursive: true, mode: 0o700 });
21
+ const file = blockedTargetsFile();
22
+ const temp = `${file}.tmp`;
23
+ await writeFile(temp, JSON.stringify(targets, null, 2) + "\n", { mode: 0o600 });
24
+ await rename(temp, file);
25
+ }
26
+ function normalizeEntry(target) {
27
+ return isAbsolute(target) ? resolve(target) : target.trim();
28
+ }
29
+ export async function addBlockedTarget(target) {
30
+ const entry = normalizeEntry(target);
31
+ const current = await readBlockedTargets();
32
+ if (current.includes(entry))
33
+ return current;
34
+ const next = [...current, entry];
35
+ await writeBlockedTargets(next);
36
+ return next;
37
+ }
38
+ export async function removeBlockedTarget(target) {
39
+ const entry = normalizeEntry(target);
40
+ const next = (await readBlockedTargets()).filter(t => t !== entry);
41
+ await writeBlockedTargets(next);
42
+ return next;
43
+ }
44
+ // Path-glob semantics: "*" matches within one path segment, "**" crosses "/".
45
+ function pathGlobMatch(entry, value) {
46
+ const escaped = entry.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "§§").replace(/\*/g, "[^/]*").replace(/§§/g, ".*");
47
+ return new RegExp(`^${escaped}$`, "i").test(value);
48
+ }
49
+ // Command-glob semantics: a command line has no path-segment structure, so "*" matches anything,
50
+ // including "/" -- otherwise `rm -rf *` would never match `rm -rf /tmp/build`.
51
+ function commandGlobMatch(entry, value) {
52
+ const escaped = entry.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
53
+ return new RegExp(`^${escaped}$`, "i").test(value);
54
+ }
55
+ // Absolute-path entries (the common case -- a file/dir path a user chose "Block always" on) match
56
+ // by equality, subdirectory containment, or glob against the current action's path. Anything else
57
+ // was recorded from a command line with no clear path (e.g. a risky shell command), so it matches
58
+ // as a glob/substring against the current command instead.
59
+ export function isTargetBlocked(ctx, blocked) {
60
+ return blocked.some(entry => {
61
+ if (isAbsolute(entry)) {
62
+ if (!ctx.path)
63
+ return false;
64
+ const target = resolve(ctx.path);
65
+ if (target === entry)
66
+ return true;
67
+ const rel = relative(entry, target);
68
+ return rel !== "" && !rel.startsWith("..") && !isAbsolute(rel);
69
+ }
70
+ if (ctx.command) {
71
+ if (entry.includes("*")) {
72
+ if (commandGlobMatch(entry, ctx.command))
73
+ return true;
74
+ }
75
+ else if (ctx.command.toLowerCase().includes(entry.toLowerCase()))
76
+ return true;
77
+ }
78
+ if (ctx.path && entry.includes("*") && pathGlobMatch(entry, ctx.path))
79
+ return true;
80
+ return false;
81
+ });
82
+ }
83
+ //# sourceMappingURL=blocked-targets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blocked-targets.js","sourceRoot":"","sources":["../src/blocked-targets.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -6,10 +6,11 @@ import { startServer } from "./serve.js";
6
6
  import { captureHook, extractPreview, extractSave, importEvents, readToken, reloadRemoteRules, scanFile } from "./client.js";
7
7
  import { supportsExtraction } from "./extract.js";
8
8
  import { AGENTS } from "./agents.js";
9
- import { installAllDetectedHooks, installHook, uninstallAllHooks } from "./install.js";
10
- import { installService, serviceLogPaths, serviceStatus, startService, stopService, uninstallService } from "./service.js";
9
+ import { installAllDetectedHooks, installHook, uninstallAllHooks, uninstallHook } from "./install.js";
10
+ import { configuredPort, installService, serviceLogPaths, serviceStatus, startService, stopService, uninstallService } from "./service.js";
11
+ import { waitForCollectorUp } from "./collector-health.js";
11
12
  import { getBeamHome, getCollectorUrl, getDataDirectory, getIdentityPath } from "./config.js";
12
- import { clearIdentity, enrollDevice, readIdentity } from "./enroll.js";
13
+ import { clearIdentity, readIdentity } from "./enroll.js";
13
14
  import { startConnect } from "./connect.js";
14
15
  import { runSetup, promptYesNo } from "./setup.js";
15
16
  import { installEnterprisePackage } from "./enterprise-install.js";
@@ -27,6 +28,10 @@ import { runAgent } from "./run.js";
27
28
  import { AGENT_BINARIES, installShims, listShims, pathExportLine, shimDir, uninstallShims } from "./shims.js";
28
29
  import { runMcpProxy } from "./mcp-proxy.js";
29
30
  import { registerJevCommands } from "./jev-cli.js";
31
+ import { addTrustedPath, readTrustedPaths, removeTrustedPath, trustedPathsFile } from "./trusted-paths.js";
32
+ import { blockedTargetsFile, readBlockedTargets, removeBlockedTarget } from "./blocked-targets.js";
33
+ import { checkForUpdate, installUpdate } from "./update.js";
34
+ import { recordExpectedHooks, reportControlEvent } from "./tamper.js";
30
35
  // Lets 'BEAM_API_URL=... beam connect' style overrides live in a .env file instead of the
31
36
  // shell profile. Checked in cwd first (handy when developing from the repo), then in
32
37
  // ~/.beam so overrides still apply when 'beam' is run globally from any directory.
@@ -70,7 +75,7 @@ program.command("start")
70
75
  const rulesNote = result.customRules.loaded ? `\nCustom rules loaded: ${result.customRules.loaded} from ${result.customRules.path}` : "";
71
76
  for (const message of result.customRules.errors)
72
77
  console.error(`✖ ${message}`);
73
- const policyNote = result.policySync ? "\nPolicy sync: on (every 60s)" : "\nPolicy sync: off (device not enrolled — run 'beam enroll')";
78
+ const policyNote = result.policySync ? "\nPolicy sync: on (every 60s)" : "\nPolicy sync: off (device not enrolled — run 'beam setup')";
74
79
  const newlyInstalled = result.agentInstalls.filter(r => r.status === "installed");
75
80
  const installNote = newlyInstalled.length
76
81
  ? `\nAgent hooks installed: ${newlyInstalled.map(r => r.name).join(", ")}`
@@ -81,19 +86,80 @@ program.command("start")
81
86
  }
82
87
  console.log(`Beam collector running.\nMode: observe only\nLocal storage: ${result.directory}${rulesNote}${policyNote}${installNote}\nRun 'beam agent list' to see every detected agent's capture status.\nRun 'beam token' for the pairing token.`);
83
88
  });
89
+ // Shared gate for every command that reduces or removes beam's visibility on this device
90
+ // (stopping/uninstalling the service, detaching an agent's hook, or logging out entirely). On an
91
+ // enrolled device these are exactly the actions an employee could otherwise use to go dark to
92
+ // their org's dashboard without anyone knowing -- see tamper.ts. So each one prints what will
93
+ // actually happen and, when enrolled, that the org admin will be notified this device did it,
94
+ // then requires an explicit "Yes" (or --yes, for scripted/CI use) before doing anything. There is
95
+ // no path to run the underlying action without either declining here or accepting the notice: the
96
+ // action and the report are the same decision, not two.
97
+ async function confirmControlAction(message, identity, yes) {
98
+ console.log(identity
99
+ ? `${message}\nYour organization admin will be notified that this device (${identity.hostname}) did this.`
100
+ : message);
101
+ if (yes)
102
+ return true;
103
+ return promptYesNo("\nProceed?", false);
104
+ }
84
105
  const service = program.command("service").description("Run the collector as a background service (launchd on macOS, systemd --user on Linux)");
85
106
  service.command("install")
86
107
  .description("Install and start the collector as a background service that survives reboots")
87
108
  .option("-p, --port <port>", "port to listen on")
88
109
  .action(async (options) => {
89
110
  const result = await installService({ port: options.port ? Number(options.port) : undefined });
90
- console.log(`✔ Installed and started the beam service (${result.platform})\n config: ${result.configPath}`);
111
+ const up = await waitForCollectorUp(result.port ?? 4319);
112
+ if (up) {
113
+ console.log(`✔ Installed and started the beam service (${result.platform})\n config: ${result.configPath}`);
114
+ }
115
+ else {
116
+ console.log(`✖ Installed the beam service (${result.platform}), but it isn't responding on port ${result.port ?? 4319} yet.\n config: ${result.configPath}\n Check the logs: beam service logs`);
117
+ process.exitCode = 1;
118
+ }
91
119
  });
92
120
  service.command("uninstall")
93
121
  .description("Stop and remove the background service")
94
- .action(async () => { await uninstallService(); console.log("✔ Removed the beam service."); });
95
- service.command("start").description("Start the installed background service").action(async () => { await startService(); console.log("✔ Started."); });
96
- service.command("stop").description("Stop the installed background service").action(async () => { await stopService(); console.log("✔ Stopped."); });
122
+ .option("--yes", "skip the confirmation prompt")
123
+ .action(async (options) => {
124
+ const identity = await readIdentity();
125
+ const proceed = await confirmControlAction("This will stop and remove beam's background service. It will no longer observe or policy-enforce AI agent activity on this device.", identity, options.yes);
126
+ if (!proceed) {
127
+ console.log("Cancelled.");
128
+ return;
129
+ }
130
+ if (identity)
131
+ await reportControlEvent("service-uninstall", `Beam service removed on ${identity.hostname}`, "This device ran 'beam service uninstall'. Beam's background collector will no longer start automatically -- it is not observing or policy-enforcing until 'beam service install' runs again.");
132
+ await uninstallService();
133
+ console.log("✔ Removed the beam service.");
134
+ });
135
+ service.command("start")
136
+ .description("Start the installed background service")
137
+ .action(async () => {
138
+ await startService();
139
+ const port = await configuredPort();
140
+ const up = await waitForCollectorUp(port);
141
+ if (up)
142
+ console.log("✔ Started.");
143
+ else {
144
+ console.log(`✖ Told to start, but the collector isn't responding on port ${port} yet.\n Check the logs: beam service logs`);
145
+ process.exitCode = 1;
146
+ }
147
+ });
148
+ service.command("stop")
149
+ .description("Stop the installed background service")
150
+ .option("--yes", "skip the confirmation prompt")
151
+ .action(async (options) => {
152
+ const identity = await readIdentity();
153
+ const proceed = await confirmControlAction("This will stop beam's background service. It will not observe or policy-enforce AI agent activity on this device until it's started again.", identity, options.yes);
154
+ if (!proceed) {
155
+ console.log("Cancelled.");
156
+ return;
157
+ }
158
+ if (identity)
159
+ await reportControlEvent("service-stop", `Beam service stopped on ${identity.hostname}`, "This device ran 'beam service stop'. Beam's background collector is not running -- it is not observing or policy-enforcing until it's started again.");
160
+ await stopService();
161
+ console.log("✔ Stopped.");
162
+ });
97
163
  service.command("status")
98
164
  .description("Show whether the background service is installed and running")
99
165
  .action(async () => {
@@ -126,27 +192,12 @@ program.command("studio")
126
192
  openBrowser(`${origin}/?token=${encodeURIComponent(token)}`);
127
193
  console.log("Opening beam studio in your browser…");
128
194
  });
129
- program.command("enroll")
130
- .description("Enroll this device with your Beam workspace using a code from your manager")
131
- .requiredOption("--code <code>", "enrollment code, e.g. BEAM-XXXX-XXXX-XXXX")
132
- .option("--url <url>", "Beam API base URL (default $BEAM_API_URL or https://collector.agentbeam.com)")
133
- .action(async (options) => {
134
- const existing = await readIdentity();
135
- if (existing)
136
- console.error(`Replacing the existing enrollment (device ${existing.deviceId}).`);
137
- const identity = await enrollDevice(options);
138
- console.log(`${green("✔")} Enrolled device ${identity.deviceId}\n` +
139
- ` org: ${identity.orgId}\n` +
140
- ` api: ${identity.apiBase}\n` +
141
- ` identity: ${getIdentityPath()} (0600)\n\n` +
142
- cyan(`Next: beam agent install-all && beam start`));
143
- });
144
195
  program.command("whoami")
145
196
  .description("Show this device's enrollment, if any")
146
197
  .action(async () => {
147
198
  const identity = await readIdentity();
148
199
  if (!identity)
149
- throw new Error("This device is not enrolled. Run 'beam enroll --code <code>'.");
200
+ throw new Error("This device is not enrolled. Run 'beam setup'.");
150
201
  console.log(`device: ${identity.deviceId}\norg: ${identity.orgId}\napi: ${identity.apiBase}\nhost: ${identity.hostname} (${identity.os})\nsince: ${identity.enrolledAt}`);
151
202
  });
152
203
  program.command("account")
@@ -154,7 +205,7 @@ program.command("account")
154
205
  .action(async () => {
155
206
  const identity = await readIdentity();
156
207
  if (!identity)
157
- throw new Error("This device is not enrolled. Run 'beam connect' or 'beam enroll --code <code>'.");
208
+ throw new Error("This device is not enrolled. Run 'beam setup'.");
158
209
  const account = await fetchAccount(identity);
159
210
  console.log(`user: ${account.user.email}${account.user.name ? ` (${account.user.name})` : ""}\n` +
160
211
  `org: ${account.org.name} (${account.org.slug})\n` +
@@ -163,12 +214,22 @@ program.command("account")
163
214
  });
164
215
  program.command("logout")
165
216
  .description("Disconnect this device from your Beam workspace and remove local credentials")
166
- .action(async () => {
217
+ .option("--yes", "skip the confirmation prompt")
218
+ .action(async (options) => {
167
219
  const identity = await readIdentity();
168
220
  if (!identity) {
169
221
  console.log("This device is not enrolled -- nothing to do.");
170
222
  return;
171
223
  }
224
+ const proceed = await confirmControlAction("This will disconnect this device from your Beam workspace. It will stop reporting activity until it's re-enrolled.", identity, options.yes);
225
+ if (!proceed) {
226
+ console.log("Cancelled.");
227
+ return;
228
+ }
229
+ // Sent while identity.json still exists, so it authenticates -- and before revokeDevice()
230
+ // below, so it's an authenticated "I chose to log out" record rather than something an admin
231
+ // has to infer from the device simply going quiet (see tamper.ts).
232
+ await reportControlEvent("logout", `Beam logged out on ${identity.hostname}`, `This device was logged out via 'beam logout'. It is no longer enrolled and will stop reporting until re-enrolled.`);
172
233
  try {
173
234
  await revokeDevice(identity);
174
235
  }
@@ -186,18 +247,23 @@ program.command("uninstall")
186
247
  .action(async (options) => {
187
248
  const beamHome = getBeamHome();
188
249
  const dataDir = getDataDirectory();
189
- console.log("This will remove:\n" +
250
+ const identityBeforeUninstall = await readIdentity();
251
+ const proceed = await confirmControlAction("This will remove:\n" +
190
252
  " - the beam background service (if installed)\n" +
191
253
  " - beam's hooks from every AI agent config it was wired into\n" +
192
254
  ` - ${beamHome} (identity, cached policy, event logs, custom rules)\n` +
193
255
  " - this device's registration with your Beam workspace" +
194
- (options.keepPackage ? "" : "\n - the globally installed beam (and beam-enterprise, if present) npm package"));
195
- if (!options.yes) {
196
- const proceed = await promptYesNo("\nProceed?", false);
197
- if (!proceed) {
198
- console.log("Cancelled.");
199
- return;
200
- }
256
+ (options.keepPackage ? "" : "\n - the globally installed beam (and beam-enterprise, if present) npm package"), identityBeforeUninstall, options.yes);
257
+ if (!proceed) {
258
+ console.log("Cancelled.");
259
+ return;
260
+ }
261
+ // Sent first, before anything below touches identity.json, the service, or hooks -- so the
262
+ // workspace has an authenticated "this was a deliberate 'beam uninstall'" record even if a
263
+ // later step in this command fails partway through. See tamper.ts: this is what distinguishes
264
+ // an authorized removal from the silent kind checkForTampering() is built to catch.
265
+ if (identityBeforeUninstall) {
266
+ await reportControlEvent("uninstall", `Beam uninstalled on ${identityBeforeUninstall.hostname}`, "This device ran 'beam uninstall'. Its background service, agent hooks, and local data are being removed, and its registration is being revoked.");
201
267
  }
202
268
  try {
203
269
  await uninstallService();
@@ -206,14 +272,23 @@ program.command("uninstall")
206
272
  catch (e) {
207
273
  console.log(`— Skipped background service (${e.message}).`);
208
274
  }
209
- const hookResults = await uninstallAllHooks();
210
- const removedHooks = hookResults.filter(r => r.removed);
211
- if (removedHooks.length) {
212
- for (const r of removedHooks)
213
- console.log(`✔ Removed beam's hook from ${r.agent}\n → ${r.path}`);
275
+ // Wrapped like uninstallService() above: one agent's hook config being unreadable (invalid
276
+ // JSON, a permission error) must not abort the rest of 'beam uninstall' -- in particular it
277
+ // must not skip revokeDevice() below, or the device is wiped locally but the dashboard shows
278
+ // it as connected forever with nothing left running here to ever tell it otherwise.
279
+ try {
280
+ const hookResults = await uninstallAllHooks();
281
+ const removedHooks = hookResults.filter(r => r.removed);
282
+ if (removedHooks.length) {
283
+ for (const r of removedHooks)
284
+ console.log(`✔ Removed beam's hook from ${r.agent}\n → ${r.path}`);
285
+ }
286
+ else {
287
+ console.log("— No installed agent hooks found.");
288
+ }
214
289
  }
215
- else {
216
- console.log("— No installed agent hooks found.");
290
+ catch (e) {
291
+ console.log(`— Could not remove every agent hook (${e.message}).`);
217
292
  }
218
293
  const identity = await readIdentity();
219
294
  if (identity) {
@@ -254,11 +329,37 @@ program.command("sync")
254
329
  .action(async () => {
255
330
  const result = await syncPolicy();
256
331
  if (result.status === "not-enrolled")
257
- throw new Error("This device is not enrolled. Run 'beam enroll --code <code>'.");
332
+ throw new Error("This device is not enrolled. Run 'beam setup'.");
258
333
  if (result.status === "unreachable")
259
334
  throw new Error("Could not reach the Beam workspace. Check the network or 'beam whoami'.");
260
335
  console.log(result.status === "updated" ? `✔ Policy v${result.version} synced → ${result.path}` : "✔ Policy already up to date.");
261
336
  });
337
+ program.command("update")
338
+ .description("Update the globally installed beam CLI to the latest published version")
339
+ .option("--check", "only check for an update, don't install it")
340
+ .action(async (options) => {
341
+ let check;
342
+ try {
343
+ check = await checkForUpdate(packageJson.version);
344
+ }
345
+ catch (e) {
346
+ throw new Error(`Could not check for updates: ${e.message}`);
347
+ }
348
+ if (check.upToDate) {
349
+ console.log(`✔ beam is up to date (v${check.current}).`);
350
+ return;
351
+ }
352
+ console.log(`A new version is available: v${check.current} → v${check.latest}`);
353
+ if (options.check)
354
+ return;
355
+ try {
356
+ await installUpdate(check.latest);
357
+ console.log(`✔ Updated to v${check.latest}. Restart any running beam service to pick it up: 'beam service stop && beam service start'.`);
358
+ }
359
+ catch (e) {
360
+ throw new Error(`Could not install the update automatically: ${e.message}\n Run manually: npm install -g @agent-beam/beam@${check.latest}`);
361
+ }
362
+ });
262
363
  const shims = program.command("shims").description("Make agent CLIs (claude, codex, ...) sandboxed automatically, without typing 'beam run'");
263
364
  shims.command("install")
264
365
  .description("Install PATH shims for the given agents (default: all known agents found on this machine)")
@@ -345,8 +446,26 @@ agent.command("install")
345
446
  .argument("<agent>", "agent id, e.g. claude-code, codex, cursor, copilot-cli")
346
447
  .action(async (agentId) => {
347
448
  const result = await installHook(agentId);
449
+ await recordExpectedHooks();
348
450
  console.log(result.alreadyInstalled ? `✔ Already installed for ${result.agent}\n → ${result.path}` : `✔ Installed beam hook for ${result.agent}\n → ${result.path}`);
349
451
  });
452
+ agent.command("uninstall")
453
+ .description("Detach beam's hook from a single agent's own hook config, leaving everything else installed")
454
+ .argument("<agent>", "agent id, e.g. claude-code, codex, cursor, copilot-cli")
455
+ .option("--yes", "skip the confirmation prompt")
456
+ .action(async (agentId, options) => {
457
+ const identity = await readIdentity();
458
+ const proceed = await confirmControlAction(`This will detach beam's hook from ${agentId}. Its activity will no longer be observed or policy-enforced by beam.`, identity, options.yes);
459
+ if (!proceed) {
460
+ console.log("Cancelled.");
461
+ return;
462
+ }
463
+ if (identity)
464
+ await reportControlEvent(`agent-uninstall-${agentId}`, `Beam hook detached from ${agentId} on ${identity.hostname}`, `This device ran 'beam agent uninstall ${agentId}'. ${agentId} is no longer being observed or policy-enforced by beam.`);
465
+ const result = await uninstallHook(agentId);
466
+ await recordExpectedHooks();
467
+ console.log(result.removed ? `✔ Detached beam's hook from ${result.agent}\n → ${result.path}` : `— No beam hook found for ${result.agent}.`);
468
+ });
350
469
  agent.command("extract")
351
470
  .description("Forensic extraction: read an agent's existing session/transcript files directly, no hook or live capture required")
352
471
  .argument("<agent>", `agent id (currently: claude-code, codex)`)
@@ -369,6 +488,7 @@ agent.command("install-all")
369
488
  .description("Detect which agents are actually installed on this machine and wire beam's hook into all of them")
370
489
  .action(async () => {
371
490
  const results = await installAllDetectedHooks();
491
+ await recordExpectedHooks();
372
492
  for (const r of results) {
373
493
  if (r.status === "installed")
374
494
  console.log(`✔ Installed for ${r.name}\n → ${r.path}`);
@@ -425,6 +545,52 @@ rule.command("reload")
425
545
  for (const e of result.errors)
426
546
  console.log(`✖ ${e}`);
427
547
  });
548
+ const trust = program.command("trust").description("Manage the global allowlist of outside-workspace paths Beam won't ask about again (advisory/enforce mode only)");
549
+ trust.command("add <path>")
550
+ .description("Pre-approve a path or directory (or a glob containing '*') so Beam stops asking about it")
551
+ .action(async (path) => {
552
+ await addTrustedPath(path);
553
+ console.log(`✔ Trusted: ${path}`);
554
+ });
555
+ trust.command("remove <path>")
556
+ .alias("rm")
557
+ .description("Remove a path from the trusted allowlist")
558
+ .action(async (path) => {
559
+ await removeTrustedPath(path);
560
+ console.log(`✔ Untrusted: ${path}`);
561
+ });
562
+ trust.command("list")
563
+ .alias("ls")
564
+ .description("List all trusted outside-workspace paths")
565
+ .action(async () => {
566
+ const paths = await readTrustedPaths();
567
+ if (!paths.length) {
568
+ console.log(`No trusted paths (${trustedPathsFile()}).`);
569
+ return;
570
+ }
571
+ for (const p of paths)
572
+ console.log(p);
573
+ });
574
+ const block = program.command("block").description("Audit or undo entries added by the 'Block always' choice on a warn prompt");
575
+ block.command("remove <target>")
576
+ .alias("rm")
577
+ .description("Remove a target from the blocked list")
578
+ .action(async (target) => {
579
+ await removeBlockedTarget(target);
580
+ console.log(`✔ Unblocked: ${target}`);
581
+ });
582
+ block.command("list")
583
+ .alias("ls")
584
+ .description("List all blocked targets")
585
+ .action(async () => {
586
+ const targets = await readBlockedTargets();
587
+ if (!targets.length) {
588
+ console.log(`No blocked targets (${blockedTargetsFile()}).`);
589
+ return;
590
+ }
591
+ for (const t of targets)
592
+ console.log(t);
593
+ });
428
594
  try {
429
595
  await program.parseAsync();
430
596
  }