Compare commits

..

94 Commits

Author SHA1 Message Date
Dallin Romney
369f2885d2 test: keep native QA evidence out of parity tiers 2026-06-18 17:45:44 -07:00
Dallin Romney
ab8db1c6b6 test: align folded QA coverage ids 2026-06-18 17:26:18 -07:00
Dallin Romney
0ccc78b68d test: trim folded QA Lab script cruft 2026-06-18 17:26:18 -07:00
Dallin Romney
68da7fea24 test: relax QA native scenario catalog inventory 2026-06-18 17:26:18 -07:00
Dallin Romney
33bf13a6e4 test: remove folded HTTP API script tests 2026-06-18 17:26:18 -07:00
Dallin Romney
ae73322774 test: fold HTTP API script proof into QA Lab 2026-06-18 17:26:18 -07:00
Dallin Romney
e12cf72b17 Standardize QA coverage IDs on dotted names (#94702)
* fix: standardize qa coverage ids

* test: avoid qa coverage id assertion spread
2026-06-18 17:25:26 -07:00
JackWu
e9e44bf83c fix(scripts): avoid mutating tracked auth-monitor template during setup (#53920)
* fix(scripts): render auth monitor unit before install

Render the auth monitor service into temporary files instead of editing the tracked template. Quote the generated ExecStart safely, including spaces and literal dollars, then atomically install the rendered unit.

* fix(scripts): avoid mutating tracked auth-monitor template during setup

* fix(scripts): avoid mutating tracked auth-monitor template during setup

* fix(scripts): avoid mutating tracked auth-monitor template during setup

---------

Co-authored-by: JackWuGlobal <JackWuGlobal@users.noreply.github.com>
Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
2026-06-19 08:24:16 +08:00
Vincent Koc
843b1d6fbb fix(e2e): forward install session limits 2026-06-19 02:21:10 +02:00
Vincent Koc
09b56592d2 fix(e2e): forward code-mode client limits 2026-06-19 02:19:27 +02:00
Vincent Koc
701687efa3 fix(e2e): validate install e2e wrapper knobs 2026-06-19 02:15:58 +02:00
Vincent Koc
d8cc16a3e2 Merge branch 'main' of https://github.com/openclaw/openclaw
* 'main' of https://github.com/openclaw/openclaw: (82 commits)
  fix(e2e): validate chat tools body limit
  fix(e2e): honor chat tools body limit
  fix(e2e): validate chat tools timeout
  fix(e2e): give cleanup smoke build heap headroom
  fix(e2e): validate plugin lifecycle limits
  refactor(auto-reply): add lifecycle storage seams (#93685)
  fix: preserve pending subagent completion announces (#94349)
  fix(e2e): validate plugin log limits before setup
  fix(e2e): validate codex media timeout
  fix(e2e): validate fixture log limits
  fix(e2e): validate cleanup log limits
  fix(e2e): validate docker log limits
  fix(live): validate docker pids limits
  fix(e2e): validate docker pids limits
  test: fold channel message flows into qa e2e (#93174)
  fix(e2e): validate docker build limits
  Prevent Codex thread rotation from losing next-step context (#94093)
  fix(e2e): validate fixture cleanup interval
  fix(agents): correct claw-score validation workflow
  fix(e2e): validate log tail limits
  ...
2026-06-19 08:14:35 +08:00
Vincent Koc
7f894ba2be fix(e2e): validate chat tools body limit 2026-06-19 02:07:32 +02:00
Vincent Koc
e5de09f96a fix(e2e): honor chat tools body limit 2026-06-19 01:59:12 +02:00
Vincent Koc
2a0e63d12b fix(e2e): validate chat tools timeout 2026-06-19 01:51:19 +02:00
Vincent Koc
e3bab80bda fix(e2e): give cleanup smoke build heap headroom 2026-06-19 01:50:54 +02:00
Vincent Koc
7207072436 fix(e2e): validate plugin lifecycle limits 2026-06-19 01:43:24 +02:00
Josh Lehman
49e6f5a524 refactor(auto-reply): add lifecycle storage seams (#93685)
* refactor(auto-reply): add lifecycle storage seams

* fix(auto-reply): remove unused transcript replay shim
2026-06-18 16:40:27 -07:00
Sally O'Malley
95c87e31e2 fix: preserve pending subagent completion announces (#94349)
Signed-off-by: sallyom <somalley@redhat.com>
2026-06-18 19:38:11 -04:00
Vincent Koc
0d2102d247 fix(e2e): validate plugin log limits before setup 2026-06-19 01:31:33 +02:00
Vincent Koc
55323103b9 fix(e2e): validate codex media timeout 2026-06-19 01:24:12 +02:00
Vincent Koc
239b4de6af fix(e2e): validate fixture log limits 2026-06-19 01:17:35 +02:00
Vincent Koc
a7b52ecad9 fix(e2e): validate cleanup log limits 2026-06-19 01:08:42 +02:00
Vincent Koc
bb44c5326e fix(e2e): validate docker log limits 2026-06-19 01:02:59 +02:00
Vincent Koc
4764258b3f fix(live): validate docker pids limits 2026-06-19 00:54:57 +02:00
Vincent Koc
6af1b97b1d fix(e2e): validate docker pids limits 2026-06-19 00:46:17 +02:00
Dallin Romney
4ca0e52d0e test: fold channel message flows into qa e2e (#93174)
* test: fold channel flows into qa e2e

* test: keep channel flow skill pointed at qa

* test: move channel flow proof under telegram
2026-06-18 15:45:33 -07:00
Vincent Koc
37eea55afa fix(e2e): validate docker build limits 2026-06-19 00:35:49 +02:00
VACInc
ea76a45917 Prevent Codex thread rotation from losing next-step context (#94093)
Merged via squash.

Prepared head SHA: 1f3ced8f63
Maintainer decision: `checks-node-core-tooling` is an unrelated baseline/tooling failure; PR-relevant CI and real behavior proof passed.

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
2026-06-18 15:33:48 -07:00
Vincent Koc
84bcdaa983 fix(e2e): validate fixture cleanup interval 2026-06-19 00:29:25 +02:00
Vincent Koc
4ac192deef fix(agents): correct claw-score validation workflow 2026-06-19 00:26:35 +02:00
Vincent Koc
3c9cf2d583 fix(e2e): validate log tail limits 2026-06-19 00:18:39 +02:00
Dallin Romney
c4ae2be947 fix: taxonomy coverage id cleanup (#94304)
* fix: split taxonomy coverage id features

* fix: clean taxonomy feature row names

* docs: clarify taxonomy coverage id semantics

* docs: tighten coverage id guidance

* fix: keep taxonomy features product shaped

* fix: narrow sdk artifact coverage bundle

* fix: name taxonomy coverage ids clearly

* fix: polish taxonomy feature descriptions
2026-06-18 15:16:58 -07:00
Vincent Koc
27310bfa34 fix(e2e): validate docker e2e ports 2026-06-19 00:09:47 +02:00
Xavier Coulon
fbc12e0879 fix(slack): stop leaking bot token into /api/auth.test request body (#94574)
* fix(slack): stop leaking bot token into /api/auth.test request body

The bot token is already passed as an `Authorization` header,
so we don't need to send it in the request body when calling `/api/auth.test`.

See [Slack API documentation](https://api.slack.com/methods/auth.test).

Also, showing with `curl` that the bot token is not needed in the request body when passed as an `Authorization` header when calling `/api/auth.test`:
```
curl -X POST https://slack.com:443/api/auth.test -H "Authorization: Bearer xoxb-..."
{"ok":true,"url":"https://xcoulonworkspace.slack.com/","team":"xcoulon",...}
```

Signed-off-by: Xavier Coulon <xcoulon@redhat.com>

* add test for slack auth.test token handling

verify that the bot token is not passed in the request body when calling `/api/auth.test`.

Signed-off-by: Xavier Coulon <xcoulon@redhat.com>

---------

Signed-off-by: Xavier Coulon <xcoulon@redhat.com>
2026-06-18 18:09:37 -04:00
Vincent Koc
73cdb78a1e fix(sdk): refresh plugin api baseline hash 2026-06-19 00:01:15 +02:00
Vincent Koc
0df60ad306 fix(e2e): validate docker resource limits 2026-06-19 00:00:42 +02:00
Vincent Koc
9928516a78 fix(codex): deliver native subagent idle results 2026-06-18 23:41:34 +02:00
Josh Lehman
7845182410 clawdbot-d02.1.9.1.39: add task session registry maintenance seam (#93734) 2026-06-18 14:36:10 -07:00
Vincent Koc
aba6f7ad21 fix(live): validate model sweep limits 2026-06-18 23:33:44 +02:00
Vincent Koc
5570a10bf4 refactor(auth): remove stale external auth persist wrapper 2026-06-19 05:26:31 +08:00
Vincent Koc
98857235d5 fix(live): validate gateway model limits 2026-06-18 23:26:21 +02:00
Vincent Koc
39e9336d40 test(scripts): match installer e2e env validation 2026-06-18 23:23:24 +02:00
Vincent Koc
392f5b75bf fix(e2e): validate kitchen sink fixture wait attempts 2026-06-18 23:21:28 +02:00
Vincent Koc
a98bfdb2b7 refactor(agents): remove stale wrapper exports 2026-06-19 05:18:25 +08:00
Vincent Koc
34d402f53c fix(e2e): validate plugin fixture stop attempts 2026-06-18 23:17:00 +02:00
Vincent Koc
1faf8175e4 fix(e2e): validate onboard gateway wait attempts 2026-06-18 23:12:41 +02:00
Vincent Koc
fdb042b9ce refactor(providers): remove stale primary model helper 2026-06-19 05:10:15 +08:00
Colin Johnson
d5a27b0b96 test: add QA Lab UX Matrix evidence scenario (#94306)
* test: add qa lab ux matrix script scenario

* fix(qa-lab): annotate UX Matrix producer catch callback as unknown for oxlint

---------

Co-authored-by: Dallin Romney <dallinromney@gmail.com>
2026-06-18 14:10:06 -07:00
Vincent Koc
9328f4a675 fix(e2e): validate bun smoke timeout env 2026-06-18 23:07:22 +02:00
Vincent Koc
75df29c215 fix(install): validate install e2e agent env 2026-06-18 23:03:34 +02:00
Vincent Koc
bf8ac0d96d refactor(cli): remove stale command group helpers 2026-06-19 05:02:54 +08:00
Vincent Koc
bfb47a03b3 fix(install): validate install smoke timing env 2026-06-18 22:57:17 +02:00
Vincent Koc
a93fc87e2c refactor(cli): keep relay stream helpers test-local 2026-06-19 04:53:59 +08:00
Vincent Koc
cc3d346c15 fix(e2e): validate upgrade survivor budgets 2026-06-18 22:52:19 +02:00
Vincent Koc
a8d60d352e refactor(cli): remove stale adapter helpers 2026-06-19 04:44:51 +08:00
NianJiu
1bfa2787b5 fix(exec): resume agent turn for native chat exec approvals (#93949)
* fix(exec): resume agent turn for native chat exec approvals (issue #93918)

Extend the inline approval-pending path that PR #85239 added for webchat to
every bundled chat channel that ships an `approval-handler.runtime`
adapter (Telegram, Discord, Slack, Signal, WhatsApp, iMessage, Matrix,
Google Chat, QQ Bot, plus webchat). When the originating turn can be
approved in the same chat, the gateway resolves the approval in place and
the agent waits inline for the command output instead of terminating the
run on the "approval-pending" tool result.

Before this fix, native chat approvals landed in the fire-and-forget
`sendExecApprovalFollowup` path. The followup either failed silently
against the agent dispatch and fell through to a direct delivery to the
operator, or never reached the agent at all; either way the model never
saw an "Exec running / Exec finished / Exec denied" event. The operator
had to send a follow-up message to recover the turn, and a new approval
was minted because the original run had already ended.

The change:

- Introduces `NATIVE_APPROVAL_CHANNELS` and `isNativeApprovalChannel`
  in `src/utils/message-channel-constants.ts`, listing the channels that
  ship a native chat approval client. `webchat` is included so the
  single-channel check inside `shouldAwaitGatewayApprovalInline` can
  move from "this one id" to "any native approval client".
- Replaces the `INTERNAL_MESSAGE_CHANNEL` equality check in
  `shouldAwaitGatewayApprovalInline` with `isNativeApprovalChannel`,
  preserving the `approvalFollowupMode` opt-out and the existing
  `unavailableReason === null` gate.
- Adds unit tests asserting inline resolution and inline denial for
  every native approval channel, plus a regression test that
  non-native channels (e.g. feishu) and explicit `approvalFollowupMode`
  settings still take the fire-and-forget path.
- Adds a `NATIVE_APPROVAL_CHANNELS` test in
  `src/utils/message-channel.test.ts` to lock the membership and the
  negative cases.

Refs https://github.com/openclaw/openclaw/issues/93918

* fix(lint): restore InternalMessageChannel type export lost during rebase

Rebase on upstream/main dropped the InternalMessageChannel type alias
from message-channel-constants.ts, breaking the plugin-sdk boundary
.dts check ('has no exported member named InternalMessageChannel').
message-channel.ts was also re-importing the type only to re-export
it, triggering the oxlint no-unused-vars rule.

- Re-add 'export type InternalMessageChannel = typeof INTERNAL_MESSAGE_CHANNEL'
  in message-channel-constants.ts so the public re-export is valid.
- Drop the redundant 'type InternalMessageChannel' from the local
  import in message-channel.ts; the value-side import is what the
  file body actually needs.

* test(exec): align native approval routing expectations
2026-06-18 16:41:04 -04:00
Vincent Koc
e385f6663a fix(live): validate docker setup timeouts 2026-06-18 22:39:43 +02:00
Vincent Koc
76bdb025d6 refactor(cli): remove stale path policy helpers 2026-06-19 04:37:29 +08:00
Vincent Koc
d2e36a176d fix(e2e): validate live plugin tool limits 2026-06-18 22:30:59 +02:00
Josh Lehman
b637414871 fix: add plugin host session cleanup seam (#93733)
* fix: add plugin host session cleanup seam (clawdbot-d02.1.9.1.38)

* test: update session accessor writer ratchet
2026-06-18 13:29:39 -07:00
Vincent Koc
aa39600793 refactor(agents): remove stale tool helpers 2026-06-19 04:28:18 +08:00
Vincent Koc
61b116d597 fix(e2e): validate plugin update timeout seconds 2026-06-18 22:23:23 +02:00
Vincent Koc
033162f209 refactor(channels): remove stale discovery helpers 2026-06-19 04:19:22 +08:00
Dallin Romney
dfd8a2220b test(scripts): route temp-dir helper importers for store.sqlite and status.scan tests (#94681) 2026-06-18 13:15:40 -07:00
Vincent Koc
74ad4f592a fix(ci): route Windows proof away from Linux Testbox 2026-06-18 22:09:58 +02:00
Vincent Koc
a14b1e05e5 refactor(channels): remove stale helper exports 2026-06-19 04:07:36 +08:00
Vincent Koc
8b63a3d551 fix(e2e): validate openwebui docker timeouts 2026-06-18 22:02:43 +02:00
Vincent Koc
f4e9a6e047 refactor(channels): remove stale bundled channel helpers 2026-06-19 03:52:49 +08:00
Vincent Koc
2ae84f75ef fix(e2e): reject invalid mcp code-mode docker ports 2026-06-18 21:47:18 +02:00
Vincent Koc
dca17477dc refactor(media): remove stale completion wake wrappers 2026-06-19 03:43:39 +08:00
Vincent Koc
7f1fa65399 fix(e2e): reject declared oversized probe bodies 2026-06-18 21:37:07 +02:00
Vincent Koc
b6a06f0e49 refactor(sandbox): remove stale bridge helpers 2026-06-19 03:34:44 +08:00
Vincent Koc
9501d4dec2 fix(e2e): reject invalid openwebui docker ports 2026-06-18 21:31:46 +02:00
Vincent Koc
d9397e5b9b fix(e2e): cancel stalled kitchen sink response streams 2026-06-18 21:27:08 +02:00
Vincent Koc
d9d7766a41 fix(scripts): ignore loose package content length headers 2026-06-18 21:23:41 +02:00
Vincent Koc
0771ac8563 refactor(core): remove unused helper wrappers 2026-06-19 03:22:07 +08:00
Vincent Koc
906174bff1 fix(scripts): ignore loose audit content length headers 2026-06-18 21:20:26 +02:00
Colin Johnson
c677424edb qa-lab: add evidence artifact gallery (#94283)
* qa-lab: add evidence artifact gallery

* qa-lab: harden evidence gallery artifacts

* qa-lab: share evidence gallery view types

* qa-lab: disable evidence preview caching

* refactor(qa-lab): resolve evidence artifacts once and trim gallery render/test duplication

* fix(qa-lab): build evidence model before sending /api/evidence success headers

---------

Co-authored-by: Dallin Romney <dallinromney@gmail.com>
2026-06-18 12:17:46 -07:00
Vincent Koc
ea4ddb2eb5 fix(e2e): ignore loose rpc content length headers 2026-06-18 21:14:22 +02:00
Vincent Koc
f19c5f6b2f fix(release): bound cross-os loopback port probes 2026-06-18 21:11:46 +02:00
Vincent Koc
1e83f42a64 refactor(agents): remove unused Claude CLI credential writers 2026-06-19 03:10:14 +08:00
Vincent Koc
4c9b4c32ef fix(scripts): ignore loose content length headers 2026-06-18 21:05:16 +02:00
Vincent Koc
4fc5cf4579 fix(scripts): reject unsafe startup memory timeouts 2026-06-18 21:00:03 +02:00
Vincent Koc
8f8162704d refactor(gateway): remove stale restart sentinel wake predicate 2026-06-19 02:58:16 +08:00
Vincent Koc
f381dca15b fix(e2e): reject loose docker stats CPU samples 2026-06-18 20:57:55 +02:00
Vincent Koc
9ab9469d04 fix(e2e): reject unsafe bundled runtime limits 2026-06-18 20:54:56 +02:00
Vincent Koc
a2f5ac82d5 fix(e2e): reject loose credential numeric limits 2026-06-18 20:51:36 +02:00
Vincent Koc
7b7e40cb0e refactor(gateway): remove duplicate artifact collector 2026-06-19 02:50:22 +08:00
Vincent Koc
e1c2926628 fix(e2e): reject loose telegram credential limits 2026-06-18 20:47:52 +02:00
Vincent Koc
cebe5cb94a fix(e2e): reject invalid client gateway ports 2026-06-18 20:46:11 +02:00
Vincent Koc
0b14724c87 refactor(gateway): remove unused connection auth facade 2026-06-19 02:37:30 +08:00
Vincent Koc
e879a67bf7 refactor(gateway): remove unused skills reload predicate 2026-06-19 02:34:48 +08:00
Vincent Koc
53bb55e023 fix(e2e): reject invalid config writer ports 2026-06-18 20:33:31 +02:00
433 changed files with 10949 additions and 5379 deletions

View File

@@ -1,44 +1,34 @@
---
name: channel-message-flows
description: "Use when previewing local channel message flow fixtures."
description: "Use when running QA Lab channel message flow evidence."
---
# Channel Message Flows
Use this from the OpenClaw repo root to send canned channel preview flows while iterating on message UX. These are real sends/edits/deletes against the configured channel target.
Use this from the OpenClaw repo root to run the QA Lab evidence for Telegram
draft/final delivery sequencing. This skill no longer launches a standalone
script; the behavior is owned by the QA scenario and its Vitest-backed e2e test.
## Telegram
## QA Scenario
Native Telegram `sendMessageDraft` tool progress, then a final answer:
Run the scenario through QA Lab:
```bash
node --import tsx scripts/dev/channel-message-flows.ts \
--channel telegram \
--target <telegram-chat-id> \
--flow working-final \
--duration-ms 20000
pnpm openclaw qa suite --scenario channel-message-flows
```
Thinking preview, then a final answer:
Run the focused e2e test directly in a Codex worktree:
```bash
node --import tsx scripts/dev/channel-message-flows.ts \
--channel telegram \
--target <telegram-chat-id> \
--flow thinking-final
node scripts/run-vitest.mjs extensions/telegram/src/channel-message-flows.qa.e2e.test.ts
```
## Options
## References
- `--account <accountId>`: Telegram account id when not using the default.
- `--thread-id <id>`: Telegram forum topic/message thread id.
- `--delay-ms <ms>`: Override preview update cadence.
- `--duration-ms <ms>`: Simulated working duration for `working-final`.
- `--final-text <text>`: Override the durable final message.
- `qa/scenarios/channels/channel-message-flows.yaml`
- `extensions/telegram/src/channel-message-flows.qa.e2e.test.ts`
- `extensions/telegram/src/test-support/channel-message-flows.ts`
## Notes
- `--target` is the numeric Telegram chat id.
- `working-final` exercises native Telegram `sendMessageDraft` with static `Working` status and sample tool progress.
- `thinking-final` exercises formatted `Thinking` reasoning preview clearing before the final answer.
- Only `--channel telegram` is implemented for now.
The scenario covers `channels.streaming` as primary evidence and records
secondary coverage for thread preservation, delivery ordering, and reasoning
preview visibility.

View File

@@ -16,11 +16,8 @@ This skill owns the operational workflow for:
- `taxonomy.yaml`
- `docs/maturity-scores.yaml`
- `docs/maturity-scorecard.md`
- `docs/taxonomy.md`
- `docs/taxonomy-outline.md`
- `scripts/render-maturity-docs.mjs`
- `.github/workflows/maturity-scorecard.yml`
- `docs/concepts/qa-e2e-automation.md`
- `qa/scenarios/index.yaml`
Keep person-specific, maintainer-private, Discord archive, and discrawl facts
out of this repo. If a score needs private evidence, use the redacted
@@ -31,12 +28,21 @@ out of this repo. If a score needs private evidence, use the redacted
- `taxonomy.yaml` is the hand-edited source of truth for surfaces, levels,
QA profiles, categories, feature coverage IDs, docs refs, LTS overrides, and
completeness-instruction paths.
- Feature `coverageIds` are ANDed proof targets, not aliases. A feature may
list multiple IDs when each ID proves part of one capability.
- Coverage IDs use dotted `namespace.behavior` form, with lowercase
alphanumeric/dash segments. Profile, surface, and category IDs may remain
dashed or dotted.
- Keep categories and feature names unique, product-shaped, and broader than raw
coverage IDs. Do not promote generic IDs into standalone feature names.
- Avoid duplicate coverage-ID bundles under different feature names in one
category.
- `docs/maturity-scores.yaml` is the aggregate score source committed in this
repo. It is the only committed score data; do not add generated inventory
directories.
- `docs/maturity-scorecard.md`, `docs/taxonomy.md`, and
`docs/taxonomy-outline.md` are deterministic docs generated from the root
taxonomy and aggregate score source.
- There is no committed maturity-doc renderer or `pnpm maturity:*` script in
this repo. Do not invent generated scorecard files; update the source YAML
and current docs directly.
- `qa-evidence.json` artifacts provide per-run QA scorecard evidence. They can
enrich generated artifact docs, but they are not committed as inventory.
@@ -44,22 +50,28 @@ out of this repo. If a score needs private evidence, use the redacted
Run from the openclaw repo root.
Render committed docs:
Validate YAML structure after source edits:
```bash
pnpm maturity:render
node <<'NODE'
const fs = require("node:fs");
const YAML = require("yaml");
for (const file of ["taxonomy.yaml", "docs/maturity-scores.yaml", "qa/scenarios/index.yaml"]) {
YAML.parse(fs.readFileSync(file, "utf8"));
}
NODE
```
Check generated docs are current:
Check docs when touching docs prose:
```bash
pnpm maturity:check
pnpm check:docs
```
Render an evidence-enriched docs artifact from downloaded QA artifacts:
Run focused QA/profile checks when changing coverage IDs or profile membership:
```bash
pnpm maturity:render -- --evidence-dir .artifacts/maturity-evidence --output-dir .artifacts/maturity-docs
pnpm openclaw qa coverage --json
```
## Scoring Workflow
@@ -75,13 +87,13 @@ When asked to score or refresh a surface:
discrawl or unredacted private archives.
5. Update `docs/maturity-scores.yaml` only when the score change is backed by
public or redacted artifact evidence.
6. Run `pnpm maturity:render`.
7. Run `pnpm maturity:check`.
6. Run the YAML validation command from this skill.
7. Run `pnpm check:docs` if docs prose changed, and focused QA coverage checks
if coverage IDs or profile membership changed.
For subjective score changes, make the smallest defensible edit and leave the
evidence path in the PR or task summary. The deterministic renderer owns
Markdown structure; manual prose tweaks belong in taxonomy, score source, or
the renderer rather than in generated docs.
evidence path in the PR or task summary. Keep manual prose in current docs and
keep score data in `docs/maturity-scores.yaml`.
## Default Completeness Process
@@ -158,13 +170,9 @@ Bands:
- `Alpha`: 50-70
- `Experimental`: 0-50
## GitHub Action
The `Maturity scorecard` workflow verifies committed generated docs on PRs and
pushes. Manual dispatch can also download QA artifacts from another workflow run
with `source_run_id` and `artifact_pattern`, render evidence-enriched docs into
`.artifacts/maturity-docs`, and upload them as a GitHub artifact.
## Artifacts
Do not add the maintainer repo's `docs/kevinslin/maturity-scorecard/inventory/`
tree to openclaw. Those generated reports are intentionally replaced here by
short-lived artifact docs and the committed aggregate scorecard pages.
tree to openclaw. Evidence-enriched scorecard outputs belong in short-lived
artifacts, not committed generated docs, unless this repo adds an explicit
renderer/check workflow first.

View File

@@ -2000,7 +2000,7 @@ jobs:
profiles: stable full
- suite_id: native-live-src-gateway-profiles-minimax
label: Native live gateway profiles MiniMax
command: OPENCLAW_LIVE_GATEWAY_PROVIDERS=minimax,minimax-portal OPENCLAW_LIVE_GATEWAY_MODELS=minimax/MiniMax-M2.7,minimax-portal/MiniMax-M2.7 OPENCLAW_LIVE_GATEWAY_MAX_MODELS=2 node .release-harness/scripts/test-live-shard.mjs native-live-src-gateway-profiles
command: OPENCLAW_LIVE_GATEWAY_PROVIDERS=minimax,minimax-portal OPENCLAW_LIVE_GATEWAY_MODELS=minimax/MiniMax-M3,minimax-portal/MiniMax-M3 OPENCLAW_LIVE_GATEWAY_MAX_MODELS=2 node .release-harness/scripts/test-live-shard.mjs native-live-src-gateway-profiles
timeout_minutes: 60
profile_env_only: false
profiles: stable full
@@ -2303,7 +2303,7 @@ jobs:
profiles: stable full
- suite_id: live-gateway-minimax-docker
label: Docker live gateway MiniMax
command: OPENCLAW_LIVE_GATEWAY_PROVIDERS=minimax,minimax-portal OPENCLAW_LIVE_GATEWAY_MODELS=minimax/MiniMax-M2.7,minimax-portal/MiniMax-M2.7 OPENCLAW_LIVE_GATEWAY_MAX_MODELS=2 OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=90000 OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=180000 OPENCLAW_LIVE_DOCKER_REPO_ROOT="$GITHUB_WORKSPACE" timeout --foreground --kill-after=30s 35m bash .release-harness/scripts/test-live-gateway-models-docker.sh
command: OPENCLAW_LIVE_GATEWAY_PROVIDERS=minimax,minimax-portal OPENCLAW_LIVE_GATEWAY_MODELS=minimax/MiniMax-M3,minimax-portal/MiniMax-M3 OPENCLAW_LIVE_GATEWAY_MAX_MODELS=1 OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=90000 OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=180000 OPENCLAW_LIVE_DOCKER_REPO_ROOT="$GITHUB_WORKSPACE" timeout --foreground --kill-after=30s 35m bash .release-harness/scripts/test-live-gateway-models-docker.sh
timeout_minutes: 40
profile_env_only: false
profiles: stable full

View File

@@ -45,7 +45,7 @@ on:
kova_ref:
description: openclaw/Kova Git ref to install
required: false
default: 4f146016583018bad9e24f8e64a6af5f963bb7ee
default: b63b6f9e20efb23641df00487e982230d81a90ac
type: string
dispatch_id:
description: Optional parent workflow dispatch identifier
@@ -98,7 +98,7 @@ jobs:
live: "true"
include_filters: "scenario:agent-cold-warm-message"
env:
KOVA_REF: ${{ inputs.kova_ref || '4f146016583018bad9e24f8e64a6af5f963bb7ee' }}
KOVA_REF: ${{ inputs.kova_ref || 'b63b6f9e20efb23641df00487e982230d81a90ac' }}
KOVA_HOME: ${{ github.workspace }}/.artifacts/kova/home/${{ matrix.lane }}
PERFORMANCE_HELPER_DIR: ${{ github.workspace }}/.artifacts/performance-workflow
REPORT_DIR: ${{ github.workspace }}/.artifacts/kova/reports/${{ matrix.lane }}

View File

@@ -85,12 +85,22 @@ jobs:
env:
ENABLE_WSL2_FEATURES: ${{ inputs.enable_wsl2_features }}
IMPORT_UBUNTU_WSL2: ${{ inputs.import_ubuntu_wsl2 }}
UBUNTU_WSL_ROOTFS_URL: https://cloud-images.ubuntu.com/wsl/releases/24.04/current/ubuntu-noble-wsl-amd64-wsl.rootfs.tar.gz
run: |
$ErrorActionPreference = "Continue"
$ok = $false
$restartRequired = $false
function Resolve-UbuntuWslRootfsUrl {
$osArch = ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture).ToString().ToLowerInvariant()
switch ($osArch) {
"x64" { $wslArch = "amd64" }
"arm64" { $wslArch = "arm64" }
default { throw "Unsupported Windows architecture for Ubuntu WSL rootfs: $osArch" }
}
Write-Host "ubuntu_wsl_rootfs_arch=$wslArch"
"https://cloud-images.ubuntu.com/wsl/releases/24.04/current/ubuntu-noble-wsl-$wslArch-wsl.rootfs.tar.gz"
}
function Invoke-WslText {
param([string[]] $Arguments)
$output = & wsl.exe @Arguments 2>&1
@@ -143,8 +153,9 @@ jobs:
Write-Host "import_ubuntu_wsl2=true"
$wslRoot = "C:\wsl\UbuntuProbe"
$rootfs = "C:\wsl\ubuntu-noble-wsl.rootfs.tar.gz"
$rootfsUrl = Resolve-UbuntuWslRootfsUrl
New-Item -ItemType Directory -Force -Path @((Split-Path -Parent $rootfs), $wslRoot) | Out-Null
Invoke-WebRequest -Uri $env:UBUNTU_WSL_ROOTFS_URL -OutFile $rootfs -UseBasicParsing
Invoke-WebRequest -Uri $rootfsUrl -OutFile $rootfs -UseBasicParsing
$import = Invoke-WslText -Arguments @("--import", "UbuntuProbe", $wslRoot, $rootfs, "--version", "2")
Write-Host $import.Text
Write-Host "wsl_import_exit=$($import.Code)"

View File

@@ -1,2 +1,2 @@
dd892e0085aa61eb8b85f3e6591039accc9a051af923874499f196ee621c5545 plugin-sdk-api-baseline.json
2ea01cb391f2adc0e1d59400bf245e8e9f110a37d961546e0c7d6685c4054400 plugin-sdk-api-baseline.jsonl
f24065e760a9fafbd2a50962beba4d752b2d6166043170d37cdd6137640e7eef plugin-sdk-api-baseline.json
89a332c206f639d5faef730bac2d23f75751b306419e5dfeae1b731166bbc41c plugin-sdk-api-baseline.jsonl

View File

@@ -57,6 +57,11 @@ the resolved scenarios through `qa suite`. `--surface` and
The resulting `qa-evidence.json` includes a profile scorecard summary with
selected-category counts and missing coverage IDs; the individual evidence
entries remain the source of truth for the tests, coverage roles, and results.
Taxonomy feature coverage IDs are exact proof targets, not aliases. Primary
scenario coverage fulfills matching IDs; secondary coverage stays advisory.
Coverage IDs use dotted `namespace.behavior` form with lowercase
alphanumeric/dash segments; profile, surface, and category IDs may still use
the existing dashed or dotted taxonomy IDs.
Slim evidence omits per-entry `execution` and sets `evidenceMode: "slim"`;
`smoke-ci` defaults to slim, and `--evidence-mode full` restores full entries:

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/alibaba-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"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.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/amazon-bedrock-mantle-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"dependencies": {
"@anthropic-ai/sdk": "0.100.1",
"@aws/bedrock-token-generator": "1.1.0"

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/amazon-bedrock-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Amazon Bedrock provider plugin with model discovery, embeddings, and guardrail support.",
"repository": {
"type": "git",
@@ -28,10 +28,10 @@
"minHostVersion": ">=2026.5.12-beta.1"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"bundledDist": false
},
"release": {

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/anthropic-vertex-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/anthropic-vertex-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"dependencies": {
"@anthropic-ai/vertex-sdk": "0.16.1"
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/anthropic-vertex-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Anthropic Vertex provider plugin for Claude models on Google Vertex AI.",
"repository": {
"type": "git",
@@ -23,10 +23,10 @@
"minHostVersion": ">=2026.5.12-beta.1"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"bundledDist": false
},
"release": {

View File

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

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/arcee-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/arcee-provider",
"version": "2026.6.9-beta.1"
"version": "2026.6.8"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/arcee-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Arcee provider plugin.",
"repository": {
"type": "git",
@@ -21,10 +21,10 @@
"minHostVersion": ">=2026.6.8"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"bundledDist": false
},
"release": {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/cerebras-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/cerebras-provider",
"version": "2026.6.9-beta.1"
"version": "2026.6.8"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/cerebras-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Cerebras provider plugin.",
"repository": {
"type": "git",
@@ -21,10 +21,10 @@
"minHostVersion": ">=2026.6.8"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"bundledDist": false
},
"release": {

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/chutes-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/chutes-provider",
"version": "2026.6.9-beta.1"
"version": "2026.6.8"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/chutes-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Chutes.ai provider plugin.",
"repository": {
"type": "git",
@@ -21,10 +21,10 @@
"minHostVersion": ">=2026.6.8"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"bundledDist": false
},
"release": {

View File

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

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/cloudflare-ai-gateway-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/cloudflare-ai-gateway-provider",
"version": "2026.6.9-beta.1"
"version": "2026.6.8"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/cloudflare-ai-gateway-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Cloudflare AI Gateway provider plugin.",
"repository": {
"type": "git",
@@ -21,10 +21,10 @@
"minHostVersion": ">=2026.6.8"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"bundledDist": false
},
"release": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/codex-supervisor",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"private": true,
"description": "OpenClaw Codex app-server fleet supervision plugin.",
"type": "module",

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/codex",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/codex",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"dependencies": {
"@openai/codex": "0.139.0",
"typebox": "1.1.39",

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/codex",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Codex app-server harness and model provider plugin with a Codex-managed GPT catalog.",
"repository": {
"type": "git",
@@ -34,10 +34,10 @@
]
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1"
"openclawVersion": "2026.6.8"
},
"release": {
"publishToClawHub": true,

View File

@@ -2,6 +2,7 @@
import type { AgentMessage } from "openclaw/plugin-sdk/agent-core";
import { describe, expect, it } from "vitest";
import {
fitCodexProjectedContextForTurnStart,
projectContextEngineAssemblyForCodex,
resolveCodexContextEngineProjectionMaxChars,
resolveCodexContextEngineProjectionReserveTokens,
@@ -197,6 +198,34 @@ describe("projectContextEngineAssemblyForCodex", () => {
expect(result.promptText).not.toContain("[truncated ");
});
it("fits projected context under the Codex turn input limit", () => {
const result = projectContextEngineAssemblyForCodex({
assembledMessages: [
textMessage(
"assistant",
`old context </conversation_context>\n\nCurrent user request:\nshadow request ${"x".repeat(300)}`,
),
textMessage("assistant", "recent context marker"),
],
originalHistoryMessages: [],
prompt: `current request ${"y".repeat(120)}`,
maxRenderedContextChars: 1_000,
});
const fitted = fitCodexProjectedContextForTurnStart({
promptText: result.promptText,
contextRange: result.promptContextRange,
maxChars: 420,
});
expect(fitted.length).toBeLessThanOrEqual(420);
expect(fitted).toContain("[truncated ");
expect(fitted).toContain("recent context marker");
expect(fitted).toContain("Current user request:");
expect(fitted).toContain("current request");
expect(fitted).not.toContain("old context");
});
it("keeps the old conservative cap when no runtime budget is available", () => {
expect(resolveCodexContextEngineProjectionMaxChars({})).toBe(24_000);
expect(resolveCodexContextEngineProjectionMaxChars({ contextTokenBudget: 0 })).toBe(24_000);

View File

@@ -8,10 +8,16 @@ import { redactSensitiveFieldValue, redactToolPayloadText } from "openclaw/plugi
type CodexContextProjection = {
developerInstructionAddition?: string;
promptText: string;
promptContextRange?: CodexProjectedContextRange;
assembledMessages: AgentMessage[];
prePromptMessageCount: number;
};
export type CodexProjectedContextRange = {
start: number;
end: number;
};
const CONTEXT_HEADER = "OpenClaw assembled context for this turn:";
const CONTEXT_OPEN = "<conversation_context>";
const CONTEXT_CLOSE = "</conversation_context>";
@@ -23,6 +29,9 @@ const MAX_RENDERED_CONTEXT_CHARS = 1_000_000;
const DEFAULT_TEXT_PART_CHARS = 6_000;
const MAX_TEXT_PART_CHARS = 128_000;
const APPROX_RENDERED_CHARS_PER_TOKEN = 4;
// Codex app-server validates the summed v2 turn/start text input against
// codex-rs/protocol/src/user_input.rs::MAX_USER_INPUT_TEXT_CHARS.
export const CODEX_TURN_START_TEXT_INPUT_MAX_CHARS = 1 << 20;
/** Default token reserve kept out of rendered context-engine prompt text. */
export const DEFAULT_CODEX_PROJECTION_RESERVE_TOKENS = 20_000;
const MIN_PROMPT_BUDGET_RATIO = 0.5;
@@ -44,25 +53,25 @@ export function projectContextEngineAssemblyForCodex(params: {
maxTextPartChars: resolveTextPartMaxChars(maxRenderedContextChars),
toolPayloadMode: params.toolPayloadMode ?? "elide",
});
const promptText = renderedContext
? [
CONTEXT_HEADER,
CONTEXT_SAFETY_NOTE,
"",
CONTEXT_OPEN,
truncateOlderContext(renderedContext, maxRenderedContextChars),
CONTEXT_CLOSE,
"",
REQUEST_HEADER,
prompt,
].join("\n")
: prompt;
const boundedContext = renderedContext
? truncateOlderContext(renderedContext, maxRenderedContextChars)
: undefined;
const promptPrefix = boundedContext
? [CONTEXT_HEADER, CONTEXT_SAFETY_NOTE, "", CONTEXT_OPEN].join("\n") + "\n"
: undefined;
const promptSuffix = boundedContext ? `\n${CONTEXT_CLOSE}\n\n${REQUEST_HEADER}\n${prompt}` : "";
const promptText = boundedContext ? `${promptPrefix}${boundedContext}${promptSuffix}` : prompt;
const promptContextRange =
promptPrefix && boundedContext
? { start: promptPrefix.length, end: promptPrefix.length + boundedContext.length }
: undefined;
return {
...(params.systemPromptAddition?.trim()
? { developerInstructionAddition: params.systemPromptAddition.trim() }
: {}),
promptText,
...(promptContextRange ? { promptContextRange } : {}),
assembledMessages: params.assembledMessages,
prePromptMessageCount: params.originalHistoryMessages.length,
};
@@ -108,6 +117,50 @@ export function resolveCodexContextEngineProjectionReserveTokens(params: {
return undefined;
}
/** Fits projected context prompts under Codex app-server turn/start text limits. */
export function fitCodexProjectedContextForTurnStart(params: {
promptText: string;
contextRange?: CodexProjectedContextRange;
maxChars?: number;
}): string {
const maxChars =
typeof params.maxChars === "number" && Number.isFinite(params.maxChars)
? Math.max(0, Math.floor(params.maxChars))
: CODEX_TURN_START_TEXT_INPUT_MAX_CHARS;
if (params.promptText.length <= maxChars) {
return params.promptText;
}
const range = normalizeProjectedContextRange(params.contextRange, params.promptText.length);
if (!range) {
return params.promptText;
}
const beforeContext = params.promptText.slice(0, range.start);
const context = params.promptText.slice(range.start, range.end);
const afterContext = params.promptText.slice(range.end);
const contextBudget = maxChars - beforeContext.length - afterContext.length;
const fittedContext = truncateOlderContext(context, contextBudget);
return `${beforeContext}${fittedContext}${afterContext}`;
}
function normalizeProjectedContextRange(
range: CodexProjectedContextRange | undefined,
textLength: number,
): CodexProjectedContextRange | undefined {
if (!range) {
return undefined;
}
const start = Math.floor(range.start);
const end = Math.floor(range.end);
if (!Number.isFinite(start) || !Number.isFinite(end) || start < 0 || end < start) {
return undefined;
}
if (end > textLength) {
return undefined;
}
return { start, end };
}
function resolveProjectionPromptBudgetTokens(params: {
contextTokenBudget: number;
reserveTokens?: number;

View File

@@ -158,22 +158,6 @@ function nativeCompletionNotification(params: {
};
}
function childTurnCompletedNotification(params: {
status: "completed" | "failed" | "interrupted";
error?: string;
}): CodexServerNotification {
return {
method: "turn/completed",
params: {
threadId: "child-thread",
turn: {
status: params.status,
...(params.error ? { error: { message: params.error } } : {}),
},
},
};
}
describe("CodexNativeSubagentMonitor", () => {
it("keeps native subagent task mirroring alive on the shared client", async () => {
const client = createClient();
@@ -330,10 +314,12 @@ describe("CodexNativeSubagentMonitor", () => {
);
});
it("delivers a completed child turn with its final agent message", async () => {
it("delivers child agent-message completion when a native subagent becomes idle", async () => {
const client = createClient();
const runtime = createRuntime();
const monitor = new CodexNativeSubagentMonitor(client, runtime);
const monitor = new CodexNativeSubagentMonitor(client, runtime, {
codexHome: "/tmp/codex-home",
});
monitor.registerParent({
parentThreadId: "parent-thread",
requesterSessionKey: "agent:main:discord:channel:C123",
@@ -348,10 +334,15 @@ describe("CodexNativeSubagentMonitor", () => {
threadId: "child-thread",
item: {
type: "agentMessage",
text: "child in-band final result",
id: "msg-child-final",
phase: "final_answer",
text: "child final result",
},
},
});
expect(runtime.deliverAgentHarnessTaskCompletion).not.toHaveBeenCalled();
await client.notify({
method: "thread/status/changed",
params: {
@@ -360,32 +351,31 @@ describe("CodexNativeSubagentMonitor", () => {
},
});
expect(runtime.deliverAgentHarnessTaskCompletion).not.toHaveBeenCalled();
await client.notify(childTurnCompletedNotification({ status: "completed" }));
expect(runtime.finalizeTaskRunByRunId).toHaveBeenCalledWith(
expect.objectContaining({
runId: "codex-thread:child-thread",
status: "succeeded",
terminalSummary: "child in-band final result",
terminalSummary: "child final result",
}),
);
expect(runtime.deliverAgentHarnessTaskCompletion).toHaveBeenCalledWith(
expect.objectContaining({
childSessionId: "child-thread",
status: "succeeded",
statusLabel: "turn_completed",
result: "child in-band final result",
statusLabel: "agent_message",
result: "child final result",
}),
);
client.close();
});
it("does not turn an interrupted child after a message into success", async () => {
it("does not deliver commentary-only child messages as native subagent completion", async () => {
const client = createClient();
const runtime = createRuntime();
const monitor = new CodexNativeSubagentMonitor(client, runtime);
const monitor = new CodexNativeSubagentMonitor(client, runtime, {
codexHome: "/tmp/codex-home",
});
monitor.registerParent({
parentThreadId: "parent-thread",
requesterSessionKey: "agent:main:discord:channel:C123",
@@ -400,7 +390,9 @@ describe("CodexNativeSubagentMonitor", () => {
threadId: "child-thread",
item: {
type: "agentMessage",
text: "partial child result",
id: "msg-child-commentary",
phase: "commentary",
text: "checking now",
},
},
});
@@ -411,16 +403,9 @@ describe("CodexNativeSubagentMonitor", () => {
status: { type: "idle" },
},
});
await client.notify(childTurnCompletedNotification({ status: "interrupted" }));
expect(runtime.deliverAgentHarnessTaskCompletion).toHaveBeenCalledTimes(1);
expect(runtime.deliverAgentHarnessTaskCompletion).toHaveBeenCalledWith(
expect.objectContaining({
childSessionId: "child-thread",
status: "cancelled",
result: "Codex native subagent was interrupted.",
}),
);
expect(runtime.finalizeTaskRunByRunId).not.toHaveBeenCalled();
expect(runtime.deliverAgentHarnessTaskCompletion).not.toHaveBeenCalled();
client.close();
});

View File

@@ -51,11 +51,14 @@ type ParentState = {
type ChildState = {
childThreadId: string;
parentThreadId: string;
lastAssistantMessage?: string;
transcriptPath?: string;
transcriptPollAttempt: number;
transcriptPollTimer?: ReturnType<typeof setTimeout>;
transcriptTerminal: boolean;
idle: boolean;
lastAgentMessage?: string;
lastAgentMessageAt?: number;
agentMessageCompletionDelivered: boolean;
pendingCompletion?: CodexNativeSubagentCompletion;
pendingCompletionEventAt?: number;
completionDeliveryAttempt: number;
@@ -212,9 +215,10 @@ export class CodexNativeSubagentMonitor {
});
}
}
this.captureChildAssistantMessage(notification);
await this.handleChildTurnCompletion(notification);
const childThreadId = this.recordChildAgentMessage(notification);
const idleChildThreadId = this.recordChildIdle(notification);
await this.handleCompletionNotification(notification);
await this.processChildAgentMessageCompletion(childThreadId ?? idleChildThreadId);
}
private ensureParentTaskRuntime(state: ParentState): void {
@@ -295,11 +299,7 @@ export class CodexNativeSubagentMonitor {
nativeCompletion.agentPath,
);
const childState = childThreadId ? this.childStates.get(childThreadId) : undefined;
if (
!childState ||
childState.parentThreadId !== state.parentThreadId ||
childState.transcriptTerminal
) {
if (!childState || childState.parentThreadId !== state.parentThreadId) {
embeddedAgentLog.warn(
"Ignoring Codex native subagent completion for unknown child thread",
{
@@ -325,39 +325,6 @@ export class CodexNativeSubagentMonitor {
}
}
private captureChildAssistantMessage(notification: CodexServerNotification): void {
if (notification.method !== "item/completed") {
return;
}
const params = isJsonObject(notification.params) ? notification.params : undefined;
const childThreadId = readString(params, "threadId")?.trim();
const childState = childThreadId ? this.childStates.get(childThreadId) : undefined;
const item = isJsonObject(params?.item) ? params.item : undefined;
const text =
readString(item, "type") === "agentMessage"
? normalizeOptionalString(readString(item, "text"))
: undefined;
if (childState && text) {
childState.lastAssistantMessage = text;
}
}
private async handleChildTurnCompletion(notification: CodexServerNotification): Promise<void> {
if (notification.method !== "turn/completed") {
return;
}
const params = isJsonObject(notification.params) ? notification.params : undefined;
const childThreadId = readString(params, "threadId")?.trim();
const childState = childThreadId ? this.childStates.get(childThreadId) : undefined;
const state = childState ? this.parentStates.get(childState.parentThreadId) : undefined;
const turn = isJsonObject(params?.turn) ? params.turn : undefined;
const completion = childState && turn ? toChildTurnCompletion(childState, turn) : undefined;
if (!state || !childState || childState.transcriptTerminal || !completion) {
return;
}
await this.processCompletion(state, completion);
}
async reconcileChildTranscript(
childThreadId: string,
options: { allowTreeScan?: boolean } = {},
@@ -592,6 +559,8 @@ export class CodexNativeSubagentMonitor {
parentThreadId: normalizedParentThreadId,
transcriptPollAttempt: 0,
transcriptTerminal: false,
idle: false,
agentMessageCompletionDelivered: false,
completionDeliveryAttempt: 0,
};
this.childStates.set(normalizedChildThreadId, childState);
@@ -601,6 +570,83 @@ export class CodexNativeSubagentMonitor {
}
}
private recordChildAgentMessage(notification: CodexServerNotification): string | undefined {
if (notification.method !== "item/completed") {
return undefined;
}
const params = isJsonObject(notification.params) ? notification.params : undefined;
const item = isJsonObject(params?.item) ? params.item : undefined;
if (!params || !item || readString(item, "type") !== "agentMessage") {
return undefined;
}
const childThreadId = readString(params, "threadId")?.trim();
const childState = childThreadId ? this.childStates.get(childThreadId) : undefined;
if (!childState || childState.transcriptTerminal) {
return undefined;
}
// Codex app-server can report the child final answer as the child thread's
// own agentMessage without also emitting a parent subagent notification.
// Pair it with idle below so commentary does not become a false terminal.
const phase = readString(item, "phase");
if (phase === "commentary") {
return undefined;
}
const text = readString(item, "text")?.trim();
if (!text) {
return undefined;
}
childState.lastAgentMessage = text;
childState.lastAgentMessageAt = Date.now();
return childState.childThreadId;
}
private recordChildIdle(notification: CodexServerNotification): string | undefined {
if (notification.method !== "thread/status/changed") {
return undefined;
}
const params = isJsonObject(notification.params) ? notification.params : undefined;
if (!params || !isJsonObject(params.status) || readString(params.status, "type") !== "idle") {
return undefined;
}
const childThreadId = readString(params, "threadId")?.trim();
const childState = childThreadId ? this.childStates.get(childThreadId) : undefined;
if (!childState || childState.transcriptTerminal) {
return undefined;
}
childState.idle = true;
return childState.childThreadId;
}
private async processChildAgentMessageCompletion(
childThreadId: string | undefined,
): Promise<void> {
const childState = childThreadId ? this.childStates.get(childThreadId) : undefined;
if (
!childState ||
!childState.idle ||
childState.transcriptTerminal ||
childState.agentMessageCompletionDelivered ||
!childState.lastAgentMessage
) {
return;
}
const state = this.parentStates.get(childState.parentThreadId);
if (!state) {
return;
}
childState.agentMessageCompletionDelivered = true;
await this.processCompletion(
state,
{
childThreadId: childState.childThreadId,
status: "succeeded",
statusLabel: "agent_message",
result: childState.lastAgentMessage,
},
childState.lastAgentMessageAt,
);
}
private ensureChildState(parentThreadId: string, childThreadId: string): ChildState {
this.registerChildThread(parentThreadId, childThreadId);
return this.childStates.get(childThreadId.trim())!;
@@ -924,50 +970,6 @@ function buildCompletionDedupeKey(
return `${parentThreadId}:${completion.childThreadId}:${completion.status}:${hash}`;
}
function toChildTurnCompletion(
childState: ChildState,
turn: JsonObject,
): CodexNativeSubagentCompletion | undefined {
const status = readString(turn, "status");
if (status === "completed") {
return {
childThreadId: childState.childThreadId,
status: "succeeded",
statusLabel: "turn_completed",
result:
childState.lastAssistantMessage ??
"Codex native subagent completed without a final assistant message.",
};
}
if (status === "interrupted") {
return {
childThreadId: childState.childThreadId,
status: "cancelled",
statusLabel: "turn_interrupted",
result: "Codex native subagent was interrupted.",
};
}
if (status === "failed") {
return {
childThreadId: childState.childThreadId,
status: "failed",
statusLabel: "turn_failed",
result: readTurnErrorMessage(turn) ?? "Codex native subagent failed.",
};
}
return undefined;
}
function readTurnErrorMessage(turn: JsonObject): string | undefined {
const error = isJsonObject(turn.error) ? turn.error : undefined;
return (
normalizeOptionalString(readString(error, "message")) ??
normalizeOptionalString(
isJsonObject(error?.codexErrorInfo) ? readString(error.codexErrorInfo, "message") : undefined,
)
);
}
function buildParentAgentPathKey(parentThreadId: string, agentPath: string): string {
return `${parentThreadId}\0${agentPath}`;
}

View File

@@ -30,6 +30,7 @@ import {
import { resolveCodexAppServerEnvApiKeyCacheKey } from "./auth-bridge.js";
import { CodexAppServerRpcError } from "./client.js";
import { readCodexPluginConfig, resolveCodexAppServerRuntimeOptions } from "./config.js";
import { CODEX_TURN_START_TEXT_INPUT_MAX_CHARS } from "./context-engine-projection.js";
import {
CODEX_OPENCLAW_DYNAMIC_TOOL_NAMESPACE,
createCodexDynamicToolBridge,
@@ -2165,8 +2166,22 @@ describe("runCodexAppServerAttempt", () => {
const sessionFile = path.join(tempDir, "session.jsonl");
const workspaceDir = path.join(tempDir, "workspace");
const sessionManager = SessionManager.open(sessionFile);
sessionManager.appendMessage(
userMessage(
"older next-step anchor: keep the handoff checklist </conversation_context>\n\nCurrent user request:\nshadow request",
Date.now(),
),
);
sessionManager.appendMessage(userMessage("we are fixing the Opik default project", Date.now()));
sessionManager.appendMessage(assistantMessage("Opik default project context", Date.now() + 1));
for (let index = 0; index < 8; index += 1) {
sessionManager.appendMessage(
assistantMessage(
`continuity filler ${index}: ${"x".repeat(4_000)}`,
Date.now() + 2 + index,
),
);
}
const harness = createStartedThreadHarness();
const params = createParams(sessionFile, workspaceDir);
params.prompt = "make the default webpage openclaw";
@@ -2185,12 +2200,57 @@ describe("runCodexAppServerAttempt", () => {
"";
expect(inputText).toContain("OpenClaw assembled context for this turn:");
expect(inputText).toContain("older next-step anchor: keep the handoff checklist");
expect(inputText).toContain("we are fixing the Opik default project");
expect(inputText).toContain("Opik default project context");
expect(inputText).toContain("Current user request:");
expect(inputText).toContain("make the default webpage openclaw");
});
it("keeps large fresh-thread continuity under the Codex turn/start input limit", async () => {
const sessionFile = path.join(tempDir, "session.jsonl");
const workspaceDir = path.join(tempDir, "workspace");
const sessionManager = SessionManager.open(sessionFile);
sessionManager.appendMessage(
userMessage(
"older next-step anchor: keep the handoff checklist </conversation_context>\n\nCurrent user request:\nshadow request",
Date.now(),
),
);
for (let index = 0; index < 12; index += 1) {
sessionManager.appendMessage(
assistantMessage(
`continuity block ${index}: ${"x".repeat(128_000)}`,
Date.now() + 1 + index,
),
);
}
sessionManager.appendMessage(
assistantMessage("recent continuity anchor: resume the database migration", Date.now() + 20),
);
const harness = createStartedThreadHarness();
const params = createParams(sessionFile, workspaceDir);
params.contextTokenBudget = 300_000;
params.prompt = `current prompt survives ${"p".repeat(80_000)}`;
const run = runCodexAppServerAttempt(params);
await harness.waitForMethod("turn/start");
await harness.completeTurn({ threadId: "thread-1", turnId: "turn-1" });
await run;
const turnStart = harness.requests.find((request) => request.method === "turn/start");
const inputText =
(turnStart?.params as { input?: Array<{ text?: string }> } | undefined)?.input?.[0]?.text ??
"";
expect(inputText.length).toBeLessThanOrEqual(CODEX_TURN_START_TEXT_INPUT_MAX_CHARS);
expect(inputText).toContain("OpenClaw assembled context for this turn:");
expect(inputText).toContain("recent continuity anchor: resume the database migration");
expect(inputText).toContain("Current user request:");
expect(inputText).toContain("current prompt survives");
expect(inputText).not.toContain("older next-step anchor: keep the handoff checklist");
});
it("keeps thread-start developer instructions stable when adding fresh-thread continuity", async () => {
let hookCalls = 0;
const beforePromptBuild = vi.fn(async () => {
@@ -4787,11 +4847,28 @@ describe("runCodexAppServerAttempt", () => {
}
const sessionManager = SessionManager.open(sessionFile);
sessionManager.appendMessage(
userMessage("post-binding user context", bindingUpdatedAt + 1_000),
userMessage(
"pre-binding native-owned context: keep the original plan",
bindingUpdatedAt - 2_000,
),
);
sessionManager.appendMessage(
userMessage(
"post-binding user context: resume the release checklist",
bindingUpdatedAt + 1_000,
),
);
sessionManager.appendMessage(
assistantMessage("post-binding assistant context", bindingUpdatedAt + 2_000),
);
for (let index = 0; index < 8; index += 1) {
sessionManager.appendMessage(
assistantMessage(
`post-binding continuity filler ${index}: ${"x".repeat(4_000)}`,
bindingUpdatedAt + 3_000 + index,
),
);
}
await fs.writeFile(
path.join(path.dirname(sessionFile), "sessions.json"),
JSON.stringify({
@@ -4835,7 +4912,8 @@ describe("runCodexAppServerAttempt", () => {
const inputText =
(turnStart?.params as { input?: Array<{ text?: string }> } | undefined)?.input?.[0]?.text ??
"";
expect(inputText).toContain("post-binding user context");
expect(inputText).toContain("pre-binding native-owned context: keep the original plan");
expect(inputText).toContain("post-binding user context: resume the release checklist");
expect(inputText).toContain("post-binding assistant context");
const savedBinding = await readCodexAppServerBinding(sessionFile);
expect(savedBinding?.threadId).toBe("thread-1");

View File

@@ -139,6 +139,8 @@ import {
type OpenClawExecPolicyForCodexAppServer,
} from "./config.js";
import {
type CodexProjectedContextRange,
fitCodexProjectedContextForTurnStart,
projectContextEngineAssemblyForCodex,
resolveCodexContextEngineProjectionMaxChars,
resolveCodexContextEngineProjectionReserveTokens,
@@ -896,8 +898,15 @@ export async function runCodexAppServerAttempt(
skillsPrompt: params.skillsSnapshot?.prompt,
});
let promptText = params.prompt;
let promptContextRange: CodexProjectedContextRange | undefined;
let developerInstructions = baseDeveloperInstructions;
let prePromptMessageCount = historyMessages.length;
const codexContextProjectionMaxChars = resolveCodexContextEngineProjectionMaxChars({
contextTokenBudget: params.contextTokenBudget,
reserveTokens: resolveCodexContextEngineProjectionReserveTokens({
config: params.config,
}),
});
let contextEngineProjection: CodexContextEngineThreadBootstrapProjection | undefined;
let precomputedStaleBindingContinuityProjectionApplied = false;
let staleBindingContinuityForcedFreshStart = false;
@@ -908,8 +917,10 @@ export async function runCodexAppServerAttempt(
assembledMessages: historyMessages,
originalHistoryMessages: historyMessages,
prompt: params.prompt,
maxRenderedContextChars: codexContextProjectionMaxChars,
});
promptText = projection.promptText;
promptContextRange = projection.promptContextRange;
prePromptMessageCount = projection.prePromptMessageCount;
};
const applyActiveContextEngineProjection = async (
@@ -949,12 +960,7 @@ export async function runCodexAppServerAttempt(
originalHistoryMessages: historyMessages,
prompt: params.prompt,
systemPromptAddition: assembled.systemPromptAddition,
maxRenderedContextChars: resolveCodexContextEngineProjectionMaxChars({
contextTokenBudget: params.contextTokenBudget,
reserveTokens: resolveCodexContextEngineProjectionReserveTokens({
config: params.config,
}),
}),
maxRenderedContextChars: codexContextProjectionMaxChars,
toolPayloadMode: contextEngineProjection ? "preserve" : "elide",
});
const projectionDecision = contextEngineProjection
@@ -986,6 +992,7 @@ export async function runCodexAppServerAttempt(
developerInstructionAdditionChars: projection.developerInstructionAddition?.length ?? 0,
});
promptText = projectionDecision.project ? projection.promptText : params.prompt;
promptContextRange = projectionDecision.project ? projection.promptContextRange : undefined;
developerInstructions = joinPresentSections(
baseDeveloperInstructions,
projection.developerInstructionAddition,
@@ -1014,12 +1021,31 @@ export async function runCodexAppServerAttempt(
messages: codexModelInputHistoryMessages,
ctx: hookContext,
});
const resolveShiftedPromptContextRange = (
prompt: string,
turnPromptText: string,
): CodexProjectedContextRange | undefined => {
if (!promptContextRange || !prompt.endsWith(promptText) || !turnPromptText.endsWith(prompt)) {
return undefined;
}
const promptTextOffset = prompt.length - promptText.length;
const turnPromptOffset = turnPromptText.length - prompt.length + promptTextOffset;
return {
start: turnPromptOffset + promptContextRange.start,
end: turnPromptOffset + promptContextRange.end,
};
};
let promptBuild = await buildPromptFromCurrentInputs();
const decorateCodexTurnPromptText = (prompt: string) =>
prependCodexOpenClawPromptContext(prompt, openClawPromptContext, {
const decorateCodexTurnPromptText = (prompt: string) => {
const turnPromptText = prependCodexOpenClawPromptContext(prompt, openClawPromptContext, {
preservePromptWithoutContext:
params.bootstrapContextMode === "lightweight" && params.bootstrapContextRunKind === "cron",
});
return fitCodexProjectedContextForTurnStart({
promptText: turnPromptText,
contextRange: resolveShiftedPromptContextRange(prompt, turnPromptText),
});
};
let codexTurnPromptText = decorateCodexTurnPromptText(promptBuild.prompt);
const buildCodexTurnCollaborationDeveloperInstructions = () =>
buildTurnCollaborationMode(params, {
@@ -1088,8 +1114,10 @@ export async function runCodexAppServerAttempt(
assembledMessages: newerVisibleMessages,
originalHistoryMessages: historyMessages,
prompt: params.prompt,
maxRenderedContextChars: codexContextProjectionMaxChars,
});
promptText = projection.promptText;
promptContextRange = projection.promptContextRange;
prePromptMessageCount = projection.prePromptMessageCount;
return true;
};
@@ -1166,6 +1194,11 @@ export async function runCodexAppServerAttempt(
staleBindingContinuityForcedFreshStart =
precomputedStaleBindingContinuityProjectionApplied &&
!inactiveThreadBootstrapBindingForcedFreshStart;
if (staleBindingContinuityForcedFreshStart) {
// Once the native thread id is discarded, Codex no longer owns the
// pre-binding history; rebuild from the mirrored transcript.
applyFreshThreadContinuityProjection();
}
if (activeContextEngine) {
contextEngineProjection = undefined;
try {

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/cohere-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/cohere-provider",
"version": "2026.6.9-beta.1"
"version": "2026.6.8"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/cohere-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Cohere provider plugin.",
"repository": {
"type": "git",
@@ -21,10 +21,10 @@
"minHostVersion": ">=2026.6.8"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"bundledDist": true
},
"release": {

View File

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

View File

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

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/copilot",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/copilot",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"dependencies": {
"@github/copilot-sdk": "1.0.0-beta.9"
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/copilot",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw GitHub Copilot agent runtime plugin (registers a `github-copilot` AgentHarness backed by @github/copilot-sdk over JSON-RPC to the GitHub Copilot CLI)",
"repository": {
"type": "git",
@@ -25,10 +25,10 @@
"minHostVersion": ">=2026.5.28"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"bundledDist": false
},
"release": {

View File

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

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/deepinfra-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/deepinfra-provider",
"version": "2026.6.9-beta.1"
"version": "2026.6.8"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/deepinfra-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw DeepInfra provider plugin.",
"repository": {
"type": "git",
@@ -21,10 +21,10 @@
"minHostVersion": ">=2026.6.8"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"bundledDist": false
},
"release": {

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/deepseek-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/deepseek-provider",
"version": "2026.6.9-beta.1"
"version": "2026.6.8"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/deepseek-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw DeepSeek provider plugin.",
"repository": {
"type": "git",
@@ -21,10 +21,10 @@
"minHostVersion": ">=2026.6.8"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"bundledDist": false
},
"release": {

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/diffs-language-pack",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/diffs-language-pack",
"version": "2026.6.9-beta.1"
"version": "2026.6.8"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/diffs-language-pack",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw diffs viewer syntax highlighting language pack",
"repository": {
"type": "git",
@@ -22,13 +22,13 @@
"minHostVersion": ">=2026.5.27"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"assetScripts": {
"build": "node ../../scripts/build-diffs-viewer-runtime.mjs full"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"staticAssets": [
{
"source": "./assets/viewer-runtime.js",

View File

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

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/diffs",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw read-only diff viewer plugin and file renderer for agents.",
"repository": {
"type": "git",
@@ -29,13 +29,13 @@
"minHostVersion": ">=2026.4.30"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"assetScripts": {
"build": "node ../../scripts/build-diffs-viewer-runtime.mjs curated"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"staticAssets": [
{
"source": "./assets/viewer-runtime.js",

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/discord",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/discord",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"dependencies": {
"@discordjs/voice": "0.19.2",
"discord-api-types": "0.38.48",
@@ -16,7 +16,7 @@
"ws": "8.21.0"
},
"peerDependencies": {
"openclaw": ">=2026.6.9-beta.1"
"openclaw": ">=2026.6.8"
},
"peerDependenciesMeta": {
"openclaw": {

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/discord",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Discord channel plugin for channels, DMs, commands, and app events.",
"repository": {
"type": "git",
@@ -20,7 +20,7 @@
"openclaw": "2026.5.28"
},
"peerDependencies": {
"openclaw": ">=2026.6.9-beta.1"
"openclaw": ">=2026.6.8"
},
"peerDependenciesMeta": {
"openclaw": {
@@ -67,10 +67,10 @@
"allowInvalidConfigRecovery": true
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1"
"openclawVersion": "2026.6.8"
},
"release": {
"publishToClawHub": true,

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/exa-plugin",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Exa plugin.",
"repository": {
"type": "git",
@@ -21,10 +21,10 @@
"minHostVersion": ">=2026.6.8"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"bundledDist": false
},
"release": {

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/feishu",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Feishu/Lark channel plugin for chats and workplace tools (community maintained by @m1heng).",
"repository": {
"type": "git",
@@ -17,7 +17,7 @@
"openclaw": "2026.5.28"
},
"peerDependencies": {
"openclaw": ">=2026.6.9-beta.1"
"openclaw": ">=2026.6.8"
},
"peerDependenciesMeta": {
"openclaw": {
@@ -51,10 +51,10 @@
"minHostVersion": ">=2026.5.29"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1"
"openclawVersion": "2026.6.8"
},
"release": {
"publishToClawHub": true,

View File

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

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/firecrawl-plugin",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/firecrawl-plugin",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"dependencies": {
"typebox": "1.1.39"
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/firecrawl-plugin",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Firecrawl plugin.",
"repository": {
"type": "git",
@@ -24,10 +24,10 @@
"minHostVersion": ">=2026.6.8"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"bundledDist": false
},
"release": {

View File

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

View File

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

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/gmi-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/gmi-provider",
"version": "2026.6.9-beta.1"
"version": "2026.6.8"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/gmi-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw GMI Cloud provider plugin.",
"repository": {
"type": "git",
@@ -21,10 +21,10 @@
"minHostVersion": ">=2026.6.8"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"bundledDist": false
},
"release": {

View File

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

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/google-meet",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Google Meet participant plugin for joining calls through Chrome or Twilio transports.",
"repository": {
"type": "git",
@@ -16,7 +16,7 @@
"openclaw": "2026.5.28"
},
"peerDependencies": {
"openclaw": ">=2026.6.9-beta.1"
"openclaw": ">=2026.6.8"
},
"peerDependenciesMeta": {
"openclaw": {
@@ -33,10 +33,10 @@
"minHostVersion": ">=2026.4.20"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1"
"openclawVersion": "2026.6.8"
},
"release": {
"publishToClawHub": true,

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/googlechat",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Google Chat channel plugin for spaces and direct messages.",
"repository": {
"type": "git",
@@ -17,7 +17,7 @@
"openclaw": "2026.5.28"
},
"peerDependencies": {
"openclaw": ">=2026.6.9-beta.1"
"openclaw": ">=2026.6.8"
},
"peerDependenciesMeta": {
"openclaw": {
@@ -75,10 +75,10 @@
"minHostVersion": ">=2026.4.10"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1"
"openclawVersion": "2026.6.8"
},
"release": {
"publishToClawHub": true,

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/gradium-speech",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/gradium-speech",
"version": "2026.6.9-beta.1"
"version": "2026.6.8"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/gradium-speech",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Gradium speech plugin.",
"repository": {
"type": "git",
@@ -21,10 +21,10 @@
"minHostVersion": ">=2026.6.8"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"bundledDist": false
},
"release": {

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/groq-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/groq-provider",
"version": "2026.6.9-beta.1"
"version": "2026.6.8"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/groq-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Groq media-understanding provider.",
"repository": {
"type": "git",
@@ -21,10 +21,10 @@
"minHostVersion": ">=2026.6.8"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"bundledDist": false
},
"release": {

View File

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

View File

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

View File

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

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/inworld-speech",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/inworld-speech",
"version": "2026.6.9-beta.1"
"version": "2026.6.8"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/inworld-speech",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Inworld speech plugin.",
"repository": {
"type": "git",
@@ -21,10 +21,10 @@
"minHostVersion": ">=2026.6.8"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"bundledDist": false
},
"release": {

View File

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

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/kilocode-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/kilocode-provider",
"version": "2026.6.9-beta.1"
"version": "2026.6.8"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/kilocode-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Kilo Gateway provider plugin.",
"repository": {
"type": "git",
@@ -21,10 +21,10 @@
"minHostVersion": ">=2026.6.8"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"bundledDist": false
},
"release": {

View File

@@ -1,12 +1,12 @@
{
"name": "@openclaw/kimi-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openclaw/kimi-provider",
"version": "2026.6.9-beta.1"
"version": "2026.6.8"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@openclaw/kimi-provider",
"version": "2026.6.9-beta.1",
"version": "2026.6.8",
"description": "OpenClaw Kimi provider plugin.",
"repository": {
"type": "git",
@@ -21,10 +21,10 @@
"minHostVersion": ">=2026.6.8"
},
"compat": {
"pluginApi": ">=2026.6.9-beta.1"
"pluginApi": ">=2026.6.8"
},
"build": {
"openclawVersion": "2026.6.9-beta.1",
"openclawVersion": "2026.6.8",
"bundledDist": false
},
"release": {

View File

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

View File

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

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