Skip to content

v0.7.0 - OpenClaw adapter

Choose a tag to compare

@AGGIB AGGIB released this 06 Sep 16:49
· 59 commits to main since this release

Stroq 0.7.0 adds a fifth agent: OpenClaw — the first adapter that runs inside the agent's own process.

OpenClaw support

  • stroq init --agent openclaw copies a small dependency-free JavaScript plugin into ~/.stroq/openclaw-plugin/ and registers it (openclaw plugins install --link + openclaw plugins enable stroq; the commands run only when openclaw is on PATH, otherwise they are printed). Restart the Gateway afterwards. The plugin registers before_tool_call (priority 100, every tool) and after_tool_call, and calls stroq hook openclaw pre|post as a child process, so the engine, rules, policy, provenance, secret-egress guard and hash-chained audit are shared with the other four adapters unchanged.
  • A real approval prompt. A policy ask becomes OpenClaw's requireApproval (allow-once or deny, answered with /approve <id> …; a timeout blocks); a deny becomes a terminal block with Stroq blocked this action (<rule>): ….
  • Fail-closed on every tool. A missing binary, a spawn error, a non-zero exit, a 10 s timeout, a non-JSON or unknown reply, a reply over 1 MiB or an aborted run all block; the CLI exits 2 with the reason on stderr on an internal error. A suspect result taints the session and is logged at warn (observe-only hook; no warning reaches the model in this version).
  • The trusted working directory always wins. The plugin sends its configured workspace (or the Gateway's cwd) and the CLI ignores params.cwd for policy, so an agent cannot point the secret index at an empty directory.
  • Tool mapping. exec/terminal and the shell aliases → Bash; read/write/edit/apply_patch; web_fetch, web_search/x_search; only ask_user, progress_card, heartbeat_respond, get_goal pass through; everything else (message, browser, tts, image_generate, tool_search, tool_describe, process, code_execution, any MCP tool) is mcp__openclaw__<name>: scanned on post, guarded on pre, fail-closed. Names are matched case-insensitively.
  • Every argument spelling is read and the worst decision wins; caller-supplied file_paths/urls lists are dropped; more than 64 targets → openclaw-too-many-targets; an unreadable high-impact call → openclaw-unreadable-input.
  • Self-protection. .openclaw/openclaw.json, .openclaw/plugins/, .openclaw/extensions/ are config.self, and so are openclaw plugins disable|remove|uninstall … and openclaw config set plugins.… — a tainted session cannot switch the plugin off.
  • Resilient install. A recorded stroq.json entry that no longer exists (a pruned npx cache) is skipped with a warning and the plugin falls back to stroq on PATH; init warns when the entry lives in the npx cache; stroq doctor reports the plugin installed only when every file and the manifest id are present.
  • Documented limits: ask needs an approval route (UI or chat channel); MCP server names are unknown to the plugin; process/code_execution are side-effect tools, not shells; unreadable read params are allowed; the plugin's config is read once at registration; plugins that run before Stroq may rewrite params; the plugin needs plugins.entries.stroq.enabled = true (and plugins.allow when an allowlist is set); the wire shapes are inferred from OpenClaw's documentation and one production plugin.

Also

  • The Copilot and OpenClaw adapters share one kind-to-input reader and one unreadable-input guard; the shared post-result scan was split out so Codex and Copilot stay byte-identical.

Verification

  • 1345 tests across 77 files (up from 1062 / 66); CI on Node 22 and 24 runs all five demos and the attack suite (12 scenarios: 8 blocked, 4 asked, 0 passed through).
  • Per-task reviews, a whole-branch security review and one fix wave, each probing the real engine and the real plugin with adversarial payloads. Found and closed before merge: generative/catalog tools exempt from the scan and the egress guard; case-sensitive tool names; params.cwd honoured as the working directory (plugin and CLI); stroqBin word-splitting; disabling the plugin not treated as self-tampering; a stale stroq.json entry locking the agent out; terminal not treated as a shell.

Install: npm install -g @stroq/cli then stroq init (Claude Code), stroq init --agent cursor|codex|copilot|openclaw; or the release tarball attached below while npm's review holds the version.