@karmaniverous/jeeves-watcher-openclaw 0.7.0 → 0.8.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.
@@ -1,7 +1,12 @@
1
1
  /**
2
- * @module rollup.config
3
2
  * Rollup configuration for the OpenClaw plugin package.
4
3
  * Two entry points: plugin (ESM + declarations) and CLI (ESM executable).
4
+ *
5
+ * `@karmaniverous/jeeves` is BUNDLED into the plugin output — the plugin
6
+ * runs in OpenClaw's extensions directory where node_modules is not
7
+ * reliably available. All node: builtins are externalized.
8
+ *
9
+ * @module rollup.config
5
10
  */
6
11
  import type { RollupOptions } from 'rollup';
7
12
  declare const _default: RollupOptions[];
@@ -72,6 +72,21 @@ You have access to a **semantic archive** of your human's working world. Documen
72
72
 
73
73
  **The principle:** Memory-core is your curated highlights. The watcher archive is your perfect recall. Use memory first for speed and signal, but never let its narrow scope be the ceiling of what you can remember.
74
74
 
75
+ ## ⚠️ Embedding Cost — Hard Behavioral Gate
76
+
77
+ **The watcher embeds every file it sees.** Embedding is the most expensive operation in the pipeline — each file triggers a Gemini API call. The index may contain hundreds of thousands of points. Any action that causes the watcher to process a large number of files has real, potentially significant cost.
78
+
79
+ **STOP and ask for a human decision before:**
80
+
81
+ - **Renaming, moving, or reorganizing watched directories.** A directory rename at the filesystem level is cheap — chokidar sees unlink + add events, but the content hasn't changed. However, if a rename is blocked (e.g., by a file lock from the watcher or another service), **do NOT work around it by creating new directories and copying/moving files**. That creates duplicate embeddings at the new paths while the old paths still exist. Instead: stop the blocking service, perform the rename, restart. This is a 30-second operation. The workaround can cost thousands of API calls.
82
+ - **Changing `watch.paths` to add large directory trees.** Adding a new watch root triggers initial indexing of every matching file under it.
83
+ - **Running `scope: "full"` reindex.** This re-embeds the entire index. Use `scope: "rules"` for inference rule changes (zero embedding cost — only metadata reapplication).
84
+ - **Any bulk file operation** (mass copy, mass move, template-based file generation) under watched paths.
85
+
86
+ **The right instinct when blocked:** If a filesystem operation fails because a service has a lock, the correct response is to stop the service, do the operation, and restart — NOT to find a creative workaround. Creative workarounds in the presence of a live watcher are how you accidentally trigger re-embedding of tens of thousands of files.
87
+
88
+ **Cost context:** A single file embedding costs a Gemini API call. 1,000 unnecessary embeddings is a noticeable cost. 100,000 unnecessary embeddings (e.g., copying an entire domain directory to a new path) is a billing event worth flagging.
89
+
75
90
  ## Plugin Installation
76
91
 
77
92
  ```
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @module plugin/constants
3
+ * Shared constants for the OpenClaw plugin package.
4
+ *
5
+ * @remarks
6
+ * Imported by both the plugin bundle (`index.ts`) and the CLI bundle
7
+ * (`cli.ts`). Rollup inlines these into each output independently.
8
+ */
9
+ /** Plugin identifier used in OpenClaw config and extensions directory. */
10
+ export declare const PLUGIN_ID = "jeeves-watcher-openclaw";
11
+ /** Default watcher API base URL. */
12
+ export declare const DEFAULT_API_URL = "http://127.0.0.1:1936";
13
+ /** Default platform config root path. */
14
+ export declare const DEFAULT_CONFIG_ROOT = "j:/config";
15
+ /** Default Qdrant health check URL (used in diagnostic output). */
16
+ export declare const DEFAULT_QDRANT_URL = "http://127.0.0.1:6333";
17
+ /** Timeout in milliseconds for service health probes. */
18
+ export declare const PROBE_TIMEOUT_MS = 1500;
19
+ /**
20
+ * Timeout in milliseconds for menu generation fetch calls.
21
+ *
22
+ * @remarks
23
+ * Must be generous enough to survive watcher startup (initial scan can
24
+ * take 15+ minutes on large filesystems). If the fetch hangs past this
25
+ * timeout, the `createAsyncContentCache` `refreshing` flag is cleared
26
+ * and the next cycle retries. Too short = unnecessary "unreachable"
27
+ * messages. Too long = `refreshing` deadlock when the server genuinely
28
+ * hangs. 10 seconds balances both concerns.
29
+ */
30
+ export declare const MENU_FETCH_TIMEOUT_MS = 10000;
@@ -5,12 +5,24 @@
5
5
  /** Minimal OpenClaw plugin API surface used for tool registration. */
6
6
  export interface PluginApi {
7
7
  config?: {
8
+ agents?: {
9
+ defaults?: {
10
+ workspace?: string;
11
+ };
12
+ };
8
13
  plugins?: {
9
14
  entries?: Record<string, {
10
15
  config?: Record<string, unknown>;
11
16
  }>;
12
17
  };
13
18
  };
19
+ /**
20
+ * Resolve a path relative to the OpenClaw workspace.
21
+ *
22
+ * @remarks
23
+ * Present on newer OpenClaw builds; optional for backwards compatibility.
24
+ */
25
+ resolvePath?: (input: string) => string;
14
26
  registerTool(tool: {
15
27
  name: string;
16
28
  description: string;
@@ -19,15 +31,6 @@ export interface PluginApi {
19
31
  }, options?: {
20
32
  optional?: boolean;
21
33
  }): void;
22
- /**
23
- * Optional internal hook registration (available on newer OpenClaw builds).
24
- * We keep this optional to preserve compatibility.
25
- */
26
- registerHook?: (event: string | string[], handler: (event: unknown) => Promise<void> | void, opts?: {
27
- name?: string;
28
- description?: string;
29
- register?: boolean;
30
- }) => void;
31
34
  }
32
35
  /** Result shape returned by each tool execution. */
33
36
  export interface ToolResult {
@@ -39,6 +42,8 @@ export interface ToolResult {
39
42
  }
40
43
  /** Resolve the watcher API base URL from plugin config. */
41
44
  export declare function getApiUrl(api: PluginApi): string;
45
+ /** Resolve the platform config root path from plugin config. */
46
+ export declare function getConfigRoot(api: PluginApi): string;
42
47
  /** Format a successful tool result. */
43
48
  export declare function ok(data: unknown): ToolResult;
44
49
  /** Format a connection error with actionable guidance. */
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @module plugin
3
- * OpenClaw plugin entry point. Registers all jeeves-watcher tools.
3
+ * OpenClaw plugin entry point. Registers all jeeves-watcher tools and starts
4
+ * the managed content writer via `@karmaniverous/jeeves` core.
4
5
  */
5
6
  import type { PluginApi } from './helpers.js';
6
7
  /** Register all jeeves-watcher tools with the OpenClaw plugin API. */
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @module plugin/watcherComponent
3
+ * Jeeves component integration for the watcher OpenClaw plugin.
4
+ *
5
+ * @remarks
6
+ * Uses `createAsyncContentCache()` from core to bridge the sync/async gap:
7
+ * `generateToolsContent()` must be synchronous, but the watcher menu requires
8
+ * async HTTP calls. The cache triggers a background refresh on each call and
9
+ * returns the most recent successful result.
10
+ */
11
+ import { type JeevesComponent } from '@karmaniverous/jeeves';
12
+ /** Options for creating the watcher component descriptor. */
13
+ interface CreateWatcherComponentOptions {
14
+ /** Base URL of the jeeves-watcher HTTP API. */
15
+ apiUrl: string;
16
+ /** Plugin package version. */
17
+ pluginVersion: string;
18
+ }
19
+ /**
20
+ * Create the watcher `JeevesComponent` descriptor.
21
+ *
22
+ * @param options - API URL and plugin version.
23
+ * @returns A fully configured component descriptor ready for `createComponentWriter()`.
24
+ */
25
+ export declare function createWatcherComponent(options: CreateWatcherComponentOptions): JeevesComponent;
26
+ export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @module plugin/watcherComponent.test
3
+ * Unit tests for the watcher JeevesComponent implementation.
4
+ */
5
+ export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @module plugin/writerIntegration.test
3
+ * Integration tests for the ComponentWriter lifecycle via jeeves-core.
4
+ */
5
+ export {};
@@ -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.7.0",
5
+ "version": "0.8.1",
6
6
  "skills": [
7
7
  "dist/skills/jeeves-watcher"
8
8
  ],
@@ -14,6 +14,11 @@
14
14
  "type": "string",
15
15
  "description": "jeeves-watcher API base URL",
16
16
  "default": "http://127.0.0.1:1936"
17
+ },
18
+ "configRoot": {
19
+ "type": "string",
20
+ "description": "Platform config root path (e.g., j:/config)",
21
+ "default": "j:/config"
17
22
  }
18
23
  }
19
24
  },
@@ -21,6 +26,10 @@
21
26
  "apiUrl": {
22
27
  "label": "Watcher API URL",
23
28
  "placeholder": "http://127.0.0.1:1936"
29
+ },
30
+ "configRoot": {
31
+ "label": "Config root",
32
+ "placeholder": "j:/config"
24
33
  }
25
34
  }
26
35
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@karmaniverous/jeeves-watcher-openclaw",
3
- "version": "0.7.0",
3
+ "version": "0.8.1",
4
4
  "author": "Jason Williscroft",
5
5
  "description": "OpenClaw plugin for jeeves-watcher — semantic search and metadata enrichment tools",
6
6
  "license": "BSD-3-Clause",
@@ -20,6 +20,7 @@
20
20
  },
21
21
  "files": [
22
22
  "dist",
23
+ "content",
23
24
  "openclaw.plugin.json"
24
25
  ],
25
26
  "publishConfig": {
@@ -50,25 +51,33 @@
50
51
  },
51
52
  "auto-changelog": {
52
53
  "output": "CHANGELOG.md",
54
+ "tagPrefix": "openclaw/",
53
55
  "unreleased": true,
54
56
  "commitLimit": false,
55
57
  "hideCredit": true
56
58
  },
59
+ "dependencies": {
60
+ "@karmaniverous/jeeves": "^0.1.6"
61
+ },
57
62
  "devDependencies": {
58
- "@dotenvx/dotenvx": "^1.54.1",
63
+ "@dotenvx/dotenvx": "^1.55.1",
64
+ "@rollup/plugin-commonjs": "^29.0.2",
65
+ "@rollup/plugin-json": "^6.1.0",
66
+ "@rollup/plugin-node-resolve": "^16.0.3",
59
67
  "@rollup/plugin-typescript": "^12.3.0",
60
68
  "auto-changelog": "^2.5.0",
61
69
  "cross-env": "^10.1.0",
62
- "knip": "^5.85.0",
70
+ "knip": "^5.87.0",
63
71
  "release-it": "^19.2.4",
64
72
  "rollup": "^4.59.0",
65
73
  "tslib": "^2.8.1",
66
- "vitest": "^4.0.18"
74
+ "vitest": "^4.1.0"
67
75
  },
68
76
  "scripts": {
69
77
  "build:plugin": "rimraf dist && cross-env NO_COLOR=1 rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript",
70
78
  "build:skills": "tsx scripts/build-skills.ts",
71
- "build": "npm run build:plugin && npm run build:skills",
79
+ "build": "npm run build:plugin && npm run build:skills && npm run build:content",
80
+ "build:content": "node scripts/copy-content.mjs",
72
81
  "changelog": "auto-changelog",
73
82
  "lint": "eslint .",
74
83
  "lint:fix": "eslint --fix .",
@@ -1,12 +0,0 @@
1
- /**
2
- * @module plugin/toolsWriter
3
- * Writes the Watcher menu section directly to TOOLS.md on disk.
4
- * Replaces the agent:bootstrap hook approach which was unreliable due to
5
- * OpenClaw's clearInternalHooks() wiping plugin-registered hooks on startup.
6
- */
7
- import { type PluginApi } from './helpers.js';
8
- /**
9
- * Start the periodic TOOLS.md writer.
10
- * Writes immediately on startup, then refreshes every REFRESH_INTERVAL_MS.
11
- */
12
- export declare function startToolsWriter(api: PluginApi): void;