* perf(doctor): keep bundled doctor contract closures dependency-light
Doctor contract enumeration cold-loads each plugin's doctor-contract-api
closure via jiti, so a static value import of openclaw/plugin-sdk/runtime-doctor
pulled the state-db/kysely graph (~4.3s per closure) into
listPluginDoctorLegacyConfigRules / listPluginDoctorStateMigrationEntries.
- migrate all light doctor-contract closures (66 files) to the
dependency-light openclaw/plugin-sdk/runtime-doctor-migrations subpath
- voice-call: load detect/repairOpenClawStateDatabaseSchema* lazily inside
the migration bodies; keep only a type-only static runtime-doctor import
- matrix: split pure credential record shapes/normalizers into
credentials-state.ts so the doctor closure no longer imports the sync
plugin-state store through credentials-read
- guard: doctor-contract-closure-guard.test.ts now forbids static value
imports of runtime-doctor in closures alongside agent-runtime
* fix(matrix): keep credential revocation record type module-local
Knip production scan flags the export as consumer-less; the type is only
referenced by the exported union and revocation guard signature.
* perf(plugins): declare doctor contract surfaces
* perf(doctor): slim migration import closures
* perf(plugins): narrow doctor declaration record surface and wire owner-test lane
Registry records carry only the doctorContract declaration instead of the whole
parsed manifest, and check:changed now selects the src/plugins-owned declaration
honesty and closure-guard tests for extension module/manifest changes so
cross-lane drift cannot pass PR classification.
* fix(doctor): keep control-plane dist imports require-safe
Keep doctor and channel control-plane chunks off exec-class dependencies, and enforce native require(esm) loading during postbuild.
* chore(plugin-sdk): regenerate API baseline
* chore(plugin-sdk): sync export ordering
* fix(plugins): satisfy doctor contract CI boundaries
* perf(doctor): make qqbot doctor closure dependency-light
qqbot was the last plugin above 5s in doctor state-migration enumeration
(~8s under tsx/jiti). The cost was not the state-key builder (already a
leaf): its doctor closure value-imported the runtime-doctor SDK barrel,
whose plugin-state-store/state-db re-exports pull kysely (~330 modules),
plus security-runtime for one fileExists (~200 modules), all resolved
per-module by jiti during enumeration.
Split the migration-define helpers and light re-exports into a new
private-local plugin-sdk/runtime-doctor-migrations subpath; runtime-doctor
re-exports it so its public surface is byte-identical (API baseline hash
unchanged). qqbot's doctor-contract and state-migrations now import only
the light subpath, swapping fileExists for the equivalent async
legacyStateFileExists already in the closure.
qqbot enumeration: ~8.0s/531 modules -> ~0.25s/18 modules.
* chore(plugin-sdk): drop private-local subpath from API baseline
runtime-doctor-migrations is private-local-only; the baseline tracks public
modules, and the earlier line was generated before the classification.
* fix(plugins): register runtime-doctor-migrations boundary paths
The private-local subpath list feeds the extension package boundary map;
the shared paths config and xai's derived overrides must carry the same
entry or the boundary contract test fails.
Aggregators republish first-party models under a namespaced id and varying
case, so the shared-model check could not group novita/moonshotai/kimi-k3 with
moonshot/kimi-k3. Matching now ignores one leading namespace segment and case,
which catches that whole class automatically instead of needing an
upstreamModel marker per row.
Declares the tier on the 18 rows this surfaces across baseten, deepinfra, gmi,
novita, nvidia, and together. All are "capable", matching what the runtime
already applied for an absent flag, so behavior is unchanged.
* build(deps): remove npm shrinkwrap; mirror pnpm lock into transient package locks
npm 12 removed shrinkwrap (command + tarball/root loading). Delete all 82
committed npm-shrinkwrap.json files and stop publishing lockfiles; keep
pnpm-lock.yaml as the single reviewed dependency boundary. The generator
becomes scripts/generate-npm-package-lock.mjs and feeds plugin bundling via
a transient package-lock.json + npm ci (works on npm 11 and 12). Tarball
validation treats the published 2026.7.2 beta train as a shrinkwrap
transition; self-update npm detection now uses install topology instead of
the shipped shrinkwrap.
* fix(deps): repair lint, deadcode, and test-type lanes for the npm 12 migration
- sort integrity comparisons with an explicit comparator (oxlint)
- keep resolveBunGlobalNodeModules module-local (knip unused-export gate)
- model npm pack --json as npm<=11 array / npm 12 name-keyed object
- default calver destructuring in the tarball test fixture
* fix(deepinfra): tag DeepSeek thinking format and use OpenAI video endpoint
Route DeepInfra video generation through the OpenAI-compatible async
/v1/openai/videos endpoint (submit, then poll) with live video-gen tag
discovery, replacing the retired native /v1/inference path; doctor
migrates api.deepinfra.com URLs and the provider fails closed with an
actionable error on retired custom native endpoints without echoing
configured URLs (they may carry credentials).
Tag the deepseek-ai/* family with thinkingFormat "deepseek" so core
strips/recovers reasoning_content and DSML tool-call markup instead of
leaking it into replies, and mark reasoning-tagged models as
reasoning-capable.
Redaction tests assemble credential-shaped fixture URLs from string
pieces so TruffleHog's URI detector does not flag them. Docs describe
the per-surface static defaults with live discovery expanding the
selectable model lists.
* fix(deepinfra): preserve custom video output host
---------
Co-authored-by: Jacob Tomlinson <jacobtomlinson@users.noreply.github.com>
* chore(plugins): gate deprecation hygiene in CI and purge internal deprecated usage
* fix(agents): migrate auth-profiles oauth import to OAuthProviderId
* fix(whatsapp): use durability param in delivery-recovery test
* chore(scripts): declare shouldRunDeprecationHygieneChecks in check-changed types
* test(plugins): update runtime-api guard for ssrf policy rename
* chore(release): close out 2026.6.10 on main
* chore(release): align native app metadata for 2026.6.10
* chore(release): sync Android 2026.6.10 notes
* docs(changelog): preserve 2026.6.9 history
* docs(changelog): preserve 2026.6.9 history
Bumps OpenClaw release metadata to 2026.5.31 across package manifests, app version files, plugin metadata, changelog headings, and generated shrinkwraps.
Verification:
- pnpm plugins:sync:check
- pnpm ios:version:check
- pnpm deps:shrinkwrap:check
- git diff --check
- stale 2026.5.30/build-code scan across changed files
- autoreview clean: no accepted/actionable findings
- PR CI green for real gates: Checks, security scans, dependency guard, app lanes, real behavior proof
Known non-code workflow issue:
- label workflow failed because this PR hits GitHub's 100-label issue cap before the size-label step.