v1 retires everything in @karmaniverous/jeeves that wrote to a live workspace from inside a plugin, in line with the OpenClaw 2026.9.6 upgrade runbook (decisions D1–D5). The library is now a runtime SDK. The jeeves CLI is the local control surface for the open-source stack: jeeves install is the only writer of static platform content, and it installs and updates the component plugins through the OpenClaw CLI. This page lists what was removed and what replaces it.
createComponentWriter(...) call and writer.start() / writer.stop() wiring.createPluginCli) and the bin entry that exposed it.generateToolsContent into registerPromptContext(api, { content }). Move everything else into your skill or behind a tool.sectionId, refreshIntervalSeconds, generateToolsContent, and dependencies from your descriptor. (Zod strips them if you forget, so this is not a hard break at parse time, but TypeScript will flag them.)openclaw.plugin.json ("skills": [...]) and ship it in the package.onPluginDispose.apiUrl to createPluginToolset(descriptor, { apiUrl }) (a string or a () => string | undefined resolver evaluated per tool call). Through 0.6.0-3 the standard {name}_status / {name}_config / {name}_config_apply tools always called http://127.0.0.1:<defaultPort> and ignored plugins.entries.<id>.config.apiUrl, so on an instance with custom service ports they hit the wrong service. The second argument is now required (0.6.0-4 shipped it optional), so an unchanged createPluginToolset(descriptor) call no longer compiles; pass { apiUrl }. apiUrl itself stays optional inside the options object: {} (or an unset apiUrl) deliberately keeps the default-port URL, which is only correct when the service runs on its default port.registerPromptContext (or any other conversation hook), declare it in package.json: "jeeves": { "conversationHooks": ["before_prompt_build"] }. jeeves install / jeeves update grant plugins.entries.<id>.hooks.allowConversationAccess: true only to plugins that declare one; without the grant OpenClaw skips the hook. Add a test with recordRegisteredHooks + validateConversationHooks so a missing declaration fails your build.| Removed (v0.x) | Replacement (v1) |
|---|---|
createComponentWriter, ComponentWriter, ComponentWriterOptions (timer cycle, TOOLS.md section writes) |
None at runtime. Always-in-context rules: registerPromptContext. Live state: your *_status tool. |
refreshPlatformContent, seedContent, RefreshPlatformContentOptions, SeedContentOptions (SOUL/AGENTS/TOOLS refresh on every cycle) |
jeeves install (the only writer; jeeves-tools runs it over SSH) |
seedSkills, seedSkill, JEEVES_SKILL_DIR, SKILLS_DIR |
None. Plugin skills ship via the plugin manifest (define your own constant if a build script needs the skills dir name) |
Platform skills content/skills/ (jeeves, coding, operations, playbooks, slack-bot-provisioner) |
None in core. jeeves install writes no skills and never deletes skill folders written by v0.x; jeeves uninstall leaves skills/ alone |
Reference templates content/templates/ (spec.md, spec-to-code-guide.md, written to {configRoot}/jeeves-core/templates/), TEMPLATES_DIR |
None in core. The templates now ship with jeeves-tools' jeeves-design skill. jeeves install writes no templates and jeeves uninstall no longer deletes jeeves-core/templates/ |
HEARTBEAT orchestration: orchestrateHeartbeat, OrchestrateHeartbeatOptions, parseHeartbeat, writeHeartbeatSection, buildHeartbeatSection, HEARTBEAT_HEADING, HeartbeatEntry, ParsedHeartbeat, ComponentDependencies, checkMemoryHealth, MEMORY_HEARTBEAT_NAME |
None. OpenClaw's heartbeat is owner-controlled; component health is jeeves status / *_status tools. |
Cleanup escalation and flags: CLEANUP_FLAG, needsCleanup, jaccard, shingles, STALENESS_THRESHOLD_MS |
None. Static render replaces the whole block. |
Multi-writer convergence: shouldWrite, version-stamp arbitration, SECTION_IDS, SECTION_ORDER, SectionId |
None. One renderer, run on demand. |
updateManagedSection, removeManagedSection, UpdateManagedSectionOptions, RemoveManagedSectionOptions (locked file I/O) |
Pure upsertManagedBlock / removeManagedBlock (+ your own write) |
parseManaged(content, markers?) result .sections, ManagedSection |
parseManaged(content, markers) (markers required; no .sections) |
createPluginCli, CreatePluginCliOptions (extension copy, npm install, plugins.installs / plugins.entries / tools.alsoAllow patching, --memory slot claim, HEARTBEAT seeding, skill seeding, writeComponentVersion) |
jeeves install / jeeves update, which run openclaw plugins install npm:<pkg>@<ver> --pin --accept-capabilities --force, set hooks.allowConversationAccess for plugins that declare conversation hooks, write plugin config, and remove legacy extensions/<id> copies |
patchConfig, PluginInstallRecord, resolveOpenClawHome, resolveConfigPath |
None; don't write openclaw.json from plugins |
readComponentVersions, writeComponentVersion, removeComponentVersion, COMPONENT_VERSIONS_FILE, ComponentVersionEntry, ComponentVersionsState, WriteComponentVersionOptions, ComponentState |
openclaw plugins inspect --json; jeeves status probes PLATFORM_COMPONENTS |
checkRegistryVersion, REGISTRY_CACHE_FILE |
None. jeeves update resolves versions with npm view when it runs |
registryCache (ttlSeconds) in core config.json / CoreConfig |
None; nothing read it. New core configs omit it. Existing files that still carry it keep validating (the key is stripped on load) and it can be deleted |
DEFAULT_CORE_VERSION, isPrime |
None |
TOOLS_MARKERS, WORKSPACE_FILES.tools, WORKSPACE_FILES.heartbeat |
LEGACY_TOOLS_MARKERS, WORKSPACE_FILES.legacyTools (strip-only) |
content/tools-platform.md (TOOLS.md platform section) |
Durable guidance folded into the AGENTS block; watcher's tool hierarchy moves to the watcher plugin's prompt hook |
createAsyncContentCache, AsyncContentCacheOptions |
None (spec v1 §2.1). registerPromptContext accepts async providers; keep them fast |
proper-lockfile (and its signal-exit process handlers), handlebars |
In-house withFileLock (same {file}.lock convention); no templating needed |
init / getWorkspacePath / getConfigRoot / getComponentConfigDir, loadWorkspaceConfig, formatBeginMarker (gains an optional now argument) / formatEndMarker, resolveWorkspacePath, resolvePluginSetting, resolveOptionalPluginSetting, getPackageVersion, getPackageRoot, createPluginToolset (gains a required options argument, { apiUrl }; see Summary step 7), ok / fail / connectionFail, fetchJson / postJson / fetchWithTimeout, JeevesComponentDescriptor / jeevesComponentDescriptorSchema, the service-side handlers and CLI (createServiceCli, createServiceManager, createConfigQueryHandler, createConfigApplyHandler, createStatusHandler), discovery (getServiceUrl, getBindAddress, ports), atomicWrite, withFileLock, analyzeMemory, script utilities, and the jeeves CLI (install, uninstall, status, config; install now also installs plugins, and update is new).
| Export | Purpose |
|---|---|
renderManagedBlock, upsertManagedBlock, removeManagedBlock, ManagedBlockStampOptions |
Pure managed-block transforms |
validateSkillFrontmatter, SkillFrontmatter |
name/description check for skill build steps |
validateConversationHooks, recordRegisteredHooks, CONVERSATION_HOOK_NAMES |
Build/test check that package.json jeeves.conversationHooks matches the conversation hooks the plugin registers |
createPluginToolset(descriptor, { apiUrl }), PluginToolsetOptions, pluginToolsetOptionsSchema, PluginApiUrlResolver |
The standard tools call the plugin's configured apiUrl (string or per-call resolver); defaultPort is only the fallback. The options argument is required (breaking) |
atomicWrite(path, content, { mode }) |
Optional file mode for the written file (backward compatible) |
jeeves update [packages...], jeeves install [plugins...], plugin removal in jeeves uninstall, --dry-run on all three, --force-reinstall on install/update |
Plugin install/update/removal through the OpenClaw CLI; an exact version that is already installed is not reinstalled (see README, CLI) |
jeeves install / jeeves update plugin config options: --config-root (shared), --runner-api-url, --watcher-api-url, --server-api-url, --server-plugin-key, --meta-api-url, --plugin-config <file.json> |
Writes missing (or explicitly passed) plugins.entries.<id>.config values through an owner-only --batch-file (replaces the per-plugin npx <plugin> install config step) |
registerPromptContext, promptContextOptionsSchema, PromptContextOptions, PromptContextProvider, HookRegistrationOptions, PromptBuild* types |
before_prompt_build → { appendSystemContext } |
onPluginDispose, PluginLifecycleApi |
Tie resources to the plugin lifecycle |
PluginApi.on, .lifecycle, .logger, .pluginConfig |
Typed subset of the OpenClaw 2026.9.x plugin API |
For a new box:
npm install -g @karmaniverous/jeeves
jeeves install --config-root /srv/jeeves/config --dry-run # files, plugin config, exact openclaw commands
jeeves install --config-root /srv/jeeves/config # content + runner/watcher/server/meta plugins at latest
keys._plugin. The CLI never restarts either, because it can't know whether they run in a console, as a service or in a container.Later:
jeeves update # every installed Jeeves plugin to latest, plus any missing config
jeeves update watcher@1.2.3 # or one plugin to a pinned version
Re-running either command is cheap: a plugin already installed at the resolved version is not reinstalled (--force-reinstall overrides), but its hook grant and missing config are still written.
jeeves install and jeeves update write each plugin's plugins.entries.<id>.config:
configRoot is required. It comes from --config-root, then --plugin-config, then the existing value, then JEEVES_CONFIG_ROOT or jeeves.config.json. With none of them, the command fails before writing anything and lists the missing options.apiUrl defaults to the service's local port.pluginKey is kept equal to the server's keys._plugin in {configRoot}/jeeves-server/config.json: the plugin takes the server's key; a server without one gets the plugin's key, or a newly generated one written to both ends; different keys on the two ends fail before any change unless you pass --server-plugin-key, which writes both. A server config write is backed up (config.json.bak-<timestamp>) and atomic, changes only keys._plugin, and needs a jeeves-server restart. Keys are shown only as <redacted>. See README, Server plugin key.Values already in openclaw.json are kept unless you pass them explicitly. See README, Plugin config.
jeeves-tools (not open source) will call the same CLI over SSH with fleet-pinned versions instead of running plugin installers itself:
ssh jeeves@<instance> 'source ~/.nvm/nvm.sh; jeeves install runner@<v> watcher@<v> server@<v> meta@<v> --config-root <root>'
ssh jeeves@<instance> 'source ~/.nvm/nvm.sh; jeeves update @karmaniverous/jeeves-runner-openclaw@<v>'
jeeves-tools no longer renders plugin config itself. It passes --config-root and any non-default values (or a --plugin-config file) to jeeves install.
jeeves exits non-zero if any openclaw or npm command fails, so the SSH exit code is the success signal.
Instances managed by v0.x keep working until their plugins are upgraded. On upgrade:
jeeves install --dry-run, review, then jeeves install. It replaces the old SOUL/AGENTS blocks in place (cleanup flags included), reinstalls each plugin from npm (the v0.x path installs never count as current), sets hooks.allowConversationAccess for plugins that declare conversation hooks, fills in missing plugin config without touching existing values, and deletes the legacy extensions/<id> copy only after the npm install succeeded. Restart the gateway afterwards.jeeves uninstall now removes the Jeeves plugins as well as the managed blocks and artifacts; there is no --plugins option. Use --dry-run to see the exact openclaw commands first.jeeves uninstall or removeManagedBlock(content, LEGACY_TOOLS_MARKERS) strips the old block. Nothing writes TOOLS.md any more; archiving the file is the owner's call.# Jeeves Platform Status section is no longer maintained and can be removed.{configRoot}/jeeves-core/component-versions.json and registry-cache.json are no longer read or written and can be deleted, as can the registryCache key in jeeves-core/config.json (harmless if left).{workspace}/skills/ (jeeves, coding, operations, playbooks, slack-bot-provisioner) are no longer updated. jeeves install and jeeves uninstall leave them in place; removing them is the owner's call.{configRoot}/jeeves-core/templates/ are no longer updated. jeeves install and jeeves uninstall leave them in place; the maintained copies ship with jeeves-tools' jeeves-design skill, and removing the old folder is the owner's call.