chore(sync): mirror docs from openclaw/openclaw@be81fa4424

This commit is contained in:
openclaw-docs-sync[bot] 2026-04-23 13:32:28 +00:00
parent d603f86f8b
commit 787d828228
6 changed files with 784 additions and 5 deletions

View File

@ -1,5 +1,5 @@
{
"repository": "openclaw/openclaw",
"sha": "bc01cbb8a2ac894fc5dea9e49419312160b5b5b5",
"syncedAt": "2026-04-23T12:49:51.488Z"
"sha": "be81fa4424abb2a18d0fecb501c2cc290a803b09",
"syncedAt": "2026-04-23T13:32:27.753Z"
}

View File

@ -56,7 +56,7 @@ Jobs are ordered so cheap checks fail before expensive ones run:
Scope logic lives in `scripts/ci-changed-scope.mjs` and is covered by unit tests in `src/scripts/ci-changed-scope.test.ts`.
CI workflow edits validate the Node CI graph plus workflow linting, but do not force Windows, Android, or macOS native builds by themselves; those platform lanes stay scoped to platform source changes.
Windows Node checks are scoped to Windows-specific process/path wrappers, npm/pnpm/UI runner helpers, package manager config, and the CI workflow surfaces that execute that lane; unrelated source, plugin, install-smoke, and test-only changes stay on the Linux Node lanes so they do not reserve a 16-vCPU Windows worker for coverage that is already exercised by the normal test shards.
The separate `install-smoke` workflow reuses the same scope script through its own `preflight` job. It computes `run_install_smoke` from the narrower changed-smoke signal, so Docker/install smoke runs for install, packaging, container-relevant changes, bundled extension production changes, and the core plugin/channel/gateway/Plugin SDK surfaces that the Docker smoke jobs exercise. Test-only and docs-only edits do not reserve Docker workers. Its QR package smoke forces the Docker `pnpm install` layer to rerun while preserving the BuildKit pnpm store cache, so it still exercises installation without redownloading dependencies on every run. Its gateway-network e2e reuses the runtime image built earlier in the job, so it adds real container-to-container WebSocket coverage without adding another Docker build. Local `test:docker:all` prebuilds one shared `scripts/e2e/Dockerfile` built-app image and reuses it across the E2E container smoke runners; the reusable live/E2E workflow mirrors that pattern by building and pushing one SHA-tagged GHCR Docker E2E image before the Docker matrix, then running the matrix with `OPENCLAW_SKIP_DOCKER_BUILD=1`. QR and installer Docker tests keep their own install-focused Dockerfiles. A separate `docker-e2e-fast` job runs the bounded bundled-plugin Docker profile under a 120-second command timeout: setup-entry dependency repair plus synthetic bundled-loader failure isolation. The full bundled update/channel matrix remains manual/full-suite because it performs repeated real npm update and doctor repair passes.
The separate `install-smoke` workflow reuses the same scope script through its own `preflight` job. It computes `run_install_smoke` from the narrower changed-smoke signal, so Docker/install smoke runs for install, packaging, container-relevant changes, bundled extension production changes, and the core plugin/channel/gateway/Plugin SDK surfaces that the Docker smoke jobs exercise. Test-only and docs-only edits do not reserve Docker workers. Its QR package smoke forces the Docker `pnpm install` layer to rerun while preserving the BuildKit pnpm store cache, so it still exercises installation without redownloading dependencies on every run. Its gateway-network e2e reuses the runtime image built earlier in the job, so it adds real container-to-container WebSocket coverage without adding another Docker build. Local `test:docker:all` prebuilds one shared live-test image and one shared `scripts/e2e/Dockerfile` built-app image, then runs the live/E2E smoke lanes in parallel with `OPENCLAW_SKIP_DOCKER_BUILD=1`; tune the default concurrency of 4 with `OPENCLAW_DOCKER_ALL_PARALLELISM`. Startup- or provider-sensitive lanes run exclusively after the parallel pool. The reusable live/E2E workflow mirrors the shared-image pattern by building and pushing one SHA-tagged GHCR Docker E2E image before the Docker matrix, then running the matrix with `OPENCLAW_SKIP_DOCKER_BUILD=1`. QR and installer Docker tests keep their own install-focused Dockerfiles. A separate `docker-e2e-fast` job runs the bounded bundled-plugin Docker profile under a 120-second command timeout: setup-entry dependency repair plus synthetic bundled-loader failure isolation. The full bundled update/channel matrix remains manual/full-suite because it performs repeated real npm update and doctor repair passes.
Local changed-lane logic lives in `scripts/changed-lanes.mjs` and is executed by `scripts/check-changed.mjs`. That local gate is stricter about architecture boundaries than the broad CI platform scope: core production changes run core prod typecheck plus core tests, core test-only changes run only core test typecheck/tests, extension production changes run extension prod typecheck plus extension tests, and extension test-only changes run only extension test typecheck/tests. Public Plugin SDK or plugin-contract changes expand to extension validation because extensions depend on those core contracts. Release metadata-only version bumps run targeted version/config/root-dependency checks. Unknown root/config changes fail safe to all lanes.

View File

@ -11603,6 +11603,780 @@
]
}
]
},
{
"language": "th",
"tabs": [
{
"tab": "Get started",
"groups": [
{
"group": "Overview",
"pages": [
"th/index",
"th/start/showcase",
"th/concepts/features"
]
},
{
"group": "First steps",
"pages": [
"th/start/getting-started",
"th/start/onboarding-overview",
"th/start/wizard",
"th/start/onboarding"
]
},
{
"group": "Guides",
"pages": [
"th/start/openclaw",
"th/start/wizard-cli-reference",
"th/start/wizard-cli-automation"
]
}
]
},
{
"tab": "Install",
"groups": [
{
"group": "Install overview",
"pages": [
"th/install/index",
"th/install/installer",
"th/install/node"
]
},
{
"group": "Containers",
"pages": [
"th/install/ansible",
"th/install/bun",
"th/install/clawdock",
"th/install/docker",
"th/install/nix",
"th/install/podman"
]
},
{
"group": "Hosting",
"pages": [
"th/install/azure",
"th/install/digitalocean",
"th/install/docker-vm-runtime",
"th/install/exe-dev",
"th/install/fly",
"th/install/gcp",
"th/install/hetzner",
"th/install/hostinger",
"th/install/kubernetes",
"th/vps",
"th/install/macos-vm",
"th/install/northflank",
"th/install/oracle",
"th/install/railway",
"th/install/raspberry-pi",
"th/install/render"
]
},
{
"group": "Maintenance",
"pages": [
"th/install/updating",
"th/install/migrating",
"th/install/migrating-matrix",
"th/install/uninstall",
"th/install/development-channels"
]
}
]
},
{
"tab": "Channels",
"groups": [
{
"group": "Overview",
"pages": [
"th/channels/index"
]
},
{
"group": "Messaging platforms",
"pages": [
"th/channels/bluebubbles",
"th/channels/discord",
"th/channels/feishu",
"th/channels/googlechat",
"th/channels/imessage",
"th/channels/irc",
"th/channels/line",
"th/channels/matrix",
"th/channels/mattermost",
"th/channels/msteams",
"th/channels/nextcloud-talk",
"th/channels/nostr",
"th/channels/qqbot",
"th/channels/signal",
"th/channels/slack",
"th/channels/synology-chat",
"th/channels/telegram",
"th/channels/tlon",
"th/channels/twitch",
"th/channels/wechat",
"th/channels/whatsapp",
"th/channels/zalo",
"th/channels/zalouser"
]
},
{
"group": "Configuration",
"pages": [
"th/channels/pairing",
"th/channels/group-messages",
"th/channels/groups",
"th/channels/broadcast-groups",
"th/channels/channel-routing",
"th/channels/location",
"th/channels/troubleshooting"
]
}
]
},
{
"tab": "Agents",
"groups": [
{
"group": "Fundamentals",
"pages": [
"th/concepts/architecture",
"th/concepts/agent",
"th/concepts/agent-loop",
"th/concepts/system-prompt",
"th/concepts/context",
"th/concepts/context-engine",
"th/concepts/agent-workspace",
"th/concepts/soul",
"th/concepts/oauth",
"th/start/bootstrapping",
"th/concepts/experimental-features"
]
},
{
"group": "Sessions and memory",
"pages": [
"th/concepts/session",
"th/concepts/session-pruning",
"th/concepts/session-tool",
{
"group": "Memory",
"pages": [
"th/concepts/memory",
"th/concepts/memory-builtin",
"th/concepts/memory-qmd",
"th/concepts/memory-honcho",
"th/concepts/memory-search",
"th/concepts/active-memory",
"th/concepts/dreaming"
]
},
"th/concepts/compaction"
]
},
{
"group": "Multi-agent",
"pages": [
"th/concepts/multi-agent",
"th/concepts/presence",
"th/concepts/delegate-architecture"
]
},
{
"group": "Messages and delivery",
"pages": [
"th/concepts/messages",
"th/concepts/streaming",
"th/concepts/retry",
"th/concepts/queue"
]
}
]
},
{
"tab": "Tools & Plugins",
"groups": [
{
"group": "Overview",
"pages": [
"th/tools/index"
]
},
{
"group": "Plugins",
"pages": [
"th/tools/plugin",
"th/plugins/community",
"th/plugins/bundles",
"th/plugins/codex-harness",
"th/plugins/webhooks",
"th/plugins/voice-call",
"th/plugins/memory-wiki",
"th/plugins/zalouser",
{
"group": "Building Plugins",
"pages": [
"th/plugins/building-plugins",
"th/plugins/sdk-channel-plugins",
"th/plugins/sdk-provider-plugins",
"th/plugins/sdk-migration"
]
},
{
"group": "SDK Reference",
"pages": [
"th/plugins/sdk-overview",
"th/plugins/sdk-entrypoints",
"th/plugins/sdk-runtime",
"th/plugins/sdk-agent-harness",
"th/plugins/sdk-setup",
"th/plugins/sdk-testing",
"th/plugins/manifest",
"th/plugins/architecture"
]
}
]
},
{
"group": "Skills",
"pages": [
"th/tools/skills",
"th/tools/creating-skills",
"th/tools/skills-config",
"th/tools/slash-commands",
"th/tools/clawhub",
"th/prose"
]
},
{
"group": "Automation & Tasks",
"pages": [
"th/automation/index",
"th/automation/cron-jobs",
"th/automation/tasks",
"th/automation/taskflow",
"th/automation/standing-orders",
"th/automation/hooks"
]
},
{
"group": "Tools",
"pages": [
"th/tools/media-overview",
"th/tools/apply-patch",
{
"group": "Web Browser",
"pages": [
"th/tools/browser",
"th/tools/browser-login",
"th/tools/browser-linux-troubleshooting",
"th/tools/browser-wsl2-windows-remote-cdp-troubleshooting"
]
},
{
"group": "Web Tools",
"pages": [
"th/tools/web-fetch",
"th/tools/web",
"th/tools/brave-search",
"th/tools/duckduckgo-search",
"th/tools/exa-search",
"th/tools/firecrawl",
"th/tools/gemini-search",
"th/tools/grok-search",
"th/tools/kimi-search",
"th/tools/minimax-search",
"th/tools/ollama-search",
"th/tools/perplexity-search",
"th/tools/searxng-search",
"th/tools/tavily"
]
},
"th/tools/btw",
"th/tools/code-execution",
"th/tools/diffs",
"th/tools/trajectory",
"th/tools/elevated",
"th/tools/exec",
"th/tools/exec-approvals",
"th/tools/image-generation",
"th/tools/music-generation",
"th/tools/llm-task",
"th/tools/lobster",
"th/tools/loop-detection",
"th/tools/pdf",
"th/tools/reactions",
"th/tools/thinking",
"th/tools/tokenjuice",
"th/tools/video-generation"
]
},
{
"group": "Agent coordination",
"pages": [
"th/tools/agent-send",
"th/tools/subagents",
"th/tools/acp-agents",
"th/tools/multi-agent-sandbox-tools"
]
}
]
},
{
"tab": "Models",
"groups": [
{
"group": "Overview",
"pages": [
"th/providers/index",
"th/providers/models"
]
},
{
"group": "Concepts and configuration",
"pages": [
"th/concepts/models",
"th/concepts/model-providers",
"th/concepts/model-failover"
]
},
{
"group": "Providers",
"pages": [
"th/providers/alibaba",
"th/providers/bedrock",
"th/providers/bedrock-mantle",
"th/providers/anthropic",
"th/providers/arcee",
"th/providers/chutes",
"th/providers/claude-max-api-proxy",
"th/providers/cloudflare-ai-gateway",
"th/providers/comfy",
"th/providers/deepgram",
"th/providers/deepseek",
"th/providers/elevenlabs",
"th/providers/fal",
"th/providers/fireworks",
"th/providers/github-copilot",
"th/providers/glm",
"th/providers/google",
"th/providers/groq",
"th/providers/huggingface",
"th/providers/inferrs",
"th/providers/kilocode",
"th/providers/litellm",
"th/providers/lmstudio",
"th/providers/minimax",
"th/providers/mistral",
"th/providers/moonshot",
"th/providers/nvidia",
"th/providers/ollama",
"th/providers/openai",
"th/providers/opencode",
"th/providers/opencode-go",
"th/providers/openrouter",
"th/providers/perplexity-provider",
"th/providers/qianfan",
"th/providers/qwen",
"th/providers/runway",
"th/providers/sglang",
"th/providers/stepfun",
"th/providers/synthetic",
"th/providers/tencent",
"th/providers/together",
"th/providers/venice",
"th/providers/vercel-ai-gateway",
"th/providers/vllm",
"th/providers/volcengine",
"th/providers/vydra",
"th/providers/xai",
"th/providers/xiaomi",
"th/providers/zai"
]
}
]
},
{
"tab": "Platforms",
"groups": [
{
"group": "Platforms overview",
"pages": [
"th/platforms/index",
"th/platforms/macos",
"th/platforms/linux",
"th/platforms/windows",
"th/platforms/android",
"th/platforms/ios"
]
},
{
"group": "macOS companion app",
"pages": [
"th/platforms/mac/dev-setup",
"th/platforms/mac/menu-bar",
"th/platforms/mac/voicewake",
"th/platforms/mac/voice-overlay",
"th/platforms/mac/webchat",
"th/platforms/mac/canvas",
"th/platforms/mac/child-process",
"th/platforms/mac/health",
"th/platforms/mac/icon",
"th/platforms/mac/logging",
"th/platforms/mac/permissions",
"th/platforms/mac/remote",
"th/platforms/mac/signing",
"th/platforms/mac/bundled-gateway",
"th/platforms/mac/xpc",
"th/platforms/mac/skills",
"th/platforms/mac/peekaboo"
]
}
]
},
{
"tab": "Gateway & Ops",
"groups": [
{
"group": "Gateway",
"pages": [
"th/gateway/index",
{
"group": "Configuration and operations",
"pages": [
"th/gateway/configuration",
"th/gateway/configuration-reference",
"th/gateway/configuration-examples",
"th/gateway/authentication",
"th/auth-credential-semantics",
"th/gateway/secrets",
"th/gateway/secrets-plan-contract",
"th/gateway/trusted-proxy-auth",
"th/gateway/health",
"th/gateway/heartbeat",
"th/gateway/doctor",
"th/gateway/logging",
"th/logging",
"th/gateway/gateway-lock",
"th/gateway/background-process",
"th/gateway/multiple-gateways",
"th/gateway/troubleshooting"
]
},
{
"group": "Security and sandboxing",
"pages": [
"th/gateway/security/index",
"th/gateway/security/audit-checks",
"th/gateway/sandboxing",
"th/gateway/openshell",
"th/gateway/sandbox-vs-tool-policy-vs-elevated"
]
},
{
"group": "Protocols and APIs",
"pages": [
"th/gateway/protocol",
"th/gateway/bridge-protocol",
"th/gateway/openai-http-api",
"th/gateway/openresponses-http-api",
"th/gateway/tools-invoke-http-api",
"th/gateway/cli-backends",
"th/gateway/local-models"
]
},
{
"group": "Networking and discovery",
"pages": [
"th/network",
"th/gateway/network-model",
"th/gateway/pairing",
"th/gateway/discovery",
"th/gateway/bonjour"
]
}
]
},
{
"group": "Remote access",
"pages": [
"th/gateway/remote",
"th/gateway/remote-gateway-readme",
"th/gateway/tailscale"
]
},
{
"group": "Security",
"pages": [
"th/security/formal-verification",
"th/security/THREAT-MODEL-ATLAS",
"th/security/CONTRIBUTING-THREAT-MODEL"
]
},
{
"group": "Nodes and media",
"pages": [
"th/nodes/index",
"th/nodes/troubleshooting",
{
"group": "Media capabilities",
"pages": [
"th/nodes/media-understanding",
"th/nodes/images",
"th/nodes/audio",
"th/nodes/camera",
"th/tools/tts"
]
},
{
"group": "Node features",
"pages": [
"th/nodes/talk",
"th/nodes/voicewake",
"th/nodes/location-command"
]
}
]
},
{
"group": "Web interfaces",
"pages": [
"th/web/index",
"th/web/control-ui",
"th/web/dashboard",
"th/web/webchat",
"th/web/tui"
]
}
]
},
{
"tab": "Reference",
"groups": [
{
"group": "CLI commands",
"pages": [
"th/cli/index",
{
"group": "Gateway and service",
"pages": [
"th/cli/backup",
"th/cli/daemon",
"th/cli/doctor",
"th/cli/gateway",
"th/cli/health",
"th/cli/logs",
"th/cli/onboard",
"th/cli/reset",
"th/cli/secrets",
"th/cli/security",
"th/cli/setup",
"th/cli/status",
"th/cli/uninstall",
"th/cli/update"
]
},
{
"group": "Agents and sessions",
"pages": [
"th/cli/agent",
"th/cli/agents",
"th/cli/hooks",
"th/cli/infer",
"th/cli/memory",
"th/cli/message",
"th/cli/models",
"th/cli/sessions",
"th/cli/system",
"th/cli/tasks"
]
},
{
"group": "Channels and messaging",
"pages": [
"th/cli/channels",
"th/cli/devices",
"th/cli/directory",
"th/cli/pairing",
"th/cli/qr",
"th/cli/voicecall"
]
},
{
"group": "Tools and execution",
"pages": [
"th/cli/approvals",
"th/cli/browser",
"th/cli/cron",
"th/cli/flows",
"th/cli/node",
"th/cli/nodes",
"th/cli/sandbox"
]
},
{
"group": "Configuration",
"pages": [
"th/cli/config",
"th/cli/configure",
"th/cli/webhooks"
]
},
{
"group": "Plugins and skills",
"pages": [
"th/cli/plugins",
"th/cli/skills"
]
},
{
"group": "Interfaces",
"pages": [
"th/cli/dashboard",
"th/cli/tui"
]
},
{
"group": "Utility",
"pages": [
"th/cli/acp",
"th/cli/clawbot",
"th/cli/completion",
"th/cli/dns",
"th/cli/docs",
"th/cli/mcp",
"th/cli/wiki"
]
}
]
},
{
"group": "RPC and API",
"pages": [
"th/reference/rpc",
"th/reference/device-models"
]
},
{
"group": "Templates",
"pages": [
"th/reference/AGENTS.default",
"th/reference/templates/AGENTS",
"th/reference/templates/BOOT",
"th/reference/templates/BOOTSTRAP",
"th/reference/templates/HEARTBEAT",
"th/reference/templates/IDENTITY",
"th/reference/templates/SOUL",
"th/reference/templates/TOOLS",
"th/reference/templates/USER"
]
},
{
"group": "Technical reference",
"pages": [
"th/pi",
"th/reference/wizard",
"th/reference/token-use",
"th/reference/secretref-credential-surface",
"th/reference/prompt-caching",
"th/reference/api-usage-costs",
"th/reference/transcript-hygiene",
"th/reference/memory-config",
"th/reference/rich-output-protocol",
"th/date-time"
]
},
{
"group": "Concept internals",
"pages": [
"th/concepts/typebox",
"th/concepts/markdown-formatting",
"th/concepts/typing-indicators",
"th/concepts/usage-tracking",
"th/concepts/timezone"
]
},
{
"group": "Project",
"pages": [
"th/reference/credits"
]
},
{
"group": "Release policy",
"pages": [
"th/reference/RELEASING",
"th/reference/test"
]
}
]
},
{
"tab": "Help",
"groups": [
{
"group": "Help",
"pages": [
"th/help/index",
"th/help/troubleshooting",
"th/help/faq"
]
},
{
"group": "Community",
"pages": [
"th/start/lore"
]
},
{
"group": "Environment and debugging",
"pages": [
"th/help/environment",
"th/help/debugging",
"th/help/testing",
"th/help/scripts",
"th/debug/node-issue",
"th/diagnostics/flags"
]
},
{
"group": "Compaction internals",
"pages": [
"th/reference/session-management-compaction"
]
},
{
"group": "Developer setup",
"pages": [
"th/start/setup",
"th/pi-dev"
]
},
{
"group": "Contributing",
"pages": [
"th/ci"
]
},
{
"group": "Docs meta",
"pages": [
"th/start/hubs",
"th/start/docs-directory"
]
}
]
}
]
}
]
}

View File

@ -32,6 +32,7 @@ title: "Tests"
- Gateway integration: opt-in via `OPENCLAW_TEST_INCLUDE_GATEWAY=1 pnpm test` or `pnpm test:gateway`.
- `pnpm test:e2e`: Runs gateway end-to-end smoke tests (multi-instance WS/HTTP/node pairing). Defaults to `threads` + `isolate: false` with adaptive workers in `vitest.e2e.config.ts`; tune with `OPENCLAW_E2E_WORKERS=<n>` and set `OPENCLAW_E2E_VERBOSE=1` for verbose logs.
- `pnpm test:live`: Runs provider live tests (minimax/zai). Requires API keys and `LIVE=1` (or provider-specific `*_LIVE_TEST=1`) to unskip.
- `pnpm test:docker:all`: Builds the shared live-test image and Docker E2E image once, then runs the Docker smoke lanes with `OPENCLAW_SKIP_DOCKER_BUILD=1` at concurrency 4 by default. Tune with `OPENCLAW_DOCKER_ALL_PARALLELISM=<n>`. Startup- or provider-sensitive lanes run exclusively after the parallel pool. Per-lane logs are written under `.artifacts/docker-tests/<run-id>/`.
- `pnpm test:docker:openwebui`: Starts Dockerized OpenClaw + Open WebUI, signs in through Open WebUI, checks `/api/models`, then runs a real proxied chat through `/api/chat/completions`. Requires a usable live model key (for example OpenAI in `~/.profile`), pulls an external Open WebUI image, and is not expected to be CI-stable like the normal unit/e2e suites.
- `pnpm test:docker:mcp-channels`: Starts a seeded Gateway container and a second client container that spawns `openclaw mcp serve`, then verifies routed conversation discovery, transcript reads, attachment metadata, live event queue behavior, outbound send routing, and Claude-style channel + permission notifications over the real stdio bridge. The Claude notification assertion reads the raw stdio MCP frames directly so the smoke reflects what the bridge actually emits.

View File

@ -255,6 +255,10 @@ plugin). Other bundled plugins still need `openclaw plugins enable <id>`.
plugins. It is not supported with `--link`, which reuses the source path instead
of copying over a managed install target.
When `plugins.allow` is already set, `openclaw plugins install` adds the
installed plugin id to that allowlist before enabling it, so installs are
immediately loadable after restart.
`openclaw plugins update <id-or-npm-spec>` applies to tracked installs. Passing
an npm package spec with a dist-tag or exact version resolves the package name
back to the tracked plugin record and records the new spec for future updates.

View File

@ -39,7 +39,7 @@ title: "Thinking Levels"
2. Session override (set by sending a directive-only message).
3. Per-agent default (`agents.list[].thinkingDefault` in config).
4. Global default (`agents.defaults.thinkingDefault` in config).
5. Fallback: provider-declared default when available, `low` for other catalog models marked reasoning-capable, `off` otherwise.
5. Fallback: provider-declared default when available; otherwise reasoning-capable models resolve to `medium` or the nearest supported non-`off` level for that model, and non-reasoning models stay `off`.
## Setting a session default
@ -113,7 +113,7 @@ title: "Thinking Levels"
- The web chat thinking selector mirrors the session's stored level from the inbound session store/config when the page loads.
- Picking another level writes the session override immediately via `sessions.patch`; it does not wait for the next send and it is not a one-shot `thinkingOnce` override.
- The first option is always `Default (<resolved level>)`, where the resolved default comes from the active session model's provider thinking profile.
- The first option is always `Default (<resolved level>)`, where the resolved default comes from the active session model's provider thinking profile plus the same fallback logic that `/status` and `session_status` use.
- The picker uses `thinkingOptions` returned by the gateway session row. The browser UI does not keep its own provider regex list; plugins own model-specific level sets.
- `/think:<level>` still works and updates the same stored session level, so chat directives and the picker stay in sync.