@basicmemory/openclaw-basic-memory 0.1.0-alpha.10 → 0.1.0-alpha.11

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
@@ -572,22 +572,9 @@ openclaw-basic-memory/
572
572
 
573
573
  ## Telemetry
574
574
 
575
- Basic Memory collects anonymous, minimal usage events to understand how the CLI-to-cloud conversion funnel performs. This helps us prioritize features and improve the product.
575
+ This plugin itself does not collect any telemetry. However, the **Basic Memory CLI** (`bm`) that the plugin spawns may send anonymous usage analytics. See the [Basic Memory documentation](https://github.com/basicmachines-co/basic-memory) for details.
576
576
 
577
- **What we collect:**
578
- - Cloud promo impressions (when the promo banner is shown)
579
- - Cloud login attempts and outcomes
580
- - Promo opt-out events
581
-
582
- **What we do NOT collect:**
583
- - No file contents, note titles, or knowledge base data
584
- - No personally identifiable information (PII)
585
- - No IP address tracking or fingerprinting
586
- - No per-command or per-tool-call tracking
587
-
588
- Events are sent to our [Umami Cloud](https://umami.is) instance, an open-source, privacy-focused analytics platform. Events are fire-and-forget on a background thread — analytics never blocks or slows the CLI.
589
-
590
- **Opt out** by setting the environment variable:
577
+ To opt out of Basic Memory CLI telemetry:
591
578
 
592
579
  ```bash
593
580
  export BASIC_MEMORY_NO_PROMOS=1
package/bm-client.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { setTimeout as delay } from "node:timers/promises"
2
2
  import { Client } from "@modelcontextprotocol/sdk/client"
3
3
  import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"
4
- import { trackToolCall } from "./analytics.ts"
5
4
  import { log } from "./logger.ts"
6
5
 
7
6
  const DEFAULT_RETRY_DELAYS_MS = [500, 1000, 2000]
@@ -450,7 +449,6 @@ export class BmClient {
450
449
  name: string,
451
450
  args: Record<string, unknown>,
452
451
  ): Promise<unknown> {
453
- trackToolCall(name)
454
452
  const result = await this.callToolRaw(name, args)
455
453
 
456
454
  if (!isRecord(result) || result.structuredContent === undefined) {
package/index.ts CHANGED
@@ -1,10 +1,5 @@
1
1
  import type { Server } from "node:http"
2
2
  import type { OpenClawPluginApi } from "openclaw/plugin-sdk"
3
- import {
4
- EVENT_PLUGIN_INSTALLED,
5
- EVENT_PLUGIN_STARTED,
6
- track,
7
- } from "./analytics.ts"
8
3
  import { BmClient } from "./bm-client.ts"
9
4
  import { registerCli } from "./commands/cli.ts"
10
5
  import { registerSkillCommands } from "./commands/skills.ts"
@@ -53,8 +48,6 @@ export default {
53
48
  `project=${cfg.project} memoryDir=${cfg.memoryDir} memoryFile=${cfg.memoryFile}`,
54
49
  )
55
50
 
56
- track(EVENT_PLUGIN_INSTALLED)
57
-
58
51
  const client = new BmClient(cfg.bmPath, cfg.project)
59
52
 
60
53
  // --- BM Tools (always registered) ---
@@ -132,7 +125,6 @@ export default {
132
125
  })
133
126
  }
134
127
 
135
- track(EVENT_PLUGIN_STARTED, { project: cfg.project })
136
128
  log.info("connected — BM MCP stdio session running")
137
129
  },
138
130
  stop: async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basicmemory/openclaw-basic-memory",
3
- "version": "0.1.0-alpha.10",
3
+ "version": "0.1.0-alpha.11",
4
4
  "type": "module",
5
5
  "description": "Basic Memory plugin for OpenClaw — local-first knowledge graph for agent memory",
6
6
  "license": "MIT",
@@ -9,7 +9,6 @@
9
9
  "url": "https://github.com/basicmachines-co/openclaw-basic-memory"
10
10
  },
11
11
  "files": [
12
- "analytics.ts",
13
12
  "index.ts",
14
13
  "bm-client.ts",
15
14
  "config.ts",
package/analytics.ts DELETED
@@ -1,162 +0,0 @@
1
- /**
2
- * Lightweight analytics via Umami event collector.
3
- *
4
- * Sends anonymous, non-blocking usage events to help understand plugin adoption
5
- * and tool usage patterns. No PII, no fingerprinting, no cookies.
6
- *
7
- * Events are fire-and-forget — analytics never blocks or breaks the plugin.
8
- *
9
- * Defaults point to the Basic Memory Umami Cloud instance. Override via:
10
- * BASIC_MEMORY_UMAMI_HOST — Custom Umami instance URL
11
- * BASIC_MEMORY_UMAMI_SITE_ID — Custom Website ID
12
- * Opt out entirely with OPENCLAW_BASIC_MEMORY_TELEMETRY=0 or BASIC_MEMORY_NO_PROMOS=1.
13
- */
14
-
15
- import { readFileSync } from "node:fs"
16
- import { join } from "node:path"
17
-
18
- // ---------------------------------------------------------------------------
19
- // Configuration
20
- // ---------------------------------------------------------------------------
21
-
22
- const DEFAULT_UMAMI_HOST = "https://cloud.umami.is"
23
- const DEFAULT_UMAMI_SITE_ID = "f6479898-ebaf-4e60-bce2-6dc60a3f6c5c"
24
- const SEND_TIMEOUT_MS = 3000
25
-
26
- function umamiHost(): string {
27
- return process.env.BASIC_MEMORY_UMAMI_HOST?.trim() || DEFAULT_UMAMI_HOST
28
- }
29
-
30
- function umamiSiteId(): string {
31
- return process.env.BASIC_MEMORY_UMAMI_SITE_ID?.trim() || DEFAULT_UMAMI_SITE_ID
32
- }
33
-
34
- export function analyticsDisabled(): boolean {
35
- // Plugin-specific opt-out
36
- const telemetry = (process.env.OPENCLAW_BASIC_MEMORY_TELEMETRY ?? "")
37
- .trim()
38
- .toLowerCase()
39
- if (telemetry === "0" || telemetry === "false" || telemetry === "no") {
40
- return true
41
- }
42
-
43
- // Shared Basic Memory opt-out (also disables BM CLI analytics)
44
- const noPromos = (process.env.BASIC_MEMORY_NO_PROMOS ?? "")
45
- .trim()
46
- .toLowerCase()
47
- return noPromos === "1" || noPromos === "true" || noPromos === "yes"
48
- }
49
-
50
- // ---------------------------------------------------------------------------
51
- // Version
52
- // ---------------------------------------------------------------------------
53
-
54
- let _cachedVersion: string | null = null
55
-
56
- function getVersion(): string {
57
- if (_cachedVersion) return _cachedVersion
58
- try {
59
- const pkg = JSON.parse(
60
- readFileSync(
61
- join(import.meta.dirname ?? __dirname, "package.json"),
62
- "utf-8",
63
- ),
64
- )
65
- _cachedVersion = pkg.version ?? "unknown"
66
- } catch {
67
- _cachedVersion = "unknown"
68
- }
69
- return _cachedVersion ?? "unknown"
70
- }
71
-
72
- // ---------------------------------------------------------------------------
73
- // Session-scoped dedup for tool calls
74
- // ---------------------------------------------------------------------------
75
-
76
- const _trackedTools = new Set<string>()
77
-
78
- export function resetTrackedTools(): void {
79
- _trackedTools.clear()
80
- }
81
-
82
- // ---------------------------------------------------------------------------
83
- // Event constants
84
- // ---------------------------------------------------------------------------
85
-
86
- export const EVENT_PLUGIN_INSTALLED = "openclaw-plugin-installed"
87
- export const EVENT_PLUGIN_STARTED = "openclaw-plugin-started"
88
- export const EVENT_TOOL_CALL = "openclaw-tool-call"
89
-
90
- // ---------------------------------------------------------------------------
91
- // Public API
92
- // ---------------------------------------------------------------------------
93
-
94
- /**
95
- * Send an analytics event to Umami. Non-blocking, silent on failure.
96
- *
97
- * @param eventName - Short kebab-case name (e.g. "openclaw-plugin-started")
98
- * @param data - Optional dict of event properties (string/number values)
99
- */
100
- export function track(
101
- eventName: string,
102
- data?: Record<string, string | number>,
103
- ): void {
104
- if (analyticsDisabled()) return
105
-
106
- const host = umamiHost()
107
- const siteId = umamiSiteId()
108
-
109
- const payload = {
110
- payload: {
111
- hostname: "openclaw.basicmemory.com",
112
- language: "en",
113
- url: `/openclaw/${eventName}`,
114
- website: siteId,
115
- name: eventName,
116
- data: {
117
- version: getVersion(),
118
- ...(data ?? {}),
119
- },
120
- },
121
- }
122
-
123
- // Fire-and-forget — never block the plugin
124
- _sendPayload(host, payload).catch(() => {})
125
- }
126
-
127
- /**
128
- * Track a tool call, deduped per tool name per session.
129
- * Only the first invocation of each tool sends an event.
130
- */
131
- export function trackToolCall(toolName: string): void {
132
- if (analyticsDisabled()) return
133
- if (_trackedTools.has(toolName)) return
134
- _trackedTools.add(toolName)
135
- track(EVENT_TOOL_CALL, { tool: toolName })
136
- }
137
-
138
- // ---------------------------------------------------------------------------
139
- // Internal send (exported for testing)
140
- // ---------------------------------------------------------------------------
141
-
142
- export async function _sendPayload(
143
- host: string,
144
- payload: unknown,
145
- ): Promise<void> {
146
- const controller = new AbortController()
147
- const timer = setTimeout(() => controller.abort(), SEND_TIMEOUT_MS)
148
-
149
- try {
150
- await fetch(`${host}/api/send`, {
151
- method: "POST",
152
- headers: {
153
- "Content-Type": "application/json",
154
- "User-Agent": `openclaw-basic-memory/${getVersion()}`,
155
- },
156
- body: JSON.stringify(payload),
157
- signal: controller.signal,
158
- })
159
- } finally {
160
- clearTimeout(timer)
161
- }
162
- }