@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 +2 -15
- package/bm-client.ts +0 -2
- package/index.ts +0 -8
- package/package.json +1 -2
- package/analytics.ts +0 -162
package/README.md
CHANGED
|
@@ -572,22 +572,9 @@ openclaw-basic-memory/
|
|
|
572
572
|
|
|
573
573
|
## Telemetry
|
|
574
574
|
|
|
575
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
}
|