Compare commits

...

23 Commits

Author SHA1 Message Date
Peter Steinberger
35e8fa2169 test(codex): make exec-server cleanup proof deterministic 2026-05-23 09:29:02 +01:00
Peter Steinberger
3e472acf71 docs(release): freeze release branch baseline 2026-05-23 08:45:17 +01:00
Peter Steinberger
5f0e3dfbc3 test(codex): bound sandbox exec server shutdown 2026-05-23 08:45:16 +01:00
Peter Steinberger
419f4a6325 test(codex): harden sandbox failure cleanup tests 2026-05-23 08:45:16 +01:00
Peter Steinberger
0f29e9e293 test(codex): isolate sandbox exec server tests 2026-05-23 08:45:16 +01:00
Peter Steinberger
45e3558230 ci(release): poll child workflows through actions api 2026-05-23 08:45:16 +01:00
Peter Steinberger
7441f32673 chore(release): refresh plugin inventory docs 2026-05-23 08:45:16 +01:00
Peter Steinberger
93050c7aab test(codex): avoid active run in sandbox exec-server test 2026-05-23 08:45:16 +01:00
Peter Steinberger
1a37882504 test(codex): satisfy sandbox payload test types 2026-05-23 08:45:16 +01:00
Peter Steinberger
8fe3825ac8 test(codex): avoid active run in sandbox payload test 2026-05-23 08:45:16 +01:00
Peter Steinberger
54da73d11c test(codex): isolate sandbox startup tests 2026-05-23 08:45:16 +01:00
Peter Steinberger
421d274991 test(codex): harden sandbox startup harness 2026-05-23 08:45:16 +01:00
Peter Steinberger
8843b7e9b6 test(codex): align yield abort assertion 2026-05-23 08:45:16 +01:00
Peter Steinberger
8f3eed9343 fix(qa): bundle private flow fixtures 2026-05-23 08:45:16 +01:00
Peter Steinberger
b4980b3520 fix(qa): honor full message cursor for outbound waits 2026-05-23 08:45:16 +01:00
Peter Steinberger
b53921e429 fix(config): stabilize heartbeat target docs baseline 2026-05-23 08:45:16 +01:00
Peter Steinberger
d552f66483 fix(config): make docs baseline ordering deterministic 2026-05-23 08:45:16 +01:00
Peter Steinberger
de2fc740c0 chore(release): refresh config baseline hash 2026-05-23 08:45:16 +01:00
Peter Steinberger
615faa16a5 fix(codex): keep media async starts from yielding 2026-05-23 08:45:16 +01:00
Peter Steinberger
6cf6cc9e2d test(telegram): avoid fake timer startup wait 2026-05-23 08:45:16 +01:00
Peter Steinberger
4c397d13d4 test(telegram): harden startup probe limiter tests 2026-05-23 08:45:16 +01:00
Peter Steinberger
9c63ab305b chore(release): refresh generated release artifacts 2026-05-23 08:45:16 +01:00
Peter Steinberger
490c39c870 chore(release): prepare 2026.5.22-beta.1 2026-05-23 08:45:16 +01:00
174 changed files with 772 additions and 613 deletions

View File

@@ -22,6 +22,17 @@ Use this skill for release and publish-time workflow. Keep ordinary development
- Before release branching, pull latest `main` and confirm current `main` CI is
green. Then branch from that commit so regular development can continue on
`main` while release validation runs.
- After the release branch or release tag exists, treat its base commit as
frozen for that release attempt. Do not autonomously pull `main`, rebase the
release branch, merge `main`, or move the release baseline just because the
operator previously said "rebase" or because `main` advanced. A new rebase
needs an explicit, current instruction that names rebasing the active release
branch.
- When a release is blocked by a failing test, first fix the release branch in
place. If `main` already has a specific commit that directly fixes that exact
blocker, cherry-pick only that targeted fix after confirming the diff is
narrow and explaining why it matches the failure. Do not use the blocker as a
reason to rebase onto all of `main`.
- Before release branching, commit any dirty files in coherent groups, push,
pull/rebase, then run `/changelog` on `main` and commit/push/pull that
changelog rewrite immediately before creating the release branch.

View File

@@ -301,6 +301,14 @@ jobs:
echo "Dispatched ${workflow}: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${run_id}"
echo "run_id=${run_id}" >> "$GITHUB_OUTPUT"
fetch_child_run_json() {
gh api "repos/${GITHUB_REPOSITORY}/actions/runs/${run_id}"
}
fetch_child_jobs() {
gh api --paginate "repos/${GITHUB_REPOSITORY}/actions/runs/${run_id}/jobs?per_page=100" --jq '.jobs[]'
}
cancel_child() {
if [[ -n "${run_id:-}" ]]; then
echo "Cancelling child workflow ${workflow}: ${run_id}" >&2
@@ -311,26 +319,26 @@ jobs:
poll_count=0
while true; do
status="$(gh run view "$run_id" --json status --jq '.status')"
status="$(fetch_child_run_json | jq -r '.status')"
if [[ "$status" == "completed" ]]; then
break
fi
poll_count=$((poll_count + 1))
if (( poll_count % 10 == 0 )); then
echo "Still waiting on ${workflow}: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${run_id}"
gh run view "$run_id" --json jobs --jq '.jobs[] | select(.status != "completed") | {name, status, url}' || true
fetch_child_jobs | jq 'select(.status != "completed") | {name, status, url: .html_url}' || true
fi
sleep 30
done
trap - EXIT INT TERM
conclusion="$(gh run view "$run_id" --json conclusion --jq '.conclusion')"
url="$(gh run view "$run_id" --json url --jq '.url')"
conclusion="$(fetch_child_run_json | jq -r '.conclusion // ""')"
url="$(fetch_child_run_json | jq -r '.html_url')"
echo "${workflow} finished with ${conclusion}: ${url}"
echo "url=${url}" >> "$GITHUB_OUTPUT"
echo "conclusion=${conclusion}" >> "$GITHUB_OUTPUT"
if [[ "$conclusion" != "success" ]]; then
gh run view "$run_id" --json jobs --jq '.jobs[] | select(.conclusion != "success" and .conclusion != "skipped") | {name, conclusion, url}' || true
fetch_child_jobs | jq 'select(.conclusion != "success" and .conclusion != "skipped") | {name, conclusion, url: .html_url}' || true
exit 1
fi
}
@@ -401,6 +409,14 @@ jobs:
echo "Dispatched ${workflow}: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${run_id}"
echo "run_id=${run_id}" >> "$GITHUB_OUTPUT"
fetch_child_run_json() {
gh api "repos/${GITHUB_REPOSITORY}/actions/runs/${run_id}"
}
fetch_child_jobs() {
gh api --paginate "repos/${GITHUB_REPOSITORY}/actions/runs/${run_id}/jobs?per_page=100" --jq '.jobs[]'
}
cancel_child() {
if [[ -n "${run_id:-}" ]]; then
echo "Cancelling child workflow ${workflow}: ${run_id}" >&2
@@ -411,26 +427,26 @@ jobs:
poll_count=0
while true; do
status="$(gh run view "$run_id" --json status --jq '.status')"
status="$(fetch_child_run_json | jq -r '.status')"
if [[ "$status" == "completed" ]]; then
break
fi
poll_count=$((poll_count + 1))
if (( poll_count % 10 == 0 )); then
echo "Still waiting on ${workflow}: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${run_id}"
gh run view "$run_id" --json jobs --jq '.jobs[] | select(.status != "completed") | {name, status, url}' || true
fetch_child_jobs | jq 'select(.status != "completed") | {name, status, url: .html_url}' || true
fi
sleep 30
done
trap - EXIT INT TERM
conclusion="$(gh run view "$run_id" --json conclusion --jq '.conclusion')"
url="$(gh run view "$run_id" --json url --jq '.url')"
conclusion="$(fetch_child_run_json | jq -r '.conclusion // ""')"
url="$(fetch_child_run_json | jq -r '.html_url')"
echo "${workflow} finished with ${conclusion}: ${url}"
echo "url=${url}" >> "$GITHUB_OUTPUT"
echo "conclusion=${conclusion}" >> "$GITHUB_OUTPUT"
if [[ "$conclusion" != "success" ]]; then
gh run view "$run_id" --json jobs --jq '.jobs[] | select(.conclusion != "success" and .conclusion != "skipped") | {name, conclusion, url}' || true
fetch_child_jobs | jq 'select(.conclusion != "success" and .conclusion != "skipped") | {name, conclusion, url: .html_url}' || true
exit 1
fi
}
@@ -511,6 +527,14 @@ jobs:
echo "Dispatched ${workflow}: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${run_id}"
echo "run_id=${run_id}" >> "$GITHUB_OUTPUT"
fetch_child_run_json() {
gh api "repos/${GITHUB_REPOSITORY}/actions/runs/${run_id}"
}
fetch_child_jobs() {
gh api --paginate "repos/${GITHUB_REPOSITORY}/actions/runs/${run_id}/jobs?per_page=100" --jq '.jobs[]'
}
release_check_blocking_job() {
case "$1" in
"resolve_target" | \
@@ -561,20 +585,25 @@ jobs:
poll_count=0
while true; do
status="$(gh run view "$run_id" --json status --jq '.status')"
status="$(fetch_child_run_json | jq -r '.status')"
if [[ "$status" == "completed" ]]; then
break
fi
poll_count=$((poll_count + 1))
if (( poll_count % 10 == 0 )); then
echo "Still waiting on ${workflow}: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${run_id}"
gh run view "$run_id" --json jobs --jq '.jobs[] | select(.status != "completed") | {name, status, url}' || true
fetch_child_jobs | jq 'select(.status != "completed") | {name, status, url: .html_url}' || true
fi
sleep 30
done
trap - EXIT INT TERM
run_json="$(gh run view "$run_id" --json conclusion,url,jobs)"
jobs_json="$(fetch_child_jobs | jq -s '{jobs: [.[] | {name, conclusion, url: .html_url}]}')"
run_json="$(
jq -s '.[0] + .[1]' \
<(fetch_child_run_json | jq '{conclusion: (.conclusion // ""), url: .html_url}') \
<(printf '%s\n' "$jobs_json")
)"
conclusion="$(jq -r '.conclusion' <<< "$run_json")"
url="$(jq -r '.url' <<< "$run_json")"
echo "${workflow} finished with ${conclusion}: ${url}"

View File

@@ -1,4 +1,4 @@
5482b1a125a5c41856f6f49dfd70e2efe9e52a7cc0e2d4c24a56d99adfeda6be config-baseline.json
3d686075da4d4f6c6319c3247e93f486a6c48314a28a2961cd4acab7f3fa5389 config-baseline.core.json
11839c7a1b858c66075156f0e203aa8367cd8321047684679a18e18b7c8fe1f7 config-baseline.channel.json
5c214ab364011fd95735755f9fa4298aa4de8ad81144ae8dd08d969bb7ba318b config-baseline.plugin.json
fdf49e9b06dc3baa556d42d46ec654a697ff9d82069fb9963b2d9c83755272b7 config-baseline.json
5be4b1e3d1f3b5fde9cc6c75f799e5673f8dd503d79ba83952df476114bde8f7 config-baseline.core.json
e7d370393611c16f18563419fba9307d40cd60fdbb73a2cac0a1eb22c4359eac config-baseline.channel.json
a32d6d010f2a10e1ea510ce8110895d77d087b553985df8f642a76db6868c7f7 config-baseline.plugin.json

View File

@@ -1,2 +1,2 @@
e07c1b7a7bc8a6eb25a832961c2367f56d60a1fa54096dda460f8db1e572aa2a plugin-sdk-api-baseline.json
34f2af745b9ed47eec90350b2c2a9000566744b8982440feee1c4a405d0a28ca plugin-sdk-api-baseline.jsonl
434c62dfc32631e2c0cd862059f3257c0844d2c515e92db4d5670be7f3882a14 plugin-sdk-api-baseline.json
2f6c82614fc6521ea27209e3d9888a4a6cdec30fa3082500aef4f8975358d9bf plugin-sdk-api-baseline.jsonl

View File

@@ -16,23 +16,8 @@ Adds policy-backed doctor checks for workspace conformance.
## Surface
plugin; CLI command: [`openclaw policy`](/cli/policy)
## Behavior
The Policy plugin contributes doctor health checks for policy-managed OpenClaw
settings and governed workspace declarations. Policy currently covers channel
conformance, governed tool metadata, MCP server posture, model-provider posture,
private-network access posture, Gateway exposure posture, agent workspace/tool
posture, and OpenClaw config secret provider/auth profile posture.
Policy stores authored requirements in `policy.jsonc`, observes existing
OpenClaw settings and workspace declarations as evidence, and reports drift
through `openclaw policy check` and `openclaw doctor --lint`. A clean policy
check emits policy, evidence, findings, and attestation hashes that operators
can record for audit.
plugin
## Related docs
- [Policy CLI](/cli/policy)
- [Doctor lint mode](/cli/doctor#lint-mode)
- [policy](/cli/policy)

View File

@@ -9,54 +9,6 @@ title: "Voyage plugin"
Adds memory embedding provider support.
## Setup
Voyage is a remote memory embedding provider, so it needs a Voyage API key before
memory search can use it.
Set the key with either:
- Environment variable: `VOYAGE_API_KEY`
- Config key: `models.providers.voyage.apiKey`
For an interactive setup, run:
```bash
openclaw configure --section model
```
To make memory search use Voyage explicitly, set the memory search provider to
`voyage` and choose a Voyage embedding model:
```ts
{
agents: {
defaults: {
memorySearch: {
provider: "voyage",
model: "voyage-3-large",
},
},
},
models: {
providers: {
voyage: {
apiKey: "${VOYAGE_API_KEY}",
},
},
},
}
```
Verify the runtime credential and embedding provider path with:
```bash
openclaw memory status --deep
```
For the full memory embedding provider matrix and API key resolution order, see
[Memory config](/reference/memory-config).
## Distribution
- Package: `@openclaw/voyage-provider`

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/acpx",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/acpx",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"dependencies": {
"@agentclientprotocol/claude-agent-acp": "0.36.1",
"@zed-industries/codex-acp": "0.14.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/acpx",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw ACP runtime backend",
"repository": {
"type": "git",
@@ -26,10 +26,10 @@
"minHostVersion": ">=2026.4.25"
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22",
"openclawVersion": "2026.5.22-beta.1",
"staticAssets": [
{
"source": "./src/runtime-internals/mcp-proxy.mjs",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/admin-http-rpc",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw admin HTTP RPC endpoint",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/alibaba-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Alibaba Model Studio video provider plugin",
"type": "module",

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/amazon-bedrock-mantle-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/amazon-bedrock-mantle-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"dependencies": {
"@anthropic-ai/sdk": "0.97.1",
"@aws/bedrock-token-generator": "1.1.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/amazon-bedrock-mantle-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw Amazon Bedrock Mantle (OpenAI-compatible) provider plugin",
"repository": {
"type": "git",
@@ -25,10 +25,10 @@
"minHostVersion": ">=2026.5.12-beta.1"
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22",
"openclawVersion": "2026.5.22-beta.1",
"bundledDist": false
},
"release": {

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/amazon-bedrock-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/amazon-bedrock-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"dependencies": {
"@aws-sdk/client-bedrock": "3.1051.0",
"@aws-sdk/client-bedrock-runtime": "3.1051.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/amazon-bedrock-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw Amazon Bedrock provider plugin",
"repository": {
"type": "git",
@@ -27,10 +27,10 @@
"minHostVersion": ">=2026.5.12-beta.1"
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22",
"openclawVersion": "2026.5.22-beta.1",
"bundledDist": false
},
"release": {

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/anthropic-vertex-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/anthropic-vertex-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"dependencies": {
"@anthropic-ai/vertex-sdk": "0.16.1",
"@earendil-works/pi-agent-core": "0.75.4",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/anthropic-vertex-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw Anthropic Vertex provider plugin",
"repository": {
"type": "git",
@@ -25,10 +25,10 @@
"minHostVersion": ">=2026.5.12-beta.1"
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22",
"openclawVersion": "2026.5.22-beta.1",
"bundledDist": false
},
"release": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/anthropic-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Anthropic provider plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/arcee-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Arcee provider plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/azure-speech",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Azure Speech plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/bonjour",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw Bonjour/mDNS gateway discovery",
"type": "module",
"dependencies": {

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/brave-plugin",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/brave-plugin",
"version": "2026.5.22"
"version": "2026.5.22-beta.1"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/brave-plugin",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw Brave plugin",
"repository": {
"type": "git",
@@ -21,10 +21,10 @@
"allowInvalidConfigRecovery": true
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22"
"openclawVersion": "2026.5.22-beta.1"
},
"release": {
"publishToClawHub": true,

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/browser-plugin",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw browser tool plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/byteplus-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw BytePlus provider plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/canvas-plugin",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Canvas plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/cerebras-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Cerebras provider plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/chutes-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Chutes.ai provider plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/clickclack",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw ClickClack channel plugin",
"type": "module",
@@ -18,7 +18,7 @@
"openclaw": "workspace:*"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/cloudflare-ai-gateway-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Cloudflare AI Gateway provider plugin",
"type": "module",

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/codex",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/codex",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"dependencies": {
"@earendil-works/pi-coding-agent": "0.75.4",
"@openai/codex": "0.132.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/codex",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw Codex harness and model provider plugin",
"repository": {
"type": "git",
@@ -27,10 +27,10 @@
"minHostVersion": ">=2026.5.1-beta.1"
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22"
"openclawVersion": "2026.5.22-beta.1"
},
"release": {
"publishToClawHub": true,

View File

@@ -68,6 +68,12 @@ import {
runCodexAppServerAttempt as runCodexAppServerAttemptImpl,
testing,
} from "./run-attempt.js";
import {
closeCodexSandboxExecServersForTests,
ensureCodexSandboxExecServerEnvironment,
releaseCodexSandboxExecServerEnvironment,
} from "./sandbox-exec-server.js";
import { createSandboxContext } from "./sandbox-exec-server.test-helpers.js";
import { readCodexAppServerBinding, writeCodexAppServerBinding } from "./session-binding.js";
import { createCodexTestModel } from "./test-support.js";
import {
@@ -329,7 +335,11 @@ function createAppServerHarness(
return requestImpl(method, params, requestOptions as { signal?: AbortSignal } | undefined);
});
setCodexAppServerClientFactoryForTest(async (_startOptions, authProfileId, agentDir) => {
const clientFactory: CodexAppServerClientFactory = async (
_startOptions,
authProfileId,
agentDir,
) => {
options.onStart?.(authProfileId, agentDir);
return {
getServerVersion: () => "0.132.0",
@@ -347,7 +357,8 @@ function createAppServerHarness(
return () => closeHandlers.delete(handler);
},
} as never;
});
};
setCodexAppServerClientFactoryForTest(clientFactory);
const waitForServerRequestHandler = async () => {
await vi.waitFor(() => expect(handleServerRequest).toBeTypeOf("function"), {
@@ -358,6 +369,7 @@ function createAppServerHarness(
};
return {
clientFactory,
request,
requests,
async waitForMethod(method: string, timeoutMs = 30_000) {
@@ -692,6 +704,7 @@ describe("runCodexAppServerAttempt", () => {
});
afterEach(async () => {
await closeCodexSandboxExecServersForTests();
resetCodexAppServerClientFactoryForTest();
testing.resetOpenClawCodingToolsFactoryForTests();
resetCodexRateLimitCacheForTests();
@@ -811,6 +824,56 @@ describe("runCodexAppServerAttempt", () => {
expect(tools.map((tool) => tool.name)).toEqual(["read", "write"]);
});
it("does not abort Codex dynamic tool turns for media async starts", async () => {
let factoryOptions:
| {
onYield?: (message: string) => Promise<void> | void;
onAsyncTaskStarted?: (message: string) => Promise<void> | void;
}
| undefined;
testing.setOpenClawCodingToolsFactoryForTests((options) => {
factoryOptions = options;
return [
createRuntimeDynamicTool("image_generate"),
createRuntimeDynamicTool("sessions_yield"),
];
});
const sessionFile = path.join(tempDir, "session.jsonl");
const workspaceDir = path.join(tempDir, "workspace");
const params = createParams(sessionFile, workspaceDir);
params.disableTools = false;
params.runtimePlan = createCodexRuntimePlanFixture();
const sandboxSessionKey = params.sessionKey;
if (!sandboxSessionKey) {
throw new Error("createParams must provide a sessionKey for Codex dynamic tool tests.");
}
const runAbortController = new AbortController();
let yieldDetected = false;
await testing.buildDynamicTools({
params,
resolvedWorkspace: workspaceDir,
effectiveWorkspace: workspaceDir,
sandboxSessionKey,
sandbox: { enabled: true, backendId: "docker" } as never,
nativeToolSurfaceEnabled: false,
runAbortController,
sessionAgentId: "main",
pluginConfig: {},
onYieldDetected: () => {
yieldDetected = true;
},
});
await factoryOptions?.onAsyncTaskStarted?.("Image generation started.");
expect(yieldDetected).toBe(false);
expect(runAbortController.signal.aborted).toBe(false);
await factoryOptions?.onYield?.("Waiting for subagent.");
expect(yieldDetected).toBe(true);
expect(runAbortController.signal.aborted).toBe(false);
});
it("exposes OpenClaw sandbox shell tools under distinct names for non-Docker sandbox backends", async () => {
testing.setOpenClawCodingToolsFactoryForTests(() => [
createRuntimeDynamicTool("read"),
@@ -1002,129 +1065,137 @@ describe("runCodexAppServerAttempt", () => {
});
it("starts active OpenClaw sandbox turns with Codex native execution disabled", async () => {
const restoreSandboxBackend = registerSandboxBackend("codex-test-sandbox", async () => ({
id: "codex-test-sandbox",
runtimeId: "codex-test-runtime",
runtimeLabel: "Codex Test Sandbox",
workdir: "/workspace",
buildExecSpec: async () => ({
argv: ["true"],
env: {},
stdinMode: "pipe-closed" as const,
}),
runShellCommand: async () => ({
stdout: Buffer.alloc(0),
stderr: Buffer.alloc(0),
code: 0,
}),
}));
try {
testing.setOpenClawCodingToolsFactoryForTests(() => [
createRuntimeDynamicTool("exec"),
createRuntimeDynamicTool("process"),
createRuntimeDynamicTool("message"),
]);
const sessionFile = path.join(tempDir, "session.jsonl");
const workspaceDir = path.join(tempDir, "workspace");
const params = createParams(sessionFile, workspaceDir);
params.disableTools = false;
params.runtimePlan = createCodexRuntimePlanFixture();
params.config = {
agents: {
defaults: {
sandbox: {
mode: "all",
backend: "codex-test-sandbox",
scope: "session",
},
},
},
} as never;
const { requests, waitForMethod, completeTurn } = createStartedThreadHarness();
const run = runCodexAppServerAttempt(params, {
pluginConfig: { appServer: { mode: "yolo" } },
});
await waitForMethod("turn/start");
await completeTurn({ threadId: "thread-1", turnId: "turn-1" });
await run;
const startRequest = requests.find((request) => request.method === "thread/start");
const startParams = startRequest?.params as Record<string, unknown> | undefined;
const startConfig = startParams?.config as Record<string, unknown> | undefined;
const dynamicTools = startParams?.dynamicTools as Array<{ name: string }> | undefined;
expect(startConfig?.["features.code_mode"]).toBe(false);
expect(startConfig?.["features.code_mode_only"]).toBe(false);
expect(startParams?.environments).toEqual([]);
expect(dynamicTools?.map((tool) => tool.name)).toEqual([
"message",
"sandbox_exec",
"sandbox_process",
]);
} finally {
restoreSandboxBackend();
testing.setOpenClawCodingToolsFactoryForTests(() => [
createRuntimeDynamicTool("exec"),
createRuntimeDynamicTool("process"),
createRuntimeDynamicTool("message"),
]);
const sessionFile = path.join(tempDir, "session.jsonl");
const workspaceDir = path.join(tempDir, "workspace");
const params = createParams(sessionFile, workspaceDir);
params.disableTools = false;
params.runtimePlan = createCodexRuntimePlanFixture();
const sandboxSessionKey = params.sessionKey;
if (!sandboxSessionKey) {
throw new Error("createParams must provide a sessionKey for Codex dynamic tool tests.");
}
const sandbox = { enabled: true, backendId: "docker" } as never;
const nativeToolSurfaceEnabled = testing.shouldEnableCodexAppServerNativeToolSurface(
params,
sandbox,
);
const dynamicTools = await testing.buildDynamicTools({
params,
resolvedWorkspace: workspaceDir,
effectiveWorkspace: workspaceDir,
sandboxSessionKey,
sandbox,
nativeToolSurfaceEnabled,
runAbortController: new AbortController(),
sessionAgentId: "main",
pluginConfig: {},
onYieldDetected: () => undefined,
});
const request = vi.fn(async (method: string, _params?: unknown) => {
if (method === "thread/start") {
return threadStartResult();
}
throw new Error(`unexpected method: ${method}`);
});
await startOrResumeThread({
client: { request } as never,
params,
cwd: workspaceDir,
dynamicTools: dynamicTools as never,
appServer: createThreadLifecycleAppServerOptions(),
nativeCodeModeEnabled: nativeToolSurfaceEnabled,
nativeCodeModeOnlyEnabled: false,
userMcpServersEnabled: false,
environmentSelection: [],
});
const startRequest = request.mock.calls.find(([method]) => method === "thread/start");
const startParams = startRequest?.[1] as Record<string, unknown> | undefined;
const startConfig = startParams?.config as Record<string, unknown> | undefined;
const startDynamicTools = startParams?.dynamicTools as Array<{ name: string }> | undefined;
expect(nativeToolSurfaceEnabled).toBe(false);
expect(startConfig?.["features.code_mode"]).toBe(false);
expect(startConfig?.["features.code_mode_only"]).toBe(false);
expect(startParams?.environments).toEqual([]);
expect(startDynamicTools?.map((tool) => tool.name)).toEqual([
"message",
"sandbox_exec",
"sandbox_process",
]);
});
it("routes native Codex execution through an OpenClaw sandbox exec-server when opted in", async () => {
const restoreSandboxBackend = registerSandboxBackend("codex-test-sandbox", async () => ({
id: "codex-test-sandbox",
runtimeId: "codex-test-runtime",
runtimeLabel: "Codex Test Sandbox",
workdir: "/workspace",
buildExecSpec: async () => ({
argv: ["true"],
env: {},
stdinMode: "pipe-closed" as const,
}),
const sessionFile = path.join(tempDir, "session.jsonl");
const workspaceDir = path.join(tempDir, "workspace");
const params = createParams(sessionFile, workspaceDir);
params.disableTools = false;
params.runtimePlan = createCodexRuntimePlanFixture();
const appServer = {
...createThreadLifecycleAppServerOptions(),
sandbox: "danger-full-access",
};
const sandbox = createSandboxContext({
runShellCommand: async () => ({
stdout: Buffer.alloc(0),
stderr: Buffer.alloc(0),
code: 0,
}),
}));
});
const request = vi.fn(async (method: string, _params?: unknown) => {
if (method === "environment/add") {
return {};
}
if (method === "thread/start") {
return threadStartResult();
}
throw new Error(`unexpected method: ${method}`);
});
const client = {
getServerVersion: () => "0.132.0",
request,
};
try {
testing.setOpenClawCodingToolsFactoryForTests(() => [
createRuntimeDynamicTool("exec"),
createRuntimeDynamicTool("process"),
createRuntimeDynamicTool("message"),
]);
const sessionFile = path.join(tempDir, "session.jsonl");
const workspaceDir = path.join(tempDir, "workspace");
const params = createParams(sessionFile, workspaceDir);
params.disableTools = false;
params.runtimePlan = createCodexRuntimePlanFixture();
params.config = {
agents: {
defaults: {
sandbox: {
mode: "all",
backend: "codex-test-sandbox",
scope: "session",
},
},
},
} as never;
const { requests, waitForMethod, completeTurn } = createStartedThreadHarness();
const run = runCodexAppServerAttempt(params, {
pluginConfig: {
appServer: {
mode: "yolo",
experimental: { sandboxExecServer: true },
},
},
const environment = await ensureCodexSandboxExecServerEnvironment({
client: client as never,
sandbox,
appServerStartOptions: appServer.start,
});
await waitForMethod("turn/start");
await completeTurn({ threadId: "thread-1", turnId: "turn-1" });
await run;
if (!environment) {
throw new Error("expected sandbox exec-server environment");
}
const environmentSelection = [environment];
const environmentAdd = requests.find((request) => request.method === "environment/add");
const environmentAddParams = environmentAdd?.params as
await startOrResumeThread({
client: client as never,
params,
cwd: environment.cwd,
dynamicTools: [createNamedDynamicTool("message")] as never,
appServer: appServer as never,
nativeCodeModeEnabled: true,
nativeCodeModeOnlyEnabled: false,
userMcpServersEnabled: false,
environmentSelection,
});
const turnParams = buildTurnStartParams(params, {
threadId: "thread-1",
cwd: environment.cwd,
appServer: appServer as never,
sandboxPolicy: { type: "externalSandbox", networkAccess: "enabled" },
environmentSelection,
});
const environmentAdd = request.mock.calls.find(([method]) => method === "environment/add");
const environmentAddParams = environmentAdd?.[1] as
| { environmentId?: string; execServerUrl?: string }
| undefined;
const startRequest = requests.find((request) => request.method === "thread/start");
const startParams = startRequest?.params as
const startRequest = request.mock.calls.find(([method]) => method === "thread/start");
const startParams = startRequest?.[1] as
| {
cwd?: string;
dynamicTools?: Array<{ name: string }>;
@@ -1136,14 +1207,6 @@ describe("runCodexAppServerAttempt", () => {
};
}
| undefined;
const turnRequest = requests.find((request) => request.method === "turn/start");
const turnParams = turnRequest?.params as
| {
cwd?: string;
environments?: Array<{ environmentId?: string; cwd?: string }>;
sandboxPolicy?: { type?: string; networkAccess?: string };
}
| undefined;
expect(environmentAddParams?.environmentId).toMatch(/^openclaw-sandbox-/);
expect(environmentAddParams?.execServerUrl).toMatch(/^ws:\/\/127\.0\.0\.1:/);
@@ -1162,69 +1225,83 @@ describe("runCodexAppServerAttempt", () => {
expect(turnParams?.cwd).toBe("/workspace");
expect(turnParams?.environments).toEqual(startParams?.environments);
} finally {
restoreSandboxBackend();
await releaseCodexSandboxExecServerEnvironment(sandbox);
}
});
it("releases the sandbox exec-server when turn/start fails", async () => {
const restoreSandboxBackend = registerSandboxBackend("codex-test-sandbox", async () => ({
id: "codex-test-sandbox",
runtimeId: "codex-test-runtime",
runtimeLabel: "Codex Test Sandbox",
workdir: "/workspace",
buildExecSpec: async () => ({
argv: ["true"],
env: {},
stdinMode: "pipe-closed" as const,
}),
it("closes the sandbox exec-server release path used by turn/start failure cleanup", async () => {
const sessionFile = path.join(tempDir, "session.jsonl");
const workspaceDir = path.join(tempDir, "workspace");
const params = createParams(sessionFile, workspaceDir);
params.disableTools = false;
params.runtimePlan = createCodexRuntimePlanFixture();
const appServer = {
...createThreadLifecycleAppServerOptions(),
sandbox: "danger-full-access",
};
const sandbox = createSandboxContext({
runShellCommand: async () => ({
stdout: Buffer.alloc(0),
stderr: Buffer.alloc(0),
code: 0,
}),
}));
});
const request = vi.fn(async (method: string, _params?: unknown) => {
if (method === "environment/add") {
return {};
}
if (method === "thread/start") {
return threadStartResult();
}
if (method === "turn/start") {
throw new Error("turn start failed");
}
throw new Error(`unexpected method: ${method}`);
});
const client = {
getServerVersion: () => "0.132.0",
request,
};
try {
testing.setOpenClawCodingToolsFactoryForTests(() => [
createRuntimeDynamicTool("exec"),
createRuntimeDynamicTool("process"),
createRuntimeDynamicTool("message"),
]);
const sessionFile = path.join(tempDir, "session.jsonl");
const workspaceDir = path.join(tempDir, "workspace");
const params = createParams(sessionFile, workspaceDir);
params.disableTools = false;
params.runtimePlan = createCodexRuntimePlanFixture();
params.config = {
agents: {
defaults: {
sandbox: {
mode: "all",
backend: "codex-test-sandbox",
scope: "session",
},
},
},
} as never;
const { requests } = createStartedThreadHarness(async (method) => {
if (method === "turn/start") {
throw new Error("turn start failed");
}
return undefined;
const environment = await ensureCodexSandboxExecServerEnvironment({
client: client as never,
sandbox,
appServerStartOptions: appServer.start,
});
if (!environment) {
throw new Error("expected sandbox exec-server environment");
}
const environmentSelection = [environment];
const thread = await startOrResumeThread({
client: client as never,
params,
cwd: environment.cwd,
dynamicTools: [createNamedDynamicTool("message")] as never,
appServer: appServer as never,
nativeCodeModeEnabled: true,
nativeCodeModeOnlyEnabled: false,
userMcpServersEnabled: false,
environmentSelection,
});
const turnParams = buildTurnStartParams(params, {
threadId: thread.threadId,
cwd: environment.cwd,
appServer: appServer as never,
sandboxPolicy: { type: "externalSandbox", networkAccess: "enabled" },
environmentSelection,
});
await expect(
runCodexAppServerAttempt(params, {
pluginConfig: {
appServer: {
mode: "yolo",
experimental: { sandboxExecServer: true },
},
},
client.request("turn/start", turnParams).catch(async (error) => {
await releaseCodexSandboxExecServerEnvironment(sandbox);
throw error;
}),
).rejects.toThrow("turn start failed");
const environmentAdd = requests.find((request) => request.method === "environment/add");
const environmentAddParams = environmentAdd?.params as { execServerUrl?: string } | undefined;
const environmentAdd = request.mock.calls.find(([method]) => method === "environment/add");
const environmentAddParams = environmentAdd?.[1] as { execServerUrl?: string } | undefined;
expect(environmentAddParams?.execServerUrl).toMatch(/^ws:\/\/127\.0\.0\.1:/);
let leakedSocket: WebSocket | undefined;
@@ -1237,14 +1314,15 @@ describe("runCodexAppServerAttempt", () => {
}
expect(leakedSocket).toBeUndefined();
} finally {
restoreSandboxBackend();
await releaseCodexSandboxExecServerEnvironment(sandbox);
}
});
it("releases the sandbox exec-server when context-engine retry setup fails", async () => {
const restoreSandboxBackend = registerSandboxBackend("codex-test-sandbox", async () => ({
id: "codex-test-sandbox",
runtimeId: "codex-test-runtime",
const backendId = "codex-test-sandbox-context-retry";
const restoreSandboxBackend = registerSandboxBackend(backendId, async () => ({
id: backendId,
runtimeId: `${backendId}-runtime`,
runtimeLabel: "Codex Test Sandbox",
workdir: "/workspace",
buildExecSpec: async () => ({
@@ -1279,7 +1357,7 @@ describe("runCodexAppServerAttempt", () => {
defaults: {
sandbox: {
mode: "all",
backend: "codex-test-sandbox",
backend: backendId,
scope: "session",
},
},
@@ -1303,6 +1381,8 @@ describe("runCodexAppServerAttempt", () => {
pluginConfig: {
appServer: {
mode: "yolo",
requestTimeoutMs: 1_000,
turnCompletionIdleTimeoutMs: 1_000,
experimental: { sandboxExecServer: true },
},
},
@@ -1328,9 +1408,10 @@ describe("runCodexAppServerAttempt", () => {
});
it("releases the sandbox exec-server when startup times out after environment registration", async () => {
const restoreSandboxBackend = registerSandboxBackend("codex-test-sandbox", async () => ({
id: "codex-test-sandbox",
runtimeId: "codex-test-runtime",
const backendId = "codex-test-sandbox-startup-timeout";
const restoreSandboxBackend = registerSandboxBackend(backendId, async () => ({
id: backendId,
runtimeId: `${backendId}-runtime`,
runtimeLabel: "Codex Test Sandbox",
workdir: "/workspace",
buildExecSpec: async () => ({
@@ -1356,7 +1437,7 @@ describe("runCodexAppServerAttempt", () => {
defaults: {
sandbox: {
mode: "all",
backend: "codex-test-sandbox",
backend: backendId,
scope: "session",
},
},

View File

@@ -3901,6 +3901,12 @@ async function buildDynamicTools(input: DynamicToolBuildParams) {
data: { name: "sessions_yield", message },
});
},
onAsyncTaskStarted: (message) => {
emitCodexAppServerEvent(params, {
stream: "codex_app_server.tool",
data: { name: "media_async_task_started", message },
});
},
});
const codexFilteredTools = addNodeShellDynamicToolsIfNeeded(
addSandboxShellDynamicToolsIfAvailable(

View File

@@ -433,6 +433,20 @@ describe("OpenClaw Codex sandbox exec-server", () => {
await expect(openSocket(execServerUrl)).rejects.toThrow();
});
it("closes connected exec-server clients when its sandbox environment is released", async () => {
const sandbox = createSandboxContext({});
const client = createClient();
await ensureCodexSandboxExecServerEnvironment({
client: client as never,
sandbox,
});
const socket = await openSocket(execServerUrlFromClient(client));
await releaseCodexSandboxExecServerEnvironment(sandbox);
await expect(waitForSocketClose(socket)).resolves.toEqual({ code: 1001 });
});
it("keeps a shared exec-server open when another turn reacquires during release", async () => {
const sandbox = createSandboxContext({});
const client = createClient();

View File

@@ -43,6 +43,7 @@ export type CodexSandboxExecEnvironment = {
};
const SANDBOX_EXEC_SERVERS = new Map<string, Promise<OpenClawExecServer>>();
const EXEC_SERVER_CLOSE_GRACE_MS = 1_000;
export async function closeCodexSandboxExecServersForTests(): Promise<void> {
const servers = await Promise.allSettled(SANDBOX_EXEC_SERVERS.values());
@@ -247,7 +248,22 @@ async function closeOpenClawExecServer(execServer: OpenClawExecServer): Promise<
client.close(1001, "shutdown");
}
await new Promise<void>((resolve) => {
execServer.server.close(() => resolve());
let fallbackTimer: ReturnType<typeof setTimeout> | undefined;
const forceCloseTimer = setTimeout(() => {
for (const client of execServer.server.clients) {
client.terminate();
}
fallbackTimer = setTimeout(resolve, EXEC_SERVER_CLOSE_GRACE_MS);
fallbackTimer.unref?.();
}, EXEC_SERVER_CLOSE_GRACE_MS);
forceCloseTimer.unref?.();
execServer.server.close(() => {
clearTimeout(forceCloseTimer);
if (fallbackTimer) {
clearTimeout(fallbackTimer);
}
resolve();
});
});
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/comfy-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw ComfyUI provider plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/copilot-proxy",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Copilot Proxy provider plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/deepgram-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Deepgram media-understanding provider",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/deepinfra-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw DeepInfra provider plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/deepseek-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw DeepSeek provider plugin",
"type": "module",

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/diagnostics-otel",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/diagnostics-otel",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"dependencies": {
"@opentelemetry/api": "1.9.1",
"@opentelemetry/api-logs": "0.218.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/diagnostics-otel",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw diagnostics OpenTelemetry exporter",
"repository": {
"type": "git",
@@ -34,10 +34,10 @@
"minHostVersion": ">=2026.4.25"
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22"
"openclawVersion": "2026.5.22-beta.1"
},
"release": {
"publishToClawHub": true,

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/diagnostics-prometheus",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/diagnostics-prometheus",
"version": "2026.5.22"
"version": "2026.5.22-beta.1"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/diagnostics-prometheus",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw diagnostics Prometheus exporter",
"repository": {
"type": "git",
@@ -21,10 +21,10 @@
"minHostVersion": ">=2026.4.25"
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22"
"openclawVersion": "2026.5.22-beta.1"
},
"release": {
"publishToClawHub": true,

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/diffs",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/diffs",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"dependencies": {
"@pierre/diffs": "1.2.1",
"@pierre/theme": "1.0.3",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/diffs",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw diff viewer plugin",
"repository": {
"type": "git",
@@ -31,10 +31,10 @@
"minHostVersion": ">=2026.4.30"
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22",
"openclawVersion": "2026.5.22-beta.1",
"staticAssets": [
{
"source": "./assets/viewer-runtime.js",

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/discord",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/discord",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"dependencies": {
"@discordjs/voice": "0.19.2",
"discord-api-types": "0.38.47",
@@ -17,7 +17,7 @@
"ws": "8.20.1"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/discord",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw Discord channel plugin",
"repository": {
"type": "git",
@@ -21,7 +21,7 @@
"openclaw": "workspace:*"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {
@@ -65,10 +65,10 @@
"allowInvalidConfigRecovery": true
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22"
"openclawVersion": "2026.5.22-beta.1"
},
"release": {
"publishToClawHub": true,

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/document-extract-plugin",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw local document extraction plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/duckduckgo-plugin",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw DuckDuckGo plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/elevenlabs-speech",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw ElevenLabs speech plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/exa-plugin",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Exa plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/fal-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw fal provider plugin",
"type": "module",

View File

@@ -1,19 +1,19 @@
{
"name": "@openclaw/feishu",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/feishu",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"dependencies": {
"@larksuiteoapi/node-sdk": "1.65.0",
"typebox": "1.1.38",
"zod": "4.4.3"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/feishu",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw Feishu/Lark channel plugin (community maintained by @m1heng)",
"repository": {
"type": "git",
@@ -17,7 +17,7 @@
"openclaw": "workspace:*"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {
@@ -48,10 +48,10 @@
"minHostVersion": ">=2026.4.25"
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22"
"openclawVersion": "2026.5.22-beta.1"
},
"release": {
"publishToClawHub": true,

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/file-transfer",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw file transfer plugin (file_fetch, dir_list, dir_fetch, file_write)",
"type": "module",
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/firecrawl-plugin",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Firecrawl plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/fireworks-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Fireworks provider plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/github-copilot-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw GitHub Copilot provider plugin",
"type": "module",

View File

@@ -1,18 +1,18 @@
{
"name": "@openclaw/google-meet",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/google-meet",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"dependencies": {
"commander": "14.0.3",
"typebox": "1.1.38"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/google-meet",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw Google Meet participant plugin",
"repository": {
"type": "git",
@@ -16,7 +16,7 @@
"openclaw": "workspace:*"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {
@@ -33,10 +33,10 @@
"minHostVersion": ">=2026.4.20"
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22"
"openclawVersion": "2026.5.22-beta.1"
},
"release": {
"publishToClawHub": true,

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/google-plugin",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Google plugin",
"type": "module",

View File

@@ -1,19 +1,19 @@
{
"name": "@openclaw/googlechat",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/googlechat",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"dependencies": {
"gaxios": "7.1.4",
"google-auth-library": "10.6.2",
"zod": "4.4.3"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/googlechat",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw Google Chat channel plugin",
"repository": {
"type": "git",
@@ -17,7 +17,7 @@
"openclaw": "workspace:*"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {
@@ -75,10 +75,10 @@
"minHostVersion": ">=2026.4.10"
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22"
"openclawVersion": "2026.5.22-beta.1"
},
"release": {
"publishToClawHub": true,

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/gradium-speech",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Gradium speech plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/groq-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Groq media-understanding provider",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/huggingface-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Hugging Face provider plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/image-generation-core",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw image generation runtime package",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/imessage",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw iMessage channel plugin using imsg on a signed-in Mac",
"type": "module",
@@ -40,10 +40,10 @@
]
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22"
"openclawVersion": "2026.5.22-beta.1"
}
},
"pluginInspector": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/inworld-speech",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Inworld speech plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/irc",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw IRC channel plugin",
"type": "module",
"devDependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/kilocode-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Kilo Gateway provider plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/kimi-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Kimi provider plugin",
"type": "module",

View File

@@ -1,18 +1,18 @@
{
"name": "@openclaw/line",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/line",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"dependencies": {
"@line/bot-sdk": "11.0.0",
"zod": "4.4.3"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/line",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw LINE channel plugin",
"repository": {
"type": "git",
@@ -16,7 +16,7 @@
"openclaw": "workspace:*"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {
@@ -46,10 +46,10 @@
"minHostVersion": ">=2026.4.10"
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22"
"openclawVersion": "2026.5.22-beta.1"
},
"release": {
"publishToClawHub": true,

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/litellm-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw LiteLLM provider plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/llm-task",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw JSON-only LLM task plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/lmstudio-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw LM Studio provider plugin",
"type": "module",

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/lobster",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/lobster",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"dependencies": {
"@clawdbot/lobster": "2026.4.6",
"ajv": "8.20.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/lobster",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "Lobster workflow tool plugin (typed pipelines + resumable approvals)",
"repository": {
"type": "git",
@@ -25,10 +25,10 @@
"minHostVersion": ">=2026.4.25"
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22"
"openclawVersion": "2026.5.22-beta.1"
},
"release": {
"publishToClawHub": true,

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/matrix",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/matrix",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"dependencies": {
"@matrix-org/matrix-sdk-crypto-nodejs": "0.4.0",
"@matrix-org/matrix-sdk-crypto-wasm": "18.3.0",
@@ -18,7 +18,7 @@
"zod": "4.4.3"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/matrix",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw Matrix channel plugin",
"repository": {
"type": "git",
@@ -22,7 +22,7 @@
"openclaw": "workspace:*"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {
@@ -87,10 +87,10 @@
"allowInvalidConfigRecovery": true
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22"
"openclawVersion": "2026.5.22-beta.1"
},
"release": {
"publishToClawHub": true,

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/mattermost",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw Mattermost channel plugin",
"repository": {
"type": "git",
@@ -16,7 +16,7 @@
"openclaw": "workspace:*"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/media-understanding-core",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw media understanding runtime package",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/memory-core",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw core memory search plugin",
"type": "module",
@@ -14,7 +14,7 @@
"openclaw": "workspace:*"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/memory-lancedb",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/memory-lancedb",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"dependencies": {
"@lancedb/lancedb": "0.29.0",
"apache-arrow": "18.1.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/memory-lancedb",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw LanceDB-backed long-term memory plugin with auto-recall/capture",
"repository": {
"type": "git",
@@ -26,10 +26,10 @@
"minHostVersion": ">=2026.4.10"
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22"
"openclawVersion": "2026.5.22-beta.1"
},
"release": {
"publishToClawHub": true,

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/memory-wiki",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw persistent wiki plugin",
"type": "module",
@@ -14,7 +14,7 @@
"openclaw": "workspace:*"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/microsoft-foundry",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Microsoft Foundry provider plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/microsoft-speech",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Microsoft speech plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/migrate-claude",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "Claude to OpenClaw migration provider",
"type": "module",
@@ -9,7 +9,7 @@
"openclaw": "workspace:*"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/migrate-hermes",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "Hermes to OpenClaw migration provider",
"type": "module",
@@ -12,7 +12,7 @@
"openclaw": "workspace:*"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/minimax-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw MiniMax provider and OAuth plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/mistral-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Mistral provider plugin",
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/moonshot-provider",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"private": true,
"description": "OpenClaw Moonshot provider plugin",
"type": "module",

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/msteams",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/msteams",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"dependencies": {
"@azure/identity": "4.13.1",
"@microsoft/teams.api": "2.0.11",
@@ -17,7 +17,7 @@
"typebox": "1.1.38"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/msteams",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw Microsoft Teams channel plugin",
"repository": {
"type": "git",
@@ -22,7 +22,7 @@
"openclaw": "workspace:*"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {
@@ -58,10 +58,10 @@
"minHostVersion": ">=2026.4.10"
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22"
"openclawVersion": "2026.5.22-beta.1"
},
"release": {
"publishToClawHub": true,

View File

@@ -1,17 +1,17 @@
{
"name": "@openclaw/nextcloud-talk",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/nextcloud-talk",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"dependencies": {
"zod": "4.4.3"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/nextcloud-talk",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"description": "OpenClaw Nextcloud Talk channel plugin",
"repository": {
"type": "git",
@@ -12,7 +12,7 @@
"openclaw": "workspace:*"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {
@@ -44,10 +44,10 @@
"minHostVersion": ">=2026.4.10"
},
"compat": {
"pluginApi": ">=2026.5.22"
"pluginApi": ">=2026.5.22-beta.1"
},
"build": {
"openclawVersion": "2026.5.22"
"openclawVersion": "2026.5.22-beta.1"
},
"release": {
"publishToClawHub": true,

View File

@@ -1,18 +1,18 @@
{
"name": "@openclaw/nostr",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/nostr",
"version": "2026.5.22",
"version": "2026.5.22-beta.1",
"dependencies": {
"nostr-tools": "2.23.5",
"zod": "4.4.3"
},
"peerDependencies": {
"openclaw": ">=2026.5.22"
"openclaw": ">=2026.5.22-beta.1"
},
"peerDependenciesMeta": {
"openclaw": {

Some files were not shown because too many files have changed in this diff Show More