@context-use/openclaw-memory 0.1.0-beta.109

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/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ MIT License
2
+
3
+ Copyright (c) [year] [fullname]
4
+
5
+ The Radiance Cascades shader portions in packages/ui/src/components/brand/light/shaders
6
+ (radiance-cascade.wgsl, rc-directions.wgsl, and sdf-sample.wgsl), and the frame-health
7
+ monitor in packages/ui/src/components/brand/light/frame-health.ts:
8
+ Copyright (c) 2025 Vercel, Inc.
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
@@ -0,0 +1,313 @@
1
+ #!/usr/bin/env node
2
+ // package.json
3
+ var package_default = {
4
+ name: "@context-use/openclaw-memory",
5
+ version: "0.1.0-beta.109",
6
+ description: "Context Use as OpenClaw's sole durable personal memory",
7
+ type: "module",
8
+ license: "MIT",
9
+ bin: {
10
+ "context-use-openclaw": "./pkg/dist/bootstrap.js"
11
+ },
12
+ openclaw: {
13
+ extensions: [
14
+ "./dist/index.js"
15
+ ]
16
+ },
17
+ scripts: {
18
+ "check:types": "bun run --bun tsc",
19
+ test: "bun test test",
20
+ "test:e2e": "bun run pack:release && bun run scripts/e2e.ts",
21
+ "test:published": "bun run scripts/e2e.ts --published",
22
+ "pack:release": "bun run build:plugin && bun run scripts/pack.ts",
23
+ "build:plugin": "bun run scripts/build.ts"
24
+ },
25
+ peerDependencies: {
26
+ openclaw: ">=2026.9.4"
27
+ },
28
+ devDependencies: {
29
+ "@repo/browser-testing": "workspace:*",
30
+ "@repo/typescript-config": "workspace:*",
31
+ "@types/proper-lockfile": "^4.1.4",
32
+ "@types/semver": "^7.8.0",
33
+ openclaw: "2026.9.4",
34
+ typescript: "catalog:"
35
+ },
36
+ dependencies: {
37
+ "@modelcontextprotocol/client": "^2",
38
+ "proper-lockfile": "^4.1.2",
39
+ semver: "^7.8.5",
40
+ typebox: "^1",
41
+ zod: "^4.4.3"
42
+ },
43
+ private: true,
44
+ engines: {
45
+ node: "^24.16.0 || >=26.1.0"
46
+ },
47
+ peerDependenciesMeta: {
48
+ openclaw: {
49
+ optional: true
50
+ }
51
+ },
52
+ repository: {
53
+ type: "git",
54
+ url: "git+https://github.com/massimoalbarello/context-use.git",
55
+ directory: "packages/openclaw-memory"
56
+ },
57
+ homepage: "https://github.com/massimoalbarello/context-use",
58
+ bugs: {
59
+ url: "https://github.com/massimoalbarello/context-use/issues"
60
+ },
61
+ publishConfig: {
62
+ access: "public",
63
+ tag: "beta"
64
+ },
65
+ exports: {
66
+ "./setup-prompt": "./src/setup-prompt.ts"
67
+ }
68
+ };
69
+
70
+ // src/setup-prompt.ts
71
+ var OPENCLAW_PACKAGE = `${package_default.name}@${package_default.publishConfig.tag}`;
72
+ var OPENCLAW_NPM_URL = `https://www.npmjs.com/package/${package_default.name}`;
73
+ var OPENCLAW_REQUIREMENT = package_default.peerDependencies.openclaw;
74
+ var OPENCLAW_INSTALL_COMMAND = `npx --yes ${OPENCLAW_PACKAGE}`;
75
+ function openclawConnectCommand(serverUrl) {
76
+ return `${OPENCLAW_INSTALL_COMMAND} connect '${serverUrl.replaceAll("'", "'\\''")}'`;
77
+ }
78
+ function openclawSetupPrompt(serverUrl) {
79
+ return `Install Context Use as my sole durable personal memory in this OpenClaw agent. Keep my conversations separate.
80
+
81
+ Check openclaw --version first (requires ${OPENCLAW_REQUIREMENT}), then run:
82
+ ${openclawConnectCommand(serverUrl)}
83
+
84
+ Follow the plugin's instructions: give me the authorization URL and ask me to return the final localhost redirect URL. When I send it back, finish connecting. Let the plugin manage configuration and gateway refresh.
85
+
86
+ After authorization, verify openclaw context-use status. If connected and authenticated, confirm that setup is complete and tell me to start a new session with /new so the memory tools become available.`;
87
+ }
88
+ var OPENCLAW_REMOVAL_PROMPT = `Remove the Context Use memory plugin using ${OPENCLAW_INSTALL_COMMAND} remove in this OpenClaw profile. This also works if authorization was never completed or the plugin is disabled. Let the plugin restore its configuration changes, clear its credentials and refresh the gateway. Preserve my remote memories and conversation history. Verify that a fresh conversation uses the restored memory provider.`;
89
+
90
+ // src/bootstrap.ts
91
+ import { join as join2 } from "node:path";
92
+ import { satisfies as satisfies2 } from "semver";
93
+
94
+ // src/contract.ts
95
+ import { satisfies } from "semver";
96
+ import { z } from "zod";
97
+
98
+ // src/error.ts
99
+ class ConnectionError extends Error {
100
+ }
101
+
102
+ // src/contract.ts
103
+ var PLUGIN_ID = "context-use";
104
+ var PACKAGE_VERSION = package_default.version;
105
+ var OPENCLAW_VERSION_RANGE = package_default.peerDependencies.openclaw;
106
+ var CALLBACK_URL = "http://127.0.0.1:49187/context-use/callback";
107
+ var REQUEST_TIMEOUT_MS = 30000;
108
+ var AUTHORIZATION_TIMEOUT_MS = 600000;
109
+ var AUTHORIZATION_SCOPE = "mcp offline_access";
110
+ var toolName = (name) => `context_use_${name}`;
111
+ var FINISH_LEARNING_TOOL = toolName("finish_learning");
112
+ var SAVE_ATTACHMENT_TOOL = toolName("save_learning_attachment");
113
+ var PluginConfigSchema = z.strictObject({
114
+ agentId: z.string().regex(/^[a-z0-9][a-z0-9_-]*$/),
115
+ serverUrl: z.url()
116
+ });
117
+ function serverUrl(input) {
118
+ const url = new URL(input);
119
+ const loopback = ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname);
120
+ if (url.protocol !== "https:" && !(url.protocol === "http:" && loopback)) {
121
+ throw new ConnectionError("Use an HTTPS instance URL (HTTP is allowed only for local development).");
122
+ }
123
+ if (url.username || url.password || url.search || url.hash || !["/", "/mcp"].includes(url.pathname)) {
124
+ throw new ConnectionError("Supply the instance origin or its /mcp endpoint, without credentials or query parameters.");
125
+ }
126
+ return new URL("/mcp", url).href;
127
+ }
128
+ function assertHostVersion(version) {
129
+ if (!satisfies(version, OPENCLAW_VERSION_RANGE)) {
130
+ throw new ConnectionError(`This plugin requires OpenClaw ${OPENCLAW_VERSION_RANGE}; found ${version}.`);
131
+ }
132
+ }
133
+ var MCP_TOOL_NAMES = [
134
+ "create_asset_upload",
135
+ "list_assets",
136
+ "read_asset",
137
+ "update_asset",
138
+ "archive_asset",
139
+ "create_entity",
140
+ "list_entities",
141
+ "read_entity",
142
+ "update_entity",
143
+ "archive_entity",
144
+ "search_hypermedia",
145
+ "read_hypermedia_curation_guide",
146
+ "create_knowledge_page",
147
+ "list_knowledge_pages",
148
+ "read_knowledge_page",
149
+ "update_knowledge_page",
150
+ "archive_knowledge_page",
151
+ "read_record"
152
+ ];
153
+
154
+ // src/gateway.ts
155
+ import { resolve } from "node:path";
156
+ import { z as z2 } from "zod";
157
+
158
+ // src/host-command.ts
159
+ import { execFile, spawn } from "node:child_process";
160
+ import { promisify } from "node:util";
161
+ var execute = promisify(execFile);
162
+ var HOST_TIMEOUT_MS = 120000;
163
+ async function runSetupCommand(input) {
164
+ const child = spawn(process.execPath, [input.script, ...input.args], { stdio: "inherit" });
165
+ return await new Promise((resolve, reject) => {
166
+ child.once("error", reject);
167
+ child.once("exit", (code) => resolve(code ?? 1));
168
+ });
169
+ }
170
+ async function openclaw(args) {
171
+ const result = await execute("openclaw", args, {
172
+ timeout: HOST_TIMEOUT_MS,
173
+ maxBuffer: 4000000
174
+ });
175
+ return result.stdout;
176
+ }
177
+ async function checkHost() {
178
+ const output = await openclaw(["--version"]);
179
+ const version = output.match(/\b\d{4}\.\d+\.\d+(?:-[\w.-]+)?\b/)?.[0];
180
+ if (!version) {
181
+ throw new ConnectionError("Could not determine the installed OpenClaw version.");
182
+ }
183
+ assertHostVersion(version);
184
+ }
185
+
186
+ // src/gateway.ts
187
+ async function refreshGateway() {
188
+ const local = z2.object({ path: z2.string() }).parse(JSON.parse(await openclaw(["config", "file", "--json"])));
189
+ let remote;
190
+ try {
191
+ remote = z2.object({ path: z2.string() }).parse(JSON.parse(await openclaw(["gateway", "call", "config.get", "--timeout", "3000", "--json"])));
192
+ } catch {
193
+ console.log(`Settings saved. No reachable gateway was verified; they apply on its next start. Run ${OPENCLAW_INSTALL_COMMAND} refresh to retry.`);
194
+ return;
195
+ }
196
+ if (resolve(remote.path) !== resolve(local.path)) {
197
+ throw new ConnectionError(`Settings saved, but the running gateway uses another configuration. Start this profile’s gateway, then run ${OPENCLAW_INSTALL_COMMAND} refresh.`);
198
+ }
199
+ const result = z2.object({ ok: z2.boolean() }).parse(JSON.parse(await openclaw([
200
+ "gateway",
201
+ "call",
202
+ "gateway.restart.request",
203
+ "--params",
204
+ JSON.stringify({ reason: "Context Use memory configuration changed" }),
205
+ "--json"
206
+ ])));
207
+ if (!result.ok) {
208
+ throw new ConnectionError(`Settings saved, but gateway refresh was not accepted. Run ${OPENCLAW_INSTALL_COMMAND} refresh to retry.`);
209
+ }
210
+ console.log("Gateway refresh requested. OpenClaw will apply the change after active work finishes.");
211
+ }
212
+
213
+ // src/package-installation.ts
214
+ import { execFile as execFile2 } from "node:child_process";
215
+ import { mkdtemp, readFile, rm } from "node:fs/promises";
216
+ import { tmpdir } from "node:os";
217
+ import { dirname, join, resolve as resolve2 } from "node:path";
218
+ import { fileURLToPath } from "node:url";
219
+ import { promisify as promisify2 } from "node:util";
220
+ import { z as z3 } from "zod";
221
+ var execute2 = promisify2(execFile2);
222
+ var INSTALL_TIMEOUT_MS = 120000;
223
+ async function installedPlugin() {
224
+ const inventory = z3.object({
225
+ plugins: z3.array(z3.object({
226
+ id: z3.string(),
227
+ rootDir: z3.string()
228
+ }))
229
+ }).parse(JSON.parse(await openclaw(["plugins", "list", "--json"])));
230
+ return inventory.plugins.find((plugin) => plugin.id === PLUGIN_ID);
231
+ }
232
+ async function installPackage() {
233
+ const existing = await installedPlugin();
234
+ if (existing) {
235
+ const installed = z3.object({ name: z3.string() }).parse(JSON.parse(await readFile(join(existing.rootDir, "package.json"), "utf8")));
236
+ if (installed.name !== package_default.name) {
237
+ throw new ConnectionError(`The context-use plugin ID belongs to another package: ${installed.name}.`);
238
+ }
239
+ return;
240
+ }
241
+ const root = resolve2(dirname(fileURLToPath(import.meta.url)), "..");
242
+ const directory = await mkdtemp(join(tmpdir(), "context-use-install-"));
243
+ try {
244
+ const packed = await execute2("npm", ["pack", root, "--ignore-scripts", "--json", "--pack-destination", directory], { timeout: INSTALL_TIMEOUT_MS });
245
+ const [{ filename }] = z3.tuple([z3.object({ filename: z3.string() })]).parse(JSON.parse(packed.stdout));
246
+ console.log(await openclaw([
247
+ "plugins",
248
+ "install",
249
+ join(directory, filename),
250
+ "--force",
251
+ "--accept-capabilities"
252
+ ]));
253
+ } catch (error) {
254
+ if (error && typeof error === "object" && "stderr" in error && typeof error.stderr === "string") {
255
+ process.stderr.write(error.stderr);
256
+ }
257
+ throw new ConnectionError("OpenClaw could not install Context Use. Resolve the installer error above and retry connect.");
258
+ } finally {
259
+ await rm(directory, { recursive: true, force: true });
260
+ }
261
+ }
262
+
263
+ // src/usage.ts
264
+ var SETUP_USAGE = `context-use-openclaw connect <instance-url> [agent-id=main]
265
+ context-use-openclaw authorize
266
+ context-use-openclaw status
267
+ context-use-openclaw disconnect
268
+ context-use-openclaw remove
269
+ context-use-openclaw refresh
270
+
271
+ Connect installs the plugin and starts browser authorization. Pass the returned URL to authorize
272
+ through standard input. After installation, these commands also work through openclaw context-use.
273
+ Use the same OpenClaw profile for every command. Remove restores your settings and uninstalls the
274
+ plugin while preserving remote memories. Refresh also works after uninstall.`;
275
+
276
+ // src/bootstrap.ts
277
+ async function main(args) {
278
+ if (!args[0] || args[0] === "--help") {
279
+ console.log(SETUP_USAGE);
280
+ return;
281
+ }
282
+ if (!satisfies2(process.versions.node, package_default.engines.node)) {
283
+ throw new ConnectionError(`This setup command requires Node ${package_default.engines.node}; found ${process.versions.node}. Use the Node runtime supported by your OpenClaw installation.`);
284
+ }
285
+ if (args[0] === "connect") {
286
+ if (!args[1]) {
287
+ throw new ConnectionError("Provide the Context Use instance URL.");
288
+ }
289
+ serverUrl(args[1]);
290
+ }
291
+ await checkHost();
292
+ if (args[0] === "refresh") {
293
+ await refreshGateway();
294
+ return;
295
+ }
296
+ if (args[0] === "connect") {
297
+ await installPackage();
298
+ }
299
+ const installed = await installedPlugin();
300
+ if (!installed) {
301
+ throw new ConnectionError("Context Use is not installed. Run connect first.");
302
+ }
303
+ process.exitCode = await runSetupCommand({
304
+ script: join2(installed.rootDir, "dist/setup.js"),
305
+ args
306
+ });
307
+ }
308
+ try {
309
+ await main(process.argv.slice(2));
310
+ } catch (error) {
311
+ console.error(error instanceof ConnectionError ? error.message : "Context Use installation failed. Check the OpenClaw installation and retry.");
312
+ process.exitCode = 1;
313
+ }