@karmaniverous/jeeves-server-openclaw 0.3.0 → 0.3.1

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
@@ -1,6 +1,8 @@
1
1
  # @karmaniverous/jeeves-server-openclaw
2
2
 
3
- OpenClaw plugin for Jeeves Server. Provides agents with tools for:
3
+ OpenClaw plugin for Jeeves Server. Integrates with `@karmaniverous/jeeves` core for managed TOOLS.md writing, service lifecycle commands, and platform content maintenance.
4
+
5
+ Provides agents with tools for:
4
6
 
5
7
  - Server status and capabilities
6
8
  - File/directory metadata browsing
@@ -35,7 +37,8 @@ Add an unscoped `_plugin` key to your Jeeves Server config:
35
37
  "enabled": true,
36
38
  "config": {
37
39
  "apiUrl": "http://127.0.0.1:1934",
38
- "pluginKey": "<same-seed-as-server-_plugin>"
40
+ "pluginKey": "<same-seed-as-server-_plugin>",
41
+ "configRoot": "j:/config"
39
42
  }
40
43
  }
41
44
  }
@@ -43,7 +46,13 @@ Add an unscoped `_plugin` key to your Jeeves Server config:
43
46
  }
44
47
  ```
45
48
 
49
+ | Config | Default | Description |
50
+ |--------|---------|-------------|
51
+ | `apiUrl` | `http://127.0.0.1:1934` | Server API base URL |
52
+ | `pluginKey` | — | Server `_plugin` key seed |
53
+ | `configRoot` | `j:/config` | Platform config root (core derives component config dirs) |
54
+
46
55
  ## Docs
47
56
 
48
- - OpenClaw Integration: ./guides/openclaw-integration.md
57
+ - [OpenClaw Integration](./guides/openclaw-integration.md) — Full configuration, tool reference, architecture
49
58
 
package/dist/cli.js CHANGED
@@ -1,43 +1,25 @@
1
1
  #!/usr/bin/env node
2
- import { existsSync, rmSync, mkdirSync, cpSync, readFileSync, writeFileSync } from 'fs';
3
- import { homedir } from 'os';
4
- import { join, dirname, resolve } from 'path';
2
+ import { existsSync as existsSync$1, rmSync as rmSync$1, mkdirSync, cpSync, readFileSync as readFileSync$1, writeFileSync as writeFileSync$1 } from 'fs';
3
+ import { homedir as homedir$1 } from 'os';
4
+ import { join as join$1, resolve as resolve$1, dirname as dirname$1 } from 'path';
5
5
  import { fileURLToPath } from 'url';
6
+ import { homedir } from 'node:os';
7
+ import { dirname, resolve, join } from 'node:path';
8
+ import { existsSync, rmSync, readFileSync, writeFileSync } from 'node:fs';
6
9
 
7
10
  /**
8
- * CLI for installing/uninstalling the jeeves-server OpenClaw plugin.
9
- *
10
- * Usage:
11
- * npx \@karmaniverous/jeeves-server-openclaw install
12
- * npx \@karmaniverous/jeeves-server-openclaw uninstall
11
+ * Shared constants for the jeeves-server OpenClaw plugin.
13
12
  */
13
+ /** Plugin identifier used in OpenClaw config and extension paths. */
14
14
  const PLUGIN_ID = 'jeeves-server-openclaw';
15
- function resolveOpenClawHome() {
16
- if (process.env.OPENCLAW_CONFIG)
17
- return dirname(resolve(process.env.OPENCLAW_CONFIG));
18
- if (process.env.OPENCLAW_HOME)
19
- return resolve(process.env.OPENCLAW_HOME);
20
- return join(homedir(), '.openclaw');
21
- }
22
- function resolveConfigPath(home) {
23
- if (process.env.OPENCLAW_CONFIG)
24
- return resolve(process.env.OPENCLAW_CONFIG);
25
- return join(home, 'openclaw.json');
26
- }
27
- function getPackageRoot() {
28
- return resolve(dirname(fileURLToPath(import.meta.url)), '..');
29
- }
30
- function readJson(p) {
31
- try {
32
- return JSON.parse(readFileSync(p, 'utf8'));
33
- }
34
- catch {
35
- return null;
36
- }
37
- }
38
- function writeJson(p, data) {
39
- writeFileSync(p, JSON.stringify(data, null, 2) + '\n');
40
- }
15
+
16
+ /**
17
+ * OpenClaw config patching utilities.
18
+ *
19
+ * @remarks
20
+ * Shared by both the `npx ... install|uninstall` CLI and by in-process
21
+ * plugin commands.
22
+ */
41
23
  function patchAllowList(parent, key, label, mode) {
42
24
  if (!Array.isArray(parent[key]) || parent[key].length === 0)
43
25
  return undefined;
@@ -86,39 +68,119 @@ function patchConfig(config, mode) {
86
68
  messages.push(toolAllow);
87
69
  return messages;
88
70
  }
71
+
72
+ /**
73
+ * OpenClaw home and config path resolution.
74
+ *
75
+ * @remarks
76
+ * Shared by the CLI installer and the in-process plugin commands.
77
+ */
78
+ /**
79
+ * Resolve the OpenClaw home directory from environment or default.
80
+ */
81
+ function resolveOpenClawHome() {
82
+ if (process.env.OPENCLAW_CONFIG)
83
+ return dirname(resolve(process.env.OPENCLAW_CONFIG));
84
+ if (process.env.OPENCLAW_HOME)
85
+ return resolve(process.env.OPENCLAW_HOME);
86
+ return join(homedir(), '.openclaw');
87
+ }
88
+ /**
89
+ * Resolve the OpenClaw config file path from environment or default.
90
+ */
91
+ function resolveConfigPath(home) {
92
+ if (process.env.OPENCLAW_CONFIG)
93
+ return resolve(process.env.OPENCLAW_CONFIG);
94
+ return join(home, 'openclaw.json');
95
+ }
96
+
97
+ /**
98
+ * Shared plugin removal logic for extension directory and config cleanup.
99
+ *
100
+ * @remarks
101
+ * Used by both the CLI `uninstall` command and the in-process
102
+ * `PluginCommands.uninstall()` implementation.
103
+ */
104
+ /**
105
+ * Remove the plugin extension directory and patch the OpenClaw config.
106
+ *
107
+ * @param home - OpenClaw home directory path.
108
+ * @param configPath - OpenClaw config file path.
109
+ * @returns Messages describing what was changed.
110
+ */
111
+ function removePlugin(home, configPath) {
112
+ const messages = [];
113
+ const extDir = join(home, 'extensions', PLUGIN_ID);
114
+ if (existsSync(extDir)) {
115
+ rmSync(extDir, { recursive: true, force: true });
116
+ messages.push('Removed ' + extDir);
117
+ }
118
+ if (existsSync(configPath)) {
119
+ const raw = readFileSync(configPath, 'utf8');
120
+ const config = JSON.parse(raw);
121
+ const patchMessages = patchConfig(config, 'remove');
122
+ if (patchMessages.length > 0) {
123
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
124
+ messages.push(...patchMessages);
125
+ }
126
+ }
127
+ return messages;
128
+ }
129
+
130
+ /**
131
+ * CLI for installing/uninstalling the jeeves-server OpenClaw plugin.
132
+ *
133
+ * Usage:
134
+ * npx \@karmaniverous/jeeves-server-openclaw install
135
+ * npx \@karmaniverous/jeeves-server-openclaw uninstall
136
+ */
137
+ function getPackageRoot() {
138
+ return resolve$1(dirname$1(fileURLToPath(import.meta.url)), '..');
139
+ }
140
+ function readJson(p) {
141
+ try {
142
+ return JSON.parse(readFileSync$1(p, 'utf8'));
143
+ }
144
+ catch {
145
+ return null;
146
+ }
147
+ }
148
+ function writeJson(p, data) {
149
+ writeFileSync$1(p, JSON.stringify(data, null, 2) + '\n');
150
+ }
89
151
  function install() {
90
152
  const home = resolveOpenClawHome();
91
153
  const configPath = resolveConfigPath(home);
92
- const extDir = join(home, 'extensions', PLUGIN_ID);
154
+ const extDir = join$1(home, 'extensions', PLUGIN_ID);
93
155
  const pkgRoot = getPackageRoot();
94
156
  console.log('OpenClaw home: ' + home);
95
157
  console.log('Config: ' + configPath);
96
158
  console.log('Extensions dir: ' + extDir);
97
159
  console.log('Package root: ' + pkgRoot);
98
160
  console.log();
99
- if (!existsSync(home)) {
161
+ if (!existsSync$1(home)) {
100
162
  console.error('Error: OpenClaw home not found at ' + home);
101
163
  process.exit(1);
102
164
  }
103
- if (!existsSync(configPath)) {
165
+ if (!existsSync$1(configPath)) {
104
166
  console.error('Error: OpenClaw config not found at ' + configPath);
105
167
  process.exit(1);
106
168
  }
107
169
  console.log('Copying plugin to extensions directory...');
108
- if (existsSync(extDir))
109
- rmSync(extDir, { recursive: true, force: true });
170
+ if (existsSync$1(extDir))
171
+ rmSync$1(extDir, { recursive: true, force: true });
110
172
  mkdirSync(extDir, { recursive: true });
111
173
  for (const file of ['dist', 'openclaw.plugin.json', 'package.json']) {
112
- const src = join(pkgRoot, file);
113
- const dest = join(extDir, file);
114
- if (existsSync(src)) {
174
+ const src = join$1(pkgRoot, file);
175
+ const dest = join$1(extDir, file);
176
+ if (existsSync$1(src)) {
115
177
  cpSync(src, dest, { recursive: true });
116
178
  console.log(' \u2713 ' + file);
117
179
  }
118
180
  }
119
- const nodeModulesSrc = join(pkgRoot, 'node_modules');
120
- if (existsSync(nodeModulesSrc)) {
121
- cpSync(nodeModulesSrc, join(extDir, 'node_modules'), { recursive: true });
181
+ const nodeModulesSrc = join$1(pkgRoot, 'node_modules');
182
+ if (existsSync$1(nodeModulesSrc)) {
183
+ cpSync(nodeModulesSrc, join$1(extDir, 'node_modules'), { recursive: true });
122
184
  console.log(' \u2713 node_modules');
123
185
  }
124
186
  console.log();
@@ -138,26 +200,12 @@ function install() {
138
200
  function uninstall() {
139
201
  const home = resolveOpenClawHome();
140
202
  const configPath = resolveConfigPath(home);
141
- const extDir = join(home, 'extensions', PLUGIN_ID);
142
203
  console.log('OpenClaw home: ' + home);
143
204
  console.log('Config: ' + configPath);
144
- console.log('Extensions dir: ' + extDir);
145
205
  console.log();
146
- if (existsSync(extDir)) {
147
- rmSync(extDir, { recursive: true, force: true });
148
- console.log('\u2713 Removed ' + extDir);
149
- }
150
- else
151
- console.log(' (extensions directory not found, skipping)');
152
- if (existsSync(configPath)) {
153
- console.log('Patching OpenClaw config...');
154
- const config = readJson(configPath);
155
- if (config) {
156
- for (const msg of patchConfig(config, 'remove'))
157
- console.log(' \u2713 ' + msg);
158
- writeJson(configPath, config);
159
- }
160
- }
206
+ const messages = removePlugin(home, configPath);
207
+ for (const msg of messages)
208
+ console.log(' \u2713 ' + msg);
161
209
  // Clean up TOOLS.md server section
162
210
  cleanupToolsMd(home, configPath);
163
211
  console.log();
@@ -172,23 +220,23 @@ function resolveWorkspaceDir(home, configPath) {
172
220
  const defaults = agents?.defaults;
173
221
  const workspace = defaults?.workspace;
174
222
  if (workspace)
175
- return resolve(workspace.replace(/^~/, homedir()));
176
- return join(home, 'workspace');
223
+ return resolve$1(workspace.replace(/^~/, homedir$1()));
224
+ return join$1(home, 'workspace');
177
225
  }
178
226
  function cleanupToolsMd(home, configPath) {
179
227
  const workspaceDir = resolveWorkspaceDir(home, configPath);
180
228
  if (!workspaceDir)
181
229
  return;
182
- const toolsPath = join(workspaceDir, 'TOOLS.md');
183
- if (!existsSync(toolsPath))
230
+ const toolsPath = join$1(workspaceDir, 'TOOLS.md');
231
+ if (!existsSync$1(toolsPath))
184
232
  return;
185
- let content = readFileSync(toolsPath, 'utf8');
233
+ let content = readFileSync$1(toolsPath, 'utf8');
186
234
  const serverRe = /^## Server\n[\s\S]*?(?=\n## |\n# |$(?![\s\S]))/m;
187
235
  if (!serverRe.test(content))
188
236
  return;
189
237
  content = content.replace(serverRe, '').replace(/\n{3,}/g, '\n\n');
190
238
  content = content.trim() + '\n';
191
- writeFileSync(toolsPath, content);
239
+ writeFileSync$1(toolsPath, content);
192
240
  console.log('\u2713 Cleaned up TOOLS.md (removed Server section)');
193
241
  }
194
242
  const command = process.argv[2];
@@ -218,5 +266,3 @@ switch (command) {
218
266
  }
219
267
  break;
220
268
  }
221
-
222
- export { patchConfig };