Update OpenClaw ClawHub docs and user-facing copy for canonical owner-qualified skill routes.\n\nEvidence:\n- pnpm docs:list\n- pnpm test src/plugins/clawhub.test.ts src/cli/plugins-cli.install.test.ts src/gateway/server-methods/skills.clawhub.test.ts ui/src/ui/views/skills.test.ts\n- pnpm exec oxfmt --check --threads=1 docs/clawhub/cli.md docs/clawhub/publishing.md docs/cli/skills.md docs/help/faq.md docs/start/showcase.md docs/tools/creating-skills.md docs/tools/skills.md src/gateway/server-methods/skills.clawhub.test.ts src/plugins/clawhub.test.ts src/plugins/clawhub.ts ui/src/ui/views/skills.test.ts\n- git diff --check\n- exact-head hosted CI passed for 8530374388d8a73235b2ac8444b95a4a4c7d0f1c\n\nNote: repo-native scripts/pr prepare-run was attempted; local broad pnpm test was stopped after unrelated existing failures in agent/media/provider shards, while hosted exact-head CI and targeted ClawHub route/copy validation were green.
* feat(browser): add optional vision understanding to screenshot tool
* fix(browser): wrap vision output as external content, enforce maxBytes, forward auth profiles
* fix(browser): remove no-op scope/attachments config, drop profile pass-through lacking runtime support
* feat(media-understanding): add profile/preferredProfile to DescribeImageFileWithModelParams and forward to describeImage
* style(browser): add curly braces to satisfy eslint curly rule
* fix(browser): correct tools.browser.enabled help text to match actual behavior
* fix(browser): thread agentDir/workspaceDir from plugin tool context into browser vision
* refactor(browser): move vision config from tools.browser to browser.models
The browser plugin's vision configuration now lives on the top-level
`browser` config namespace (browser.models, browser.visionEnabled,
browser.visionPrompt, etc.) instead of `tools.browser`. This aligns
with the plugin's existing config location and avoids confusion between
tool-level and plugin-level settings.
- Remove tools.browser from ToolsSchema and ToolsConfig
- Add models/vision* fields to BrowserConfig and its zod schema
- Update getBrowserVisionConfig to read from cfg.browser
- Update schema help, labels, and quality test
- Update vision.test.ts to use new config shape
* docs(browser): add screenshot vision configuration section
Document the new browser.models config for automatic screenshot
description via vision models, enabling text-only main models to
reason about web page content.
* fix(browser): remove deliverable media markers from vision result, drop unused import
P1: Vision-success path no longer exposes the raw screenshot as
deliverable media (removes MEDIA: line and details.media.mediaUrl).
This prevents channel delivery from auto-sending sensitive page content
when the intended output is a text description.
P2: Remove unused ToolsMediaUnderstandingSchema import that would fail
noUnusedLocals typecheck.
* fix(browser): add command/args fields to browser models schema
The browser vision model schema uses .strict(), so CLI-type entries
with command/args were rejected by TypeScript. Add these fields to
align with MediaUnderstandingModelSchema.
* chore(browser): remove debug console.log statements
* fix(browser): harden screenshot vision result against MEDIA: directive injection and restore image sanitization on failure fallback
ClawSweeper #84247 review round 2:
P1 (security, high): neutralize line-start MEDIA: directives in vision descriptions
before wrapping with wrapExternalContent. The agent media extractor scans every
browser tool-result text block via splitMediaFromOutput which treats line-start
MEDIA: as a trusted local-media delivery directive, and browser is on the
trusted-media allowlist. Without neutralization, page or vision-provider output
containing 'MEDIA:/tmp/secret.png' could synthesize a channel-deliverable media
artifact from untrusted content. wrapExternalContent itself does not strip
line-start directives. Introduce neutralizeMediaDirectives in vision.ts that
prepends '[neutralized] ' to any line whose trimStart() begins with MEDIA:
(case-insensitive), defanging the parser anchor while keeping the original
text human-readable.
P2 (compatibility): pass resolveRuntimeImageSanitization() to imageResultFromFile
in the vision-failure catch fallback. The non-vision screenshot path already
forwards this option (d5cc0d53b7) so configured agents.defaults.imageMaxDimensionPx
takes effect. Without this fix, any provider timeout/error silently bypasses the
sanitization guard and returns a raw full-resolution screenshot.
Regression coverage:
- vision.test.ts: 6 unit cases for neutralizeMediaDirectives (no-op fast path,
mid-line MEDIA: untouched, line-start defanged, leading-whitespace defanged,
case-insensitive, multiple directives per blob).
- browser-tool.test.ts: 2 integration cases that drive the full screenshot
tool execute path:
- 'neutralizes MEDIA: directives in vision text and does not attach media'
asserts no line matches /^\s*MEDIA:/i in returned text, secret path text
is preserved verbatim, details.media is absent, and imageResultFromFile
is not called on the success path.
- 'preserves screenshot image sanitization on vision failure fallback'
mocks describeImageFileWithModel to reject and asserts the fallback
imageResultFromFile call receives imageSanitization: {maxDimensionPx:1600}
plus the 'browser screenshot vision failed' extraText.
* fix(browser): apply clawsweeper fallback media fix from PR #84247
* refactor: reuse media image understanding for browser screenshots
* refactor: use structured media delivery
* test: update music completion media instruction expectation
* fix: trim buffered reply directive padding
* test: refresh codex prompt snapshots for message media aliases
---------
Co-authored-by: scotthuang <scotthuang@tencent.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Summary:
- Adds `--global` to `openclaw skills install` and `openclaw skills update`, routing ClawHub installs and updates to the shared managed skills root with docs, changelog, and CLI command tests.
- Reproducibility: not applicable. as a bug reproduction; this is a new CLI feature request. Source inspection confirms current `main` lacks `--global`, and the source PR includes after-fix terminal proof for the new path.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(cli): address skills global review
- PR branch already contained follow-up commit before automerge: feat(cli): support installing skills to shared global directory via -…
Validation:
- ClawSweeper review passed for head 6eb7187fc1.
- Required merge gates passed before the squash merge.
Prepared head SHA: 6eb7187fc1
Review: https://github.com/openclaw/openclaw/pull/83705#issuecomment-4480023577
Co-authored-by: Hongwei Ma <marvae24@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
feat(docker): add image apt package build arg
Add OPENCLAW_IMAGE_APT_PACKAGES as the preferred runtime-neutral image build arg for Docker and Podman apt package installs while keeping OPENCLAW_DOCKER_APT_PACKAGES as the legacy fallback.
Maintainer verification:
- pnpm docs:list
- node scripts/run-vitest.mjs run --config test/vitest/vitest.e2e.config.ts src/docker-setup.e2e.test.ts
- node scripts/run-vitest.mjs src/dockerfile.test.ts test/scripts/test-install-sh-docker.test.ts
- node scripts/run-vitest.mjs run --config test/vitest/vitest.cron.config.ts src/cron/isolated-agent.model-overrides.test.ts
- pnpm exec oxfmt --check --threads=1 docs/install/docker.md docs/install/podman.md scripts/clawdock/README.md docs/help/faq.md CHANGELOG.md
- git diff --check origin/main...HEAD
- .agents/skills/autoreview/scripts/autoreview --mode local
- .agents/skills/autoreview/scripts/autoreview --mode branch
- pnpm check:changed via Blacksmith Testbox tbx_01krwqmfhcdekaczvrkxnb7t59, Actions run 26014630478, exit 0
Known CI note: checks-node-core-runtime-shared timed out repeatedly in unrelated src/cron/isolated-agent.model-overrides.test.ts on GitHub Actions; the same test passes locally after this rebase.
Co-authored-by: Said Urtabajev <said@bumpclub.ee>