@karmaniverous/jeeves-watcher-openclaw 0.6.2 → 0.7.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 +3 -2
- package/dist/index.js +65 -34
- package/dist/skills/jeeves-watcher/SKILL.md +83 -24
- package/dist/src/helpers.d.ts +0 -4
- package/dist/src/promptInjection.d.ts +0 -6
- package/dist/src/toolsWriter.d.ts +0 -8
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,10 +53,11 @@ On startup, the plugin writes a `## Watcher` section to `TOOLS.md` in the agent'
|
|
|
53
53
|
| `watcher_status` | Service health, uptime, and collection stats |
|
|
54
54
|
| `watcher_search` | Semantic search across indexed documents |
|
|
55
55
|
| `watcher_enrich` | Enrich document metadata via rules engine |
|
|
56
|
-
| `
|
|
56
|
+
| `watcher_config` | Query the effective runtime config via JSONPath |
|
|
57
|
+
| `watcher_walk` | Walk watched filesystem paths with glob intersection |
|
|
57
58
|
| `watcher_validate` | Validate a watcher configuration |
|
|
58
59
|
| `watcher_config_apply` | Apply a new configuration |
|
|
59
|
-
| `watcher_reindex` | Trigger a
|
|
60
|
+
| `watcher_reindex` | Trigger a scoped reindex with blast area plan |
|
|
60
61
|
| `watcher_scan` | Filter-only point query with cursor pagination |
|
|
61
62
|
| `watcher_issues` | List indexing issues and errors |
|
|
62
63
|
|
package/dist/index.js
CHANGED
|
@@ -79,24 +79,14 @@ async function generateWatcherMenu(apiUrl) {
|
|
|
79
79
|
const activeRules = [];
|
|
80
80
|
const watchPaths = [];
|
|
81
81
|
const ignoredPaths = [];
|
|
82
|
+
const scoreThresholds = { strong: 0.75, relevant: 0.5, noise: 0.25 };
|
|
82
83
|
try {
|
|
83
|
-
const [statusRes, rulesRes, pathsRes, ignoredRes] = (await Promise.all([
|
|
84
|
+
const [statusRes, rulesRes, pathsRes, thresholdsRes, ignoredRes] = (await Promise.all([
|
|
84
85
|
fetchJson(`${apiUrl}/status`),
|
|
85
|
-
fetchJson(`${apiUrl}/config
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}),
|
|
90
|
-
fetchJson(`${apiUrl}/config/query`, {
|
|
91
|
-
method: 'POST',
|
|
92
|
-
headers: { 'Content-Type': 'application/json' },
|
|
93
|
-
body: JSON.stringify({ path: '$.watch.paths[*]' }),
|
|
94
|
-
}),
|
|
95
|
-
fetchJson(`${apiUrl}/config/query`, {
|
|
96
|
-
method: 'POST',
|
|
97
|
-
headers: { 'Content-Type': 'application/json' },
|
|
98
|
-
body: JSON.stringify({ path: '$.watch.ignored[*]' }),
|
|
99
|
-
}),
|
|
86
|
+
fetchJson(`${apiUrl}/config?path=${encodeURIComponent('$.inferenceRules[*]')}`),
|
|
87
|
+
fetchJson(`${apiUrl}/config?path=${encodeURIComponent('$.watch.paths[*]')}`),
|
|
88
|
+
fetchJson(`${apiUrl}/config?path=${encodeURIComponent('$.search.scoreThresholds')}`),
|
|
89
|
+
fetchJson(`${apiUrl}/config?path=${encodeURIComponent('$.watch.ignored[*]')}`),
|
|
100
90
|
]));
|
|
101
91
|
pointCount = statusRes.collection?.pointCount ?? 0;
|
|
102
92
|
if (Array.isArray(rulesRes.result)) {
|
|
@@ -119,6 +109,16 @@ async function generateWatcherMenu(apiUrl) {
|
|
|
119
109
|
ignoredPaths.push(p);
|
|
120
110
|
}
|
|
121
111
|
}
|
|
112
|
+
if (Array.isArray(thresholdsRes.result) &&
|
|
113
|
+
thresholdsRes.result.length > 0) {
|
|
114
|
+
const t = thresholdsRes.result[0];
|
|
115
|
+
if (typeof t.strong === 'number')
|
|
116
|
+
scoreThresholds.strong = t.strong;
|
|
117
|
+
if (typeof t.relevant === 'number')
|
|
118
|
+
scoreThresholds.relevant = t.relevant;
|
|
119
|
+
if (typeof t.noise === 'number')
|
|
120
|
+
scoreThresholds.noise = t.noise;
|
|
121
|
+
}
|
|
122
122
|
}
|
|
123
123
|
catch {
|
|
124
124
|
let qdrantStatus = '*Unknown*';
|
|
@@ -153,10 +153,10 @@ async function generateWatcherMenu(apiUrl) {
|
|
|
153
153
|
'**Scan-first rule:** When a task involves structural queries (file enumeration, staleness checks, domain listing, counts), use `watcher_scan` instead of `watcher_search`. Scan does NOT use embeddings and does NOT accept a query string.',
|
|
154
154
|
'**Search-first rule:** When a task involves finding, reading, or modifying files in indexed paths, run `watcher_search` FIRST — even if you already know the file path. Search surfaces related files you may not have considered and catches stale artifacts. Direct filesystem access is for acting on search results, not bypassing them.',
|
|
155
155
|
'',
|
|
156
|
-
'### Score Interpretation:',
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
156
|
+
'### Score Interpretation (see skill for detail):',
|
|
157
|
+
`* **Strong:** >= ${String(scoreThresholds.strong)} — High confidence. Use directly.`,
|
|
158
|
+
`* **Relevant:** >= ${String(scoreThresholds.relevant)} — Likely useful. Verify context before relying on it.`,
|
|
159
|
+
`* **Noise:** < ${String(scoreThresholds.noise)} — Discard. If all results are noise, broaden your query or try different terms.`,
|
|
160
160
|
'',
|
|
161
161
|
"### What's on the menu:",
|
|
162
162
|
];
|
|
@@ -379,23 +379,23 @@ function registerWatcherTools(api, baseUrl) {
|
|
|
379
379
|
],
|
|
380
380
|
},
|
|
381
381
|
{
|
|
382
|
-
name: '
|
|
383
|
-
description: 'Query the
|
|
382
|
+
name: 'watcher_config',
|
|
383
|
+
description: 'Query the effective runtime config via JSONPath. Returns the full resolved merged document when no path is provided.',
|
|
384
384
|
parameters: {
|
|
385
385
|
type: 'object',
|
|
386
|
-
required: ['path'],
|
|
387
386
|
properties: {
|
|
388
|
-
path: {
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
items: { type: 'string', enum: ['files', 'globals'] },
|
|
392
|
-
description: 'Resolution scopes to include (e.g., ["files"], ["globals"], or both).',
|
|
387
|
+
path: {
|
|
388
|
+
type: 'string',
|
|
389
|
+
description: 'JSONPath expression (optional).',
|
|
393
390
|
},
|
|
394
391
|
},
|
|
395
392
|
},
|
|
396
393
|
buildRequest: (params) => {
|
|
397
|
-
const
|
|
398
|
-
|
|
394
|
+
const path = params.path;
|
|
395
|
+
if (path) {
|
|
396
|
+
return [`/config?path=${encodeURIComponent(path)}`];
|
|
397
|
+
}
|
|
398
|
+
return ['/config'];
|
|
399
399
|
},
|
|
400
400
|
},
|
|
401
401
|
{
|
|
@@ -443,14 +443,29 @@ function registerWatcherTools(api, baseUrl) {
|
|
|
443
443
|
properties: {
|
|
444
444
|
scope: {
|
|
445
445
|
type: 'string',
|
|
446
|
-
enum: ['rules', 'full'],
|
|
447
|
-
description: 'Reindex scope: "rules" (default) re-applies inference rules; "full" re-embeds everything.',
|
|
446
|
+
enum: ['rules', 'full', 'issues', 'path', 'prune'],
|
|
447
|
+
description: 'Reindex scope: "rules" (default) re-applies inference rules; "full" re-embeds everything; "issues" re-processes files with errors; "path" reindexes a specific file or directory (requires path parameter); "prune" deletes points for files no longer in watch scope.',
|
|
448
|
+
},
|
|
449
|
+
path: {
|
|
450
|
+
oneOf: [
|
|
451
|
+
{ type: 'string' },
|
|
452
|
+
{ type: 'array', items: { type: 'string' } },
|
|
453
|
+
],
|
|
454
|
+
description: 'Target file or directory path (required when scope is "path"). Accepts a single path or array of paths.',
|
|
455
|
+
},
|
|
456
|
+
dryRun: {
|
|
457
|
+
type: 'boolean',
|
|
458
|
+
description: 'When true, compute and return the blast area plan without executing. Returns counts by root showing impact.',
|
|
448
459
|
},
|
|
449
460
|
},
|
|
450
461
|
},
|
|
451
462
|
buildRequest: (params) => [
|
|
452
|
-
'/
|
|
453
|
-
{
|
|
463
|
+
'/reindex',
|
|
464
|
+
{
|
|
465
|
+
scope: params.scope ?? 'rules',
|
|
466
|
+
...(params.path ? { path: params.path } : {}),
|
|
467
|
+
...(params.dryRun ? { dryRun: true } : {}),
|
|
468
|
+
},
|
|
454
469
|
],
|
|
455
470
|
},
|
|
456
471
|
{
|
|
@@ -500,6 +515,22 @@ function registerWatcherTools(api, baseUrl) {
|
|
|
500
515
|
parameters: { type: 'object', properties: {} },
|
|
501
516
|
buildRequest: () => ['/issues'],
|
|
502
517
|
},
|
|
518
|
+
{
|
|
519
|
+
name: 'watcher_walk',
|
|
520
|
+
description: 'Walk watched filesystem paths with glob intersection. Returns matching file paths from all configured watch roots, applying watch.ignored and gitignore filtering.',
|
|
521
|
+
parameters: {
|
|
522
|
+
type: 'object',
|
|
523
|
+
required: ['globs'],
|
|
524
|
+
properties: {
|
|
525
|
+
globs: {
|
|
526
|
+
type: 'array',
|
|
527
|
+
items: { type: 'string' },
|
|
528
|
+
description: 'Glob patterns to intersect with watch paths (e.g., ["**/.meta/meta.json"]).',
|
|
529
|
+
},
|
|
530
|
+
},
|
|
531
|
+
},
|
|
532
|
+
buildRequest: (params) => ['/walk', { globs: params.globs }],
|
|
533
|
+
},
|
|
503
534
|
];
|
|
504
535
|
for (const tool of tools) {
|
|
505
536
|
registerApiTool(api, baseUrl, tool);
|
|
@@ -30,9 +30,7 @@ curl -X POST http://127.0.0.1:<PORT>/search \
|
|
|
30
30
|
-d '{"query": "search text", "limit": 5}'
|
|
31
31
|
|
|
32
32
|
# Query config
|
|
33
|
-
curl
|
|
34
|
-
-H "Content-Type: application/json" \
|
|
35
|
-
-d '{"path": "$.inferenceRules[*].name"}'
|
|
33
|
+
curl http://127.0.0.1:<PORT>/config
|
|
36
34
|
```
|
|
37
35
|
|
|
38
36
|
**Key endpoints:**
|
|
@@ -40,14 +38,15 @@ curl -X POST http://127.0.0.1:<PORT>/config/query \
|
|
|
40
38
|
|----------|--------|---------|
|
|
41
39
|
| `/status` | GET | Health check, uptime, collection stats |
|
|
42
40
|
| `/search` | POST | Semantic search (main query interface) |
|
|
43
|
-
| `/config
|
|
41
|
+
| `/config` | GET | Full resolved config; optional `?path=<jsonpath>` filter |
|
|
44
42
|
| `/config/validate` | POST | Validate candidate config |
|
|
45
43
|
| `/config/apply` | POST | Apply config changes |
|
|
46
|
-
| `/
|
|
44
|
+
| `/reindex` | POST | Trigger reindex |
|
|
47
45
|
| `/metadata` | POST | Enrich document metadata |
|
|
48
46
|
| `/scan` | POST | Filter-only point query (no embeddings) |
|
|
47
|
+
| `/walk` | POST | Filesystem walk with glob intersection |
|
|
49
48
|
| `/issues` | GET | Runtime embedding failures |
|
|
50
|
-
| `/rules/register` | POST | Register virtual inference rules |
|
|
49
|
+
| `/rules/register` | POST | Register virtual inference rules (auto-triggers rules reindex) |
|
|
51
50
|
| `/rules/unregister` | DELETE | Remove virtual rules by source |
|
|
52
51
|
| `/points/delete` | POST | Delete points matching a Qdrant filter |
|
|
53
52
|
|
|
@@ -350,12 +349,17 @@ Set or update metadata on a document.
|
|
|
350
349
|
- `metadata` (object, required) — key-value metadata to merge
|
|
351
350
|
|
|
352
351
|
### `watcher_status`
|
|
353
|
-
Service health check. Returns uptime, collection stats, reindex status.
|
|
352
|
+
Service health check. Returns uptime, version, collection stats, reindex status, and initial scan progress.
|
|
353
|
+
|
|
354
|
+
After a service restart, the `initialScan` field shows scan progress:
|
|
355
|
+
- `active: true` — filesystem walk in progress; `filesMatched` and `filesEnqueued` grow until chokidar completes
|
|
356
|
+
- `active: false` with `completedAt`/`durationMs` — scan finished
|
|
357
|
+
|
|
358
|
+
Use this to determine if the service is still initializing after a restart.
|
|
354
359
|
|
|
355
|
-
### `
|
|
356
|
-
Query the
|
|
357
|
-
- `path` (string,
|
|
358
|
-
- `resolve` (string[], optional) — `["files"]`, `["globals"]`, or `["files","globals"]`
|
|
360
|
+
### `watcher_config`
|
|
361
|
+
Query the effective runtime config via JSONPath. Returns the full resolved merged document when no path is provided.
|
|
362
|
+
- `path` (string, optional) — JSONPath expression
|
|
359
363
|
|
|
360
364
|
### `watcher_validate`
|
|
361
365
|
Validate config and optionally test file paths.
|
|
@@ -371,10 +375,38 @@ Apply config changes atomically.
|
|
|
371
375
|
Validates, writes to disk, and triggers configured reindex behavior. Returns validation errors if invalid.
|
|
372
376
|
|
|
373
377
|
### `watcher_reindex`
|
|
374
|
-
Trigger a reindex.
|
|
375
|
-
|
|
378
|
+
Trigger a reindex operation. All scopes return a `plan` object showing blast area before execution begins.
|
|
379
|
+
|
|
380
|
+
**Parameters:**
|
|
381
|
+
- `scope` (string, optional) — Reindex scope. Default: `"rules"`. One of:
|
|
382
|
+
- `"rules"` — Re-apply inference rules to all watched files. No re-embedding. Lightweight.
|
|
383
|
+
- `"full"` — Re-extract text, re-embed, and re-apply rules for all watched files. Expensive.
|
|
384
|
+
- `"issues"` — Re-process only files that previously failed embedding (from `watcher_issues`).
|
|
385
|
+
- `"path"` — Re-embed a specific file or all files under a directory. Requires `path` parameter.
|
|
386
|
+
- `"prune"` — Delete Qdrant points for files no longer in watch scope (removed paths, gitignored files, stale data). No re-embedding. Pure cleanup.
|
|
387
|
+
- `path` (string, required when scope is `"path"`) — Target file or directory path.
|
|
388
|
+
- `dryRun` (boolean, optional) — When `true`, compute and return the blast area plan without executing. Returns synchronously.
|
|
389
|
+
|
|
390
|
+
**Response (normal):**
|
|
391
|
+
```json
|
|
392
|
+
{ "status": "started", "scope": "rules", "plan": { "total": 148000, "toProcess": 148000, "toDelete": 0, "byRoot": { "j:/domains": 95000, "j:/config": 3000 } } }
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
**Response (dryRun):**
|
|
396
|
+
```json
|
|
397
|
+
{ "status": "dry_run", "scope": "prune", "plan": { "total": 562000, "toProcess": 0, "toDelete": 2300, "byRoot": { "j:/jeeves/node_modules": 1800, "j:/jeeves/.bridge": 500 } } }
|
|
398
|
+
```
|
|
376
399
|
|
|
377
|
-
|
|
400
|
+
**Plan fields:**
|
|
401
|
+
- `total` — Total points (prune) or files (other scopes) examined.
|
|
402
|
+
- `toProcess` — Items to embed/re-apply rules (0 for prune).
|
|
403
|
+
- `toDelete` — Points to delete (prune only, 0 for others).
|
|
404
|
+
- `byRoot` — Counts grouped by watch root prefix. Shows where the impact concentrates.
|
|
405
|
+
|
|
406
|
+
**Guidance:**
|
|
407
|
+
- Use `dryRun: true` before any large-blast operation to preview impact.
|
|
408
|
+
- `prune` is safe — it only deletes orphaned points, never re-embeds. Use after changing watch paths, fixing gitignore, or cleaning up stale data.
|
|
409
|
+
- `prune` is NOT triggered by config-watch auto-reindex (too dangerous for auto-trigger).
|
|
378
410
|
|
|
379
411
|
|
|
380
412
|
### `watcher_scan`
|
|
@@ -417,6 +449,30 @@ do {
|
|
|
417
449
|
### `watcher_issues`
|
|
418
450
|
Get runtime embedding failures. Returns `{ filePath: IssueRecord }` showing files that failed and why.
|
|
419
451
|
|
|
452
|
+
### `watcher_walk`
|
|
453
|
+
Walk watched filesystem paths with glob intersection. Returns matching file paths from all configured watch roots.
|
|
454
|
+
- `globs` (string[], required) — glob patterns to intersect with watch paths
|
|
455
|
+
|
|
456
|
+
**Response:**
|
|
457
|
+
```json
|
|
458
|
+
{
|
|
459
|
+
"paths": ["j:/domains/foo/.meta/meta.json", "j:/domains/bar/.meta/meta.json"],
|
|
460
|
+
"matchedCount": 2,
|
|
461
|
+
"scannedRoots": ["j:/domains", "j:/config"]
|
|
462
|
+
}
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
**Use cases:**
|
|
466
|
+
- Discover files matching a pattern across all watched directories (e.g., `["**/.meta/meta.json"]`)
|
|
467
|
+
- Enumerate files before rule registration to understand scope
|
|
468
|
+
- Find files that aren't yet indexed (no Qdrant dependency — works even before first embedding)
|
|
469
|
+
|
|
470
|
+
**Key differences from `watcher_scan`:**
|
|
471
|
+
- Walks the actual filesystem, not the Qdrant index
|
|
472
|
+
- No embedding or indexing required — works immediately after service start
|
|
473
|
+
- Returns file paths only (no metadata, no vectors)
|
|
474
|
+
- Applies `watch.ignored` and gitignore filtering automatically
|
|
475
|
+
|
|
420
476
|
## Query Planning: Scan vs Search
|
|
421
477
|
|
|
422
478
|
**Decision rule:** If the query has no semantic/natural-language dimension, use `watcher_scan`. If you need meaning-based similarity, use `watcher_search`.
|
|
@@ -523,7 +579,7 @@ Each result from `watcher_search` contains:
|
|
|
523
579
|
| `payload.content_hash` | string | Hash of the full document content |
|
|
524
580
|
| `payload.matched_rules` | string[] | Names of inference rules that matched |
|
|
525
581
|
|
|
526
|
-
Additional metadata fields depend on the deployment's inference rules (e.g., `domain`, `status`, `author`). Use `
|
|
582
|
+
Additional metadata fields depend on the deployment's inference rules (e.g., `domain`, `status`, `author`). Use `watcher_config` to discover available fields.
|
|
527
583
|
|
|
528
584
|
## Query Planning (Per Search Task)
|
|
529
585
|
|
|
@@ -531,7 +587,7 @@ Identify relevant rule(s) from the orientation model, then retrieve their schema
|
|
|
531
587
|
|
|
532
588
|
**Retrieve complete schema for a rule:**
|
|
533
589
|
```
|
|
534
|
-
|
|
590
|
+
watcher_config: path="$.inferenceRules[?(@.name=='jira-issue')].schema"
|
|
535
591
|
resolve=["files","globals"]
|
|
536
592
|
```
|
|
537
593
|
|
|
@@ -539,7 +595,7 @@ Returns the fully merged schema with properties, types, `set` provenance, `uiHin
|
|
|
539
595
|
|
|
540
596
|
**For select/multiselect fields without `enum` in schema:**
|
|
541
597
|
```
|
|
542
|
-
|
|
598
|
+
watcher_config: path="$.inferenceRules[?(@.name=='jira-issue')].values.status"
|
|
543
599
|
```
|
|
544
600
|
|
|
545
601
|
Retrieves valid filter values from the runtime values index (distinct values accumulated during embedding).
|
|
@@ -613,9 +669,9 @@ A consuming UI will necessarily compose simple single-field filters. The assista
|
|
|
613
669
|
|
|
614
670
|
### Score Interpretation
|
|
615
671
|
Use `scoreThresholds` from config (queried during orientation). Values are deployment-specific, constrained to [-1, 1]:
|
|
616
|
-
- `strong` — minimum score for a strong match
|
|
617
|
-
- `relevant` — minimum score for relevance
|
|
618
|
-
- `noise` — maximum score below which results are noise
|
|
672
|
+
- `strong` — minimum score for a strong match. **Action:** High confidence. Use these results directly.
|
|
673
|
+
- `relevant` — minimum score for relevance. **Action:** Likely useful but verify context before relying on them.
|
|
674
|
+
- `noise` — maximum score below which results are noise. **Action:** Discard. If all results fall below this threshold, broaden your query or try different terms.
|
|
619
675
|
|
|
620
676
|
### Chunk Grouping
|
|
621
677
|
Multiple results with the same `file_path` are chunks of one document. Read the full file for complete context.
|
|
@@ -623,7 +679,7 @@ Multiple results with the same `file_path` are chunks of one document. Read the
|
|
|
623
679
|
### Schema Lookup
|
|
624
680
|
Use `matched_rules` on results to look up applicable schemas for metadata interpretation:
|
|
625
681
|
```
|
|
626
|
-
|
|
682
|
+
watcher_config: path="$.inferenceRules[?(@.name=='jira-issue')].schema"
|
|
627
683
|
resolve=["files","globals"]
|
|
628
684
|
```
|
|
629
685
|
|
|
@@ -636,7 +692,7 @@ Search gives you chunks; use `read` with `file_path` for the complete document.
|
|
|
636
692
|
|
|
637
693
|
When uncertain whether a file is indexed, use the path test endpoint:
|
|
638
694
|
```
|
|
639
|
-
|
|
695
|
+
watcher_config: path="$.inferenceRules[?(@.name=='<rule>')].match"
|
|
640
696
|
```
|
|
641
697
|
|
|
642
698
|
Or check if a specific path would match:
|
|
@@ -672,15 +728,18 @@ Progress is reported via `watcher_status` (`reindex.filesProcessed` / `reindex.t
|
|
|
672
728
|
### When to Reindex
|
|
673
729
|
- **Rules scope** (`"rules"`): Changed rule matching patterns, set expressions, schema mappings. No re-embedding needed.
|
|
674
730
|
- **Full scope** (`"full"`): Changed embedding config, added watch paths, broad schema restructuring. Re-embeds everything.
|
|
731
|
+
- **Issues scope** (`"issues"`): After fixing the root cause of embedding failures (permissions, encoding, file format). Re-processes only failed files.
|
|
732
|
+
- **Path scope** (`"path"`): Edited files in a specific directory and want to force re-embedding without a full reindex. Or a single file's embedding looks wrong.
|
|
733
|
+
- **Prune scope** (`"prune"`): After changing `watch.paths`, adding gitignore rules, or discovering stale/orphaned points (e.g., indexed `node_modules`). Deletes points for out-of-scope files. Always `dryRun: true` first to preview.
|
|
675
734
|
|
|
676
735
|
---
|
|
677
736
|
|
|
678
737
|
## Diagnostics
|
|
679
738
|
|
|
680
739
|
### Escalation Path
|
|
681
|
-
1. `watcher_status` — is the service healthy? Is a reindex running?
|
|
740
|
+
1. `watcher_status` — is the service healthy? Is a reindex running? Is the initial scan still active?
|
|
682
741
|
2. `watcher_issues` — what files are failing and why?
|
|
683
|
-
3. `
|
|
742
|
+
3. `watcher_config` with `$.issues` — same data via JSONPath
|
|
684
743
|
4. Check logs at the configured log path
|
|
685
744
|
|
|
686
745
|
### Error Categories
|
package/dist/src/helpers.d.ts
CHANGED
|
@@ -39,12 +39,8 @@ export interface ToolResult {
|
|
|
39
39
|
}
|
|
40
40
|
/** Resolve the watcher API base URL from plugin config. */
|
|
41
41
|
export declare function getApiUrl(api: PluginApi): string;
|
|
42
|
-
/** Resolve the cache TTL for plugin hooks from config. */
|
|
43
|
-
export declare function getCacheTtlMs(api: PluginApi): number;
|
|
44
42
|
/** Format a successful tool result. */
|
|
45
43
|
export declare function ok(data: unknown): ToolResult;
|
|
46
|
-
/** Format an error tool result. */
|
|
47
|
-
export declare function fail(error: unknown): ToolResult;
|
|
48
44
|
/** Format a connection error with actionable guidance. */
|
|
49
45
|
export declare function connectionFail(error: unknown, baseUrl: string): ToolResult;
|
|
50
46
|
/** Fetch JSON from a URL, throwing on non-OK responses. */
|
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
import { type PluginApi } from './helpers.js';
|
|
2
1
|
/**
|
|
3
2
|
* Fetches data from the watcher API and generates a Markdown menu string.
|
|
4
3
|
* The string is platform-agnostic and safe to inject into TOOLS.md.
|
|
5
4
|
*/
|
|
6
5
|
export declare function generateWatcherMenu(apiUrl: string): Promise<string>;
|
|
7
|
-
/**
|
|
8
|
-
* Hook handler for agent:bootstrap.
|
|
9
|
-
* Injects/updates the Watcher Menu into the TOOLS.md payload.
|
|
10
|
-
*/
|
|
11
|
-
export declare function handleAgentBootstrap(event: unknown, api: PluginApi): Promise<void>;
|
|
@@ -10,11 +10,3 @@ import { type PluginApi } from './helpers.js';
|
|
|
10
10
|
* Writes immediately on startup, then refreshes every REFRESH_INTERVAL_MS.
|
|
11
11
|
*/
|
|
12
12
|
export declare function startToolsWriter(api: PluginApi): void;
|
|
13
|
-
/**
|
|
14
|
-
* Force an immediate refresh (e.g., after watcher_config_apply).
|
|
15
|
-
*/
|
|
16
|
-
export declare function forceRefreshToolsMd(api: PluginApi): Promise<void>;
|
|
17
|
-
/**
|
|
18
|
-
* Stop the periodic writer (for cleanup).
|
|
19
|
-
*/
|
|
20
|
-
export declare function stopToolsWriter(): void;
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "jeeves-watcher-openclaw",
|
|
3
3
|
"name": "Jeeves Watcher",
|
|
4
4
|
"description": "Semantic search, metadata enrichment, and instance administration for a jeeves-watcher deployment.",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.7.0",
|
|
6
6
|
"skills": [
|
|
7
7
|
"dist/skills/jeeves-watcher"
|
|
8
8
|
],
|
package/package.json
CHANGED