manifest: declare contracts.tools, bump to 1.2.0#35
Merged
Conversation
OpenClaw 2026.5.2 began enforcing `contracts.tools` as the manifest ownership contract for plugin tool registration: any runtime `registerTool()` call whose name isn't declared in the manifest is rejected, so the gateway reports `toolNames: []` and tools like `flow_run` are invisible to agents. Declares all 11 tools registered in src/plugin/index.ts: flow_create, flow_delete, flow_restore_from_bin, flow_run, flow_resume, flow_send_event, flow_status, flow_list, flow_read, flow_publish, flow_edit. Also: - Bumps compat.pluginApi / minGatewayVersion to >=2026.5.2 (the release that enforced the contract) and build.openclawVersion to 2026.5.12. - Syncs openclaw.plugin.json version (was stale at 0.2.2) with package.json (now both 1.2.0). - Drops the unreferenced duplicate manifest at src/plugin/openclaw.plugin.json.
OpenClaw's plugin loader uses `package.json.main` (./dist/index.js) as
the entry point, so dist/index.js must expose `default.register` for
the plugin to register tools.
Before this change, src/index.ts contained only library re-exports
(FlowRunner, validateFlow, etc.) — compiled dist/index.js had no
`default` export at all, and the gateway logged
`[plugins] clawflow missing register/activate export`.
After: dist/index.js exports BOTH the plugin default (id + register)
AND the public library surface, so OpenClaw can register the 11 flow
tools while standalone consumers can still `import { FlowRunner }`.
OpenClaw 2026.4.26 began requiring an explicit hook name in the third
argument of `api.registerHook()`. Without it the loader rejects the
plugin entirely with:
plugin load failed: clawflow: Error: hook registration missing name
This prevents the plugin's register() from completing, so none of the
11 flow_* tools end up registered either.
Passes { name: "clawflow-flow-run-approval" } as the opts argument
and updates the local PluginApi typing to match the current SDK shape
(events: string|string[], opts.name required).
The approval hook previously prompted unconditionally on every flow_run
and returned a boolean `requireApproval: true` with a plain prompt string
— inflexible and incompatible with hook-driven, unattended automation
(e.g. inbound-email workflows whose session has no interactive channel
to surface the prompt in).
Adds `approval` to PluginConfig with four knobs, all backward-compatible
(the default behavior is still "ask on every run"):
approval:
enabled: boolean # default true; false disables entirely
skipSessionPatterns: string[] # substrings; if any appears in
# ctx.sessionKey the gate is skipped
# (e.g. ["email"] for inbound-email
# automation: session keys look like
# `agent:main:main:email:<id>`)
timeoutMs: number # default 300000 (5 min)
timeoutBehavior: "allow"|"deny" # default "deny"
Also modernizes the hook:
- Reads `event.toolName` (keeps `event.tool` fallback for older runtimes).
- Reads `event.context.sessionKey` per current OpenClaw event shape.
- Returns the rich `requireApproval: { title, description, severity,
timeoutMs, timeoutBehavior }` object the gateway and dashboard render
natively, instead of the legacy boolean+prompt pair.
Hosts that want unattended automation (e.g. Clawnify) can configure
`plugins.entries.clawflow.config.approval.skipSessionPatterns = ["email"]`.
Standalone users keep the safe default.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Restores
flow_run/flow_create/etc. as native OpenClaw tools on hosts running ≥ 2026.4.26, and replaces the legacy boolean approval gate with a configurable one. Four compounding issues addressed:1. Manifest missing
contracts.tools(OpenClaw 2026.5.2)Adds all 11 runtime tools:
flow_create,flow_delete,flow_restore_from_bin,flow_run,flow_resume,flow_send_event,flow_status,flow_list,flow_read,flow_publish,flow_edit.2.
dist/index.jshad no plugin default exportOpenClaw's loader resolves through
package.json.main. Previouslysrc/index.tsexported only the library surface, sodist/index.jshad nodefault.register→ gateway logged[plugins] clawflow missing register/activate export.src/index.tsnow re-exportsdefaultfrom./plugin/index.jssodist/index.jsexposes both plugin entry + public library symbols.3.
registerHookmissing requiredname(OpenClaw 2026.4.26)The plugin called
api.registerHook("before_tool_call", handler)without opts. The current SDK signature requires{ name }. Now passes{ name: "clawflow-flow-run-approval", description: ... }.4. Approval gate hardcoded + inflexible
Previously: prompted unconditionally on every
flow_runwith a booleanrequireApproval: true+ plainpromptstring. Incompatible with hook-driven, unattended automation (e.g. inbound-email workflows whose session has no interactive channel).Adds
approvaltoPluginConfig(andconfigSchema):Hosts running unattended workflows (e.g. Clawnify with
"skipSessionPatterns": ["email"]) bypass the gate for those sessions. Standalone clawflow users keep the safe default.Also modernizes the hook event handling:
event.toolName(withevent.toolfallback for older runtimes).event.context.sessionKeyper current OpenClaw event shape.requireApproval: { title, description, severity, timeoutMs, timeoutBehavior }object the gateway and dashboard render natively.Also
0.2.2/1.1.0→1.2.0(syncopenclaw.plugin.jsonwithpackage.json).compat.pluginApi/minGatewayVersionto>=2026.5.2,build.openclawVersionto2026.5.12.src/plugin/openclaw.plugin.json.Test plan
npm run build+npm run lintpassnode -e "import('./dist/index.js').then(m => …)"→default.register: function[clawflow] flow server listening on :3335openclaw agent --agent main --message "is flow_run available?"→ YESplugins.entries.clawflow.config.approval.skipSessionPatterns = ["email"]