@basicmemory/openclaw-basic-memory 0.2.3 → 0.23.0

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.
Files changed (91) hide show
  1. package/README.md +49 -19
  2. package/bm-client.ts +55 -21
  3. package/commands/cli.ts +1 -2
  4. package/commands/skills.ts +71 -10
  5. package/commands/slash.ts +4 -2
  6. package/config.ts +0 -16
  7. package/context-engine/basic-memory-context-engine.ts +22 -90
  8. package/dist/bm-client.d.ts +179 -0
  9. package/dist/bm-client.js +582 -0
  10. package/dist/commands/cli.d.ts +4 -0
  11. package/dist/commands/cli.js +116 -0
  12. package/dist/commands/skills.d.ts +2 -0
  13. package/dist/commands/skills.js +86 -0
  14. package/dist/commands/slash.d.ts +3 -0
  15. package/dist/commands/slash.js +92 -0
  16. package/dist/config.d.ts +17 -0
  17. package/dist/config.js +99 -0
  18. package/dist/context-engine/basic-memory-context-engine.d.ts +34 -0
  19. package/dist/context-engine/basic-memory-context-engine.js +176 -0
  20. package/dist/hooks/capture.d.ts +24 -0
  21. package/dist/hooks/capture.js +88 -0
  22. package/dist/hooks/recall.d.ts +24 -0
  23. package/dist/hooks/recall.js +56 -0
  24. package/dist/index.d.ts +9 -0
  25. package/dist/index.js +135 -0
  26. package/dist/logger.d.ts +13 -0
  27. package/dist/logger.js +34 -0
  28. package/dist/schema/conversation-schema.d.ts +5 -0
  29. package/dist/schema/conversation-schema.js +33 -0
  30. package/dist/schema/task-schema.d.ts +5 -0
  31. package/dist/schema/task-schema.js +34 -0
  32. package/dist/tools/build-context.d.ts +3 -0
  33. package/dist/tools/build-context.js +100 -0
  34. package/dist/tools/delete-note.d.ts +3 -0
  35. package/dist/tools/delete-note.js +52 -0
  36. package/dist/tools/edit-note.d.ts +3 -0
  37. package/dist/tools/edit-note.js +81 -0
  38. package/dist/tools/list-memory-projects.d.ts +3 -0
  39. package/dist/tools/list-memory-projects.js +86 -0
  40. package/dist/tools/list-workspaces.d.ts +3 -0
  41. package/dist/tools/list-workspaces.js +64 -0
  42. package/dist/tools/memory-provider.d.ts +15 -0
  43. package/dist/tools/memory-provider.js +274 -0
  44. package/dist/tools/move-note.d.ts +3 -0
  45. package/dist/tools/move-note.js +56 -0
  46. package/dist/tools/read-note.d.ts +3 -0
  47. package/dist/tools/read-note.js +57 -0
  48. package/dist/tools/schema-diff.d.ts +3 -0
  49. package/dist/tools/schema-diff.js +81 -0
  50. package/dist/tools/schema-infer.d.ts +3 -0
  51. package/dist/tools/schema-infer.js +66 -0
  52. package/dist/tools/schema-validate.d.ts +3 -0
  53. package/dist/tools/schema-validate.js +73 -0
  54. package/dist/tools/search-notes.d.ts +3 -0
  55. package/dist/tools/search-notes.js +97 -0
  56. package/dist/tools/write-note.d.ts +3 -0
  57. package/dist/tools/write-note.js +80 -0
  58. package/index.ts +27 -17
  59. package/openclaw.plugin.json +27 -20
  60. package/package.json +27 -8
  61. package/scripts/fetch-skills.ts +62 -67
  62. package/scripts/setup-bm.sh +27 -10
  63. package/skills/manifest.json +25 -0
  64. package/skills/memory-capture/SKILL.md +275 -0
  65. package/skills/memory-ci-capture/SKILL.md +56 -0
  66. package/skills/memory-continue/SKILL.md +148 -0
  67. package/skills/memory-curate/SKILL.md +243 -0
  68. package/skills/memory-literary-analysis/SKILL.md +15 -12
  69. package/skills/memory-notes/SKILL.md +22 -6
  70. package/skills/memory-onboarding/SKILL.md +142 -0
  71. package/skills/memory-onboarding/evals/evals.json +29 -0
  72. package/skills/memory-onboarding/references/assistant-setup.md +64 -0
  73. package/skills/memory-onboarding/references/conventions.md +118 -0
  74. package/skills/memory-onboarding/references/domain-playbooks.md +159 -0
  75. package/skills/memory-onboarding/references/schema-guide.md +136 -0
  76. package/skills/memory-schema/SKILL.md +7 -5
  77. package/skills/memory-tasks/SKILL.md +1 -1
  78. package/tools/build-context.ts +1 -1
  79. package/tools/delete-note.ts +1 -1
  80. package/tools/edit-note.ts +1 -1
  81. package/tools/list-memory-projects.ts +3 -2
  82. package/tools/list-workspaces.ts +1 -1
  83. package/tools/memory-provider.ts +1 -1
  84. package/tools/move-note.ts +1 -1
  85. package/tools/read-note.ts +1 -1
  86. package/tools/schema-diff.ts +1 -1
  87. package/tools/schema-infer.ts +1 -1
  88. package/tools/schema-validate.ts +1 -1
  89. package/tools/search-notes.ts +1 -1
  90. package/tools/write-note.ts +1 -1
  91. package/context-engine/basic-memory-context-engine.test.ts +0 -398
@@ -0,0 +1,66 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ import { log } from "../logger.js";
3
+ export function registerSchemaInferTool(api, client) {
4
+ api.registerTool({
5
+ name: "schema_infer",
6
+ label: "Schema Infer",
7
+ description: "Analyze existing notes of a given type and suggest a Picoschema definition. " +
8
+ "Examines observation categories and relation types to infer required and optional fields.",
9
+ parameters: Type.Object({
10
+ noteType: Type.String({
11
+ description: 'The note type to analyze (e.g., "person", "meeting", "Task")',
12
+ }),
13
+ threshold: Type.Optional(Type.Number({
14
+ description: "Minimum frequency (0-1) for a field to be suggested as optional. Default 0.25.",
15
+ })),
16
+ project: Type.Optional(Type.String({
17
+ description: "Target project name (defaults to current project)",
18
+ })),
19
+ }),
20
+ async execute(_toolCallId, params) {
21
+ log.debug(`schema_infer: noteType="${params.noteType}" threshold=${params.threshold ?? 0.25}`);
22
+ try {
23
+ const result = await client.schemaInfer(params.noteType, params.threshold, params.project);
24
+ const lines = [
25
+ `**Type:** ${result.entity_type}`,
26
+ `**Notes analyzed:** ${result.notes_analyzed}`,
27
+ ];
28
+ if (result.suggested_required.length > 0) {
29
+ lines.push(`**Required fields:** ${result.suggested_required.join(", ")}`);
30
+ }
31
+ if (result.suggested_optional.length > 0) {
32
+ lines.push(`**Optional fields:** ${result.suggested_optional.join(", ")}`);
33
+ }
34
+ if (result.field_frequencies.length > 0) {
35
+ lines.push("", "### Field Frequencies");
36
+ for (const f of result.field_frequencies) {
37
+ lines.push(`- **${f.name}** — ${(f.percentage * 100).toFixed(0)}% (${f.count} notes)`);
38
+ }
39
+ }
40
+ if (Object.keys(result.suggested_schema).length > 0) {
41
+ lines.push("", "### Suggested Schema", "```json", JSON.stringify(result.suggested_schema, null, 2), "```");
42
+ }
43
+ return {
44
+ content: [{ type: "text", text: lines.join("\n") }],
45
+ details: result,
46
+ };
47
+ }
48
+ catch (err) {
49
+ log.error("schema_infer failed", err);
50
+ return {
51
+ content: [
52
+ {
53
+ type: "text",
54
+ text: "Schema inference failed. Check logs for details.",
55
+ },
56
+ ],
57
+ details: {
58
+ noteType: params.noteType,
59
+ threshold: params.threshold ?? 0.25,
60
+ error: "schema_infer_failed",
61
+ },
62
+ };
63
+ }
64
+ },
65
+ }, { name: "schema_infer" });
66
+ }
@@ -0,0 +1,3 @@
1
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
2
+ import type { BmClient } from "../bm-client.ts";
3
+ export declare function registerSchemaValidateTool(api: OpenClawPluginApi, client: BmClient): void;
@@ -0,0 +1,73 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ import { log } from "../logger.js";
3
+ export function registerSchemaValidateTool(api, client) {
4
+ api.registerTool({
5
+ name: "schema_validate",
6
+ label: "Schema Validate",
7
+ description: "Validate notes against their Picoschema definitions. " +
8
+ "Validates a specific note by identifier, or all notes of a given type.",
9
+ parameters: Type.Object({
10
+ noteType: Type.Optional(Type.String({
11
+ description: 'Note type to batch-validate (e.g., "person", "meeting")',
12
+ })),
13
+ identifier: Type.Optional(Type.String({
14
+ description: "Specific note to validate (permalink, title, or path)",
15
+ })),
16
+ project: Type.Optional(Type.String({
17
+ description: "Target project name (defaults to current project)",
18
+ })),
19
+ }),
20
+ async execute(_toolCallId, params) {
21
+ log.debug(`schema_validate: noteType="${params.noteType ?? ""}" identifier="${params.identifier ?? ""}"`);
22
+ try {
23
+ const result = await client.schemaValidate(params.noteType, params.identifier, params.project);
24
+ // Handle error responses from BM (e.g., no schema found)
25
+ const resultRecord = result;
26
+ if ("error" in result && typeof resultRecord.error === "string") {
27
+ return {
28
+ content: [{ type: "text", text: resultRecord.error }],
29
+ details: result,
30
+ };
31
+ }
32
+ const lines = [];
33
+ if (result.entity_type) {
34
+ lines.push(`**Type:** ${result.entity_type}`);
35
+ }
36
+ lines.push(`**Notes:** ${result.total_notes ?? 0} | **Valid:** ${result.valid_count ?? 0} | **Warnings:** ${result.warning_count ?? 0} | **Errors:** ${result.error_count ?? 0}`);
37
+ if (result.results && result.results.length > 0) {
38
+ lines.push("");
39
+ for (const r of result.results) {
40
+ const status = r.valid ? "valid" : "invalid";
41
+ lines.push(`- **${r.identifier}** — ${status}`);
42
+ for (const w of r.warnings) {
43
+ lines.push(` - warning: ${w}`);
44
+ }
45
+ for (const e of r.errors) {
46
+ lines.push(` - error: ${e}`);
47
+ }
48
+ }
49
+ }
50
+ return {
51
+ content: [{ type: "text", text: lines.join("\n") }],
52
+ details: result,
53
+ };
54
+ }
55
+ catch (err) {
56
+ log.error("schema_validate failed", err);
57
+ return {
58
+ content: [
59
+ {
60
+ type: "text",
61
+ text: "Schema validation failed. Check logs for details.",
62
+ },
63
+ ],
64
+ details: {
65
+ noteType: params.noteType ?? null,
66
+ identifier: params.identifier ?? null,
67
+ error: "schema_validate_failed",
68
+ },
69
+ };
70
+ }
71
+ },
72
+ }, { name: "schema_validate" });
73
+ }
@@ -0,0 +1,3 @@
1
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
2
+ import type { BmClient } from "../bm-client.ts";
3
+ export declare function registerSearchTool(api: OpenClawPluginApi, client: BmClient): void;
@@ -0,0 +1,97 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ import { log } from "../logger.js";
3
+ export function registerSearchTool(api, client) {
4
+ api.registerTool({
5
+ name: "search_notes",
6
+ label: "Knowledge Search",
7
+ description: "Search the Basic Memory knowledge graph for relevant notes, concepts, and connections. " +
8
+ "Returns matching notes with titles, content previews, and relevance scores. " +
9
+ "Optionally filter by frontmatter metadata fields, tags, or status.",
10
+ parameters: Type.Object({
11
+ query: Type.String({ description: "Search query" }),
12
+ limit: Type.Optional(Type.Number({ description: "Max results (default: 10)" })),
13
+ project: Type.Optional(Type.String({
14
+ description: "Target project name (defaults to current project)",
15
+ })),
16
+ metadata_filters: Type.Optional(Type.Object({}, {
17
+ additionalProperties: true,
18
+ description: "Filter by frontmatter fields. Supports equality, $in, $gt/$gte/$lt/$lte, $between, and array-contains operators.",
19
+ })),
20
+ tags: Type.Optional(Type.Array(Type.String(), {
21
+ description: "Filter by frontmatter tags (all must match)",
22
+ })),
23
+ status: Type.Optional(Type.String({
24
+ description: "Filter by frontmatter status field",
25
+ })),
26
+ }),
27
+ async execute(_toolCallId, params) {
28
+ const limit = params.limit ?? 10;
29
+ log.debug(`search_notes: query="${params.query}" limit=${limit} project="${params.project ?? "default"}"`);
30
+ const metadata = params.metadata_filters || params.tags || params.status
31
+ ? {
32
+ filters: params.metadata_filters,
33
+ tags: params.tags,
34
+ status: params.status,
35
+ }
36
+ : undefined;
37
+ try {
38
+ const results = await client.search(params.query, limit, params.project, metadata);
39
+ if (results.length === 0) {
40
+ return {
41
+ content: [
42
+ {
43
+ type: "text",
44
+ text: "No matching notes found in the knowledge graph.",
45
+ },
46
+ ],
47
+ details: {
48
+ count: 0,
49
+ results: [],
50
+ },
51
+ };
52
+ }
53
+ const text = results
54
+ .map((r, i) => {
55
+ const score = r.score ? ` (${(r.score * 100).toFixed(0)}%)` : "";
56
+ const content = r.content ?? "";
57
+ const preview = content.length > 200 ? `${content.slice(0, 200)}...` : content;
58
+ return `${i + 1}. **${r.title}**${score}\n ${preview}`;
59
+ })
60
+ .join("\n\n");
61
+ return {
62
+ content: [
63
+ {
64
+ type: "text",
65
+ text: `Found ${results.length} notes:\n\n${text}`,
66
+ },
67
+ ],
68
+ details: {
69
+ count: results.length,
70
+ results: results.map((r) => ({
71
+ title: r.title,
72
+ permalink: r.permalink,
73
+ score: r.score,
74
+ })),
75
+ },
76
+ };
77
+ }
78
+ catch (err) {
79
+ log.error("search_notes failed", err);
80
+ return {
81
+ content: [
82
+ {
83
+ type: "text",
84
+ text: "Search failed. Is Basic Memory running? Check logs for details.",
85
+ },
86
+ ],
87
+ details: {
88
+ count: 0,
89
+ results: [],
90
+ query: params.query,
91
+ error: "search_notes_failed",
92
+ },
93
+ };
94
+ }
95
+ },
96
+ }, { name: "search_notes" });
97
+ }
@@ -0,0 +1,3 @@
1
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
2
+ import type { BmClient } from "../bm-client.ts";
3
+ export declare function registerWriteTool(api: OpenClawPluginApi, client: BmClient): void;
@@ -0,0 +1,80 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ import { NoteAlreadyExistsError } from "../bm-client.js";
3
+ import { log } from "../logger.js";
4
+ export function registerWriteTool(api, client) {
5
+ api.registerTool({
6
+ name: "write_note",
7
+ label: "Write Note",
8
+ description: "Create a note in the Basic Memory knowledge graph. " +
9
+ "If the note already exists, returns an error by default. " +
10
+ "Pass overwrite=true to replace, or use edit_note for incremental updates.",
11
+ parameters: Type.Object({
12
+ title: Type.String({ description: "Note title" }),
13
+ content: Type.String({
14
+ description: "Note content in Markdown format",
15
+ }),
16
+ folder: Type.String({ description: "Folder to write the note in" }),
17
+ project: Type.Optional(Type.String({
18
+ description: "Target project name (defaults to current project)",
19
+ })),
20
+ overwrite: Type.Optional(Type.Boolean({
21
+ description: "Set to true to replace an existing note. Defaults to false.",
22
+ })),
23
+ }),
24
+ async execute(_toolCallId, params) {
25
+ log.debug(`write_note: title=${params.title} folder=${params.folder}`);
26
+ try {
27
+ const note = await client.writeNote(params.title, params.content, params.folder, params.project, params.overwrite);
28
+ const msg = `Note saved: ${note.title} (${note.permalink})`;
29
+ return {
30
+ content: [
31
+ {
32
+ type: "text",
33
+ text: msg,
34
+ },
35
+ ],
36
+ details: {
37
+ title: note.title,
38
+ permalink: note.permalink,
39
+ file_path: note.file_path,
40
+ },
41
+ };
42
+ }
43
+ catch (err) {
44
+ if (err instanceof NoteAlreadyExistsError) {
45
+ const hint = [
46
+ `Note already exists: "${params.title}" (${err.permalink})`,
47
+ "",
48
+ "To update this note, use one of:",
49
+ ` - edit_note("${err.permalink}", operation="append", content="...")`,
50
+ ` - edit_note("${err.permalink}", operation="replace_section", section="...", content="...")`,
51
+ ` - write_note("${params.title}", ..., overwrite=true) to fully replace`,
52
+ ` - read_note("${err.permalink}") to inspect current content first`,
53
+ ].join("\n");
54
+ return {
55
+ content: [{ type: "text", text: hint }],
56
+ details: {
57
+ title: params.title,
58
+ permalink: err.permalink,
59
+ error: "note_already_exists",
60
+ },
61
+ };
62
+ }
63
+ log.error("write_note failed", err);
64
+ return {
65
+ content: [
66
+ {
67
+ type: "text",
68
+ text: "Failed to write note. Is Basic Memory running? Check logs for details.",
69
+ },
70
+ ],
71
+ details: {
72
+ title: params.title,
73
+ folder: params.folder,
74
+ error: "write_note_failed",
75
+ },
76
+ };
77
+ }
78
+ },
79
+ }, { name: "write_note" });
80
+ }
package/index.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { execSync } from "node:child_process"
1
+ import { execFileSync } from "node:child_process"
2
2
 
3
- import type { OpenClawPluginApi } from "openclaw/plugin-sdk"
3
+ import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry"
4
4
  import { BmClient } from "./bm-client.ts"
5
5
  import { registerCli } from "./commands/cli.ts"
6
6
  import { registerSkillCommands } from "./commands/skills.ts"
@@ -31,17 +31,23 @@ import { registerSchemaValidateTool } from "./tools/schema-validate.ts"
31
31
  import { registerSearchTool } from "./tools/search-notes.ts"
32
32
  import { registerWriteTool } from "./tools/write-note.ts"
33
33
 
34
- const BASIC_MEMORY_RELEASE_TAG = "v0.20.2"
34
+ export function isCommandAvailable(command: string): boolean {
35
+ try {
36
+ execFileSync(command, ["--version"], { stdio: "ignore" })
37
+ return true
38
+ } catch {
39
+ return false
40
+ }
41
+ }
35
42
 
36
- export default {
43
+ export default definePluginEntry({
37
44
  id: "openclaw-basic-memory",
38
45
  name: "Basic Memory",
39
46
  description:
40
47
  "Local-first knowledge graph for OpenClaw — persistent memory with graph search and composited memory_search",
41
- kind: "memory" as const,
42
48
  configSchema: basicMemoryConfigSchema,
43
49
 
44
- register(api: OpenClawPluginApi) {
50
+ register(api) {
45
51
  const cfg = parseConfig(api.pluginConfig)
46
52
 
47
53
  initLogger(api.logger, cfg.debug)
@@ -88,27 +94,31 @@ export default {
88
94
 
89
95
  // Auto-install bm CLI if not found
90
96
  const bmBin = cfg.bmPath || "bm"
91
- try {
92
- execSync(`command -v ${bmBin}`, { stdio: "ignore" })
93
- } catch {
97
+ if (!isCommandAvailable(bmBin)) {
94
98
  log.info("bm CLI not found on PATH — attempting auto-install...")
95
99
  try {
96
- execSync("command -v uv", { stdio: "ignore" })
100
+ if (!isCommandAvailable("uv")) {
101
+ throw new Error("uv not found")
102
+ }
97
103
  log.info(
98
104
  "installing basic-memory via uv (this may take a minute)...",
99
105
  )
100
- const result = execSync(
101
- `uv tool install "basic-memory @ git+https://github.com/basicmachines-co/basic-memory.git@${BASIC_MEMORY_RELEASE_TAG}" --force`,
102
- { encoding: "utf-8", timeout: 120_000, stdio: "pipe" },
106
+ const result = execFileSync(
107
+ "uv",
108
+ ["tool", "install", "basic-memory", "--force"],
109
+ {
110
+ encoding: "utf-8",
111
+ timeout: 120_000,
112
+ stdio: ["ignore", "pipe", "pipe"],
113
+ },
103
114
  )
104
115
  log.info(
105
116
  `basic-memory installed: ${result.trim().split("\n").pop()}`,
106
117
  )
107
118
  // Verify it worked
108
- try {
109
- execSync(`command -v ${bmBin}`, { stdio: "ignore" })
119
+ if (isCommandAvailable(bmBin)) {
110
120
  log.info("bm CLI now available on PATH")
111
- } catch {
121
+ } else {
112
122
  log.error(
113
123
  "bm installed but not found on PATH. You may need to add uv's bin directory to your PATH (typically ~/.local/bin).",
114
124
  )
@@ -159,4 +169,4 @@ export default {
159
169
  },
160
170
  })
161
171
  },
162
- }
172
+ })
@@ -23,8 +23,10 @@
23
23
  "skills/memory-defrag",
24
24
  "skills/memory-ingest",
25
25
  "skills/memory-lifecycle",
26
+ "skills/memory-literary-analysis",
26
27
  "skills/memory-metadata-search",
27
28
  "skills/memory-notes",
29
+ "skills/memory-onboarding",
28
30
  "skills/memory-reflect",
29
31
  "skills/memory-research",
30
32
  "skills/memory-schema",
@@ -52,16 +54,26 @@
52
54
  "help": "Path to the basic-memory CLI binary (default: 'bm')",
53
55
  "advanced": true
54
56
  },
55
- "indexInterval": {
56
- "label": "Index Interval (seconds)",
57
- "placeholder": "300",
58
- "help": "Seconds between periodic re-indexing sweeps",
59
- "advanced": true
60
- },
61
57
  "autoCapture": {
62
58
  "label": "Auto-Capture",
63
59
  "help": "Automatically index conversation content after each turn"
64
60
  },
61
+ "captureMinChars": {
62
+ "label": "Capture Min Characters",
63
+ "placeholder": "10",
64
+ "help": "Minimum user/assistant text length before auto-capture indexes a turn",
65
+ "advanced": true
66
+ },
67
+ "autoRecall": {
68
+ "label": "Auto-Recall",
69
+ "help": "Automatically load relevant Basic Memory context when a session starts"
70
+ },
71
+ "recallPrompt": {
72
+ "label": "Recall Prompt",
73
+ "placeholder": "Check for active tasks and recent activity...",
74
+ "help": "Prompt used to gather initial Basic Memory context",
75
+ "advanced": true
76
+ },
65
77
  "debug": {
66
78
  "label": "Debug Logging",
67
79
  "help": "Enable verbose debug logs",
@@ -72,11 +84,6 @@
72
84
  "placeholder": ".",
73
85
  "help": "Filesystem path for Basic Memory project data (defaults to workspace root; relative paths resolve from workspace)",
74
86
  "advanced": true
75
- },
76
- "cloud": {
77
- "label": "Cloud Backend",
78
- "help": "Optional cloud backend config (url + api_key). If present, uses cloud instead of local BM.",
79
- "advanced": true
80
87
  }
81
88
  },
82
89
  "configSchema": {
@@ -85,19 +92,19 @@
85
92
  "properties": {
86
93
  "project": { "type": "string" },
87
94
  "memoryDir": { "type": "string" },
95
+ "memory_dir": { "type": "string" },
88
96
  "memoryFile": { "type": "string" },
97
+ "memory_file": { "type": "string" },
89
98
  "bmPath": { "type": "string" },
90
- "indexInterval": { "type": "number", "minimum": 30, "maximum": 3600 },
91
99
  "autoCapture": { "type": "boolean" },
100
+ "captureMinChars": { "type": "number", "minimum": 0 },
101
+ "capture_min_chars": { "type": "number", "minimum": 0 },
102
+ "autoRecall": { "type": "boolean" },
103
+ "auto_recall": { "type": "boolean" },
104
+ "recallPrompt": { "type": "string" },
105
+ "recall_prompt": { "type": "string" },
92
106
  "debug": { "type": "boolean" },
93
- "projectPath": { "type": "string" },
94
- "cloud": {
95
- "type": "object",
96
- "properties": {
97
- "url": { "type": "string" },
98
- "api_key": { "type": "string" }
99
- }
100
- }
107
+ "projectPath": { "type": "string" }
101
108
  },
102
109
  "required": []
103
110
  }
package/package.json CHANGED
@@ -1,17 +1,20 @@
1
1
  {
2
2
  "name": "@basicmemory/openclaw-basic-memory",
3
- "version": "0.2.3",
3
+ "version": "0.23.0",
4
4
  "type": "module",
5
- "description": "Basic Memory plugin for OpenClaw — local-first knowledge graph for agent memory",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "description": "Basic Memory plugin for OpenClaw \u2014 local-first knowledge graph for agent memory",
6
8
  "license": "MIT",
7
9
  "repository": {
8
10
  "type": "git",
9
- "url": "https://github.com/basicmachines-co/openclaw-basic-memory"
11
+ "url": "https://github.com/basicmachines-co/basic-memory.git",
12
+ "directory": "integrations/openclaw"
10
13
  },
11
14
  "files": [
12
15
  "index.ts",
13
16
  "bm-client.ts",
14
- "context-engine/",
17
+ "context-engine/basic-memory-context-engine.ts",
15
18
  "config.ts",
16
19
  "logger.ts",
17
20
  "commands/cli.ts",
@@ -35,6 +38,7 @@
35
38
  "schema/task-schema.ts",
36
39
  "schema/conversation-schema.ts",
37
40
  "skills/",
41
+ "dist/",
38
42
  "scripts/fetch-skills.ts",
39
43
  "scripts/setup-bm.sh",
40
44
  "openclaw.plugin.json",
@@ -53,25 +57,40 @@
53
57
  },
54
58
  "scripts": {
55
59
  "postinstall": "bash scripts/setup-bm.sh || true",
60
+ "build": "tsc -p tsconfig.build.json",
56
61
  "check-types": "tsc --noEmit",
57
62
  "lint": "bunx @biomejs/biome ci .",
58
63
  "lint:fix": "bunx @biomejs/biome check --write .",
59
64
  "fetch-skills": "bun scripts/fetch-skills.ts",
60
- "prepack": "bun scripts/fetch-skills.ts",
65
+ "prepack": "bun run fetch-skills && bun run build",
61
66
  "test": "bun test",
62
67
  "test:int": "BM_INTEGRATION=1 BM_BIN=${BM_BIN:-./scripts/bm-local.sh} bun test integration --timeout 120000",
63
68
  "test:coverage": "bun test --coverage",
64
- "release:check": "bun run check-types && bun test && npm pack --dry-run"
69
+ "release:check": "bun run fetch-skills && bun run check-types && bun run lint && bun run build && bun test && npm pack --dry-run"
65
70
  },
66
71
  "openclaw": {
67
72
  "extensions": [
68
73
  "./index.ts"
69
- ]
74
+ ],
75
+ "runtimeExtensions": [
76
+ "./dist/index.js"
77
+ ],
78
+ "compat": {
79
+ "pluginApi": ">=2026.5.2",
80
+ "minGatewayVersion": "2026.5.2"
81
+ },
82
+ "build": {
83
+ "openclawVersion": "2026.5.4",
84
+ "pluginSdkVersion": "2026.5.4"
85
+ },
86
+ "install": {
87
+ "minHostVersion": ">=2026.5.2"
88
+ }
70
89
  },
71
90
  "devDependencies": {
72
91
  "@biomejs/biome": "^2.4.6",
73
92
  "@types/node": "^20.0.0",
74
- "openclaw": "^2026.3.8",
93
+ "openclaw": "^2026.5.4",
75
94
  "typescript": "^5.9.3"
76
95
  }
77
96
  }