@karmaniverous/jeeves-watcher-openclaw 0.1.2 → 0.3.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.
package/README.md CHANGED
@@ -38,7 +38,7 @@ Set the `apiUrl` in the plugin configuration to point at your jeeves-watcher ser
38
38
 
39
39
  ```json
40
40
  {
41
- "apiUrl": "http://localhost:3000"
41
+ "apiUrl": "http://127.0.0.1:3458"
42
42
  }
43
43
  ```
44
44
 
@@ -54,6 +54,8 @@ Set the `apiUrl` in the plugin configuration to point at your jeeves-watcher ser
54
54
  | `watcher_config_apply` | Apply a new configuration |
55
55
  | `watcher_reindex` | Trigger a full reindex |
56
56
  | `watcher_issues` | List indexing issues and errors |
57
+ | `memory_search` | Semantically search memory files (MEMORY.md and memory/*.md) |
58
+ | `memory_get` | Read content from memory files with optional line range |
57
59
 
58
60
  ## Documentation
59
61
 
package/dist/cli.js CHANGED
@@ -22,15 +22,12 @@ import { fileURLToPath } from 'url';
22
22
  const PLUGIN_ID = 'jeeves-watcher-openclaw';
23
23
  /** Resolve the OpenClaw home directory. */
24
24
  function resolveOpenClawHome() {
25
- // 1. OPENCLAW_CONFIG points directly to the config file
26
25
  if (process.env.OPENCLAW_CONFIG) {
27
26
  return dirname(resolve(process.env.OPENCLAW_CONFIG));
28
27
  }
29
- // 2. OPENCLAW_HOME points to the .openclaw directory
30
28
  if (process.env.OPENCLAW_HOME) {
31
29
  return resolve(process.env.OPENCLAW_HOME);
32
30
  }
33
- // 3. Default location
34
31
  return join(homedir(), '.openclaw');
35
32
  }
36
33
  /** Resolve the config file path. */
@@ -43,8 +40,6 @@ function resolveConfigPath(home) {
43
40
  /** Get the package root (where this CLI lives). */
44
41
  function getPackageRoot() {
45
42
  const thisFile = fileURLToPath(import.meta.url);
46
- // In dist: dist/cli.js → package root is ..
47
- // In src: src/cli.ts → package root is ..
48
43
  return resolve(dirname(thisFile), '..');
49
44
  }
50
45
  /** Read and parse JSON, returning null on failure. */
@@ -60,6 +55,63 @@ function readJson(path) {
60
55
  function writeJson(path, data) {
61
56
  writeFileSync(path, JSON.stringify(data, null, 2) + '\n');
62
57
  }
58
+ /**
59
+ * Patch an allowlist array: add or remove the plugin ID.
60
+ * Returns a log message if a change was made, or undefined.
61
+ */
62
+ function patchAllowList(parent, key, label, mode) {
63
+ if (!Array.isArray(parent[key]) || parent[key].length === 0)
64
+ return undefined;
65
+ const list = parent[key];
66
+ if (mode === 'add') {
67
+ if (!list.includes(PLUGIN_ID)) {
68
+ list.push(PLUGIN_ID);
69
+ return `Added "${PLUGIN_ID}" to ${label}`;
70
+ }
71
+ }
72
+ else {
73
+ const filtered = list.filter((id) => id !== PLUGIN_ID);
74
+ if (filtered.length !== list.length) {
75
+ parent[key] = filtered;
76
+ return `Removed "${PLUGIN_ID}" from ${label}`;
77
+ }
78
+ }
79
+ return undefined;
80
+ }
81
+ /** Patch OpenClaw config for install or uninstall. Returns log messages. */
82
+ function patchConfig(config, mode) {
83
+ const messages = [];
84
+ // Ensure plugins section
85
+ if (!config.plugins || typeof config.plugins !== 'object') {
86
+ config.plugins = {};
87
+ }
88
+ const plugins = config.plugins;
89
+ // plugins.allow
90
+ const pluginAllow = patchAllowList(plugins, 'allow', 'plugins.allow', mode);
91
+ if (pluginAllow)
92
+ messages.push(pluginAllow);
93
+ // plugins.entries
94
+ if (!plugins.entries || typeof plugins.entries !== 'object') {
95
+ plugins.entries = {};
96
+ }
97
+ const entries = plugins.entries;
98
+ if (mode === 'add') {
99
+ if (!entries[PLUGIN_ID]) {
100
+ entries[PLUGIN_ID] = { enabled: true };
101
+ messages.push(`Added "${PLUGIN_ID}" to plugins.entries`);
102
+ }
103
+ }
104
+ else if (PLUGIN_ID in entries) {
105
+ Reflect.deleteProperty(entries, PLUGIN_ID);
106
+ messages.push(`Removed "${PLUGIN_ID}" from plugins.entries`);
107
+ }
108
+ // tools.allow
109
+ const tools = (config.tools ?? {});
110
+ const toolAllow = patchAllowList(tools, 'allow', 'tools.allow', mode);
111
+ if (toolAllow)
112
+ messages.push(toolAllow);
113
+ return messages;
114
+ }
63
115
  /** Install the plugin into OpenClaw's extensions directory. */
64
116
  function install() {
65
117
  const home = resolveOpenClawHome();
@@ -71,19 +123,16 @@ function install() {
71
123
  console.log(`Extensions dir: ${extDir}`);
72
124
  console.log(`Package root: ${pkgRoot}`);
73
125
  console.log();
74
- // Validate OpenClaw home exists
75
126
  if (!existsSync(home)) {
76
127
  console.error(`Error: OpenClaw home directory not found at ${home}`);
77
128
  console.error('Set OPENCLAW_HOME or OPENCLAW_CONFIG if using a non-default installation.');
78
129
  process.exit(1);
79
130
  }
80
- // Validate config exists
81
131
  if (!existsSync(configPath)) {
82
132
  console.error(`Error: OpenClaw config not found at ${configPath}`);
83
133
  console.error('Set OPENCLAW_CONFIG if using a non-default config location.');
84
134
  process.exit(1);
85
135
  }
86
- // Validate package root has openclaw.plugin.json
87
136
  const pluginManifestPath = join(pkgRoot, 'openclaw.plugin.json');
88
137
  if (!existsSync(pluginManifestPath)) {
89
138
  console.error(`Error: openclaw.plugin.json not found at ${pluginManifestPath}`);
@@ -95,9 +144,7 @@ function install() {
95
144
  rmSync(extDir, { recursive: true, force: true });
96
145
  }
97
146
  mkdirSync(extDir, { recursive: true });
98
- // Copy dist/, openclaw.plugin.json, package.json
99
- const filesToCopy = ['dist', 'openclaw.plugin.json', 'package.json'];
100
- for (const file of filesToCopy) {
147
+ for (const file of ['dist', 'openclaw.plugin.json', 'package.json']) {
101
148
  const src = join(pkgRoot, file);
102
149
  const dest = join(extDir, file);
103
150
  if (existsSync(src)) {
@@ -105,13 +152,12 @@ function install() {
105
152
  console.log(` ✓ ${file}`);
106
153
  }
107
154
  }
108
- // Copy node_modules if present (for runtime dependencies)
109
155
  const nodeModulesSrc = join(pkgRoot, 'node_modules');
110
156
  if (existsSync(nodeModulesSrc)) {
111
157
  cpSync(nodeModulesSrc, join(extDir, 'node_modules'), { recursive: true });
112
158
  console.log(' ✓ node_modules');
113
159
  }
114
- // Patch OpenClaw config
160
+ // Patch config
115
161
  console.log();
116
162
  console.log('Patching OpenClaw config...');
117
163
  const config = readJson(configPath);
@@ -119,36 +165,8 @@ function install() {
119
165
  console.error(`Error: Could not parse ${configPath}`);
120
166
  process.exit(1);
121
167
  }
122
- // Ensure plugins section exists
123
- if (!config.plugins || typeof config.plugins !== 'object') {
124
- config.plugins = {};
125
- }
126
- const plugins = config.plugins;
127
- // If plugins.allow exists and is populated, add ourselves to it
128
- if (Array.isArray(plugins.allow) && plugins.allow.length > 0) {
129
- const allow = plugins.allow;
130
- if (!allow.includes(PLUGIN_ID)) {
131
- allow.push(PLUGIN_ID);
132
- console.log(` ✓ Added "${PLUGIN_ID}" to plugins.allow`);
133
- }
134
- }
135
- // Add to plugins.entries
136
- if (!plugins.entries || typeof plugins.entries !== 'object') {
137
- plugins.entries = {};
138
- }
139
- const entries = plugins.entries;
140
- if (!entries[PLUGIN_ID]) {
141
- entries[PLUGIN_ID] = { enabled: true };
142
- console.log(` ✓ Added "${PLUGIN_ID}" to plugins.entries`);
143
- }
144
- // If tools.allow exists and is populated, add ourselves to it
145
- const tools = (config.tools ?? {});
146
- if (Array.isArray(tools.allow) && tools.allow.length > 0) {
147
- const toolsAllow = tools.allow;
148
- if (!toolsAllow.includes(PLUGIN_ID)) {
149
- toolsAllow.push(PLUGIN_ID);
150
- console.log(` ✓ Added "${PLUGIN_ID}" to tools.allow`);
151
- }
168
+ for (const msg of patchConfig(config, 'add')) {
169
+ console.log(` ✓ ${msg}`);
152
170
  }
153
171
  writeJson(configPath, config);
154
172
  console.log();
@@ -164,7 +182,6 @@ function uninstall() {
164
182
  console.log(`Config: ${configPath}`);
165
183
  console.log(`Extensions dir: ${extDir}`);
166
184
  console.log();
167
- // Remove extensions directory
168
185
  if (existsSync(extDir)) {
169
186
  rmSync(extDir, { recursive: true, force: true });
170
187
  console.log(`✓ Removed ${extDir}`);
@@ -172,30 +189,12 @@ function uninstall() {
172
189
  else {
173
190
  console.log(` (extensions directory not found, skipping)`);
174
191
  }
175
- // Patch OpenClaw config
176
192
  if (existsSync(configPath)) {
177
193
  console.log('Patching OpenClaw config...');
178
194
  const config = readJson(configPath);
179
195
  if (config) {
180
- const plugins = (config.plugins ?? {});
181
- // Remove from plugins.allow if it exists and is populated
182
- if (Array.isArray(plugins.allow) && plugins.allow.length > 0) {
183
- plugins.allow = plugins.allow.filter((id) => id !== PLUGIN_ID);
184
- console.log(` ✓ Removed "${PLUGIN_ID}" from plugins.allow`);
185
- }
186
- // Remove from plugins.entries
187
- if (plugins.entries && typeof plugins.entries === 'object') {
188
- const entries = plugins.entries;
189
- if (PLUGIN_ID in entries) {
190
- Reflect.deleteProperty(entries, PLUGIN_ID);
191
- console.log(` ✓ Removed "${PLUGIN_ID}" from plugins.entries`);
192
- }
193
- }
194
- // Remove from tools.allow if it exists and is populated
195
- const tools = (config.tools ?? {});
196
- if (Array.isArray(tools.allow) && tools.allow.length > 0) {
197
- tools.allow = tools.allow.filter((id) => id !== PLUGIN_ID);
198
- console.log(` ✓ Removed "${PLUGIN_ID}" from tools.allow`);
196
+ for (const msg of patchConfig(config, 'remove')) {
197
+ console.log(` ✓ ${msg}`);
199
198
  }
200
199
  writeJson(configPath, config);
201
200
  }
@@ -234,3 +233,5 @@ switch (command) {
234
233
  }
235
234
  break;
236
235
  }
236
+
237
+ export { patchConfig };