@karmaniverous/jeeves-meta-openclaw 0.1.4 → 0.2.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.
@@ -3,13 +3,13 @@
3
3
  ## Overview
4
4
 
5
5
  jeeves-meta is the Jeeves platform's knowledge synthesis engine. It discovers
6
- `.meta/` directories, gathers context from the Qdrant vector index, and uses
7
- a three-step LLM process (architect, builder, critic) to produce structured
8
- synthesis artifacts.
6
+ `.meta/` directories via watcher scan, gathers context from the Qdrant vector
7
+ index, and uses a three-step LLM process (architect, builder, critic) to
8
+ produce structured synthesis artifacts co-located with source content.
9
9
 
10
10
  ## Available Tools
11
11
 
12
- ### synth_list
12
+ ### meta_list
13
13
  List all `.meta/` directories with summary stats and per-meta projection.
14
14
  Supports filtering by path prefix, error status, staleness, and lock state.
15
15
  Use for engine health checks and finding stale knowledge.
@@ -19,7 +19,7 @@ Use for engine health checks and finding stale knowledge.
19
19
  - `filter` (optional): Structured filter (`{ hasError: true }`, `{ staleHours: 24 }`)
20
20
  - `fields` (optional): Property projection array
21
21
 
22
- ### synth_detail
22
+ ### meta_detail
23
23
  Full detail for a single meta, with optional archive history.
24
24
 
25
25
  **Parameters:**
@@ -27,15 +27,21 @@ Full detail for a single meta, with optional archive history.
27
27
  - `fields` (optional): Property projection
28
28
  - `includeArchive` (optional): false, true, or number (N most recent)
29
29
 
30
- ### synth_preview
30
+ ### meta_preview
31
31
  Dry-run for the next synthesis cycle. Shows scope files, delta files,
32
32
  architect trigger reasons, steer status, and structure changes — without
33
- running any LLM calls. Use before `synth_trigger` to understand what
33
+ running any LLM calls. Use before `meta_trigger` to understand what
34
34
  will happen.
35
35
 
36
- ### synth_trigger
37
- Manually trigger a full synthesis cycle (architect builder critic) for
38
- a specific meta or the next-stalest candidate.
36
+ **Parameters:**
37
+ - `path` (optional): Specific `.meta/` or owner directory path. If omitted,
38
+ previews the stalest candidate.
39
+
40
+ ### meta_trigger
41
+ Enqueue a synthesis cycle for a specific meta or the next-stalest candidate.
42
+ The synthesis runs asynchronously in the service queue; the tool returns
43
+ immediately with the queue position. The full cycle (architect → builder →
44
+ critic) runs in the background.
39
45
 
40
46
  **Parameters:**
41
47
  - `path` (optional): Specific `.meta/` or owner directory path. If omitted,
@@ -43,13 +49,16 @@ a specific meta or the next-stalest candidate.
43
49
 
44
50
  ## When to Use
45
51
 
46
- - **Checking synthesis health:** `synth_list`
47
- - **Finding stale knowledge:** `synth_list` with `filter: { staleHours: 24 }`
48
- - **Checking errors:** `synth_list` with `filter: { hasError: true }`
49
- - **Getting full details:** `synth_detail` with optional `includeArchive: 5`
50
- - **Understanding what a cycle will do:** `synth_preview`
51
- - **Forcing a refresh:** `synth_trigger` with optional path
52
- - **Reading synthesis output:** Use `watcher_search` with domain `synth-meta`
52
+ - **Checking synthesis health:** `meta_list`
53
+ - **Finding stale knowledge:** `meta_list` with `filter: { staleHours: 24 }`
54
+ - **Checking errors:** `meta_list` with `filter: { hasError: true }`
55
+ - **Getting full details:** `meta_detail` with optional `includeArchive: 5`
56
+ - **Understanding what a cycle will do:** `meta_preview`
57
+ - **Forcing a refresh:** `meta_trigger` with optional path
58
+ - **Reading synthesis output:** Use `watcher_search` filtered by the properties
59
+ configured in `metaProperty` (e.g. `{ "domains": ["meta"] }` in production).
60
+ The default properties are `{ _meta: "current" }` for live metas and
61
+ `{ _meta: "archive" }` for archive snapshots.
53
62
 
54
63
  ## Key Concepts
55
64
 
@@ -65,15 +74,18 @@ a specific meta or the next-stalest candidate.
65
74
 
66
75
  ### Config File
67
76
 
68
- Location determined by `JEEVES_META_CONFIG` env var or plugin `configPath` setting.
77
+ Location determined by `JEEVES_META_CONFIG` env var or `--config` CLI flag.
69
78
  Canonical deployment: `J:\config\jeeves-meta.config.json`.
70
79
 
71
80
  Key settings:
81
+
72
82
  | Setting | Default | Description |
73
83
  |---------|---------|-------------|
74
- | `watchPaths` | (required) | Array of paths to scan for `.meta/` directories |
75
84
  | `watcherUrl` | (required) | Watcher service URL (e.g. `http://localhost:1936`) |
76
- | `gatewayUrl` | `http://127.0.0.1:3000` | OpenClaw gateway URL for subprocess spawning |
85
+ | `gatewayUrl` | `http://127.0.0.1:18789` | OpenClaw gateway URL for subprocess spawning |
86
+ | `gatewayApiKey` | (optional) | API key for gateway authentication |
87
+ | `metaProperty` | `{ _meta: "current" }` | Watcher metadata properties applied to live `.meta/meta.json` files. `Record<string, unknown>` — any shape accepted. |
88
+ | `metaArchiveProperty` | `{ _meta: "archive" }` | Watcher metadata properties applied to `.meta/archive/**` snapshots. Same shape flexibility. |
77
89
  | `architectEvery` | 10 | Re-run architect every N cycles even if structure unchanged |
78
90
  | `depthWeight` | 0.5 | Exponent for depth-based scheduling (0 = pure staleness) |
79
91
  | `maxArchive` | 20 | Max archived snapshots per meta |
@@ -81,6 +93,62 @@ Key settings:
81
93
  | `architectTimeout` | 120s | Architect subprocess timeout |
82
94
  | `builderTimeout` | 600s | Builder subprocess timeout |
83
95
  | `criticTimeout` | 300s | Critic subprocess timeout |
96
+ | `skipUnchanged` | true | Skip candidates with no changes since last synthesis |
97
+ | `thinking` | `low` | Thinking level for spawned LLM sessions |
98
+ | `port` | 1938 | HTTP API listen port |
99
+ | `schedule` | `*/30 * * * *` | Cron expression for automatic synthesis scheduling |
100
+ | `reportChannel` | (optional) | Gateway channel target for progress messages (e.g. Slack channel ID) |
101
+ | `logging.level` | `info` | Log level (trace/debug/info/warn/error) |
102
+ | `logging.file` | (optional) | Log file path |
103
+
104
+ ### Meta Discovery
105
+
106
+ Discovery is entirely watcher-based. The engine:
107
+
108
+ 1. **Registers virtual inference rules** at service startup. These rules match
109
+ file paths (`**/.meta/meta.json` and `**/.meta/archive/*.json`) and apply
110
+ the configured `metaProperty`/`metaArchiveProperty` values as watcher
111
+ metadata on those indexed points.
112
+
113
+ 2. **Queries the watcher** via `buildMetaFilter(config)`, which constructs a
114
+ Qdrant filter from the key-value pairs in `metaProperty`. For example:
115
+ - Default `{ _meta: "current" }` → filter on `_meta: "current"`
116
+ - Configured `{ domains: ["meta"] }` → filter on `domains: "meta"`
117
+
118
+ 3. **Deduplicates** scan results by `.meta/` directory path and builds the
119
+ ownership tree.
120
+
121
+ **Important:** If you change `metaProperty` or `metaArchiveProperty` in config,
122
+ you must:
123
+ - Restart the jeeves-meta service (so it re-registers virtual rules with the
124
+ new property values)
125
+ - Trigger a watcher rules reindex (`watcher_reindex` with scope `rules`) so
126
+ existing indexed points get retagged with the new properties
127
+
128
+ ### Configuring Meta Properties
129
+
130
+ `metaProperty` and `metaArchiveProperty` are `Record<string, unknown>` — any
131
+ JSON-serializable key-value structure. The virtual rules spread these properties
132
+ onto every matching indexed point. The discovery filter is derived from the same
133
+ properties.
134
+
135
+ **Example configurations:**
136
+
137
+ ```json
138
+ // Default (no config needed):
139
+ // Live metas get { _meta: "current" }, archives get { _meta: "archive" }
140
+
141
+ // Using watcher domains:
142
+ {
143
+ "metaProperty": { "domains": ["meta"] },
144
+ "metaArchiveProperty": { "domains": ["meta-archive"] }
145
+ }
146
+
147
+ // Custom tagging:
148
+ {
149
+ "metaProperty": { "project": "myproject", "kind": "synthesis" }
150
+ }
151
+ ```
84
152
 
85
153
  ### Prompt Customization
86
154
 
@@ -94,21 +162,79 @@ referenced via `@file:` in the config:
94
162
  }
95
163
  ```
96
164
 
165
+ `@file:` paths are resolved relative to the config file's directory.
166
+
97
167
  **Per-meta overrides:** Set `_architect` or `_critic` directly in a `meta.json`
98
168
  to override the defaults for that specific entity.
99
169
 
100
- ### Adding New Domains
170
+ ### Minimal Config Example
171
+
172
+ A minimum viable config file requires only `watcherUrl`, `defaultArchitect`,
173
+ and `defaultCritic`:
174
+
175
+ ```json
176
+ {
177
+ "watcherUrl": "http://localhost:1936",
178
+ "gatewayUrl": "http://127.0.0.1:18789",
179
+ "gatewayApiKey": "your-api-key",
180
+ "defaultArchitect": "@file:prompts/architect.md",
181
+ "defaultCritic": "@file:prompts/critic.md"
182
+ }
183
+ ```
184
+
185
+ All other fields use sensible defaults (port 1938, schedule every 30 min,
186
+ depth weight 0.5, etc). Add `reportChannel`, `metaProperty`, `logging`,
187
+ etc. as needed.
188
+
189
+ ### Adding New Metas
101
190
 
102
- 1. Create a `.meta/` directory under the domain path
103
- 2. The engine auto-creates `meta.json` with a UUID on first discovery
104
- 3. Optionally set `_steer`, `_depth`, and `_emphasis` in `meta.json`
105
- 4. The entity appears in `synth_list` on the next cycle
191
+ 1. Create the `.meta/` directory under the domain path
192
+ 2. Seed it: `jeeves-meta seed <path>` — creates `meta.json`
193
+ with a UUID (`_id`). All other fields are populated on first synthesis
194
+ 3. Optionally edit `meta.json` to set `_steer`, `_depth`, and `_emphasis`
195
+ 4. Wait for the watcher to index the new `meta.json` (typically seconds via
196
+ chokidar file watching)
197
+ 5. The entity appears in `meta_list` on the next query
106
198
 
107
199
  ### Tuning Scheduling
108
200
 
109
- - **`_depth`:** Higher = updates more often. Defaults from tree nesting.
110
- - **`_emphasis`:** Per-meta multiplier (default 1). Set 2 to double depth effect, 0 to ignore depth.
201
+ - **`_depth`:** Higher = updates more often. Defaults from tree nesting depth.
202
+ - **`_emphasis`:** Per-meta multiplier (default 1). Set 2 to double priority,
203
+ 0.5 to halve it.
111
204
  - **`depthWeight`:** Global exponent. Set 0 for pure staleness rotation.
205
+ - **`architectEvery`:** Higher = fewer architect runs (cheaper but slower to
206
+ adapt to structural changes).
207
+
208
+ ### Config Hot-Reload
209
+
210
+ The following fields can be changed without restarting the service:
211
+ - `schedule` — cron expression
212
+ - `reportChannel` — progress reporting target
213
+ - `logging.level` — log verbosity
214
+
215
+ Edit the config file and save; the service detects changes via `fs.watchFile`.
216
+ All other fields (including `metaProperty`, `port`, timeouts) require a service
217
+ restart.
218
+
219
+ ### Progress Reporting
220
+
221
+ When `reportChannel` is set, the service sends real-time progress messages
222
+ to that channel via the OpenClaw gateway. Events include: synthesis started,
223
+ phase started/completed (architect, builder, critic), synthesis completed,
224
+ and errors. This uses
225
+ `/tools/invoke` → `message` tool — zero LLM token cost.
226
+
227
+ ### TOOLS.md Bootstrapping Prompts
228
+
229
+ The plugin's TOOLS.md injection automatically prompts bootstrapping:
230
+ - **Service unreachable:** Shows "ACTION REQUIRED: jeeves-meta service is
231
+ unreachable" with troubleshooting steps and directs to this skill's
232
+ Bootstrapping section
233
+ - **No entities found:** Shows "ACTION REQUIRED: No synthesis entities found"
234
+ and directs to this skill's Bootstrapping section
235
+
236
+ These messages appear in the agent's system prompt, ensuring proactive
237
+ discovery of configuration issues.
112
238
 
113
239
  ## Bootstrapping
114
240
 
@@ -116,30 +242,35 @@ to override the defaults for that specific entity.
116
242
 
117
243
  Before the synthesis engine can operate:
118
244
 
119
- 1. **jeeves-watcher** must be running and indexing data
120
- - Verify: `curl http://localhost:1936/status` should return point count > 0
245
+ 1. **OpenClaw gateway** must be running (the service spawns LLM sessions
246
+ through it via `gatewayUrl`)
247
+ - Verify: `openclaw gateway status` or check the URL in config
248
+
249
+ 2. **jeeves-watcher** must be running and indexing data
250
+ - Verify: `watcher_status` tool or `curl http://localhost:1936/status`
121
251
  - The watcher provides both semantic search and structured scan
122
252
 
123
- 2. **Qdrant** must be running with indexed data
253
+ 3. **Qdrant** must be running
124
254
  - Verify: `curl http://localhost:6333/healthz`
125
255
 
126
- 3. **Config file** must exist
127
- - Default: path from `JEEVES_META_CONFIG` env var
128
- - Must contain valid `watchPaths` and `watcherUrl`
256
+ 4. **Config file** must exist at the path specified by `JEEVES_META_CONFIG`
257
+ - Must contain valid `watcherUrl`
258
+ - Must contain `defaultArchitect` and `defaultCritic` (or `@file:` refs)
129
259
 
130
- 4. **Prompt files** must exist
131
- - `J:\config\jeeves-meta\prompts\architect.md`
132
- - `J:\config\jeeves-meta\prompts\critic.md`
260
+ 5. **Prompt files** must exist if using `@file:` references
261
+ - e.g. `J:\config\jeeves-meta\prompts\architect.md`
262
+ - e.g. `J:\config\jeeves-meta\prompts\critic.md`
133
263
 
134
- 5. **Watch paths** must be indexed by the watcher
135
- - The paths in `watchPaths` must overlap with the watcher's configured paths
264
+ 6. **`.meta/` directories** must exist and be within paths the watcher indexes
265
+ - Seed new metas: `jeeves-meta seed <path>`
136
266
 
137
267
  ### Installation
138
268
 
139
- 1. Install the core library globally (provides the CLI and the dependency for the plugin):
269
+ 1. Install and start the jeeves-meta service:
140
270
 
141
271
  ```bash
142
272
  npm install -g @karmaniverous/jeeves-meta
273
+ jeeves-meta start --config J:\config\jeeves-meta.config.json
143
274
  ```
144
275
 
145
276
  2. Install the OpenClaw plugin:
@@ -148,7 +279,13 @@ npm install -g @karmaniverous/jeeves-meta
148
279
  npx @karmaniverous/jeeves-meta-openclaw install
149
280
  ```
150
281
 
151
- 3. Configure the plugin in `openclaw.json`:
282
+ For non-default OpenClaw installations, set `OPENCLAW_CONFIG` (path to
283
+ `openclaw.json`) or `OPENCLAW_HOME` (path to `.openclaw` directory).
284
+
285
+ To uninstall: `npx @karmaniverous/jeeves-meta-openclaw uninstall`
286
+
287
+ 3. (Optional) Configure the plugin with the service URL — only needed if the
288
+ service runs on a non-default port or host:
152
289
 
153
290
  ```json
154
291
  {
@@ -157,7 +294,7 @@ npx @karmaniverous/jeeves-meta-openclaw install
157
294
  "jeeves-meta-openclaw": {
158
295
  "enabled": true,
159
296
  "config": {
160
- "configPath": "/path/to/jeeves-meta.config.json"
297
+ "serviceUrl": "http://127.0.0.1:1938"
161
298
  }
162
299
  }
163
300
  }
@@ -165,70 +302,179 @@ npx @karmaniverous/jeeves-meta-openclaw install
165
302
  }
166
303
  ```
167
304
 
168
- Alternatively, set the `JEEVES_META_CONFIG` environment variable instead of using plugin config.
169
-
170
305
  4. Restart the OpenClaw gateway to load the plugin.
171
306
 
307
+ 5. Verify: check that `## Meta` appears in TOOLS.md injection and
308
+ `jeeves-meta` appears in available skills.
309
+
172
310
  ### First Synthesis
173
311
 
174
- 1. Check discovery: `synth_list` — should show your `.meta/` entities
175
- 2. Preview: `synth_preview` — verify scope files and delta detection
176
- 3. Trigger: `synth_trigger` — run the first cycle
177
- 4. Review: `synth_detail <path> --includeArchive 1` — check output quality
312
+ 1. Check discovery: `meta_list` — should show your `.meta/` entities
313
+ 2. Preview: `meta_preview` — verify scope files and delta detection
314
+ 3. Trigger: `meta_trigger` — run the first cycle
315
+ 4. Review: `meta_detail <path>` with `includeArchive: 1` — check output quality
178
316
  5. Iterate on `_steer` prompts if needed
179
317
 
318
+ ### System Service Management
319
+
320
+ For production deployments, install as a system service:
321
+
322
+ ```bash
323
+ jeeves-meta service install --config J:\config\jeeves-meta.config.json
324
+ ```
325
+
326
+ This prints OS-specific instructions:
327
+ - **Windows:** NSSM service commands
328
+ - **macOS:** launchd plist
329
+ - **Linux:** systemd unit
330
+
331
+ Management commands (print OS-specific equivalents):
332
+ ```bash
333
+ jeeves-meta service start # print start instructions
334
+ jeeves-meta service stop # print stop instructions
335
+ jeeves-meta service status # query running service via HTTP API
336
+ jeeves-meta service remove # print removal instructions
337
+ ```
338
+
339
+ ### HTTP API
340
+
341
+ The service exposes these endpoints (default port 1938):
342
+
343
+ | Method | Path | Description |
344
+ |--------|------|-------------|
345
+ | GET | `/status` | Service health, queue state, dependency checks |
346
+ | GET | `/metas` | List metas with filtering and field projection |
347
+ | GET | `/metas/:path` | Single meta detail with optional archive |
348
+ | GET | `/preview` | Dry-run next synthesis candidate |
349
+ | POST | `/synthesize` | Enqueue synthesis (stalest or specific path) |
350
+ | POST | `/seed` | Create `.meta/` directory + meta.json |
351
+ | POST | `/unlock` | Remove `.lock` file from a meta entity |
352
+ | GET | `/config/validate` | Return sanitized active configuration |
353
+
354
+ All endpoints return JSON. The OpenClaw plugin tools are thin wrappers
355
+ around these endpoints.
356
+
357
+ ## Service CLI
358
+
359
+ The service package ships a CLI:
360
+
361
+ ```bash
362
+ jeeves-meta <command> [options]
363
+ ```
364
+
365
+ Commands: `start`, `status`, `list`, `detail`, `preview`, `synthesize`,
366
+ `seed`, `unlock`, `validate`, `service install|start|stop|status|remove`.
367
+
368
+ Config resolution: `--config` flag → `JEEVES_META_CONFIG` env var → error.
369
+ All client commands support `-p, --port` to specify the service port (default: 1938).
370
+ The `start` command uses `--config`/`-c` instead (port is read from the config file).
371
+
372
+ ## Operational Monitoring
373
+
374
+ Recommended periodic checks:
375
+ - **Errors:** `meta_list` with `filter: { hasError: true }` — investigate
376
+ and retry with `meta_trigger`
377
+ - **Stuck locks:** `meta_list` with `filter: { locked: true }` — locks
378
+ older than 30 minutes indicate a crashed synthesis; use `jeeves-meta unlock`
379
+ - **Stale knowledge:** `meta_list` with `filter: { staleHours: 48 }` — check
380
+ if the scheduler is running and the watcher is up
381
+ - **Service health:** `/status` endpoint (via `meta_list` summary or direct
382
+ HTTP) includes dependency status for watcher and gateway
383
+
384
+ The TOOLS.md injection surfaces the most critical stats (entity count, errors,
385
+ stalest entity) in the agent's system prompt automatically.
386
+
180
387
  ## Troubleshooting
181
388
 
389
+ ### Service unreachable
390
+
391
+ **Symptom:** TOOLS.md shows "ACTION REQUIRED: jeeves-meta service is unreachable"
392
+ **Cause:** Meta service not running or wrong `serviceUrl` in plugin config
393
+ **Fix:**
394
+ 1. Check if the service is running: `jeeves-meta service status` or `curl http://localhost:1938/status`
395
+ 2. If down, start it: `jeeves-meta service start` or `jeeves-meta start --config <path>`
396
+ 3. If running on a different port, update `serviceUrl` in plugin config
397
+
182
398
  ### Watcher unreachable
183
399
 
184
- **Symptom:** TOOLS.md shows "ACTION REQUIRED: jeeves-watcher is unreachable"
185
- **Cause:** Watcher service not running or wrong URL in config
400
+ **Symptom:** TOOLS.md shows a ⚠️ **Watcher** dependency warning in the entity summary
401
+ **Cause:** Watcher service not running or wrong URL in meta service config
186
402
  **Fix:**
187
- 1. Check watcher status: `curl http://localhost:1936/status`
403
+ 1. Check watcher status: `watcher_status` tool or `curl http://localhost:1936/status`
188
404
  2. If down, start the watcher service
189
- 3. If running on a different port, update `watcherUrl` in config
405
+ 3. If running on a different port, update `watcherUrl` in meta service config and restart the service
190
406
 
191
407
  ### No entities discovered
192
408
 
193
- **Symptom:** `synth_list` returns empty, TOOLS.md shows "No synthesis entities found"
194
- **Cause:** No `.meta/` directories in configured `watchPaths`, or paths not indexed
409
+ **Symptom:** `meta_list` returns empty, TOOLS.md shows "No synthesis entities found"
410
+ **Cause:** No `.meta/meta.json` files indexed, or `metaProperty` mismatch
195
411
  **Fix:**
196
- 1. Check `watchPaths` in config matches where `.meta/` dirs exist
197
- 2. Create `.meta/` directories if needed: `mkdir <domain>/.meta`
198
- 3. Verify watcher indexes those paths
412
+ 1. Verify `.meta/meta.json` files exist on disk
413
+ 2. Check that the watcher indexes those paths (paths must be in watcher's
414
+ configured `watch` globs)
415
+ 3. Check that `metaProperty` in config matches the properties actually set
416
+ on indexed points. If you changed `metaProperty`, run `watcher_reindex`
417
+ with scope `rules` and restart the meta service.
418
+ 4. Seed new metas if needed: `jeeves-meta seed <path>`
199
419
 
200
420
  ### Synthesis stuck (locked entities)
201
421
 
202
- **Symptom:** `synth_list` shows locked entities that never unlock
422
+ **Symptom:** `meta_list` shows locked entities that never unlock
203
423
  **Cause:** Previous synthesis crashed, leaving stale `.lock` file
204
424
  **Fix:**
205
- 1. Check lock: `synth_detail <path>` — look for `locked: true`
425
+ 1. Check lock: `meta_detail <path>` — look for `locked: true`
206
426
  2. Locks auto-expire after 30 minutes
207
- 3. For immediate unlock: delete `.meta/.lock` file manually
427
+ 3. For immediate unlock: `jeeves-meta unlock <path>`
428
+ or delete `.meta/.lock` file manually
208
429
 
209
430
  ### Executor timeouts
210
431
 
211
- **Symptom:** `synth_trigger` fails with timeout error
432
+ **Symptom:** `meta_trigger` fails with timeout error
212
433
  **Cause:** Subprocess took longer than configured timeout
213
434
  **Fix:**
214
- 1. Increase timeout in config (`architectTimeout`, `builderTimeout`, `criticTimeout`)
435
+ 1. Increase timeout in config (`architectTimeout`, `builderTimeout`,
436
+ `criticTimeout`)
215
437
  2. Check if the LLM provider is slow or rate-limited
216
438
  3. Check scope size: large scopes with many files take longer
217
439
 
218
440
  ### LLM errors in synthesis steps
219
441
 
220
- **Symptom:** `synth_detail` shows `_error` field with step/code/message
442
+ **Symptom:** `meta_detail` shows `_error` field with step/code/message
221
443
  **Cause:** Subprocess failed (API error, malformed output, rate limit)
222
444
  **Fix:**
223
- 1. Check error details: `synth_detail <path>` — the `_error.step` tells you which step failed
224
- 2. Architect failure with existing `_builder`: engine reuses cached brief (self-healing)
225
- 3. Architect failure without `_builder` (first run): retry with `synth_trigger`
445
+ 1. Check error details: `meta_detail <path>` — `_error.step` tells you
446
+ which step failed
447
+ 2. Architect failure with existing `_builder`: engine reuses cached brief
448
+ (self-healing)
449
+ 3. Architect failure without `_builder` (first run): retry with `meta_trigger`
226
450
  4. Builder failure: meta stays stale, retried next cycle automatically
227
451
  5. Critic failure: content saved without feedback, not critical
228
452
 
453
+ ### Discovery returns wrong/stale results
454
+
455
+ **Symptom:** `meta_list` shows old metas or misses new ones
456
+ **Cause:** Virtual rules not re-registered after config change, or watcher
457
+ not yet indexed new files
458
+ **Fix:**
459
+ 1. If `metaProperty` changed: restart meta service + `watcher_reindex` (scope: rules)
460
+ 2. If new `.meta/` directory: wait for chokidar detection (seconds) or
461
+ trigger `watcher_reindex` (scope: full)
462
+ 3. Verify with `watcher_scan`: query for the expected properties to confirm
463
+ the watcher has the right metadata on the points
464
+
229
465
  ## Gotchas
230
466
 
231
- - `synth_trigger` runs a full LLM cycle (3 subprocess calls). It can take
467
+ - `meta_trigger` runs a full LLM cycle (3 subprocess calls). It can take
232
468
  several minutes.
233
469
  - A locked meta (another synthesis in progress) will be skipped silently.
234
470
  - First-run quality is lower — the feedback loop needs 2-3 cycles to calibrate.
471
+ - Changing `metaProperty` requires both a meta service restart AND a watcher reindex.
472
+ The service restart re-registers virtual rules; the reindex retags existing points.
473
+ - The `@file:` prefix in `defaultArchitect`/`defaultCritic` is resolved relative
474
+ to the config file's directory, not the working directory.
475
+ - The synthesis queue is single-threaded: one synthesis at a time. HTTP-triggered
476
+ syntheses get priority over scheduler-triggered ones.
477
+ - The scheduler uses adaptive backoff: if no stale candidates are found, it
478
+ doubles the skip interval (max 4×). Backoff resets after a successful synthesis.
479
+ - All CLI commands except `start` require the service to be running (they call
480
+ the HTTP API).
@@ -30,14 +30,14 @@ export interface ToolResult {
30
30
  isError?: boolean;
31
31
  }
32
32
  /**
33
- * Resolve the config file path.
33
+ * Resolve the service URL.
34
34
  *
35
35
  * Resolution order:
36
- * 1. Plugin config `configPath` setting
37
- * 2. `JEEVES_META_CONFIG` environment variable
38
- * 3. Error — no default path
36
+ * 1. Plugin config `serviceUrl` setting
37
+ * 2. `JEEVES_META_URL` environment variable
38
+ * 3. Default: http://127.0.0.1:1938
39
39
  */
40
- export declare function getConfigPath(api: PluginApi): string;
40
+ export declare function getServiceUrl(api: PluginApi): string;
41
41
  /** Format a successful tool result. */
42
42
  export declare function ok(data: unknown): ToolResult;
43
43
  /** Format an error tool result. */
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * OpenClaw plugin for jeeves-meta.
3
3
  *
4
- * Registers synthesis tools, virtual inference rules, and starts
5
- * the periodic TOOLS.md writer at gateway startup.
4
+ * Thin HTTP client all operations delegate to the jeeves-meta service.
5
+ * The plugin registers tools and starts the periodic TOOLS.md writer.
6
6
  *
7
7
  * @packageDocumentation
8
8
  */
9
- import type { PluginApi } from './helpers.js';
10
- /** Register all jeeves-meta tools and rules with the OpenClaw plugin API. */
9
+ import { type PluginApi } from './helpers.js';
10
+ /** Register all jeeves-meta tools with the OpenClaw plugin API. */
11
11
  export default function register(api: PluginApi): void;
@@ -1,21 +1,16 @@
1
1
  /**
2
2
  * Generate the Meta menu content for TOOLS.md injection.
3
3
  *
4
- * Queries the watcher API for synthesis entity stats and produces
4
+ * Queries the jeeves-meta service for entity stats and produces
5
5
  * a Markdown section suitable for agent system prompt injection.
6
6
  *
7
7
  * @module promptInjection
8
8
  */
9
- import { type SynthConfig } from '@karmaniverous/jeeves-meta';
9
+ import type { MetaServiceClient } from './serviceClient.js';
10
10
  /**
11
11
  * Generate the Meta menu Markdown for TOOLS.md.
12
12
  *
13
- * Three output modes:
14
- * 1. Watcher unreachable - ACTION REQUIRED with diagnostic
15
- * 2. No entities found - ACTION REQUIRED with setup guidance
16
- * 3. Healthy - entity stats + tool listing + skill reference
17
- *
18
- * @param config - Full synth config (for listMetas and watcherUrl).
13
+ * @param client - MetaServiceClient instance.
19
14
  * @returns Markdown string for the Meta section.
20
15
  */
21
- export declare function generateMetaMenu(config: SynthConfig): Promise<string>;
16
+ export declare function generateMetaMenu(client: MetaServiceClient): Promise<string>;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Thin HTTP client for the jeeves-meta service.
3
+ *
4
+ * Plugin delegates all operations to the running service via HTTP.
5
+ *
6
+ * @module serviceClient
7
+ */
8
+ export interface MetaServiceConfig {
9
+ /** Base URL of the jeeves-meta service (e.g. http://127.0.0.1:1938). */
10
+ serviceUrl: string;
11
+ }
12
+ export declare class MetaServiceClient {
13
+ private readonly baseUrl;
14
+ constructor(config: MetaServiceConfig);
15
+ /** GET helper — returns parsed JSON. */
16
+ private get;
17
+ /** POST helper — returns parsed JSON. */
18
+ private post;
19
+ /** GET /status — service health + queue state. */
20
+ status(): Promise<unknown>;
21
+ /** GET /metas — list all meta entities with summary. */
22
+ listMetas(params?: {
23
+ pathPrefix?: string;
24
+ hasError?: boolean;
25
+ staleHours?: number;
26
+ neverSynthesized?: boolean;
27
+ locked?: boolean;
28
+ fields?: string[];
29
+ }): Promise<unknown>;
30
+ /** GET /metas/:path — detail for a single meta. */
31
+ detail(metaPath: string, options?: {
32
+ includeArchive?: boolean | number;
33
+ fields?: string[];
34
+ }): Promise<unknown>;
35
+ /** GET /preview — dry-run next synthesis candidate. */
36
+ preview(path?: string): Promise<unknown>;
37
+ /** POST /synthesize — enqueue synthesis. */
38
+ synthesize(path?: string): Promise<unknown>;
39
+ /** POST /seed — create .meta/ for a path. */
40
+ seed(path: string): Promise<unknown>;
41
+ /** POST /unlock — remove .lock from a meta entity. */
42
+ unlock(path: string): Promise<unknown>;
43
+ /** GET /config/validate — validate current config. */
44
+ validate(): Promise<unknown>;
45
+ }
@@ -1,8 +1,11 @@
1
1
  /**
2
- * Synth tool registrations for OpenClaw.
2
+ * Meta tool registrations for OpenClaw.
3
+ *
4
+ * All tools delegate to the jeeves-meta HTTP service.
3
5
  *
4
6
  * @module tools
5
7
  */
6
8
  import { type PluginApi } from './helpers.js';
7
- /** Register all synth_* tools. */
8
- export declare function registerSynthTools(api: PluginApi): void;
9
+ import type { MetaServiceClient } from './serviceClient.js';
10
+ /** Register all meta_* tools. */
11
+ export declare function registerMetaTools(api: PluginApi, client: MetaServiceClient): void;
@@ -6,8 +6,8 @@
6
6
  *
7
7
  * @module toolsWriter
8
8
  */
9
- import { type SynthConfig } from '@karmaniverous/jeeves-meta';
10
9
  import type { PluginApi } from './helpers.js';
10
+ import type { MetaServiceClient } from './serviceClient.js';
11
11
  /**
12
12
  * Upsert the Meta section in TOOLS.md content.
13
13
  *
@@ -22,6 +22,6 @@ export declare function upsertMetaSection(existing: string, metaMenu: string): s
22
22
  * Defers first write by 5s, then refreshes every 60s.
23
23
  *
24
24
  * @param api - Plugin API.
25
- * @param watcherUrl - Watcher API base URL.
25
+ * @param client - MetaServiceClient instance.
26
26
  */
27
- export declare function startToolsWriter(api: PluginApi, config: SynthConfig): void;
27
+ export declare function startToolsWriter(api: PluginApi, client: MetaServiceClient): void;