@openbat/cli 0.1.1 → 0.2.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.
package/README.md CHANGED
@@ -280,6 +280,24 @@ Per-tool buckets keyed by credential. The strict ones to know about:
280
280
 
281
281
  ---
282
282
 
283
+ ## Pre-loaded context for AI assistants
284
+
285
+ If you're an AI agent (or driving one) and you'd like the procedural
286
+ knowledge for using this CLI delivered straight into your context,
287
+ install the OpenBat agent skill bundle:
288
+
289
+ ```bash
290
+ npx skills add openbat-dev/agent-skills
291
+ ```
292
+
293
+ Drops 8 `SKILL.md` files into your project's `.claude/skills/` (or the
294
+ equivalent for Cursor / Copilot / Gemini CLI / Codex / OpenCode / Amp).
295
+ The bundle covers chatbot onboarding, key management, webhooks,
296
+ workflows, AI reports, SDK install, and safety patterns — written
297
+ specifically for the four-kind auth ladder this CLI exposes.
298
+
299
+ Source + docs: https://github.com/openbat-dev/agent-skills.
300
+
283
301
  ## See also
284
302
 
285
303
  - [`@openbat/mcp`](../mcp/README.md) — the same surface to Claude /
@@ -288,5 +306,7 @@ Per-tool buckets keyed by credential. The strict ones to know about:
288
306
  app (uses the ingest key only).
289
307
  - [`lib/openbat-tools/`](../../lib/openbat-tools/README.md) — the
290
308
  registry that powers every CLI command + MCP tool + v1 route.
309
+ - [Agent skill bundle](https://github.com/openbat-dev/agent-skills) —
310
+ procedural knowledge for AI agents (`npx skills add openbat-dev/agent-skills`).
291
311
  - [A-Z test guide](../../docs/agent-surface-testing.md) — clone the
292
312
  repo and exercise every key kind, CLI, MCP, SDK in ~30 minutes.
@@ -14,6 +14,15 @@
14
14
  type ApiClientOptions = {
15
15
  baseUrl: string;
16
16
  apiKey: string;
17
+ /**
18
+ * Identifies the caller for analytics. Defaults to `"cli"`. The MCP server
19
+ * passes `"mcp"`. Reaches the server as `x-openbat-client` and surfaces in
20
+ * PostHog as the `client` event property — used to distinguish CLI usage
21
+ * from MCP-via-Cursor usage in cohorts and funnels.
22
+ */
23
+ clientLabel?: "cli" | "mcp";
24
+ /** SDK / CLI / MCP package version, sent as `x-openbat-client-version`. */
25
+ clientVersion?: string;
17
26
  };
18
27
  declare class ApiClient {
19
28
  #private;
@@ -14,6 +14,15 @@
14
14
  type ApiClientOptions = {
15
15
  baseUrl: string;
16
16
  apiKey: string;
17
+ /**
18
+ * Identifies the caller for analytics. Defaults to `"cli"`. The MCP server
19
+ * passes `"mcp"`. Reaches the server as `x-openbat-client` and surfaces in
20
+ * PostHog as the `client` event property — used to distinguish CLI usage
21
+ * from MCP-via-Cursor usage in cohorts and funnels.
22
+ */
23
+ clientLabel?: "cli" | "mcp";
24
+ /** SDK / CLI / MCP package version, sent as `x-openbat-client-version`. */
25
+ clientVersion?: string;
17
26
  };
18
27
  declare class ApiClient {
19
28
  #private;
@@ -32,6 +32,7 @@ __export(api_client_exports, {
32
32
  });
33
33
  module.exports = __toCommonJS(api_client_exports);
34
34
  var import_node_url = require("url");
35
+ var CLI_VERSION = "0.1.1";
35
36
  var KEY_REGEX = /ob_(?:live|read|admin|pat)_[0-9a-f]{32}/g;
36
37
  function redact(s) {
37
38
  return s.replace(KEY_REGEX, (k) => `${k.slice(0, 16)}\u2026<hidden>`);
@@ -51,14 +52,18 @@ function assertHttpsOrLocalhost(baseUrl) {
51
52
  "Refusing to use a non-HTTPS base URL. localhost / 127.0.0.1 are allowed for dev."
52
53
  );
53
54
  }
54
- var _apiKey, _ApiClient_instances, mutate_fn;
55
+ var _apiKey, _clientLabel, _clientVersion, _ApiClient_instances, commonHeaders_fn, mutate_fn;
55
56
  var ApiClient = class {
56
57
  constructor(opts) {
57
58
  __privateAdd(this, _ApiClient_instances);
58
59
  __privateAdd(this, _apiKey);
60
+ __privateAdd(this, _clientLabel);
61
+ __privateAdd(this, _clientVersion);
59
62
  assertHttpsOrLocalhost(opts.baseUrl);
60
63
  this.baseUrl = opts.baseUrl.replace(/\/$/, "");
61
64
  __privateSet(this, _apiKey, opts.apiKey);
65
+ __privateSet(this, _clientLabel, opts.clientLabel ?? "cli");
66
+ __privateSet(this, _clientVersion, opts.clientVersion ?? CLI_VERSION);
62
67
  }
63
68
  /**
64
69
  * Issue a GET against `path` (must begin with `/`). Returns the parsed
@@ -71,10 +76,7 @@ var ApiClient = class {
71
76
  try {
72
77
  res = await fetch(url, {
73
78
  method: "GET",
74
- headers: {
75
- "x-openbat-key": __privateGet(this, _apiKey),
76
- accept: "application/json"
77
- }
79
+ headers: __privateMethod(this, _ApiClient_instances, commonHeaders_fn).call(this, { accept: "application/json" })
78
80
  });
79
81
  } catch (err) {
80
82
  const msg = err instanceof Error ? err.message : String(err);
@@ -99,9 +101,7 @@ var ApiClient = class {
99
101
  const url = `${this.baseUrl}${path}`;
100
102
  const res = await fetch(url, {
101
103
  method: "GET",
102
- headers: {
103
- "x-openbat-key": __privateGet(this, _apiKey)
104
- }
104
+ headers: __privateMethod(this, _ApiClient_instances, commonHeaders_fn).call(this)
105
105
  });
106
106
  if (!res.ok || !res.body) {
107
107
  const errText = await res.text().catch(() => "");
@@ -116,18 +116,28 @@ var ApiClient = class {
116
116
  }
117
117
  };
118
118
  _apiKey = new WeakMap();
119
+ _clientLabel = new WeakMap();
120
+ _clientVersion = new WeakMap();
119
121
  _ApiClient_instances = new WeakSet();
122
+ commonHeaders_fn = function(extra) {
123
+ const h = {
124
+ "x-openbat-key": __privateGet(this, _apiKey),
125
+ "x-openbat-client": __privateGet(this, _clientLabel),
126
+ ...extra ?? {}
127
+ };
128
+ if (__privateGet(this, _clientVersion)) h["x-openbat-client-version"] = __privateGet(this, _clientVersion);
129
+ return h;
130
+ };
120
131
  mutate_fn = async function(method, path, body) {
121
132
  const url = `${this.baseUrl}${path}`;
122
133
  let res;
123
134
  try {
124
135
  res = await fetch(url, {
125
136
  method,
126
- headers: {
127
- "x-openbat-key": __privateGet(this, _apiKey),
137
+ headers: __privateMethod(this, _ApiClient_instances, commonHeaders_fn).call(this, {
128
138
  "content-type": "application/json",
129
139
  accept: "application/json"
130
- },
140
+ }),
131
141
  body: body === void 0 ? void 0 : JSON.stringify(body)
132
142
  });
133
143
  } catch (err) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ApiClient
3
- } from "./chunk-CRJZM45P.mjs";
3
+ } from "./chunk-NYKJTHHK.mjs";
4
4
  export {
5
5
  ApiClient
6
6
  };
@@ -9,6 +9,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
9
9
 
10
10
  // src/api-client.ts
11
11
  import { URL } from "url";
12
+ var CLI_VERSION = "0.1.1";
12
13
  var KEY_REGEX = /ob_(?:live|read|admin|pat)_[0-9a-f]{32}/g;
13
14
  function redact(s) {
14
15
  return s.replace(KEY_REGEX, (k) => `${k.slice(0, 16)}\u2026<hidden>`);
@@ -28,14 +29,18 @@ function assertHttpsOrLocalhost(baseUrl) {
28
29
  "Refusing to use a non-HTTPS base URL. localhost / 127.0.0.1 are allowed for dev."
29
30
  );
30
31
  }
31
- var _apiKey, _ApiClient_instances, mutate_fn;
32
+ var _apiKey, _clientLabel, _clientVersion, _ApiClient_instances, commonHeaders_fn, mutate_fn;
32
33
  var ApiClient = class {
33
34
  constructor(opts) {
34
35
  __privateAdd(this, _ApiClient_instances);
35
36
  __privateAdd(this, _apiKey);
37
+ __privateAdd(this, _clientLabel);
38
+ __privateAdd(this, _clientVersion);
36
39
  assertHttpsOrLocalhost(opts.baseUrl);
37
40
  this.baseUrl = opts.baseUrl.replace(/\/$/, "");
38
41
  __privateSet(this, _apiKey, opts.apiKey);
42
+ __privateSet(this, _clientLabel, opts.clientLabel ?? "cli");
43
+ __privateSet(this, _clientVersion, opts.clientVersion ?? CLI_VERSION);
39
44
  }
40
45
  /**
41
46
  * Issue a GET against `path` (must begin with `/`). Returns the parsed
@@ -48,10 +53,7 @@ var ApiClient = class {
48
53
  try {
49
54
  res = await fetch(url, {
50
55
  method: "GET",
51
- headers: {
52
- "x-openbat-key": __privateGet(this, _apiKey),
53
- accept: "application/json"
54
- }
56
+ headers: __privateMethod(this, _ApiClient_instances, commonHeaders_fn).call(this, { accept: "application/json" })
55
57
  });
56
58
  } catch (err) {
57
59
  const msg = err instanceof Error ? err.message : String(err);
@@ -76,9 +78,7 @@ var ApiClient = class {
76
78
  const url = `${this.baseUrl}${path}`;
77
79
  const res = await fetch(url, {
78
80
  method: "GET",
79
- headers: {
80
- "x-openbat-key": __privateGet(this, _apiKey)
81
- }
81
+ headers: __privateMethod(this, _ApiClient_instances, commonHeaders_fn).call(this)
82
82
  });
83
83
  if (!res.ok || !res.body) {
84
84
  const errText = await res.text().catch(() => "");
@@ -93,18 +93,28 @@ var ApiClient = class {
93
93
  }
94
94
  };
95
95
  _apiKey = new WeakMap();
96
+ _clientLabel = new WeakMap();
97
+ _clientVersion = new WeakMap();
96
98
  _ApiClient_instances = new WeakSet();
99
+ commonHeaders_fn = function(extra) {
100
+ const h = {
101
+ "x-openbat-key": __privateGet(this, _apiKey),
102
+ "x-openbat-client": __privateGet(this, _clientLabel),
103
+ ...extra ?? {}
104
+ };
105
+ if (__privateGet(this, _clientVersion)) h["x-openbat-client-version"] = __privateGet(this, _clientVersion);
106
+ return h;
107
+ };
97
108
  mutate_fn = async function(method, path, body) {
98
109
  const url = `${this.baseUrl}${path}`;
99
110
  let res;
100
111
  try {
101
112
  res = await fetch(url, {
102
113
  method,
103
- headers: {
104
- "x-openbat-key": __privateGet(this, _apiKey),
114
+ headers: __privateMethod(this, _ApiClient_instances, commonHeaders_fn).call(this, {
105
115
  "content-type": "application/json",
106
116
  accept: "application/json"
107
- },
117
+ }),
108
118
  body: body === void 0 ? void 0 : JSON.stringify(body)
109
119
  });
110
120
  } catch (err) {