@karmaniverous/jeeves-watcher-openclaw 0.15.6 → 0.16.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 +18 -24
- package/dist/index.js +3048 -1525
- package/dist/rollup.config.d.ts +3 -4
- package/dist/skills/jeeves-watcher/SKILL.md +132 -40
- package/dist/src/constants.d.ts +9 -15
- package/dist/src/helpers.d.ts +21 -3
- package/dist/src/index.d.ts +10 -3
- package/dist/src/lazyCore.d.ts +40 -0
- package/dist/src/lazyCore.test.d.ts +1 -0
- package/dist/src/manifest.test.d.ts +5 -0
- package/dist/src/promptContext.d.ts +19 -0
- package/dist/src/promptContext.test.d.ts +1 -0
- package/dist/src/toolGating.d.ts +27 -0
- package/dist/src/toolGating.test.d.ts +1 -0
- package/dist/src/watcherComponent.d.ts +7 -22
- package/dist/src/watcherComponent.test.d.ts +0 -4
- package/openclaw.plugin.json +3 -4
- package/package.json +15 -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 -27594
- package/dist/src/cli.d.ts +0 -10
- package/dist/src/promptInjection.d.ts +0 -13
- package/dist/src/writerIntegration.test.d.ts +0 -5
package/dist/src/constants.d.ts
CHANGED
|
@@ -1,27 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module plugin/constants
|
|
3
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
4
|
*/
|
|
9
5
|
export { COMPONENT_NAME, DEFAULT_PORT, PLUGIN_PACKAGE, SERVICE_PACKAGE, } from '@karmaniverous/jeeves-watcher-core';
|
|
10
|
-
/** Plugin identifier used in OpenClaw config
|
|
6
|
+
/** Plugin identifier used in OpenClaw config (`plugins.entries.<id>`). */
|
|
11
7
|
export declare const PLUGIN_ID = "jeeves-watcher-openclaw";
|
|
12
8
|
/** Default watcher API base URL. */
|
|
13
9
|
export declare const DEFAULT_API_URL: string;
|
|
14
|
-
/**
|
|
15
|
-
export declare const
|
|
10
|
+
/** Environment variable consulted when plugin config has no `configRoot`. */
|
|
11
|
+
export declare const CONFIG_ROOT_ENV_VAR = "JEEVES_CONFIG_ROOT";
|
|
16
12
|
/**
|
|
17
|
-
*
|
|
13
|
+
* Tool error returned when `configRoot` cannot be resolved.
|
|
18
14
|
*
|
|
19
15
|
* @remarks
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* timeout, the `createAsyncContentCache` `refreshing` flag is cleared
|
|
23
|
-
* and the next cycle retries. Too short = unnecessary "unreachable"
|
|
24
|
-
* messages. Too long = `refreshing` deadlock when the server genuinely
|
|
25
|
-
* hangs. 10 seconds balances both concerns.
|
|
16
|
+
* There is deliberately no default config root: a hard-coded path is only
|
|
17
|
+
* correct on one installation (see #227).
|
|
26
18
|
*/
|
|
27
|
-
export declare const
|
|
19
|
+
export declare const CONFIG_ROOT_NOT_CONFIGURED = "configRoot not configured \u2014 set it in plugin config (plugins.entries.jeeves-watcher-openclaw.config.configRoot) or via JEEVES_CONFIG_ROOT env var";
|
|
20
|
+
/** Warning logged once at registration when `configRoot` is unset. */
|
|
21
|
+
export declare const CONFIG_ROOT_UNSET_WARNING = "[jeeves-watcher-openclaw] configRoot not configured yet \u2014 watcher_service install will be unavailable until it is set in plugin config or JEEVES_CONFIG_ROOT (HTTP API tools are unaffected)";
|
package/dist/src/helpers.d.ts
CHANGED
|
@@ -9,7 +9,25 @@
|
|
|
9
9
|
* @module plugin/helpers
|
|
10
10
|
*/
|
|
11
11
|
import { type PluginApi } from '@karmaniverous/jeeves';
|
|
12
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* Resolve the watcher API base URL.
|
|
14
|
+
*
|
|
15
|
+
* @remarks
|
|
16
|
+
* Resolution order: plugin-scoped config (`api.pluginConfig`), then
|
|
17
|
+
* `plugins.entries.<id>.config`, then `JEEVES_WATCHER_URL`, then
|
|
18
|
+
* `DEFAULT_API_URL`. Safe to call per tool invocation.
|
|
19
|
+
*/
|
|
13
20
|
export declare function getApiUrl(api: PluginApi): string;
|
|
14
|
-
/**
|
|
15
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Resolve the platform config root path, if configured.
|
|
23
|
+
*
|
|
24
|
+
* @remarks
|
|
25
|
+
* Resolution order: plugin-scoped config (`api.pluginConfig`), then
|
|
26
|
+
* `plugins.entries.<id>.config`, then `JEEVES_CONFIG_ROOT`. There is no
|
|
27
|
+
* default. Call this lazily (at tool invocation), never to gate
|
|
28
|
+
* registration: `openclaw plugins install` activates the plugin before
|
|
29
|
+
* `jeeves install` writes its config.
|
|
30
|
+
*
|
|
31
|
+
* @returns The config root, or `undefined` when unset.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getConfigRoot(api: PluginApi): string | undefined;
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module plugin
|
|
3
|
-
* OpenClaw plugin entry point. Registers
|
|
4
|
-
*
|
|
3
|
+
* OpenClaw plugin entry point. Registers the jeeves-watcher tools and the
|
|
4
|
+
* always-in-context watcher rules.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* A standard OpenClaw plugin on `@karmaniverous/jeeves` core: it writes no
|
|
8
|
+
* workspace files and starts no timers. Registration never requires
|
|
9
|
+
* `configRoot`; it is resolved lazily when a gated tool runs (see
|
|
10
|
+
* `lazyCore`). Only invocations that read `configRoot` (`CONFIG_ROOT_READERS`:
|
|
11
|
+
* `watcher_service install`) are gated; HTTP-only tools work without it.
|
|
5
12
|
*/
|
|
6
|
-
import type
|
|
13
|
+
import { type PluginApi } from '@karmaniverous/jeeves';
|
|
7
14
|
/** Register all jeeves-watcher tools with the OpenClaw plugin API. */
|
|
8
15
|
export default function register(api: PluginApi): void;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module plugin/lazyCore
|
|
3
|
+
* Lazy `configRoot` resolution and deferred jeeves-core initialization.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Registration must always succeed, even with no plugin config (#235). The
|
|
7
|
+
* config root is resolved on first tool use; core `init()` runs once, only
|
|
8
|
+
* after it resolves. Only invocations that read `configRoot` are gated
|
|
9
|
+
* (see `CONFIG_ROOT_READERS`); invoked before then they return a clear
|
|
10
|
+
* error. HTTP-only tools are registered unwrapped and work without it.
|
|
11
|
+
*/
|
|
12
|
+
import { type PluginApi, type ToolDescriptor } from '@karmaniverous/jeeves';
|
|
13
|
+
import { type ConfigRootPredicate } from './toolGating.js';
|
|
14
|
+
/** Resolves `configRoot` and initializes core on first success. */
|
|
15
|
+
export type EnsureCore = () => string | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Create a lazy core initializer bound to a plugin API instance.
|
|
18
|
+
*
|
|
19
|
+
* @returns A function that resolves `configRoot` (initializing core once)
|
|
20
|
+
* or returns `undefined` while it is unset.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createLazyCore(api: PluginApi): EnsureCore;
|
|
23
|
+
/**
|
|
24
|
+
* Log the "configRoot not configured" warning if it is currently unset.
|
|
25
|
+
*
|
|
26
|
+
* @returns `true` when the warning was logged.
|
|
27
|
+
*/
|
|
28
|
+
export declare function warnIfConfigRootUnset(api: PluginApi): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Wrap a tool so invocations that read `configRoot` (per `readsConfigRoot`)
|
|
31
|
+
* resolve core before executing; all other invocations run unguarded.
|
|
32
|
+
*/
|
|
33
|
+
export declare function guardTool(tool: ToolDescriptor, ensureCore: EnsureCore, readsConfigRoot?: ConfigRootPredicate): ToolDescriptor;
|
|
34
|
+
/**
|
|
35
|
+
* Derive a plugin API whose `registerTool` guards the tools listed in
|
|
36
|
+
* `readers` with {@link guardTool} (per call, using each tool's predicate);
|
|
37
|
+
* all other tools are registered unchanged. All other members delegate to
|
|
38
|
+
* the original API.
|
|
39
|
+
*/
|
|
40
|
+
export declare function withGuardedTools(api: PluginApi, ensureCore: EnsureCore, readers?: Readonly<Partial<Record<string, ConfigRootPredicate>>>): PluginApi;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module plugin/promptContext
|
|
3
|
+
* Always-in-context watcher rules, injected via `before_prompt_build`.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Replaces the v0.x TOOLS.md `## Watcher` section that core's
|
|
7
|
+
* `ComponentWriter` wrote on a timer. The rules are static; live numbers
|
|
8
|
+
* (point counts, configured score thresholds, VCS roots) are served by
|
|
9
|
+
* `watcher_status` and `watcher_config`, and detail lives in the skill.
|
|
10
|
+
*/
|
|
11
|
+
import { type PluginApi } from '@karmaniverous/jeeves';
|
|
12
|
+
/** Static watcher rules the agent must see on every turn. */
|
|
13
|
+
export declare const WATCHER_PROMPT_CONTEXT: string;
|
|
14
|
+
/**
|
|
15
|
+
* Register the watcher rules with OpenClaw's `before_prompt_build` hook.
|
|
16
|
+
*
|
|
17
|
+
* @returns `true` when the hook was registered.
|
|
18
|
+
*/
|
|
19
|
+
export declare function registerWatcherPromptContext(api: PluginApi): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module plugin/toolGating
|
|
3
|
+
* Which watcher tool invocations read `configRoot`, and so must be gated on it.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Uniform Jeeves rule: a tool refuses with the "configRoot not configured"
|
|
7
|
+
* error only when its implementation actually reads `configRoot`. Tools
|
|
8
|
+
* that only call the service HTTP API keep working without it.
|
|
9
|
+
*
|
|
10
|
+
* Audit of the core standard toolset (`createPluginToolset`, core 0.6.0-6):
|
|
11
|
+
* - `watcher_status`, `watcher_config`, `watcher_config_apply`: HTTP only
|
|
12
|
+
* (`{apiUrl}/…`, resolved per call).
|
|
13
|
+
* - `watcher_service`: only `install` reads `configRoot`
|
|
14
|
+
* (`createServiceManager` → `resolveConfigFilePath` →
|
|
15
|
+
* `getComponentConfigDir`); the other actions query or drive the OS
|
|
16
|
+
* service manager by service name.
|
|
17
|
+
*
|
|
18
|
+
* The 14 domain tools call `{apiUrl}/…` via `fetchJson`/`postJson` and are
|
|
19
|
+
* never gated.
|
|
20
|
+
*/
|
|
21
|
+
/** Decides, per call, whether a tool invocation reads `configRoot`. */
|
|
22
|
+
export type ConfigRootPredicate = (params: Record<string, unknown> | undefined) => boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Tools whose implementation reads `configRoot`, keyed by tool name. A tool
|
|
25
|
+
* absent from this map is HTTP only and is never gated.
|
|
26
|
+
*/
|
|
27
|
+
export declare const CONFIG_ROOT_READERS: Readonly<Partial<Record<string, ConfigRootPredicate>>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -3,31 +3,16 @@
|
|
|
3
3
|
* Jeeves component descriptor for the watcher OpenClaw plugin.
|
|
4
4
|
*
|
|
5
5
|
* @remarks
|
|
6
|
-
*
|
|
7
|
-
* `
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* Feeds `createPluginToolset()` (`watcher_status`, `watcher_config`,
|
|
7
|
+
* `watcher_config_apply`, `watcher_service`). The service descriptor
|
|
8
|
+
* (`packages/service/src/descriptor.ts`) is the canonical source for the
|
|
9
|
+
* config schema and CLI commands.
|
|
10
10
|
*/
|
|
11
11
|
import { type JeevesComponentDescriptor } 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
12
|
/**
|
|
20
13
|
* Create the watcher component descriptor.
|
|
21
14
|
*
|
|
22
|
-
* @
|
|
23
|
-
*
|
|
24
|
-
* ready for `createComponentWriter()`. The service descriptor
|
|
25
|
-
* (`packages/service/src/descriptor.ts`) is the canonical source for
|
|
26
|
-
* config schema and CLI commands; this plugin-side descriptor carries only
|
|
27
|
-
* the fields `ComponentWriter` needs (identity, content generation).
|
|
28
|
-
*
|
|
29
|
-
* @param options - API URL and plugin version.
|
|
30
|
-
* @returns A validated component descriptor.
|
|
15
|
+
* @param pluginVersion - Plugin package version.
|
|
16
|
+
* @returns A component descriptor conforming to the core Zod schema.
|
|
31
17
|
*/
|
|
32
|
-
export declare function createWatcherComponent(
|
|
33
|
-
export {};
|
|
18
|
+
export declare function createWatcherComponent(pluginVersion: string): JeevesComponentDescriptor;
|
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.16.0-0",
|
|
6
6
|
"skills": [
|
|
7
7
|
"dist/skills/jeeves-watcher"
|
|
8
8
|
],
|
|
@@ -17,8 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"configRoot": {
|
|
19
19
|
"type": "string",
|
|
20
|
-
"description": "Platform config root path (e.g
|
|
21
|
-
"default": "j:/config"
|
|
20
|
+
"description": "Platform config root path (e.g. /srv/jeeves/config). No default: set it here (jeeves install --config-root) or via the JEEVES_CONFIG_ROOT env var."
|
|
22
21
|
}
|
|
23
22
|
}
|
|
24
23
|
},
|
|
@@ -51,7 +50,7 @@
|
|
|
51
50
|
},
|
|
52
51
|
"configRoot": {
|
|
53
52
|
"label": "Config root",
|
|
54
|
-
"placeholder": "
|
|
53
|
+
"placeholder": "/path/to/config"
|
|
55
54
|
}
|
|
56
55
|
}
|
|
57
56
|
}
|
package/package.json
CHANGED
|
@@ -1,28 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "Jason Williscroft",
|
|
3
|
-
"bin": {
|
|
4
|
-
"jeeves-watcher-openclaw": "./dist/cli.js"
|
|
5
|
-
},
|
|
6
3
|
"bugs": {
|
|
7
4
|
"url": "https://github.com/karmaniverous/jeeves-watcher/issues"
|
|
8
5
|
},
|
|
9
6
|
"dependencies": {
|
|
10
|
-
"@karmaniverous/jeeves": "
|
|
7
|
+
"@karmaniverous/jeeves": "0.6.0-6",
|
|
11
8
|
"@karmaniverous/jeeves-watcher-core": "^0.2.5"
|
|
12
9
|
},
|
|
13
10
|
"description": "OpenClaw plugin for jeeves-watcher — semantic search and metadata enrichment tools",
|
|
14
11
|
"devDependencies": {
|
|
15
|
-
"@dotenvx/dotenvx": "^
|
|
16
|
-
"@rollup/plugin-commonjs": "^29.0.
|
|
12
|
+
"@dotenvx/dotenvx": "^2.30.0",
|
|
13
|
+
"@rollup/plugin-commonjs": "^29.0.3",
|
|
17
14
|
"@rollup/plugin-json": "^6.1.0",
|
|
18
15
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
19
16
|
"@rollup/plugin-typescript": "^12.3.0",
|
|
20
17
|
"cross-env": "^10.1.0",
|
|
21
|
-
"knip": "^6.
|
|
22
|
-
"release-it": "^
|
|
23
|
-
"rollup": "^4.
|
|
18
|
+
"knip": "^6.38.0",
|
|
19
|
+
"release-it": "^21.1.0",
|
|
20
|
+
"rollup": "^4.63.5",
|
|
24
21
|
"tslib": "^2.8.1",
|
|
25
|
-
"vitest": "^
|
|
22
|
+
"vitest": "^5.0.2"
|
|
26
23
|
},
|
|
27
24
|
"engines": {
|
|
28
25
|
"node": ">=22"
|
|
@@ -37,10 +34,14 @@
|
|
|
37
34
|
},
|
|
38
35
|
"files": [
|
|
39
36
|
"dist",
|
|
40
|
-
"content",
|
|
41
37
|
"openclaw.plugin.json"
|
|
42
38
|
],
|
|
43
39
|
"homepage": "https://github.com/karmaniverous/jeeves-watcher#readme",
|
|
40
|
+
"jeeves": {
|
|
41
|
+
"conversationHooks": [
|
|
42
|
+
"before_prompt_build"
|
|
43
|
+
]
|
|
44
|
+
},
|
|
44
45
|
"keywords": [
|
|
45
46
|
"openclaw",
|
|
46
47
|
"plugin",
|
|
@@ -98,19 +99,18 @@
|
|
|
98
99
|
"url": "git+https://github.com/karmaniverous/jeeves-watcher.git"
|
|
99
100
|
},
|
|
100
101
|
"scripts": {
|
|
101
|
-
"build": "npm run build:plugin && npm run build:skills
|
|
102
|
-
"build:content": "node scripts/copy-content.mjs",
|
|
102
|
+
"build": "npm run build:plugin && npm run build:skills",
|
|
103
103
|
"build:plugin": "rimraf dist && cross-env NO_COLOR=1 rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript",
|
|
104
104
|
"build:skills": "tsx scripts/build-skills.ts",
|
|
105
105
|
"changelog": "git-cliff -o CHANGELOG.md",
|
|
106
106
|
"lint": "eslint .",
|
|
107
107
|
"lint:fix": "eslint --fix .",
|
|
108
108
|
"release": "dotenvx run -f .env.local -- release-it",
|
|
109
|
-
"release:pre": "dotenvx run -f .env.local -- release-it --no-git.requireBranch --github.
|
|
109
|
+
"release:pre": "dotenvx run -f .env.local -- release-it --no-git.requireBranch --github.preRelease --preRelease",
|
|
110
110
|
"test": "vitest run",
|
|
111
111
|
"typecheck": "tsc"
|
|
112
112
|
},
|
|
113
113
|
"type": "module",
|
|
114
114
|
"types": "dist/index.d.ts",
|
|
115
|
-
"version": "0.
|
|
115
|
+
"version": "0.16.0-0"
|
|
116
116
|
}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
## "I'll Note This" Is Not Noting
|
|
2
|
-
|
|
3
|
-
**Never say "I'll note this" or "I'll add that."** It's a verbal tic that leads to nothing. If something is worth noting, **write it immediately, then confirm**.
|
|
4
|
-
|
|
5
|
-
- Wrong: "I'll note this for the email path." → (conversation moves on, never written)
|
|
6
|
-
- Right: *[writes to file]* → "Noted in `memory/2026-02-08.md`."
|
|
7
|
-
- **Action first, confirmation after.** No promises, only receipts.
|
|
8
|
-
|
|
9
|
-
## Context Compaction Recovery
|
|
10
|
-
|
|
11
|
-
On compaction: read conversation history, reconstruct context, re-run skill selection against the reconstructed task, report briefly ("Context compacted — reviewing thread..."), then continue. Check notes before announcing amnesia.
|
|
12
|
-
|
|
13
|
-
## Subagent Briefing Protocol
|
|
14
|
-
|
|
15
|
-
When spawning sub-agents for code tasks, **include the relevant rules in the task prompt**. Sub-agents don't inherit your context — if you don't pass the rules, they don't exist.
|
|
16
|
-
|
|
17
|
-
At minimum, always brief sub-agents on:
|
|
18
|
-
- eslint-disable prohibition
|
|
19
|
-
- Testing requirements
|
|
20
|
-
- Commit AND Push discipline
|
|
21
|
-
- Any project-specific conventions from the active spec
|
|
22
|
-
|
|
23
|
-
## Cost Consciousness
|
|
24
|
-
|
|
25
|
-
**Gateway crons AND heartbeat items are cost bombs.** Every cycle is a full LLM session. Heartbeat items without termination conditions accumulate indefinitely.
|
|
26
|
-
|
|
27
|
-
**Strong runner preference:** Any recurring task that can run as a script (no LLM session needed) belongs in jeeves-runner, not gateway cron or heartbeat. If runner is installed, use it. If not, suggest bootstrapping it. Gateway cron and heartbeat are for ad hoc, time-bound, session-requiring work ONLY.
|
|
28
|
-
|
|
29
|
-
**Before creating a recurring gateway cron job**, assess whether it will frequently no-op. If so, flag it: *"This would be cheaper as a runner job. Want me to implement it that way instead?"*
|
|
30
|
-
|
|
31
|
-
## Heartbeat Discipline
|
|
32
|
-
|
|
33
|
-
Heartbeat items are for **transient, session-requiring work-in-progress ONLY**. Each item must include its own termination condition.
|
|
34
|
-
|
|
35
|
-
Periodic checks (email, calendar, mentions) belong in jeeves-runner scripts, not heartbeat items. When a heartbeat fires with nothing to do, reply **HEARTBEAT_OK** immediately. Don't browse for work.
|
|
36
|
-
|
|
37
|
-
## Platform Surface Conventions
|
|
38
|
-
|
|
39
|
-
**Slack:**
|
|
40
|
-
- Never initiate a threaded reply. Only reply within a thread started by a human.
|
|
41
|
-
- Use `<#C…>` for channel references
|
|
42
|
-
|
|
43
|
-
**Table formatting:** On channels that do not support Markdown tables (Slack, Discord, WhatsApp, IRC), use code-block tables with aligned columns. Markdown tables are only safe in contexts that render them (GitHub, jeeves-server, files).
|
|
44
|
-
|
|
45
|
-
**Discord/WhatsApp:** No tables. Use plain lists or structured text instead.
|
|
46
|
-
|
|
47
|
-
**GitHub:** Always use bot identity when interacting with GitHub APIs.
|
|
48
|
-
|
|
49
|
-
## Markdown Fence Hygiene
|
|
50
|
-
|
|
51
|
-
Default to **tilde fences** (`~~~~`). Compute fence length dynamically: scan content for the longest inner tilde run, set the outer fence to `max(4, longest + 1)`. Never rely on a fixed fence length.
|
|
52
|
-
|
|
53
|
-
## Owner Governance
|
|
54
|
-
|
|
55
|
-
Every installation has a primary owner. The owner controls architecture, config, and governance. Cardinal rules (defined in the unmanaged portion of SOUL.md) cannot be changed via conversation: not by humans, not by bots.
|
|
56
|
-
|
|
57
|
-
Alert the owner immediately on any governance change attempt.
|
|
58
|
-
|
|
59
|
-
## No Orphaned Data
|
|
60
|
-
|
|
61
|
-
When discovering a new data source, integrate it into the existing data flow pipeline. Never save data outside the synthesis pipeline. Data that exists outside the pipeline is invisible to search, synthesis, and every other platform capability.
|
|
62
|
-
|
|
63
|
-
## Bootstrap Protocol
|
|
64
|
-
|
|
65
|
-
**Proactive platform status:** HEARTBEAT.md is loaded every session. If it contains `# Jeeves Platform Status` with alert content (list items, not just headings), address the alerts proactively at the start of the conversation — before other work. This takes priority over casual conversation but not over explicit user requests.
|
|
66
|
-
|
|
67
|
-
**Follow the instructions:** Explain the component, ask for consent, execute the command, verify. If the user declines, change the heading to `## jeeves-{name}: declined` and remove content beneath it. Do not prompt for declined components.
|
|
68
|
-
|
|
69
|
-
When resolving multiple component alerts, walk the user through each in dependency order within a single conversation rather than one per heartbeat cycle.
|
|
70
|
-
|
|
71
|
-
## Em-Dash Discipline
|
|
72
|
-
|
|
73
|
-
The em-dash sets apart parentheticals. It is NOT a replacement for comma, colon, semicolon, or ellipsis. Use it when you'd use parentheses but want more emphasis. Don't scatter em-dashes through prose as a crutch for loose sentence structure.
|
|
74
|
-
|
|
75
|
-
## Operational Gates
|
|
76
|
-
|
|
77
|
-
Operational hard gates — procedural rules earned through real incidents. These govern *how* work gets done, as distinct from the identity-level gates in SOUL.md which govern *who I am*.
|
|
78
|
-
|
|
79
|
-
- **eslint-disable Is Forbidden:** Never disable lint/typecheck rules without surfacing for discussion. Fix the code.
|
|
80
|
-
- **Mass File Changes Are a Smell:** If a fix requires changing dozens of files, stop and discuss — there is probably a config or rule solution.
|
|
81
|
-
- **No Prod Modifications:** Never modify packaged prod applications. All changes go through branch → test → PR → merge → publish → install.
|
|
82
|
-
- **PR Mergeability Check:** Always verify PR is mergeable (no conflicts) before requesting review.
|
|
83
|
-
- **Pre-Push Verification Gate:** Run ALL quality checks before pushing. Zero errors AND zero warnings.
|
|
84
|
-
- **Commit AND Push:** Push immediately after every commit. Unpushed commits are invisible and at risk.
|
|
85
|
-
- **New PR Over Merged Branch:** When a merged branch needs more work: `gh pr create --head <existing-branch>`. Do not cherry-pick or create new branches.
|
|
86
|
-
|
|
87
|
-
### Check PR State Before Pushing
|
|
88
|
-
|
|
89
|
-
**Before EVERY `git push`**, run `gh pr list --head <branch> --repo <repo> --json number,state` to check whether a PR exists on that branch and whether it's merged.
|
|
90
|
-
|
|
91
|
-
- **No PR exists:** Safe to push.
|
|
92
|
-
- **PR is `OPEN`:** Safe to push.
|
|
93
|
-
- **PR is `MERGED` or `CLOSED`:** **STOP** and report to the user. Do not push to a merged PR branch.
|
|
94
|
-
|
|
95
|
-
This is not optional. It applies to every push, every branch, every time. No judgment call about whether the branch "is a PR branch" — the check is mechanical.
|
|
96
|
-
|
|
97
|
-
## Managed Content Self-Maintenance
|
|
98
|
-
|
|
99
|
-
The Jeeves platform maintains managed sections in SOUL.md, AGENTS.md, and TOOLS.md using comment markers. If any of these files contains a **cleanup flag** indicating orphaned Jeeves content below the managed section markers:
|
|
100
|
-
|
|
101
|
-
1. **Review** the file — compare content above (managed) and below (user zone) the END marker
|
|
102
|
-
2. **Remove** any content in the user zone that duplicates what appears in the managed section
|
|
103
|
-
3. **Preserve** any user-authored content that is genuinely unique
|
|
104
|
-
|
|
105
|
-
The cleanup flag is injected automatically when the platform detects high similarity between managed and user-zone content (indicating a recovery or migration left orphaned duplicates). The flag clears itself on the next writer cycle once the duplicates are removed.
|
package/content/skill.md
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: jeeves
|
|
3
|
-
description: Jeeves platform architecture, data flow, component interaction, scripts repo, and coordination knowledge. Use when making architectural decisions, coordinating across components, checking platform health, managing service lifecycle, or working with the scripts repo.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Jeeves Platform Skill
|
|
7
|
-
|
|
8
|
-
## Platform Architecture
|
|
9
|
-
|
|
10
|
-
Jeeves is a four-component platform coordinated by a shared library (`@karmaniverous/jeeves`):
|
|
11
|
-
|
|
12
|
-
| Component | Role | Port |
|
|
13
|
-
|-----------|------|------|
|
|
14
|
-
| **jeeves-runner** | Execute: scheduled jobs, SQLite state, HTTP API | 1937 |
|
|
15
|
-
| **jeeves-watcher** | Index: file→Qdrant semantic indexing, inference rules | 1936 |
|
|
16
|
-
| **jeeves-server** | Present: web UI, file browser, doc render, export | 1934 |
|
|
17
|
-
| **jeeves-meta** | Distill: LLM synthesis, .meta/ directories, scheduling | 1938 |
|
|
18
|
-
|
|
19
|
-
Core (`@karmaniverous/jeeves`) is a **library + CLI**, not a service. No port.
|
|
20
|
-
|
|
21
|
-
## Data Flow
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
Files → Watcher (index) → Qdrant → Meta (synthesize) → .meta/ → Watcher (re-index)
|
|
25
|
-
↓
|
|
26
|
-
Runner (schedule) → Scripts → Services ← Server (present) ← Browser
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Component Interaction
|
|
30
|
-
|
|
31
|
-
- **Watcher** indexes files into Qdrant with inference rules and enrichments.
|
|
32
|
-
- **Meta** reads from Qdrant, synthesizes `.meta/` directories, which watcher re-indexes.
|
|
33
|
-
- **Runner** executes scheduled scripts that may call any service's HTTP API.
|
|
34
|
-
- **Server** presents files, renders documents, and provides the event gateway.
|
|
35
|
-
- **Core** provides shared content management (TOOLS.md, SOUL.md, AGENTS.md), service discovery, config resolution, and the component SDK.
|
|
36
|
-
|
|
37
|
-
## Service Discovery
|
|
38
|
-
|
|
39
|
-
Services find each other via config resolution:
|
|
40
|
-
1. Component's own config file (`{configRoot}/jeeves-{name}/config.json`)
|
|
41
|
-
2. Core config file (`{configRoot}/jeeves-core/config.json`)
|
|
42
|
-
3. Default port constants
|
|
43
|
-
|
|
44
|
-
## Scripts Repo
|
|
45
|
-
|
|
46
|
-
Location: `{configRoot}/jeeves-core/scripts/`
|
|
47
|
-
Template: `@karmaniverous/jeeves-scripts-template`
|
|
48
|
-
|
|
49
|
-
Scripts use utilities from `@karmaniverous/jeeves` (general) and `@karmaniverous/jeeves-runner` (runner-specific). Any script that could be useful outside runner scheduling belongs in core.
|
|
50
|
-
|
|
51
|
-
## Managed Content System
|
|
52
|
-
|
|
53
|
-
Core maintains managed sections in workspace files using comment markers:
|
|
54
|
-
- **TOOLS.md** — Component sections (section mode) + Platform section
|
|
55
|
-
- **SOUL.md** — Professional discipline and behavioral foundations (block mode)
|
|
56
|
-
- **AGENTS.md** — Operational protocols and memory architecture (block mode)
|
|
57
|
-
- **HEARTBEAT.md** — Platform health status (heading-based)
|
|
58
|
-
|
|
59
|
-
Managed blocks are stationary after initial insertion. Cleanup detection uses Jaccard similarity on 3-word shingles. Cleanup escalation spawns a gateway session when orphaned content is detected.
|
|
60
|
-
|
|
61
|
-
## Workspace Configuration
|
|
62
|
-
|
|
63
|
-
`jeeves.config.json` at workspace root provides shared defaults:
|
|
64
|
-
- Precedence: CLI flags → env vars → file → defaults
|
|
65
|
-
- Namespaced: `core.*` (workspace, configRoot, gatewayUrl, devRepos) and `memory.*` (budget, warningThreshold)
|
|
66
|
-
- Inspect with `jeeves config [jsonpath]`
|
|
67
|
-
|
|
68
|
-
## HEARTBEAT Protocol
|
|
69
|
-
|
|
70
|
-
The HEARTBEAT system uses a state machine per component:
|
|
71
|
-
`not_installed → deps_missing → config_missing → service_not_installed → service_stopped → healthy`
|
|
72
|
-
|
|
73
|
-
Dependency-aware: hard deps block alerts, soft deps add informational notes. Declined components are tracked via heading suffix.
|
|
74
|
-
|
|
75
|
-
## Plugin Lifecycle
|
|
76
|
-
|
|
77
|
-
```bash
|
|
78
|
-
# Core install (seed workspace content)
|
|
79
|
-
npx @karmaniverous/jeeves install
|
|
80
|
-
|
|
81
|
-
# Component plugin install
|
|
82
|
-
npx @karmaniverous/jeeves-{component}-openclaw install
|
|
83
|
-
|
|
84
|
-
# Component plugin uninstall
|
|
85
|
-
npx @karmaniverous/jeeves-{component}-openclaw uninstall
|
|
86
|
-
|
|
87
|
-
# Core uninstall (remove managed sections)
|
|
88
|
-
npx @karmaniverous/jeeves uninstall
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
## Memory Hygiene
|
|
92
|
-
|
|
93
|
-
MEMORY.md has a character budget (default 20,000). Core tracks:
|
|
94
|
-
- Character count and usage percentage
|
|
95
|
-
- Warning at 80% of budget
|
|
96
|
-
- Stale section candidates (H2 sections whose most recent ISO date exceeds the staleness threshold)
|
|
97
|
-
- Evergreen sections (no dates) are never flagged
|
|
98
|
-
|
|
99
|
-
Review is human/agent-mediated — core does not auto-delete.
|
|
100
|
-
|
|
101
|
-
### HEARTBEAT Integration
|
|
102
|
-
|
|
103
|
-
Memory hygiene is checked on every `ComponentWriter` cycle alongside component health. When budget or staleness thresholds are breached, a `## MEMORY.md` alert appears in HEARTBEAT.md under `# Jeeves Platform Status`. The alert includes character count, budget usage percentage, and any stale section names. When memory is healthy, the heading is absent — no alert content, no LLM cost on heartbeat polls.
|
|
104
|
-
|
|
105
|
-
The `## MEMORY.md` heading follows the same declined/active lifecycle as component headings (`## jeeves-{name}`). Users can decline memory alerts by changing the heading to `## MEMORY.md: declined`.
|
|
106
|
-
|
|
107
|
-
## Workspace File Size Monitoring
|
|
108
|
-
|
|
109
|
-
OpenClaw applies a ~20,000-char injection limit to all workspace bootstrap files (AGENTS.md, SOUL.md, TOOLS.md, USER.md, MEMORY.md). Files exceeding the limit are silently truncated.
|
|
110
|
-
|
|
111
|
-
Core monitors all five files on every `ComponentWriter` cycle:
|
|
112
|
-
- Warning at 80% of budget (fixed threshold; not configurable via `jeeves.config.json`)
|
|
113
|
-
- Over-budget alert when charCount exceeds the budget
|
|
114
|
-
- Missing files are silently skipped
|
|
115
|
-
|
|
116
|
-
### HEARTBEAT Integration
|
|
117
|
-
|
|
118
|
-
When a workspace file exceeds the warning threshold, a `## {filename}` alert appears in HEARTBEAT.md (e.g., `## AGENTS.md`). The alert includes:
|
|
119
|
-
- Character count, budget, and usage percentage
|
|
120
|
-
- Trimming guidance in priority order: (1) move domain-specific content to a local skill, (2) extract reference material to companion files with a pointer, (3) summarize verbose instructions, (4) remove stale content
|
|
121
|
-
|
|
122
|
-
Each file heading follows the same declined/active lifecycle as component headings. Users can decline alerts by changing the heading to `## {filename}: declined` (e.g., `## AGENTS.md: declined`).
|