@karmaniverous/jeeves-meta-openclaw 0.13.3 → 0.15.0-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 +22 -13
- package/dist/index.js +140 -218
- package/dist/rollup.config.d.ts +3 -4
- package/dist/skills/jeeves-meta/SKILL.md +164 -330
- package/dist/src/configRoot.d.ts +43 -0
- package/dist/src/configRoot.test.d.ts +6 -0
- package/dist/src/helpers.d.ts +13 -2
- package/dist/src/index.d.ts +9 -2
- package/dist/src/index.test.d.ts +6 -0
- package/dist/src/manifest.test.d.ts +6 -0
- package/dist/src/pluginConfigSchema.d.ts +17 -0
- package/dist/src/serviceClient.d.ts +2 -2
- package/dist/src/tools.d.ts +2 -1
- package/openclaw.plugin.json +7 -6
- package/package.json +12 -15
- package/content/agents-section.md +0 -105
- package/content/skill.md +0 -122
- package/content/skills/coding.md +0 -149
- package/content/skills/jeeves.md +0 -122
- package/content/skills/operations.md +0 -125
- package/content/skills/playbooks.md +0 -75
- package/content/skills/slack-bot-provisioner.md +0 -57
- package/content/soul-section.md +0 -90
- package/content/templates/spec-to-code-guide.md +0 -250
- package/content/templates/spec.md +0 -177
- package/content/tools-platform.md +0 -102
- package/dist/cli.js +0 -26376
- package/dist/src/cli.d.ts +0 -12
- package/dist/src/cli.test.d.ts +0 -1
- package/dist/src/promptInjection.d.ts +0 -26
- package/dist/src/promptInjection.test.d.ts +0 -6
package/README.md
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
# @karmaniverous/jeeves-meta-openclaw
|
|
2
2
|
|
|
3
|
-
OpenClaw plugin for [jeeves-meta](
|
|
3
|
+
OpenClaw plugin for [jeeves-meta](https://github.com/karmaniverous/jeeves-meta/tree/main/packages/service). A standard OpenClaw plugin and thin HTTP client that registers interactive tools on top of the [`@karmaniverous/jeeves`](https://github.com/karmaniverous/jeeves) core SDK. It writes no workspace files: static platform content is rendered by `jeeves install`, and live state is served by the tools.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- **Twelve tools** — standard: `meta_status`, `meta_config`, `meta_config_apply`, `meta_service`; custom: `meta_list`, `meta_detail`, `meta_trigger`, `meta_preview`, `meta_seed`, `meta_unlock`, `meta_queue` (list/clear/abort), `meta_update`
|
|
8
8
|
- **MetaServiceClient** — typed HTTP client delegating all operations to the running service
|
|
9
|
-
- **TOOLS.md injection** — periodic refresh of entity stats, phase-state summary, failed-phase alerts, and next-phase indicator via `ComponentWriter` from `@karmaniverous/jeeves` (73-second prime interval)
|
|
10
9
|
- **Phase-state awareness** — tools expose per-meta `_phaseState`, `owedPhase`, and phase-state summary from the service's phase-state machine
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **Consumer skill** — `SKILL.md` for agent integration
|
|
10
|
+
- **Lazy config** — registers with no config; `configRoot` is resolved when a tool needs it
|
|
11
|
+
- **Consumer skill** — `jeeves-meta` skill shipped through the plugin manifest
|
|
14
12
|
|
|
15
13
|
## Plugin Lifecycle
|
|
16
14
|
|
|
@@ -18,24 +16,28 @@ OpenClaw plugin for [jeeves-meta](../service/). A thin HTTP client that register
|
|
|
18
16
|
|
|
19
17
|
## Install
|
|
20
18
|
|
|
19
|
+
Install with the Jeeves CLI, which runs the OpenClaw install and writes the plugin config:
|
|
20
|
+
|
|
21
21
|
```bash
|
|
22
|
-
|
|
22
|
+
jeeves install meta --config-root j:/config
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
Or install it as a standard OpenClaw plugin and configure it yourself:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
|
|
28
|
+
openclaw plugins install npm:@karmaniverous/jeeves-meta-openclaw@<version> --pin --accept-capabilities
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
Restart the gateway afterwards. There is no plugin-specific installer (the `npx @karmaniverous/jeeves-meta-openclaw install` CLI was removed in favour of `jeeves install`).
|
|
32
|
+
|
|
31
33
|
## Configuration
|
|
32
34
|
|
|
33
|
-
The plugin resolves settings via a
|
|
35
|
+
The plugin resolves settings via a fallback chain: plugin config → environment variable → default.
|
|
34
36
|
|
|
35
37
|
| Setting | Plugin Config Key | Env Var | Default |
|
|
36
|
-
|
|
38
|
+
| --- | --- | --- | --- |
|
|
37
39
|
| Service URL | `apiUrl` | `JEEVES_META_URL` | `http://127.0.0.1:1938` |
|
|
38
|
-
| Config Root | `configRoot` | `JEEVES_CONFIG_ROOT` |
|
|
40
|
+
| Config Root | `configRoot` | `JEEVES_CONFIG_ROOT` | _none_ |
|
|
39
41
|
|
|
40
42
|
```json
|
|
41
43
|
{
|
|
@@ -53,14 +55,21 @@ The plugin resolves settings via a three-step fallback chain: plugin config →
|
|
|
53
55
|
}
|
|
54
56
|
```
|
|
55
57
|
|
|
56
|
-
The `configRoot` setting tells `@karmaniverous/jeeves` core where to find the platform config directory. Core derives `{configRoot}/jeeves-meta/` for component-specific configuration.
|
|
58
|
+
The `configRoot` setting tells `@karmaniverous/jeeves` core where to find the platform config directory. Core derives `{configRoot}/jeeves-meta/` for component-specific configuration. It has no default: `jeeves install --config-root <path>` writes it.
|
|
59
|
+
|
|
60
|
+
`configRoot` is resolved **lazily**. Registration always succeeds without it (with a running gateway, `openclaw plugins install` activates the plugin before `jeeves install` writes its config), logging one warning:
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
[jeeves-meta] configRoot not configured yet — meta_service install will be unavailable until it is set in plugin config or JEEVES_CONFIG_ROOT
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Only `meta_service` with `action: "install"` reads it (core resolves the service config path from it); invoked without it, that call returns an error naming both ways to set it. Core `init()` runs the first time `configRoot` resolves. The other `meta_service` actions (`status`, `start`, `stop`, `restart`, `uninstall`) address the OS service by name, and every other tool only talks HTTP to the service at `apiUrl`, so all of them work without it.
|
|
57
67
|
|
|
58
68
|
## Documentation
|
|
59
69
|
|
|
60
70
|
- **[Plugin Setup](guides/plugin-setup.md)** — installation, config, lifecycle
|
|
61
71
|
- **[Tools Reference](guides/tools-reference.md)** — 12 tools: standard (meta_status, meta_config, meta_config_apply, meta_service) + custom (meta_list, meta_detail, meta_trigger, meta_preview, meta_seed, meta_unlock, meta_queue, meta_update)
|
|
62
72
|
- **[Virtual Rules](guides/virtual-rules.md)** — watcher inference rules
|
|
63
|
-
- **[TOOLS.md Injection](guides/tools-injection.md)** — dynamic prompt generation
|
|
64
73
|
|
|
65
74
|
## License
|
|
66
75
|
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { resolvePluginSetting, resolveOptionalPluginSetting,
|
|
2
|
-
import {
|
|
1
|
+
import { resolvePluginSetting, resolveOptionalPluginSetting, fail, init, resolveWorkspacePath, getErrorMessage, fetchJson, postJson, ok, connectionFail, createPluginToolset, jeevesComponentDescriptorSchema, getPackageVersion } from '@karmaniverous/jeeves';
|
|
2
|
+
import { getEndpoint, META_COMPONENT } from '@karmaniverous/jeeves-meta-core';
|
|
3
|
+
import { z } from 'zod';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Shared constants for the jeeves-meta OpenClaw plugin.
|
|
@@ -14,184 +15,97 @@ const PLUGIN_ID = 'jeeves-meta-openclaw';
|
|
|
14
15
|
*
|
|
15
16
|
* @module helpers
|
|
16
17
|
*/
|
|
18
|
+
/** Environment variable consulted when plugin config has no `configRoot`. */
|
|
19
|
+
const CONFIG_ROOT_ENV = 'JEEVES_CONFIG_ROOT';
|
|
20
|
+
/** Error returned by tools that need `configRoot` when it is not set. */
|
|
21
|
+
const CONFIG_ROOT_MISSING_MESSAGE = `configRoot not configured — set it in plugin config (plugins.entries.${PLUGIN_ID}.config.configRoot) or via ${CONFIG_ROOT_ENV}`;
|
|
17
22
|
/** Resolve the meta service URL. */
|
|
18
23
|
function getServiceUrl(api) {
|
|
19
24
|
return resolvePluginSetting(api, PLUGIN_ID, 'apiUrl', 'JEEVES_META_URL', 'http://127.0.0.1:1938');
|
|
20
25
|
}
|
|
21
|
-
/** Resolve the platform config root. */
|
|
22
|
-
function getConfigRoot(api) {
|
|
23
|
-
const value = resolveOptionalPluginSetting(api, PLUGIN_ID, 'configRoot', 'JEEVES_CONFIG_ROOT');
|
|
24
|
-
if (!value) {
|
|
25
|
-
throw new Error('configRoot not configured — set it in plugin config or via JEEVES_CONFIG_ROOT env var');
|
|
26
|
-
}
|
|
27
|
-
return value;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
26
|
/**
|
|
31
|
-
*
|
|
27
|
+
* Resolve the platform config root without throwing.
|
|
32
28
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
29
|
+
* Order: the plugin's own config (`api.pluginConfig`), then
|
|
30
|
+
* `plugins.entries.<id>.config`, then the `JEEVES_CONFIG_ROOT` env var.
|
|
35
31
|
*
|
|
36
|
-
* @
|
|
32
|
+
* @returns The config root, or `undefined` when none is set.
|
|
37
33
|
*/
|
|
38
|
-
|
|
39
|
-
const
|
|
34
|
+
function resolveConfigRoot(api) {
|
|
35
|
+
const own = api.pluginConfig?.['configRoot'];
|
|
36
|
+
if (typeof own === 'string' && own)
|
|
37
|
+
return own;
|
|
38
|
+
return (resolveOptionalPluginSetting(api, PLUGIN_ID, 'configRoot', CONFIG_ROOT_ENV) || undefined);
|
|
39
|
+
}
|
|
40
|
+
|
|
40
41
|
/**
|
|
41
|
-
*
|
|
42
|
+
* Lazy `configRoot` resolution for the jeeves-meta plugin.
|
|
42
43
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
44
|
+
* With a running gateway, `openclaw plugins install` activates the plugin
|
|
45
|
+
* before `jeeves install` writes its config, so `register()` must not
|
|
46
|
+
* depend on `configRoot`. The gate resolves it on first use, initializes
|
|
47
|
+
* core once it is known, and lets tools that need it fail cleanly.
|
|
45
48
|
*
|
|
46
|
-
* @
|
|
47
|
-
* @returns Formatted interval string.
|
|
49
|
+
* @module configRoot
|
|
48
50
|
*/
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return 'never synthesized';
|
|
52
|
-
const d = Math.floor(seconds / 86400);
|
|
53
|
-
const h = Math.floor((seconds % 86400) / 3600);
|
|
54
|
-
const m = Math.floor((seconds % 3600) / 60);
|
|
55
|
-
if (d > 0 && h > 0)
|
|
56
|
-
return `${d.toString()}d ${h.toString()}h`;
|
|
57
|
-
if (d > 0)
|
|
58
|
-
return `${d.toString()}d`;
|
|
59
|
-
if (h > 0 && m > 0)
|
|
60
|
-
return `${h.toString()}h ${m.toString()}m`;
|
|
61
|
-
if (h > 0)
|
|
62
|
-
return `${h.toString()}h`;
|
|
63
|
-
return `${Math.max(m, 1).toString()}m`;
|
|
64
|
-
}
|
|
51
|
+
/** Warning logged once at registration when `configRoot` is unset. */
|
|
52
|
+
const CONFIG_ROOT_WARNING = `[jeeves-meta] configRoot not configured yet — meta_service install will be unavailable until it is set in plugin config or ${CONFIG_ROOT_ENV}`;
|
|
65
53
|
/**
|
|
66
|
-
*
|
|
54
|
+
* Create a gate over the plugin API.
|
|
67
55
|
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
56
|
+
* Nothing is resolved or initialized until {@link ConfigRootGate.ensure}
|
|
57
|
+
* is called, so config written after registration is picked up.
|
|
70
58
|
*/
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
'> on creating `.meta/` directories.',
|
|
83
|
-
].join('\n');
|
|
84
|
-
}
|
|
85
|
-
const { summary } = metas;
|
|
86
|
-
// Find stalest age
|
|
87
|
-
let stalestAge = 0;
|
|
88
|
-
for (const item of metas.metas) {
|
|
89
|
-
const s = item.stalenessSeconds !== null ? item.stalenessSeconds : Infinity;
|
|
90
|
-
if (s > stalestAge)
|
|
91
|
-
stalestAge = s;
|
|
92
|
-
}
|
|
93
|
-
const stalestDisplay = summary.stalestPath
|
|
94
|
-
? summary.stalestPath + ' (' + formatAge(stalestAge) + ')'
|
|
95
|
-
: 'n/a';
|
|
96
|
-
const lastSynthDisplay = summary.lastSynthesizedAt
|
|
97
|
-
? (summary.lastSynthesizedPath ?? '') +
|
|
98
|
-
' (' +
|
|
99
|
-
summary.lastSynthesizedAt +
|
|
100
|
-
')'
|
|
101
|
-
: 'n/a';
|
|
102
|
-
// Service status + dependency health
|
|
103
|
-
// The core SDK's createStatusHandler nests getHealth() under `health`.
|
|
104
|
-
const { dependencies } = status.health;
|
|
105
|
-
const depLines = [];
|
|
106
|
-
if (dependencies.watcher.status === 'indexing') {
|
|
107
|
-
depLines.push('> ⏳ **Watcher indexing**: Initial filesystem scan in progress. Synthesis will resume when complete.');
|
|
108
|
-
}
|
|
109
|
-
else if (dependencies.watcher.status !== 'ok' &&
|
|
110
|
-
dependencies.watcher.status !== 'indexing') {
|
|
111
|
-
depLines.push('> ⚠️ **Watcher**: ' + dependencies.watcher.status);
|
|
112
|
-
}
|
|
113
|
-
if (dependencies.watcher.rulesRegistered === false &&
|
|
114
|
-
dependencies.watcher.status === 'ok') {
|
|
115
|
-
depLines.push('> ⚠️ **Watcher rules not registered**: Meta files may not render properly in search/server.');
|
|
116
|
-
}
|
|
117
|
-
if (dependencies.gateway.status !== 'ok') {
|
|
118
|
-
depLines.push('> ⚠️ **Gateway**: ' + dependencies.gateway.status);
|
|
119
|
-
}
|
|
120
|
-
// Phase-state summary from /status health
|
|
121
|
-
const phaseLines = [];
|
|
122
|
-
const phaseSummary = status.health.phaseStateSummary;
|
|
123
|
-
if (phaseSummary) {
|
|
124
|
-
// Fresh counts are aggregated; non-fresh show <count> <state> <phase>
|
|
125
|
-
let freshTotal = 0;
|
|
126
|
-
for (const phase of phaseNames) {
|
|
127
|
-
freshTotal += phaseSummary[phase].fresh;
|
|
128
|
-
}
|
|
129
|
-
const parts = [];
|
|
130
|
-
if (freshTotal > 0)
|
|
131
|
-
parts.push(freshTotal.toString() + ' fresh');
|
|
132
|
-
for (const phase of phaseNames) {
|
|
133
|
-
for (const state of nonFreshStatuses) {
|
|
134
|
-
const count = phaseSummary[phase][state];
|
|
135
|
-
if (count > 0)
|
|
136
|
-
parts.push(`${count.toString()} ${state} ${phase}`);
|
|
59
|
+
function createConfigRootGate(api) {
|
|
60
|
+
let resolved;
|
|
61
|
+
return {
|
|
62
|
+
ensure: () => {
|
|
63
|
+
if (resolved)
|
|
64
|
+
return { ok: true, configRoot: resolved };
|
|
65
|
+
const configRoot = resolveConfigRoot(api);
|
|
66
|
+
if (!configRoot)
|
|
67
|
+
return { ok: false, error: CONFIG_ROOT_MISSING_MESSAGE };
|
|
68
|
+
try {
|
|
69
|
+
init({ workspacePath: resolveWorkspacePath(api), configRoot });
|
|
137
70
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const failedParts = [];
|
|
144
|
-
for (const item of metas.metas) {
|
|
145
|
-
const ps = item.phaseState;
|
|
146
|
-
if (!ps)
|
|
147
|
-
continue;
|
|
148
|
-
for (const phase of phaseNames) {
|
|
149
|
-
if (ps[phase] === 'failed') {
|
|
150
|
-
const p = item.path;
|
|
151
|
-
failedParts.push(p + ' (' + phase + ')');
|
|
152
|
-
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
return {
|
|
73
|
+
ok: false,
|
|
74
|
+
error: `jeeves core init failed: ${getErrorMessage(error)}`,
|
|
75
|
+
};
|
|
153
76
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
'| Errors | ' + summary.errors.toString() + ' |',
|
|
187
|
-
'| Never synthesized | ' + summary.neverSynthesized.toString() + ' |',
|
|
188
|
-
'| Stalest | ' + stalestDisplay + ' |',
|
|
189
|
-
'| Last synthesized | ' + lastSynthDisplay + ' |',
|
|
190
|
-
...(phaseLines.length > 0 ? ['', '### Phase State', ...phaseLines] : []),
|
|
191
|
-
...(depLines.length > 0 ? ['', '### Dependencies', ...depLines] : []),
|
|
192
|
-
'',
|
|
193
|
-
'Read the `jeeves-meta` skill for usage guidance, configuration, and troubleshooting.',
|
|
194
|
-
].join('\n');
|
|
77
|
+
resolved = configRoot;
|
|
78
|
+
return { ok: true, configRoot };
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/** Log {@link CONFIG_ROOT_WARNING} once if `configRoot` cannot be resolved now. */
|
|
83
|
+
function warnIfConfigRootMissing(api) {
|
|
84
|
+
if (resolveConfigRoot(api))
|
|
85
|
+
return;
|
|
86
|
+
const warn = api.logger?.warn ??
|
|
87
|
+
((m) => {
|
|
88
|
+
console.warn(m);
|
|
89
|
+
});
|
|
90
|
+
warn(CONFIG_ROOT_WARNING);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Wrap a tool so calls that read `configRoot` return a clear error until
|
|
94
|
+
* it resolves. Calls for which `needsConfigRoot` is false pass straight
|
|
95
|
+
* through without touching the gate.
|
|
96
|
+
*/
|
|
97
|
+
function requireConfigRoot(tool, gate, needsConfigRoot = () => true) {
|
|
98
|
+
return {
|
|
99
|
+
...tool,
|
|
100
|
+
execute: (id, params) => {
|
|
101
|
+
if (!needsConfigRoot(params))
|
|
102
|
+
return tool.execute(id, params);
|
|
103
|
+
const check = gate.ensure();
|
|
104
|
+
if (!check.ok)
|
|
105
|
+
return Promise.resolve(fail(check.error));
|
|
106
|
+
return tool.execute(id, params);
|
|
107
|
+
},
|
|
108
|
+
};
|
|
195
109
|
}
|
|
196
110
|
|
|
197
111
|
/**
|
|
@@ -580,12 +494,30 @@ function buildMetaUpdateTool(client, baseUrl) {
|
|
|
580
494
|
*
|
|
581
495
|
* @module tools
|
|
582
496
|
*/
|
|
497
|
+
/**
|
|
498
|
+
* Tool calls that read `configRoot`, keyed by tool name.
|
|
499
|
+
*
|
|
500
|
+
* Only `meta_service` with `action: 'install'` reads it: core's service
|
|
501
|
+
* manager resolves the component config path via `getComponentConfigDir()`.
|
|
502
|
+
* The other `meta_service` actions drive the OS service manager by name,
|
|
503
|
+
* and every other tool only talks HTTP to the meta service at `apiUrl`,
|
|
504
|
+
* so none of them are gated.
|
|
505
|
+
*/
|
|
506
|
+
const CONFIG_ROOT_TOOLS = new Map([
|
|
507
|
+
['meta_service', (params) => params.action === 'install'],
|
|
508
|
+
]);
|
|
583
509
|
/** Register all meta_* tools (standard + custom). */
|
|
584
|
-
function registerMetaTools(api, client, descriptor) {
|
|
510
|
+
function registerMetaTools(api, client, descriptor, gate) {
|
|
585
511
|
const baseUrl = client.getBaseUrl();
|
|
586
|
-
// Standard tools from factory: meta_status, meta_config, meta_config_apply, meta_service
|
|
587
|
-
|
|
588
|
-
|
|
512
|
+
// Standard tools from factory: meta_status, meta_config, meta_config_apply, meta_service.
|
|
513
|
+
// `apiUrl` is resolved on every call with the same resolution as the
|
|
514
|
+
// custom tools, so the standard HTTP tools hit the configured service.
|
|
515
|
+
const toolset = createPluginToolset(descriptor, {
|
|
516
|
+
apiUrl: () => getServiceUrl(api),
|
|
517
|
+
});
|
|
518
|
+
for (const tool of toolset) {
|
|
519
|
+
const needsConfigRoot = CONFIG_ROOT_TOOLS.get(tool.name);
|
|
520
|
+
api.registerTool(needsConfigRoot ? requireConfigRoot(tool, gate, needsConfigRoot) : tool);
|
|
589
521
|
}
|
|
590
522
|
// Custom domain-specific tools
|
|
591
523
|
for (const tool of buildCustomTools(client, baseUrl)) {
|
|
@@ -593,59 +525,46 @@ function registerMetaTools(api, client, descriptor) {
|
|
|
593
525
|
}
|
|
594
526
|
}
|
|
595
527
|
|
|
528
|
+
/**
|
|
529
|
+
* Zod schema for the jeeves-meta OpenClaw plugin configuration.
|
|
530
|
+
*
|
|
531
|
+
* This is the source of truth for the plugin configSchema.
|
|
532
|
+
* The build-time script `scripts/generate-plugin-schema.mjs` derives
|
|
533
|
+
* the JSON Schema in `openclaw.plugin.json` from this definition.
|
|
534
|
+
*
|
|
535
|
+
* @module pluginConfigSchema
|
|
536
|
+
*/
|
|
537
|
+
/** Zod schema for the jeeves-meta OpenClaw plugin configuration. */
|
|
538
|
+
const pluginConfigSchema = z.object({
|
|
539
|
+
apiUrl: z
|
|
540
|
+
.string()
|
|
541
|
+
.default('http://127.0.0.1:1938')
|
|
542
|
+
.describe('URL of the jeeves-meta HTTP service. Falls back to JEEVES_META_URL env var.'),
|
|
543
|
+
configRoot: z
|
|
544
|
+
.string()
|
|
545
|
+
.optional()
|
|
546
|
+
.describe('Absolute path to the platform config root (e.g. j:/config). Used by @karmaniverous/jeeves core for config directory resolution.'),
|
|
547
|
+
});
|
|
548
|
+
|
|
596
549
|
/**
|
|
597
550
|
* OpenClaw plugin for jeeves-meta.
|
|
598
551
|
*
|
|
599
552
|
* Thin HTTP client — all operations delegate to the jeeves-meta service.
|
|
600
|
-
*
|
|
553
|
+
* A standard OpenClaw plugin: it writes no workspace files and is installed
|
|
554
|
+
* by `jeeves install` (or `openclaw plugins install`).
|
|
601
555
|
*
|
|
602
556
|
* @packageDocumentation
|
|
603
557
|
*/
|
|
604
|
-
/**
|
|
605
|
-
function
|
|
606
|
-
|
|
607
|
-
const workspacePath = resolveWorkspacePath(api);
|
|
608
|
-
init({
|
|
609
|
-
workspacePath,
|
|
610
|
-
configRoot: getConfigRoot(api),
|
|
611
|
-
});
|
|
612
|
-
const gatewayUrl = loadWorkspaceConfig(workspacePath)?.core?.gatewayUrl ??
|
|
613
|
-
WORKSPACE_CONFIG_DEFAULTS.core.gatewayUrl;
|
|
614
|
-
const placeholder = 'The jeeves-meta synthesis engine is initializing...\n\n' +
|
|
615
|
-
'Read the `jeeves-meta` skill for usage guidance, configuration, and troubleshooting.';
|
|
616
|
-
let consecutive503s = 0;
|
|
617
|
-
const getContent = createAsyncContentCache({
|
|
618
|
-
fetch: async () => {
|
|
619
|
-
const content = await generateMetaMenu(client);
|
|
620
|
-
consecutive503s = 0;
|
|
621
|
-
return content;
|
|
622
|
-
},
|
|
623
|
-
placeholder,
|
|
624
|
-
onError: (error) => {
|
|
625
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
626
|
-
if (/HTTP 503\b/i.test(msg) || /scan.in.progress/i.test(msg)) {
|
|
627
|
-
consecutive503s++;
|
|
628
|
-
if (consecutive503s === 1) {
|
|
629
|
-
console.warn('[jeeves-meta] Watcher scan still in progress — will retry on next refresh cycle.');
|
|
630
|
-
}
|
|
631
|
-
else {
|
|
632
|
-
console.debug(`[jeeves-meta] Watcher scan still in progress (attempt ${String(consecutive503s)}) — suppressing repeated warnings.`);
|
|
633
|
-
}
|
|
634
|
-
return;
|
|
635
|
-
}
|
|
636
|
-
consecutive503s = 0;
|
|
637
|
-
console.warn('[jeeves-meta] Content fetch failed:', msg);
|
|
638
|
-
},
|
|
639
|
-
});
|
|
640
|
-
const descriptor = jeevesComponentDescriptorSchema.parse({
|
|
558
|
+
/** Build the plugin-side component descriptor used by the standard toolset. */
|
|
559
|
+
function buildDescriptor() {
|
|
560
|
+
return jeevesComponentDescriptorSchema.parse({
|
|
641
561
|
name: META_COMPONENT.name,
|
|
642
562
|
version: getPackageVersion(import.meta.url),
|
|
643
563
|
servicePackage: META_COMPONENT.servicePackage,
|
|
644
564
|
pluginPackage: META_COMPONENT.pluginPackage,
|
|
645
565
|
defaultPort: META_COMPONENT.defaultPort,
|
|
646
|
-
// The
|
|
647
|
-
|
|
648
|
-
configSchema: { parse: (v) => v },
|
|
566
|
+
// The plugin never validates service config; the service descriptor does.
|
|
567
|
+
configSchema: z.unknown(),
|
|
649
568
|
configFileName: 'config.json',
|
|
650
569
|
initTemplate: () => ({}),
|
|
651
570
|
startCommand: (configPath) => [
|
|
@@ -655,19 +574,22 @@ function register(api) {
|
|
|
655
574
|
'-c',
|
|
656
575
|
configPath,
|
|
657
576
|
],
|
|
658
|
-
//
|
|
659
|
-
// content. The real run callback lives in the service descriptor.
|
|
577
|
+
// The real run callback lives in the service descriptor.
|
|
660
578
|
run: () => {
|
|
661
579
|
return Promise.reject(new Error('run() is not available on the plugin-side descriptor'));
|
|
662
580
|
},
|
|
663
|
-
sectionId: 'Meta',
|
|
664
|
-
refreshIntervalSeconds: 73,
|
|
665
|
-
generateToolsContent: getContent,
|
|
666
|
-
dependencies: { hard: ['watcher'], soft: [] },
|
|
667
581
|
});
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Register all jeeves-meta tools with the OpenClaw plugin API.
|
|
585
|
+
*
|
|
586
|
+
* Always succeeds, even with no plugin config: `configRoot` is resolved
|
|
587
|
+
* lazily when a tool that needs it runs.
|
|
588
|
+
*/
|
|
589
|
+
function register(api) {
|
|
590
|
+
const client = new MetaServiceClient({ apiUrl: getServiceUrl(api) });
|
|
591
|
+
warnIfConfigRootMissing(api);
|
|
592
|
+
registerMetaTools(api, client, buildDescriptor(), createConfigRootGate(api));
|
|
671
593
|
}
|
|
672
594
|
|
|
673
|
-
export { register as default };
|
|
595
|
+
export { register as default, pluginConfigSchema };
|
package/dist/rollup.config.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Rollup configuration for the OpenClaw plugin package.
|
|
3
|
-
*
|
|
3
|
+
* Single entry point: the plugin (ESM + declarations).
|
|
4
4
|
*
|
|
5
|
-
* Runtime dependencies (`@karmaniverous/jeeves`, `@karmaniverous/jeeves-meta
|
|
6
|
-
* are externalized
|
|
7
|
-
* CLI bundles everything for standalone execution.
|
|
5
|
+
* Runtime dependencies (`@karmaniverous/jeeves`, `@karmaniverous/jeeves-meta-core`,
|
|
6
|
+
* `zod`) are externalized and resolved from the plugin's installed dependencies.
|
|
8
7
|
*/
|
|
9
8
|
import type { RollupOptions } from 'rollup';
|
|
10
9
|
declare const _default: RollupOptions[];
|