bereach-openclaw 0.2.6 → 0.2.9

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 CHANGED
@@ -10,16 +10,19 @@ openclaw plugins install bereach-openclaw
10
10
 
11
11
  ## Setup
12
12
 
13
- Set your API key in OpenClaw config (`~/.openclaw/openclaw.json`):
13
+ The API key can be set in 3 ways (in order of precedence):
14
14
 
15
- ```json5
15
+ **1. OpenClaw config** (recommended) — `~/.openclaw/openclaw.json` or `/data/.openclaw/openclaw.json`:
16
+
17
+ ```json
16
18
  {
17
- plugins: {
18
- entries: {
19
- bereach: {
20
- enabled: true,
21
- config: {
22
- BEREACH_API_KEY: "brc_your_token_here"
19
+ "plugins": {
20
+ "allow": ["bereach"],
21
+ "entries": {
22
+ "bereach": {
23
+ "enabled": true,
24
+ "config": {
25
+ "BEREACH_API_KEY": "brc_your_token_here"
23
26
  }
24
27
  }
25
28
  }
@@ -27,7 +30,11 @@ Set your API key in OpenClaw config (`~/.openclaw/openclaw.json`):
27
30
  }
28
31
  ```
29
32
 
30
- Or pass it via Docker environment: `docker run -e BEREACH_API_KEY=brc_xxx ...`
33
+ > **Note:** Add `"bereach"` to `plugins.allow` OpenClaw requires explicit allowlist for non-bundled plugins.
34
+
35
+ **2. Environment variable** — `BEREACH_API_KEY=brc_xxx` in your shell or `export BEREACH_API_KEY="brc_xxx"` in `~/.bashrc`.
36
+
37
+ **3. Docker** — pass via `-e` when launching the container: `docker run -e BEREACH_API_KEY=brc_xxx ...`
31
38
 
32
39
  Restart the Gateway after configuring.
33
40
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bereach-openclaw",
3
- "version": "0.2.6",
3
+ "version": "0.2.9",
4
4
  "description": "BeReach LinkedIn automation plugin for OpenClaw",
5
5
  "license": "AGPL-3.0",
6
6
  "scripts": {
@@ -15,6 +15,7 @@
15
15
  "bereach": "^0.1.4"
16
16
  },
17
17
  "devDependencies": {
18
+ "@types/node": "^22.10.0",
18
19
  "tsx": "^4.21.0",
19
20
  "typescript": "^5.9.3"
20
21
  }
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env tsx
2
+ /// <reference types="node" />
2
3
  /**
3
4
  * Simulates OpenClaw plugin registration to catch config/trim errors.
4
5
  * Run: pnpm exec tsx scripts/test-register.ts
@@ -10,13 +11,13 @@ import register from "../src/index";
10
11
  const apiKey = process.env.BEREACH_API_KEY || "brc_test_placeholder";
11
12
 
12
13
  const mockApi = {
13
- config: { BEREACH_API_KEY: apiKey },
14
+ pluginConfig: { BEREACH_API_KEY: apiKey },
14
15
  registerTool: () => {},
15
16
  registerCommand: () => {},
16
17
  registerCli: () => {},
17
18
  };
18
19
 
19
- console.log("Testing plugin register (simulates OpenClaw load)...");
20
+ console.log("Testing plugin register with config (simulates OpenClaw load)...");
20
21
  try {
21
22
  register(mockApi);
22
23
  console.log("✓ register() completed — no trim/undefined errors");
@@ -24,3 +25,14 @@ try {
24
25
  console.error("✗ register() failed:", err?.message || err);
25
26
  process.exit(1);
26
27
  }
28
+
29
+ console.log("\nTesting plugin register WITHOUT config (should load, fail on first use)...");
30
+ try {
31
+ register({ pluginConfig: undefined, registerTool: () => {}, registerCommand: () => {}, registerCli: () => {} });
32
+ console.log("✓ register() completed — plugin loads without config (lazy init)");
33
+ } catch (err: any) {
34
+ console.error("✗ register() failed with missing config:", err?.message || err);
35
+ process.exit(1);
36
+ }
37
+
38
+ console.log("\n✓ All tests passed");
package/src/client.ts CHANGED
@@ -1,12 +1,22 @@
1
1
  import { Bereach } from "bereach";
2
2
 
3
3
  let instance: Bereach | null = null;
4
+ let pendingKey: string | undefined;
5
+
6
+ function normalizeKey(raw: unknown): string | undefined {
7
+ if (raw == null) return undefined;
8
+ const s = typeof raw === "string" ? raw : String(raw);
9
+ const t = s.trim();
10
+ return t.length > 0 ? t : undefined;
11
+ }
12
+
13
+ export function setApiKey(key: string | undefined): void {
14
+ pendingKey = normalizeKey(key);
15
+ }
4
16
 
5
17
  export function createClient(key?: string): Bereach {
6
18
  if (!instance) {
7
- const raw = key ?? process.env.BEREACH_API_KEY;
8
- const apiKey =
9
- typeof raw === "string" && raw.trim().length > 0 ? raw.trim() : undefined;
19
+ const apiKey = normalizeKey(key ?? pendingKey ?? process.env.BEREACH_API_KEY);
10
20
  if (!apiKey) {
11
21
  throw new Error(
12
22
  "BEREACH_API_KEY is required (set in plugin config or environment)",
@@ -16,3 +26,7 @@ export function createClient(key?: string): Bereach {
16
26
  }
17
27
  return instance;
18
28
  }
29
+
30
+ export function getClient(): Bereach {
31
+ return createClient();
32
+ }
@@ -1,14 +1,16 @@
1
- import type { Bereach } from "bereach";
1
+ import { getClient } from "../client";
2
2
 
3
3
  /**
4
4
  * Registers auto-reply commands and CLI commands.
5
5
  * Auto-reply commands execute without invoking the LLM.
6
+ * Client is created lazily on first command invocation.
6
7
  */
7
- export function registerCommands(api: any, client: Bereach) {
8
+ export function registerCommands(api: any) {
8
9
  api.registerCommand({
9
10
  name: "bereach-credits",
10
11
  description: "Show current BeReach credit balance",
11
12
  handler: async () => {
13
+ const client = getClient();
12
14
  const res = await (client as any).profile.getCredits();
13
15
  const c = res.credits;
14
16
  return {
@@ -24,6 +26,7 @@ export function registerCommands(api: any, client: Bereach) {
24
26
  name: "bereach-status",
25
27
  description: "Show LinkedIn rate limit summary",
26
28
  handler: async () => {
29
+ const client = getClient();
27
30
  const res = await (client as any).profile.getLimits();
28
31
  const lines = ["BeReach Rate Limits:"];
29
32
  for (const [action, data] of Object.entries(res.limits) as [string, any][]) {
@@ -38,6 +41,7 @@ export function registerCommands(api: any, client: Bereach) {
38
41
  name: "bereach-limits",
39
42
  description: "Show detailed per-action LinkedIn rate limits",
40
43
  handler: async () => {
44
+ const client = getClient();
41
45
  const res = await (client as any).profile.getLimits();
42
46
  const lines = [`BeReach Rate Limits (multiplier: ${res.multiplier}x):`];
43
47
  for (const [action, data] of Object.entries(res.limits) as [string, any][]) {
@@ -62,6 +66,7 @@ export function registerCommands(api: any, client: Bereach) {
62
66
  .command("status")
63
67
  .description("Show LinkedIn rate limit summary")
64
68
  .action(async () => {
69
+ const client = getClient();
65
70
  const res = await (client as any).profile.getLimits();
66
71
  console.log("BeReach Rate Limits:");
67
72
  for (const [action, data] of Object.entries(res.limits) as [string, any][]) {
package/src/index.ts CHANGED
@@ -1,18 +1,18 @@
1
- import { createClient } from "./client";
1
+ import { setApiKey } from "./client";
2
2
  import { registerAllTools } from "./tools";
3
3
  import { registerCommands } from "./commands";
4
4
 
5
5
  function getApiKey(api: any): string | undefined {
6
- const cfg = api?.config;
7
6
  const key =
8
- cfg?.BEREACH_API_KEY ??
9
- cfg?.plugins?.entries?.bereach?.config?.BEREACH_API_KEY;
7
+ api?.pluginConfig?.BEREACH_API_KEY ?? // 1. OpenClaw config (plugins.entries.bereach.config)
8
+ api?.config?.BEREACH_API_KEY ?? // 2. Fallback config path
9
+ process.env.BEREACH_API_KEY; // 3. Env var (or ~/.bashrc export)
10
10
  return typeof key === "string" && key.trim().length > 0 ? key.trim() : undefined;
11
11
  }
12
12
 
13
13
  export default function register(api: any) {
14
14
  const apiKey = getApiKey(api);
15
- const client = createClient(apiKey);
16
- registerAllTools(api, client);
17
- registerCommands(api, client);
15
+ setApiKey(apiKey);
16
+ registerAllTools(api);
17
+ registerCommands(api);
18
18
  }
@@ -1,11 +1,12 @@
1
+ import { getClient } from "./../client";
1
2
  import { definitions } from "./definitions";
2
- import type { Bereach } from "bereach";
3
3
 
4
4
  /**
5
5
  * Registers all 33 BeReach tools with the OpenClaw agent.
6
6
  * Each tool delegates to the corresponding SDK method via dot-path resolution.
7
+ * Client is created lazily on first tool invocation to avoid trim/undefined errors during plugin load.
7
8
  */
8
- export function registerAllTools(api: any, client: Bereach) {
9
+ export function registerAllTools(api: any) {
9
10
  for (const def of definitions) {
10
11
  api.registerTool(
11
12
  def.name,
@@ -14,6 +15,7 @@ export function registerAllTools(api: any, client: Bereach) {
14
15
  parameters: def.parameters,
15
16
  },
16
17
  async (params: Record<string, unknown>) => {
18
+ const client = getClient();
17
19
  const [resource, method] = def.handler.split(".");
18
20
  const result = await (client as any)[resource][method](params);
19
21
  return result;
package/tsconfig.json CHANGED
@@ -8,7 +8,8 @@
8
8
  "skipLibCheck": true,
9
9
  "outDir": "dist",
10
10
  "rootDir": "src",
11
- "declaration": true
11
+ "declaration": true,
12
+ "types": ["node"]
12
13
  },
13
14
  "include": ["src/**/*.ts"],
14
15
  "exclude": ["__tests__", "node_modules", "dist"]