From 00d8d7ead05990b6e80e5094ef1b4ccbfde81e87 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 31 May 2026 01:33:00 +0100 Subject: [PATCH] refactor: extract normalization core package Extract shared normalization/coercion helpers into private @openclaw/normalization-core workspace package while preserving existing plugin SDK helper subpaths.\n\nAlso keeps direct normalization-core imports internal, wires UI/build/loader resolution, and replaces the slow PR network CodeQL lane with a fast added-line boundary scan while retaining full CodeQL for scheduled/manual runs.\n\nVerification: local moved tests, plugin SDK boundary tests, extension loader tests, agents-support shard, UI build/test, build artifacts, lint, workflow guards, autoreview, and GitHub CI passed on PR head 963d893715b6526ff9e7806e2614c1a1f8013801. --- ...work-runtime-boundary-critical-quality.yml | 12 +- .github/workflows/codeql-critical-quality.yml | 34 +++- .../tsconfig.package-boundary.paths.json | 80 +++++--- extensions/xai/tsconfig.json | 80 +++++--- packages/normalization-core/dist/index.d.mts | 5 + packages/normalization-core/dist/index.mjs | 5 + .../dist/number-coercion.d.mts | 70 +++++++ .../dist/number-coercion.mjs | 178 ++++++++++++++++++ .../dist/record-coerce.d.mts | 10 + .../normalization-core/dist/record-coerce.mjs | 25 +++ .../dist/string-coerce.d.mts | 17 ++ .../normalization-core/dist/string-coerce.mjs | 72 +++++++ .../dist/string-normalization.d.mts | 21 +++ .../dist/string-normalization.mjs | 75 ++++++++ packages/normalization-core/package.json | 41 ++++ packages/normalization-core/src/index.ts | 4 + .../src}/number-coercion.test.ts | 0 .../src}/number-coercion.ts | 0 .../src}/record-coerce.test.ts | 5 +- .../normalization-core/src}/record-coerce.ts | 0 .../src}/string-coerce.test.ts | 2 +- .../normalization-core/src}/string-coerce.ts | 0 .../src}/string-normalization.test.ts | 2 +- .../src}/string-normalization.ts | 0 packages/plugin-sdk/tsconfig.json | 1 + pnpm-lock.yaml | 9 +- scripts/build-all.mjs | 2 + scripts/debug-claude-usage.ts | 2 +- scripts/e2e/mcp-channels-harness.ts | 2 +- scripts/lib/plugin-npm-release.ts | 2 +- scripts/lib/tsdown-output-roots.mjs | 1 + ...e-extension-package-boundary-artifacts.mjs | 6 + scripts/run-node-watch-paths.mjs | 1 + scripts/write-plugin-sdk-entry-dts.ts | 5 +- src/acp/approval-classifier.ts | 8 +- src/acp/client-helpers.ts | 8 +- src/acp/client.ts | 2 +- src/acp/control-plane/manager.core.ts | 4 +- .../control-plane/manager.runtime-controls.ts | 4 +- src/acp/control-plane/manager.test.ts | 2 +- src/acp/control-plane/manager.utils.ts | 2 +- src/acp/control-plane/runtime-options.ts | 2 +- src/acp/event-mapper.ts | 2 +- src/acp/meta.ts | 2 +- src/acp/normalize-text.ts | 2 +- src/acp/numeric-options.ts | 2 +- src/acp/permission-relay.ts | 2 +- src/acp/persistent-bindings.lifecycle.ts | 2 +- src/acp/persistent-bindings.types.ts | 2 +- src/acp/record-shared.ts | 2 +- src/acp/runtime/adapter-contract.testkit.ts | 2 +- src/acp/runtime/registry.ts | 2 +- src/acp/runtime/session-identifiers.ts | 2 +- src/acp/runtime/session-meta.ts | 2 +- src/acp/server.ts | 2 +- src/acp/session-interaction-mode.ts | 2 +- src/acp/session-lineage-meta.ts | 2 +- src/acp/translator.ts | 4 +- src/acp/types.ts | 2 +- src/agents/accepted-session-spawn.ts | 4 +- src/agents/acp-spawn-parent-stream.ts | 4 +- src/agents/acp-spawn.ts | 8 +- src/agents/agent-auth-credentials.ts | 4 +- src/agents/agent-bundle-lsp-runtime.ts | 2 +- src/agents/agent-bundle-mcp-materialize.ts | 2 +- src/agents/agent-bundle-mcp-names.ts | 2 +- src/agents/agent-bundle-mcp-runtime.ts | 2 +- src/agents/agent-command.ts | 2 +- src/agents/agent-delete-safety.ts | 2 +- .../compaction-safeguard-quality.ts | 4 +- .../agent-hooks/context-pruning/tools.ts | 2 +- src/agents/agent-model-discovery.auth.test.ts | 2 +- src/agents/agent-scope-config.ts | 2 +- src/agents/agent-scope.ts | 12 +- src/agents/agent-tools-parameter-schema.ts | 6 +- src/agents/agent-tools.before-tool-call.ts | 2 +- .../agent-tools.message-provider-policy.ts | 2 +- src/agents/agent-tools.policy.ts | 16 +- src/agents/agent-tools.ts | 8 +- src/agents/anthropic-transport-stream.ts | 2 +- src/agents/api-key-rotation.ts | 2 +- src/agents/auth-health.test.ts | 2 +- src/agents/auth-health.ts | 4 +- src/agents/auth-profiles/credential-state.ts | 2 +- .../auth-profiles/external-cli-discovery.ts | 2 +- src/agents/auth-profiles/identity.ts | 2 +- .../auth-profiles/oauth-identity.test.ts | 2 +- src/agents/auth-profiles/oauth-identity.ts | 2 +- src/agents/auth-profiles/oauth.ts | 2 +- src/agents/auth-profiles/persisted.ts | 4 +- src/agents/auth-profiles/profile-list.ts | 2 +- src/agents/auth-profiles/profiles.ts | 2 +- src/agents/auth-profiles/state.ts | 8 +- src/agents/auth-profiles/usage.ts | 6 +- ...bash-tools.exec-approval-followup-state.ts | 4 +- .../bash-tools.exec-approval-followup.ts | 8 +- .../bash-tools.exec-approval-request.ts | 13 +- src/agents/bash-tools.exec-host-gateway.ts | 4 +- .../bash-tools.exec-host-node-phases.ts | 2 +- .../bash-tools.exec-host-shared.test.ts | 2 +- src/agents/bash-tools.exec-host-shared.ts | 2 +- src/agents/bash-tools.exec-runtime.ts | 2 +- src/agents/bash-tools.exec.ts | 12 +- src/agents/bash-tools.shared.ts | 2 +- src/agents/bootstrap-budget.ts | 2 +- src/agents/bootstrap-files.ts | 2 +- src/agents/btw.ts | 2 +- .../cache/agent-cache-store.sqlite.test.ts | 2 +- src/agents/cache/agent-cache-store.sqlite.ts | 14 +- src/agents/channel-tools.ts | 2 +- src/agents/chutes-oauth.ts | 2 +- src/agents/cli-auth-epoch.ts | 2 +- src/agents/cli-backends.ts | 4 +- src/agents/cli-credentials.ts | 8 +- src/agents/cli-output.ts | 4 +- .../cli-runner/bundle-mcp-adapter-shared.ts | 4 +- src/agents/cli-runner/bundle-mcp-claude.ts | 2 +- src/agents/cli-runner/claude-skills-plugin.ts | 2 +- src/agents/cli-runner/helpers.ts | 8 +- src/agents/cli-runner/prepare.ts | 2 +- src/agents/cli-runner/reliability.ts | 2 +- src/agents/cli-runner/toml-inline.ts | 2 +- src/agents/cli-session.ts | 2 +- src/agents/code-mode-namespaces.ts | 2 +- src/agents/code-mode.test.ts | 2 +- src/agents/code-mode.ts | 10 +- src/agents/codex-mcp-config.ts | 2 +- src/agents/codex-native-web-search.shared.ts | 2 +- src/agents/command/claude-cli-project-dir.ts | 2 +- src/agents/command/session-store.ts | 2 +- src/agents/context.ts | 2 +- src/agents/current-time.ts | 2 +- src/agents/date-time.ts | 2 +- .../embedded-agent-error-observation.ts | 2 +- .../embedded-agent-helpers/bootstrap.ts | 2 +- src/agents/embedded-agent-helpers/errors.ts | 8 +- .../failover-matches.ts | 2 +- .../messaging-dedupe.ts | 2 +- .../sanitize-user-facing-text.ts | 2 +- src/agents/embedded-agent-helpers/thinking.ts | 2 +- src/agents/embedded-agent-helpers/turns.ts | 2 +- src/agents/embedded-agent-messaging.ts | 2 +- src/agents/embedded-agent-runner/abort.ts | 2 +- src/agents/embedded-agent-runner/cache-ttl.ts | 8 +- .../embedded-agent-runner/compact-reasons.ts | 2 +- .../compaction-duplicate-user-messages.ts | 2 +- .../compaction-safety-timeout.ts | 2 +- .../compaction-successor-transcript.ts | 2 +- .../context-engine-capabilities.ts | 2 +- .../context-engine-maintenance.ts | 2 +- .../empty-assistant-turn.ts | 2 +- .../embedded-agent-runner/extensions.ts | 2 +- .../embedded-agent-runner/failure-signal.ts | 2 +- .../google-prompt-cache.ts | 12 +- src/agents/embedded-agent-runner/history.ts | 2 +- .../model.inline-provider.ts | 2 +- .../model.provider-runtime.test-support.ts | 2 +- .../embedded-agent-runner/model.test.ts | 2 +- src/agents/embedded-agent-runner/model.ts | 2 +- .../prompt-cache-retention.ts | 2 +- .../run.overflow-compaction.harness.ts | 2 +- src/agents/embedded-agent-runner/run.ts | 2 +- .../run/attempt.session-lock.ts | 2 +- .../attempt.spawn-workspace.test-support.ts | 8 +- .../run/attempt.tool-call-normalization.ts | 4 +- .../embedded-agent-runner/run/attempt.ts | 2 +- ...compaction-retry-aggregate-timeout.test.ts | 2 +- .../run/compaction-retry-aggregate-timeout.ts | 2 +- .../embedded-agent-runner/run/images.ts | 2 +- .../run/incomplete-turn.ts | 4 +- .../run/llm-idle-timeout.test.ts | 2 +- .../run/llm-idle-timeout.ts | 6 +- .../embedded-agent-runner/run/payloads.ts | 8 +- .../run/preemptive-compaction.ts | 2 +- src/agents/embedded-agent-runner/runs.ts | 2 +- .../tool-result-truncation.ts | 2 +- ...edded-agent-subscribe.handlers.messages.ts | 4 +- ...embedded-agent-subscribe.handlers.tools.ts | 13 +- ...d-agent-subscribe.tool-text-diagnostics.ts | 2 +- src/agents/embedded-agent-subscribe.tools.ts | 12 +- src/agents/embedded-agent-subscribe.ts | 2 +- src/agents/exec-approval-result.ts | 2 +- src/agents/exec-auto-reviewer.test.ts | 2 +- src/agents/exec-auto-reviewer.ts | 4 +- src/agents/execution-contract.ts | 2 +- src/agents/failover-error.ts | 2 +- src/agents/generated-attachments.ts | 4 +- src/agents/gpt5-prompt-overlay.ts | 2 +- src/agents/harness/lifecycle-hook-helpers.ts | 2 +- src/agents/harness/native-hook-relay.ts | 8 +- src/agents/harness/tool-result-middleware.ts | 2 +- src/agents/heartbeat-system-prompt.ts | 2 +- src/agents/identity-avatar.ts | 2 +- src/agents/identity-file.ts | 2 +- src/agents/inherited-tool-deny.ts | 2 +- src/agents/live-auth-keys.ts | 6 +- src/agents/live-cache-regression-runner.ts | 2 +- src/agents/live-model-dynamic-candidates.ts | 2 +- src/agents/live-model-filter.ts | 4 +- src/agents/live-model-switch.ts | 2 +- src/agents/live-target-matcher.ts | 4 +- src/agents/live-test-provider-drift.ts | 2 +- src/agents/main-session-restart-recovery.ts | 2 +- src/agents/mcp-oauth.ts | 2 +- src/agents/mcp-transport-config.ts | 2 +- src/agents/mcp-transport.ts | 2 +- .../media-generation-task-status-shared.ts | 4 +- src/agents/memory-search.ts | 5 +- src/agents/model-alias-lines.ts | 2 +- src/agents/model-auth-env.ts | 2 +- src/agents/model-auth-label.ts | 2 +- src/agents/model-auth-markers.ts | 5 +- src/agents/model-auth.ts | 10 +- src/agents/model-catalog-browse.ts | 2 +- src/agents/model-catalog-lookup.ts | 2 +- src/agents/model-catalog-scope.ts | 2 +- src/agents/model-catalog.ts | 8 +- src/agents/model-fallback.ts | 2 +- src/agents/model-ref-shared.ts | 2 +- src/agents/model-runtime-aliases.ts | 2 +- src/agents/model-scan.test.ts | 2 +- src/agents/model-scan.ts | 15 +- src/agents/model-selection-display.ts | 2 +- src/agents/model-selection-normalize.ts | 2 +- src/agents/model-selection-shared.ts | 8 +- src/agents/model-selection.ts | 8 +- src/agents/model-suppression.ts | 2 +- src/agents/model-thinking-default.ts | 6 +- src/agents/models-config.merge.ts | 2 +- .../models-config.providers.implicit.ts | 5 +- .../models-config.providers.policy.lookup.ts | 2 +- .../models-config.providers.secret-helpers.ts | 2 +- src/agents/openai-reasoning-compat.ts | 3 +- src/agents/openai-reasoning-effort.ts | 7 +- src/agents/openai-responses-payload-policy.ts | 2 +- src/agents/openai-strict-tool-setting.ts | 2 +- src/agents/openai-text-verbosity.ts | 2 +- src/agents/openai-transport-stream.ts | 4 +- .../openclaw-tools.media-factory-plan.ts | 2 +- src/agents/openclaw-tools.registration.ts | 2 +- src/agents/owner-display.ts | 2 +- src/agents/payload-redaction.ts | 2 +- src/agents/prompt-cache-stability.ts | 2 +- src/agents/provider-attribution.ts | 8 +- src/agents/provider-http-errors.ts | 6 +- src/agents/provider-local-service.test.ts | 2 +- src/agents/provider-local-service.ts | 8 +- src/agents/provider-request-config.ts | 2 +- src/agents/provider-transport-fetch.test.ts | 2 +- src/agents/provider-transport-fetch.ts | 12 +- src/agents/pty-keys.ts | 2 +- .../responses-image-payload-sanitizer.ts | 2 +- src/agents/run-wait.test.ts | 4 +- src/agents/run-wait.ts | 8 +- src/agents/runtime-capabilities.ts | 4 +- src/agents/sandbox-tool-policy.ts | 2 +- src/agents/sandbox/backend.ts | 2 +- src/agents/sandbox/browser.ts | 8 +- src/agents/sandbox/config.test.ts | 2 +- src/agents/sandbox/config.ts | 4 +- src/agents/sandbox/fs-bridge.ts | 2 +- src/agents/sandbox/fs-paths.ts | 4 +- src/agents/sandbox/network-mode.ts | 2 +- src/agents/sandbox/novnc-auth.ts | 4 +- src/agents/sandbox/runtime-status.ts | 2 +- src/agents/sandbox/shared.ts | 2 +- src/agents/sandbox/ssh-backend.ts | 2 +- src/agents/sandbox/tool-policy.ts | 4 +- .../sandbox/validate-sandbox-security.ts | 2 +- src/agents/session-agent-binding.ts | 8 +- src/agents/session-async-task-status.ts | 2 +- src/agents/session-runtime-compat.ts | 2 +- src/agents/session-tool-result-guard.ts | 4 +- src/agents/session-transcript-repair.ts | 2 +- src/agents/session-write-lock.test.ts | 2 +- src/agents/session-write-lock.ts | 2 +- src/agents/sessions/extensions/loader.ts | 2 + src/agents/sessions/tools/bash.test.ts | 2 +- src/agents/sessions/tools/bash.ts | 2 +- src/agents/spawned-context.ts | 2 +- src/agents/subagent-announce-delivery.ts | 9 +- src/agents/subagent-announce-origin.ts | 2 +- src/agents/subagent-announce-output.ts | 2 +- src/agents/subagent-announce.timeout.test.ts | 2 +- src/agents/subagent-announce.ts | 2 +- src/agents/subagent-attachments.ts | 2 +- src/agents/subagent-capabilities.ts | 10 +- src/agents/subagent-depth.test.ts | 2 +- src/agents/subagent-list.ts | 2 +- src/agents/subagent-registry-helpers.ts | 2 +- src/agents/subagent-registry-lifecycle.ts | 2 +- src/agents/subagent-registry.store.ts | 2 +- src/agents/subagent-session-key.ts | 2 +- src/agents/subagent-session-reconciliation.ts | 2 +- src/agents/subagent-spawn-thinking.ts | 2 +- src/agents/subagent-spawn.context.test.ts | 2 +- src/agents/subagent-spawn.test-helpers.ts | 2 +- src/agents/subagent-spawn.ts | 10 +- src/agents/subagent-system-prompt.ts | 2 +- src/agents/subagent-target-policy.ts | 5 +- src/agents/subagent-task-name.ts | 2 +- src/agents/subagent-yield-output.ts | 2 +- src/agents/system-prompt-params.ts | 2 +- src/agents/system-prompt.ts | 18 +- .../fast-openclaw-tools-sessions.ts | 2 +- src/agents/timeout.ts | 5 +- src/agents/tool-allowlist-guard.ts | 2 +- src/agents/tool-call-shared.ts | 2 +- src/agents/tool-description-summary.ts | 4 +- src/agents/tool-display-common.ts | 4 +- src/agents/tool-display-exec-shell.ts | 2 +- src/agents/tool-display-record.ts | 2 +- src/agents/tool-display.ts | 2 +- src/agents/tool-error-summary.ts | 2 +- src/agents/tool-images.ts | 2 +- src/agents/tool-loop-detection.ts | 8 +- src/agents/tool-mutation.ts | 2 +- src/agents/tool-policy-shared.ts | 4 +- src/agents/tool-policy.ts | 4 +- src/agents/tool-search.ts | 10 +- src/agents/tools-effective-inventory-build.ts | 8 +- src/agents/tools-effective-inventory.ts | 8 +- src/agents/tools-effective-mcp-inventory.ts | 25 +-- src/agents/tools/common.ts | 12 +- src/agents/tools/cron-tool.ts | 2 +- src/agents/tools/gateway-tool.ts | 7 +- src/agents/tools/gateway.ts | 8 +- src/agents/tools/heartbeat-response-tool.ts | 2 +- src/agents/tools/image-tool.helpers.ts | 2 +- src/agents/tools/media-tool-shared.ts | 10 +- src/agents/tools/message-tool.ts | 4 +- src/agents/tools/music-generate-tool.ts | 2 +- src/agents/tools/nodes-tool-commands.ts | 2 +- src/agents/tools/nodes-tool-media.ts | 2 +- src/agents/tools/nodes-utils.ts | 2 +- src/agents/tools/pdf-tool.ts | 8 +- src/agents/tools/session-status-tool.ts | 2 +- src/agents/tools/sessions-access.ts | 2 +- src/agents/tools/sessions-announce-target.ts | 2 +- src/agents/tools/sessions-helpers.ts | 2 +- src/agents/tools/sessions-history-tool.ts | 2 +- src/agents/tools/sessions-list-tool.ts | 5 +- src/agents/tools/sessions-resolution.ts | 2 +- src/agents/tools/sessions-send-tool.ts | 4 +- src/agents/tools/sessions.test.ts | 2 +- src/agents/tools/transcripts-tool.ts | 2 +- src/agents/tools/web-fetch-visibility.ts | 2 +- src/agents/tools/web-fetch.test-harness.ts | 2 +- src/agents/tools/web-fetch.ts | 10 +- src/agents/tools/web-guarded-fetch.test.ts | 2 +- src/agents/tools/web-guarded-fetch.ts | 2 +- .../tools/web-search-provider-common.ts | 2 +- src/agents/tools/web-shared.test.ts | 2 +- src/agents/tools/web-shared.ts | 4 +- src/agents/transcript-policy.ts | 2 +- src/agents/usage.ts | 2 +- src/agents/workspace-default.ts | 2 +- src/agents/workspace.ts | 2 +- src/auto-reply/command-auth.ts | 12 +- src/auto-reply/command-detection.ts | 4 +- src/auto-reply/command-status-builders.ts | 10 +- src/auto-reply/command-turn-context.ts | 2 +- src/auto-reply/command-turn-detection.ts | 2 +- src/auto-reply/commands-args.ts | 2 +- src/auto-reply/commands-registry-normalize.ts | 4 +- src/auto-reply/commands-registry.shared.ts | 4 +- src/auto-reply/commands-registry.ts | 2 +- src/auto-reply/commands-text-routing.ts | 2 +- src/auto-reply/envelope.ts | 8 +- src/auto-reply/fallback-state.ts | 2 +- src/auto-reply/group-activation.ts | 2 +- src/auto-reply/heartbeat-filter.ts | 6 +- src/auto-reply/heartbeat-tool-response.ts | 4 +- src/auto-reply/heartbeat.ts | 2 +- src/auto-reply/media-note.ts | 2 +- src/auto-reply/model-runtime.ts | 4 +- src/auto-reply/model.ts | 2 +- ...irective.directive-behavior.e2e-harness.ts | 2 +- src/auto-reply/reply/abort-cutoff.ts | 2 +- src/auto-reply/reply/abort-primitives.ts | 2 +- src/auto-reply/reply/abort.ts | 8 +- src/auto-reply/reply/acp-projector.ts | 8 +- src/auto-reply/reply/acp-reset-target.ts | 8 +- .../reply/agent-runner-cli-dispatch.ts | 10 +- .../reply/agent-runner-execution.ts | 12 +- src/auto-reply/reply/agent-runner-memory.ts | 8 +- .../reply/agent-runner-reminder-guard.ts | 2 +- src/auto-reply/reply/agent-runner-utils.ts | 8 +- src/auto-reply/reply/agent-runner.ts | 2 +- .../reply/agent-turn-attachments.ts | 2 +- src/auto-reply/reply/bash-command.ts | 8 +- src/auto-reply/reply/btw-command.ts | 2 +- src/auto-reply/reply/channel-context.ts | 6 +- src/auto-reply/reply/commands-acp/context.ts | 2 +- .../reply/commands-acp/diagnostics.ts | 8 +- .../reply/commands-acp/install-hints.ts | 6 +- .../reply/commands-acp/lifecycle.ts | 2 +- .../reply/commands-acp/runtime-options.ts | 4 +- src/auto-reply/reply/commands-acp/shared.ts | 8 +- src/auto-reply/reply/commands-acp/targets.ts | 2 +- src/auto-reply/reply/commands-allowlist.ts | 10 +- src/auto-reply/reply/commands-approve.ts | 2 +- src/auto-reply/reply/commands-compact.ts | 10 +- src/auto-reply/reply/commands-config.ts | 2 +- .../reply/commands-context-report.ts | 2 +- src/auto-reply/reply/commands-context.ts | 6 +- src/auto-reply/reply/commands-diagnostics.ts | 2 +- src/auto-reply/reply/commands-dock.ts | 6 +- .../reply/commands-export-session.ts | 6 +- src/auto-reply/reply/commands-goal.ts | 8 +- src/auto-reply/reply/commands-models.ts | 10 +- src/auto-reply/reply/commands-plugin.ts | 2 +- src/auto-reply/reply/commands-plugins.ts | 2 +- .../reply/commands-private-route.test.ts | 2 +- .../reply/commands-private-route.ts | 10 +- src/auto-reply/reply/commands-reset-mode.ts | 2 +- .../reply/commands-session-abort.ts | 2 +- src/auto-reply/reply/commands-session.ts | 12 +- src/auto-reply/reply/commands-slash-parse.ts | 2 +- src/auto-reply/reply/commands-steer.ts | 2 +- .../reply/commands-subagents/action-agents.ts | 2 +- .../reply/commands-subagents/action-focus.ts | 2 +- .../reply/commands-subagents/action-info.ts | 2 +- .../reply/commands-subagents/action-log.ts | 4 +- .../commands-subagents/action-unfocus.ts | 2 +- .../reply/commands-subagents/shared.ts | 8 +- src/auto-reply/reply/commands-tts.ts | 6 +- .../reply/conversation-binding-input.ts | 2 +- src/auto-reply/reply/current-turn-images.ts | 2 +- .../reply/directive-handling.auth-profile.ts | 2 +- .../reply/directive-handling.auth.ts | 2 +- .../reply/directive-handling.impl.ts | 2 +- .../reply/directive-handling.model-picker.ts | 8 +- .../reply/directive-handling.model.ts | 8 +- .../reply/directive-handling.shared.ts | 2 +- src/auto-reply/reply/dispatch-acp-delivery.ts | 8 +- src/auto-reply/reply/dispatch-acp.ts | 10 +- src/auto-reply/reply/dispatch-from-config.ts | 10 +- .../reply/elevated-allowlist-matcher.ts | 6 +- src/auto-reply/reply/exec/directive.ts | 2 +- src/auto-reply/reply/followup-runner.ts | 2 +- .../reply/get-reply-directive-aliases.ts | 4 +- src/auto-reply/reply/get-reply-directives.ts | 8 +- src/auto-reply/reply/get-reply-fast-path.ts | 10 +- .../reply/get-reply-inline-actions.ts | 8 +- .../reply/get-reply-native-slash-fast-path.ts | 2 +- src/auto-reply/reply/get-reply-run.ts | 2 +- src/auto-reply/reply/get-reply.ts | 4 +- src/auto-reply/reply/group-id-simple.ts | 2 +- src/auto-reply/reply/group-id.ts | 10 +- src/auto-reply/reply/groups.ts | 8 +- src/auto-reply/reply/history-media.ts | 4 +- src/auto-reply/reply/inbound-context.ts | 2 +- src/auto-reply/reply/inbound-dedupe.ts | 8 +- src/auto-reply/reply/inbound-media.ts | 2 +- src/auto-reply/reply/inbound-meta.ts | 4 +- src/auto-reply/reply/mentions.ts | 10 +- .../reply/message-preprocess-hooks.ts | 2 +- .../reply/model-selection-directive.ts | 2 +- src/auto-reply/reply/normalize-reply.ts | 2 +- src/auto-reply/reply/origin-routing.ts | 2 +- src/auto-reply/reply/plugins-commands.ts | 2 +- .../reply/post-compaction-context.ts | 2 +- src/auto-reply/reply/prompt-prelude.ts | 2 +- .../provider-request-error-classifier.ts | 2 +- src/auto-reply/reply/queue/cleanup.ts | 2 +- src/auto-reply/reply/queue/directive.ts | 2 +- src/auto-reply/reply/queue/enqueue.ts | 2 +- src/auto-reply/reply/queue/normalize.ts | 2 +- .../reply/queue/settings-runtime.ts | 2 +- src/auto-reply/reply/queue/settings.ts | 2 +- src/auto-reply/reply/queue/state.ts | 2 +- src/auto-reply/reply/reply-elevated.ts | 4 +- src/auto-reply/reply/reply-inline.ts | 2 +- src/auto-reply/reply/reply-payloads-base.ts | 2 +- src/auto-reply/reply/reply-payloads-dedupe.ts | 8 +- src/auto-reply/reply/reply-reference.ts | 2 +- src/auto-reply/reply/reply-run-registry.ts | 2 +- src/auto-reply/reply/reply-threading.ts | 2 +- .../reply/response-prefix-template.ts | 2 +- src/auto-reply/reply/route-reply.ts | 2 +- .../reply/runtime-policy-session-key.ts | 8 +- src/auto-reply/reply/session-delivery.ts | 8 +- src/auto-reply/reply/session-reset-model.ts | 2 +- src/auto-reply/reply/session-system-events.ts | 8 +- src/auto-reply/reply/session-updates.ts | 2 +- src/auto-reply/reply/session.ts | 10 +- src/auto-reply/reply/stage-sandbox-media.ts | 2 +- src/auto-reply/reply/startup-context.ts | 2 +- src/auto-reply/reply/stored-model-override.ts | 2 +- src/auto-reply/reply/subagents-utils.ts | 4 +- src/auto-reply/reply/typing-mode.ts | 2 +- src/auto-reply/reply/typing.ts | 2 +- src/auto-reply/send-policy.ts | 2 +- .../command-auth-registry-fixture.ts | 4 +- src/auto-reply/thinking.shared.ts | 2 +- src/auto-reply/thinking.ts | 8 +- src/auto-reply/tool-meta.ts | 2 +- src/channels/account-snapshot-fields.ts | 6 +- src/channels/account-summary.ts | 2 +- src/channels/allow-from.ts | 2 +- src/channels/allowlist-match.ts | 2 +- src/channels/allowlists/resolve-utils.ts | 6 +- src/channels/bundled-channel-catalog-read.ts | 4 +- src/channels/channel-config.ts | 4 +- src/channels/chat-meta-shared.ts | 2 +- src/channels/chat-type.ts | 2 +- src/channels/config-presence.ts | 4 +- src/channels/conversation-label.ts | 4 +- src/channels/conversation-resolution.ts | 10 +- src/channels/direct-dm-guard-policy.ts | 2 +- src/channels/ids.ts | 2 +- src/channels/inbound-debounce-policy.ts | 2 +- src/channels/inbound-event/media.ts | 2 +- src/channels/message-access/allowlist.ts | 2 +- src/channels/message-access/decision.ts | 2 +- src/channels/message-access/dm-allow-state.ts | 2 +- .../message-access/runtime-access-groups.ts | 5 +- src/channels/message-access/runtime.ts | 5 +- src/channels/message-access/state.ts | 5 +- src/channels/message/receipt.ts | 2 +- src/channels/model-overrides.ts | 8 +- .../native-command-session-targets.ts | 2 +- src/channels/plugins/account-helpers.ts | 4 +- .../acp-configured-binding-consumer.ts | 8 +- src/channels/plugins/bootstrap-registry.ts | 2 +- src/channels/plugins/bundled.ts | 2 +- src/channels/plugins/catalog.ts | 7 +- src/channels/plugins/chat-target-prefixes.ts | 6 +- src/channels/plugins/config-writes.ts | 2 +- .../plugins/configured-binding-compiler.ts | 8 +- .../plugins/configured-binding-match.ts | 6 +- .../plugins/directory-config-helpers.ts | 6 +- src/channels/plugins/dm-access.ts | 2 +- src/channels/plugins/helpers.ts | 2 +- .../plugins/message-action-discovery.ts | 4 +- src/channels/plugins/meta-normalization.ts | 2 +- .../plugins/native-approval-prompt.ts | 2 +- .../plugins/outbound/presentation-limits.ts | 2 +- src/channels/plugins/package-state-probes.ts | 4 +- .../plugins/read-only-command-defaults.ts | 2 +- src/channels/plugins/read-only.ts | 5 +- src/channels/plugins/registry-loaded-read.ts | 2 +- src/channels/plugins/registry-loaded.ts | 2 +- src/channels/plugins/registry.ts | 2 +- src/channels/plugins/session-conversation.ts | 10 +- .../plugins/session-thread-info-loaded.ts | 2 +- src/channels/plugins/setup-group-access.ts | 2 +- .../plugins/setup-promotion-helpers.ts | 2 +- src/channels/plugins/setup-registry.ts | 2 +- src/channels/plugins/setup-wizard-helpers.ts | 7 +- src/channels/plugins/setup-wizard.ts | 2 +- src/channels/plugins/status-issues/shared.ts | 2 +- src/channels/plugins/status.ts | 2 +- src/channels/plugins/target-parsing-loaded.ts | 10 +- src/channels/plugins/thread-binding-api.ts | 2 +- src/channels/registry-lookup.ts | 2 +- src/channels/registry-normalize.ts | 2 +- src/channels/registry.ts | 2 +- src/channels/reply-prefix.ts | 2 +- src/channels/sender-identity.ts | 2 +- src/channels/sender-label.ts | 2 +- src/channels/session.ts | 2 +- src/channels/status-reactions.ts | 2 +- src/channels/status/read-model.ts | 6 +- src/channels/streaming.ts | 4 +- src/channels/targets.ts | 2 +- src/channels/thread-binding-id.ts | 2 +- src/channels/thread-bindings-messages.ts | 2 +- src/channels/thread-bindings-policy.ts | 2 +- src/channels/transport/stall-watchdog.test.ts | 2 +- src/channels/transport/stall-watchdog.ts | 2 +- src/channels/turn/durable-delivery.ts | 2 +- src/channels/typing.ts | 2 +- src/chat/canvas-render.ts | 4 +- src/cli/capability-cli.ts | 10 +- src/cli/channel-auth.ts | 2 +- src/cli/channel-options.ts | 2 +- src/cli/command-secret-gateway.ts | 2 +- src/cli/command-secret-targets.ts | 6 +- src/cli/completion-runtime.ts | 4 +- src/cli/config-cli.ts | 9 +- src/cli/config-set-input.ts | 4 +- src/cli/container-target.ts | 2 +- src/cli/cron-cli/register.cron-add.ts | 8 +- src/cli/cron-cli/register.cron-edit.ts | 8 +- src/cli/cron-cli/register.cron-simple.ts | 2 +- src/cli/cron-cli/schedule-options.ts | 2 +- src/cli/cron-cli/shared.ts | 16 +- src/cli/cron-cli/thread-id-shared.ts | 2 +- src/cli/daemon-cli/install.ts | 2 +- src/cli/daemon-cli/lifecycle.ts | 2 +- src/cli/daemon-cli/restart-health.ts | 8 +- src/cli/daemon-cli/status.gather.ts | 2 +- src/cli/devices-cli.runtime.ts | 12 +- src/cli/directory-cli.ts | 8 +- src/cli/exec-approvals-cli.ts | 2 +- src/cli/gateway-cli/dev.ts | 2 +- src/cli/gateway-cli/qa-parent-watchdog.ts | 2 +- src/cli/gateway-cli/run.ts | 8 +- src/cli/gateway-secret-options.ts | 2 +- src/cli/logs-cli.ts | 2 +- src/cli/mcp-cli.ts | 8 +- src/cli/message-secret-scope.ts | 2 +- src/cli/node-cli/daemon.ts | 2 +- src/cli/node-cli/register.ts | 2 +- src/cli/nodes-cli/format.ts | 2 +- src/cli/nodes-cli/register.camera.ts | 8 +- src/cli/nodes-cli/register.invoke.ts | 8 +- src/cli/nodes-cli/register.location.ts | 2 +- src/cli/nodes-cli/register.notify.ts | 2 +- src/cli/nodes-cli/register.pairing.ts | 2 +- src/cli/nodes-cli/register.push.ts | 6 +- src/cli/nodes-cli/register.status.ts | 10 +- src/cli/nodes-cli/rpc.ts | 2 +- src/cli/nodes-media-utils.ts | 6 +- src/cli/outbound-send-mapping.ts | 2 +- src/cli/pairing-cli.ts | 8 +- src/cli/parse-bytes.ts | 2 +- src/cli/parse-duration.ts | 2 +- src/cli/plugin-install-config-policy.ts | 2 +- src/cli/plugins-authoring-command.ts | 2 +- src/cli/plugins-command-helpers.ts | 2 +- src/cli/plugins-install-command.ts | 4 +- src/cli/plugins-search-command.ts | 2 +- src/cli/profile-utils.ts | 2 +- src/cli/profile.ts | 6 +- src/cli/program/message/register.thread.ts | 2 +- src/cli/program/register-command-groups.ts | 2 +- src/cli/program/register.agent.ts | 2 +- src/cli/prompt.ts | 2 +- src/cli/run-main-policy.ts | 8 +- src/cli/run-main.ts | 2 +- src/cli/security-cli.ts | 8 +- src/cli/send-runtime/channel-outbound-send.ts | 2 +- src/cli/skills-cli.ts | 2 +- src/cli/system-cli.ts | 2 +- src/cli/update-cli/progress.ts | 2 +- src/cli/update-cli/restart-helper.ts | 2 +- src/cli/update-cli/shared.ts | 2 +- src/cli/update-cli/update-command.ts | 4 +- src/cli/webhooks-cli.ts | 2 +- src/cli/windows-argv.ts | 2 +- src/commands/agent-via-gateway.ts | 2 +- src/commands/agents.bindings.ts | 4 +- src/commands/agents.commands.add.ts | 8 +- src/commands/agents.commands.bind.ts | 2 +- src/commands/agents.commands.identity.ts | 2 +- src/commands/agents.config.ts | 7 +- src/commands/auth-choice-options.ts | 2 +- src/commands/backup-verify.ts | 2 +- .../channel-plugin-resolution.ts | 2 +- src/commands/channels/add.ts | 2 +- src/commands/channels/capabilities.ts | 8 +- src/commands/channels/logs.ts | 2 +- src/commands/channels/remove.ts | 2 +- src/commands/channels/resolve.ts | 10 +- src/commands/chutes-oauth.ts | 2 +- src/commands/commitments.ts | 6 +- src/commands/configure.gateway.ts | 7 +- src/commands/configure.shared.ts | 2 +- src/commands/configure.wizard.ts | 2 +- src/commands/doctor-auth-flat-profiles.ts | 2 +- src/commands/doctor-auth-oauth-sidecar.ts | 2 +- src/commands/doctor-auth-profile-config.ts | 8 +- src/commands/doctor-claude-cli.ts | 10 +- src/commands/doctor-command-owner.ts | 4 +- src/commands/doctor-config-analysis.ts | 2 +- src/commands/doctor-device-pairing.ts | 2 +- src/commands/doctor-gateway-services.ts | 8 +- .../doctor-heartbeat-main-session-repair.ts | 2 +- .../doctor-heartbeat-session-target.ts | 2 +- src/commands/doctor-memory-search.ts | 2 +- src/commands/doctor-platform-notes.ts | 2 +- src/commands/doctor-plugin-manifests.ts | 4 +- src/commands/doctor-plugin-registry.ts | 2 +- src/commands/doctor-security.ts | 2 +- .../doctor-service-audit.test-helpers.ts | 2 +- src/commands/doctor-session-snapshots.ts | 2 +- .../doctor-session-state-providers.ts | 4 +- src/commands/doctor-state-integrity.ts | 6 +- src/commands/doctor-update.ts | 2 +- src/commands/doctor.e2e-harness.ts | 2 +- .../doctor/cron/dreaming-payload-migration.ts | 2 +- src/commands/doctor/cron/index.ts | 2 +- .../doctor/cron/legacy-store-migration.ts | 4 +- src/commands/doctor/cron/payload-migration.ts | 2 +- src/commands/doctor/cron/store-migration.ts | 4 +- .../shared/allowfrom-fallback-migration.ts | 2 +- .../doctor/shared/allowlist-policy-repair.ts | 4 +- src/commands/doctor/shared/allowlist.ts | 2 +- src/commands/doctor/shared/channel-doctor.ts | 2 +- .../doctor/shared/channel-plugin-blockers.ts | 2 +- .../doctor/shared/codex-native-assets.ts | 4 +- .../doctor/shared/codex-route-warnings.ts | 4 +- .../configured-runtime-plugin-installs.ts | 2 +- .../shared/context-engine-host-compat.ts | 2 +- .../doctor/shared/default-account-warnings.ts | 8 +- src/commands/doctor/shared/exec-safe-bins.ts | 2 +- .../shared/legacy-config-core-normalizers.ts | 8 +- ...legacy-config-migrations.runtime.agents.ts | 2 +- ...egacy-config-migrations.runtime.gateway.ts | 2 +- .../doctor/shared/legacy-oauth-sidecar.ts | 4 +- .../shared/legacy-talk-config-normalizer.ts | 2 +- .../missing-configured-plugin-install.ts | 2 +- .../doctor/shared/plugin-runtime-symlinks.ts | 2 +- .../shared/plugin-tool-allowlist-warnings.ts | 9 +- .../doctor/shared/preview-warnings.ts | 4 +- .../release-configured-plugin-installs.ts | 2 +- .../shared/stale-oauth-profile-shadows.ts | 2 +- .../doctor/shared/stale-subagent-allowlist.ts | 2 +- src/commands/flows.ts | 4 +- src/commands/gateway-install-token.ts | 2 +- src/commands/gateway-presence.ts | 2 +- src/commands/gateway-status/discovery.ts | 2 +- src/commands/gateway-status/helpers.ts | 2 +- src/commands/gateway-status/probe-run.ts | 5 +- src/commands/health-format.ts | 2 +- src/commands/health.ts | 2 +- src/commands/message-format.ts | 4 +- src/commands/message.ts | 8 +- src/commands/migrate/context.ts | 2 +- src/commands/migrate/selection.ts | 6 +- src/commands/models/auth-list.ts | 2 +- src/commands/models/auth-order.ts | 2 +- src/commands/models/auth.test.ts | 2 +- src/commands/models/auth.ts | 10 +- src/commands/models/list.auth-overview.ts | 8 +- src/commands/models/list.list-command.ts | 2 +- src/commands/models/list.local-url.ts | 2 +- src/commands/models/list.probe.ts | 2 +- src/commands/models/list.provider-catalog.ts | 2 +- src/commands/models/list.status-command.ts | 2 +- src/commands/oauth-tls-preflight.test.ts | 2 +- src/commands/onboard-custom-config.ts | 10 +- src/commands/onboard-helpers.ts | 4 +- .../local/auth-choice-inference.ts | 2 +- .../local/gateway-config.ts | 2 +- .../onboard-non-interactive/remote.ts | 2 +- src/commands/onboarding-plugin-install.ts | 2 +- src/commands/sandbox-explain.ts | 8 +- src/commands/sessions.ts | 8 +- .../status-all/channels-token-summary.ts | 4 +- src/commands/status-all/channels.ts | 4 +- src/commands/status-all/diagnosis.ts | 2 +- src/commands/status-all/format.ts | 2 +- src/commands/status-all/gateway.ts | 2 +- src/commands/status.command-report-data.ts | 2 +- src/commands/status.command-sections.ts | 2 +- src/commands/status.format.ts | 2 +- src/commands/status.scan.shared.ts | 8 +- src/commands/status.summary.runtime.ts | 10 +- src/commands/tasks.ts | 4 +- src/commitments/extraction.ts | 7 +- src/commitments/runtime.ts | 4 +- src/commitments/store.ts | 4 +- src/config/agent-dirs.ts | 2 +- src/config/allowed-values.ts | 2 +- src/config/channel-capabilities.ts | 2 +- src/config/commands.ts | 2 +- src/config/defaults.ts | 2 +- src/config/doc-baseline.ts | 2 +- src/config/group-policy.ts | 8 +- src/config/model-input.ts | 4 +- src/config/plugin-auto-enable.prefer-over.ts | 4 +- src/config/plugin-auto-enable.shared.ts | 2 +- src/config/plugin-install-config-migration.ts | 2 +- src/config/plugin-web-search-config.ts | 2 +- src/config/redact-snapshot.raw.ts | 2 +- src/config/redact-snapshot.ts | 4 +- src/config/runtime-group-policy.ts | 2 +- src/config/schema.tags.ts | 2 +- src/config/schema.ts | 2 +- src/config/sensitive-paths.ts | 2 +- src/config/sessions/artifacts.ts | 2 +- src/config/sessions/delivery-info.ts | 2 +- src/config/sessions/disk-budget.ts | 2 +- .../explicit-session-key-normalization.ts | 8 +- src/config/sessions/group.ts | 10 +- src/config/sessions/metadata.ts | 8 +- .../sessions/model-override-provenance.ts | 2 +- src/config/sessions/paths.ts | 2 +- src/config/sessions/reset.ts | 4 +- src/config/sessions/session-file-rotation.ts | 2 +- src/config/sessions/store-entry-shape.ts | 2 +- src/config/sessions/store-entry.ts | 2 +- src/config/sessions/store-load.ts | 2 +- src/config/sessions/store-maintenance.ts | 8 +- src/config/sessions/targets.ts | 2 +- src/config/sessions/transcript-append.ts | 2 +- src/config/sessions/types.ts | 2 +- src/config/shell-env-expected-keys.ts | 2 +- src/config/silent-reply.ts | 2 +- src/config/talk.ts | 5 +- src/config/types.tools.ts | 2 +- src/config/validation.ts | 2 +- src/config/zod-schema.agent-runtime.ts | 12 +- src/config/zod-schema.agents.ts | 2 +- src/config/zod-schema.core.ts | 2 +- src/config/zod-schema.providers-core.ts | 2 +- src/config/zod-schema.providers-whatsapp.ts | 2 +- .../zod-schema.secret-input-validation.ts | 2 +- src/config/zod-schema.session.ts | 2 +- src/config/zod-schema.ts | 8 +- src/crestodian/probes.test.ts | 2 +- src/crestodian/probes.ts | 2 +- src/crestodian/rescue-message.ts | 5 +- src/cron/delivery-field-schemas.ts | 2 +- src/cron/delivery-plan.ts | 6 +- ...solated-agent.run-timeout-override.test.ts | 2 +- .../isolated-agent/channel-output-policy.ts | 2 +- src/cron/isolated-agent/delivery-dispatch.ts | 2 +- src/cron/isolated-agent/delivery-target.ts | 4 +- src/cron/isolated-agent/helpers.ts | 2 +- .../isolated-agent/model-preflight.runtime.ts | 2 +- src/cron/isolated-agent/run-timeout.ts | 2 +- src/cron/isolated-agent/run.test-harness.ts | 2 +- src/cron/isolated-agent/run.ts | 2 +- .../isolated-agent/subagent-followup-hints.ts | 2 +- src/cron/normalize-job-identity.ts | 2 +- src/cron/normalize.ts | 8 +- src/cron/run-diagnostics.ts | 2 +- src/cron/run-log-jsonl.ts | 2 +- src/cron/run-log.ts | 12 +- src/cron/schedule-identity.ts | 2 +- src/cron/schedule-number.ts | 2 +- src/cron/schedule.ts | 2 +- src/cron/service/jobs.ts | 4 +- src/cron/service/normalize.ts | 2 +- src/cron/service/ops.ts | 2 +- src/cron/service/timeout-policy.test.ts | 2 +- src/cron/service/timeout-policy.ts | 2 +- src/cron/service/timer.ts | 2 +- src/cron/store.ts | 4 +- src/cron/validate-timestamp.ts | 7 +- src/daemon/constants.ts | 2 +- src/daemon/container-context.ts | 2 +- src/daemon/inspect.ts | 2 +- src/daemon/launchd-restart-handoff.ts | 2 +- src/daemon/launchd.ts | 2 +- src/daemon/paths.ts | 2 +- src/daemon/runtime-binary.ts | 2 +- src/daemon/runtime-parse.ts | 2 +- src/daemon/runtime-paths.ts | 2 +- src/daemon/schtasks.ts | 4 +- src/daemon/service-audit.ts | 11 +- src/daemon/service-env.ts | 2 +- src/daemon/service-managed-env.ts | 2 +- src/daemon/service-path-policy.ts | 2 +- src/daemon/service-runtime.ts | 2 +- src/daemon/service.ts | 2 +- src/daemon/systemd-linger.ts | 6 +- src/daemon/systemd-unavailable.ts | 2 +- src/daemon/systemd-unit.ts | 2 +- src/daemon/systemd.ts | 4 +- src/flows/bundled-health-checks.ts | 2 +- src/flows/doctor-repair-flow.ts | 2 +- src/flows/model-picker.ts | 4 +- src/flows/provider-flow.runtime.ts | 2 +- src/flows/search-setup.ts | 2 +- src/gateway/agent-list.ts | 2 +- src/gateway/auth-install-policy.ts | 2 +- src/gateway/auth-token-source-conflict.ts | 2 +- src/gateway/auth.ts | 8 +- src/gateway/call.ts | 2 +- src/gateway/chat-abort.ts | 10 +- src/gateway/chat-attachments.ts | 2 +- src/gateway/chat-display-projection.ts | 6 +- src/gateway/chat-sanitize.ts | 2 +- src/gateway/cli-session-history.claude.ts | 4 +- src/gateway/cli-session-history.merge.ts | 7 +- src/gateway/connection-details.ts | 2 +- src/gateway/control-ui-csp.ts | 2 +- src/gateway/control-ui.ts | 5 +- src/gateway/credential-planner.ts | 2 +- src/gateway/device-metadata-normalization.ts | 2 +- src/gateway/embeddings-http.ts | 8 +- src/gateway/exec-approval-ios-push.ts | 2 +- src/gateway/exec-approval-manager.ts | 4 +- .../gateway-cli-backend.live-helpers.ts | 2 +- .../gateway-cli-backend.live-probe-helpers.ts | 2 +- src/gateway/gateway-config-prompts.shared.ts | 2 +- src/gateway/hooks-mapping.ts | 5 +- src/gateway/hooks.ts | 8 +- src/gateway/http-auth-utils.ts | 6 +- src/gateway/http-utils.ts | 8 +- src/gateway/input-allowlist.ts | 2 +- src/gateway/live-agent-probes.ts | 4 +- src/gateway/live-tool-probe-utils.ts | 2 +- src/gateway/mcp-http.request.ts | 2 +- src/gateway/mcp-http.schema.ts | 2 +- src/gateway/mcp-http.ts | 2 +- src/gateway/method-scopes.ts | 2 +- src/gateway/model-pricing-cache-state.ts | 2 +- src/gateway/model-pricing-cache.ts | 2 +- src/gateway/net.ts | 2 +- src/gateway/node-catalog.ts | 4 +- src/gateway/node-command-policy.ts | 4 +- src/gateway/node-invoke-plugin-policy.ts | 2 +- .../node-invoke-system-run-approval.ts | 4 +- src/gateway/node-pending-work.ts | 2 +- src/gateway/node-registry.test.ts | 5 +- src/gateway/node-registry.ts | 4 +- src/gateway/openai-http.ts | 10 +- src/gateway/openresponses-http.ts | 2 +- src/gateway/origin-check.ts | 2 +- src/gateway/plugin-channel-reload-targets.ts | 2 +- src/gateway/plugin-node-capability.ts | 4 +- src/gateway/probe-auth.ts | 2 +- src/gateway/probe-target.ts | 2 +- .../resolve-configured-secret-input-string.ts | 2 +- src/gateway/security-path.ts | 2 +- src/gateway/server-close.ts | 2 +- src/gateway/server-cron-notifications.ts | 8 +- src/gateway/server-json.ts | 2 +- src/gateway/server-maintenance.ts | 2 +- .../server-methods/agent-wait-dedupe.ts | 4 +- src/gateway/server-methods/agent.ts | 13 +- src/gateway/server-methods/agents.ts | 2 +- src/gateway/server-methods/approval-shared.ts | 2 +- src/gateway/server-methods/artifacts.ts | 4 +- src/gateway/server-methods/channels.ts | 2 +- .../server-methods/chat-webchat-media.ts | 2 +- src/gateway/server-methods/chat.ts | 4 +- src/gateway/server-methods/commands.ts | 2 +- src/gateway/server-methods/config.ts | 12 +- src/gateway/server-methods/environments.ts | 2 +- src/gateway/server-methods/exec-approval.ts | 2 +- src/gateway/server-methods/nodes.helpers.ts | 2 +- .../server-methods/nodes.invoke-wake.test.ts | 2 +- src/gateway/server-methods/nodes.ts | 12 +- src/gateway/server-methods/plugin-approval.ts | 2 +- .../server-methods/plugin-host-hooks.ts | 4 +- src/gateway/server-methods/push.ts | 2 +- src/gateway/server-methods/record-shared.ts | 2 +- src/gateway/server-methods/restart-request.ts | 2 +- src/gateway/server-methods/send.ts | 10 +- .../server-methods/server-methods.test.ts | 2 +- src/gateway/server-methods/sessions.ts | 10 +- src/gateway/server-methods/skills.ts | 2 +- src/gateway/server-methods/system.ts | 10 +- src/gateway/server-methods/talk-client.ts | 8 +- src/gateway/server-methods/talk-session.ts | 8 +- src/gateway/server-methods/talk-shared.ts | 10 +- src/gateway/server-methods/talk.ts | 10 +- src/gateway/server-methods/tasks.ts | 2 +- src/gateway/server-methods/tools-catalog.ts | 2 +- src/gateway/server-methods/tools-effective.ts | 8 +- src/gateway/server-methods/tools-invoke.ts | 2 +- src/gateway/server-methods/tts.ts | 2 +- src/gateway/server-methods/usage.ts | 2 +- src/gateway/server-methods/wizard.ts | 2 +- src/gateway/server-node-events.ts | 8 +- src/gateway/server-plugins.ts | 2 +- src/gateway/server-session-events.ts | 4 +- src/gateway/server-session-key.ts | 5 +- src/gateway/server-startup-log.ts | 2 +- src/gateway/server-talk-nodes.ts | 2 +- src/gateway/server-utils.ts | 2 +- src/gateway/server.impl.ts | 2 +- src/gateway/server/hooks.ts | 10 +- .../server/plugins-http/path-context.ts | 2 +- .../server/preauth-connection-budget.ts | 5 +- src/gateway/server/ws-connection.ts | 2 +- .../server/ws-connection/auth-context.ts | 2 +- .../ws-connection/handshake-auth-helpers.ts | 2 +- .../handshake-auth-log-limiter.ts | 2 +- .../server/ws-connection/message-handler.ts | 2 +- .../ws-connection/unauthorized-flood-guard.ts | 2 +- src/gateway/session-child-sessions.ts | 2 +- src/gateway/session-history-state.ts | 2 +- src/gateway/session-kill-http.ts | 2 +- src/gateway/session-store-key.ts | 8 +- src/gateway/session-transcript-files.fs.ts | 2 +- src/gateway/session-transcript-key.ts | 2 +- src/gateway/session-utils.fs.ts | 10 +- src/gateway/session-utils.ts | 12 +- src/gateway/sessions-history-http.ts | 8 +- src/gateway/sessions-patch.ts | 8 +- src/gateway/sessions-resolve.ts | 2 +- src/gateway/startup-auth.ts | 2 +- src/gateway/talk-handoff.ts | 4 +- src/gateway/talk-realtime-relay.ts | 5 +- src/gateway/talk-transcription-relay.ts | 6 +- src/gateway/test-helpers.e2e.ts | 2 +- src/gateway/test-helpers.server.ts | 6 +- src/gateway/test-helpers.speech.ts | 2 +- src/gateway/tools-invoke-http.ts | 2 +- src/gateway/tools-invoke-shared.ts | 8 +- src/gateway/ws-log.ts | 2 +- .../bundled/bootstrap-extra-files/handler.ts | 2 +- .../bundled/compaction-notifier/handler.ts | 2 +- src/hooks/frontmatter.ts | 2 +- src/hooks/gmail.ts | 4 +- src/hooks/install.ts | 2 +- src/hooks/llm-slug-generator.ts | 2 +- src/hooks/message-hook-mappers.ts | 8 +- src/hooks/workspace.ts | 2 +- src/image-generation/image-assets.ts | 6 +- src/image-generation/live-test-helpers.ts | 2 +- src/infra/approval-errors.ts | 2 +- .../approval-native-route-coordinator.ts | 2 +- src/infra/approval-native-route-notice.ts | 2 +- src/infra/approval-request-account-binding.ts | 2 +- src/infra/approval-request-filters.ts | 2 +- src/infra/backup-create.ts | 2 +- src/infra/bonjour-discovery.ts | 7 +- src/infra/clawhub-spec.ts | 2 +- src/infra/clawhub.ts | 6 +- src/infra/command-analysis/explain.ts | 2 +- src/infra/command-analysis/inline-eval.ts | 2 +- src/infra/command-analysis/risks.ts | 2 +- src/infra/control-ui-assets.ts | 2 +- src/infra/device-bootstrap.ts | 5 +- src/infra/device-pairing.ts | 2 +- src/infra/diagnostic-flags.ts | 4 +- src/infra/dispatch-wrapper-resolution.ts | 4 +- src/infra/env.ts | 2 +- src/infra/event-session-routing.ts | 4 +- src/infra/exec-allowlist-pattern.ts | 2 +- src/infra/exec-approval-forwarder.ts | 4 +- src/infra/exec-approval-reply.ts | 8 +- src/infra/exec-approval-session-target.ts | 2 +- src/infra/exec-approval-surface.ts | 2 +- src/infra/exec-approvals-allowlist.ts | 2 +- src/infra/exec-approvals-analysis.ts | 2 +- src/infra/exec-approvals-effective.ts | 2 +- src/infra/exec-approvals.ts | 4 +- src/infra/exec-command-resolution.ts | 2 +- src/infra/exec-safe-bin-policy-profiles.ts | 4 +- src/infra/exec-safe-bin-semantics.ts | 2 +- src/infra/exec-safe-bin-trust.ts | 2 +- src/infra/exec-wrapper-tokens.ts | 2 +- src/infra/executable-path.ts | 2 +- src/infra/gateway-discovery-targets.ts | 2 +- src/infra/gateway-lock.ts | 2 +- src/infra/gateway-process-argv.ts | 4 +- src/infra/gateway-processes.ts | 2 +- src/infra/git-commit.ts | 2 +- src/infra/heartbeat-events-filter.ts | 2 +- src/infra/heartbeat-reason.ts | 2 +- src/infra/heartbeat-runner.ts | 10 +- src/infra/heartbeat-summary.ts | 2 +- src/infra/heartbeat-wake.ts | 2 +- .../host-env-security.policy-parity.test.ts | 2 +- ...ost-env-security.reported-baseline.test.ts | 2 +- src/infra/host-env-security.ts | 2 +- src/infra/http-body.test.ts | 2 +- src/infra/http-body.ts | 2 +- src/infra/install-package-dir.ts | 2 +- src/infra/install-source-utils.ts | 2 +- src/infra/jsonl-socket.test.ts | 2 +- src/infra/jsonl-socket.ts | 2 +- src/infra/machine-name.ts | 2 +- src/infra/net/hostname.ts | 2 +- src/infra/net/http-connect-tunnel.test.ts | 2 +- src/infra/net/http-connect-tunnel.ts | 2 +- src/infra/net/proxy/managed-proxy-undici.ts | 2 +- src/infra/net/redirect-headers.ts | 2 +- src/infra/net/ssrf.ts | 2 +- src/infra/net/undici-runtime.ts | 2 +- src/infra/node-pairing-surface.ts | 2 +- src/infra/node-pairing.ts | 2 +- src/infra/node-shell.ts | 2 +- src/infra/npm-install-env.ts | 2 +- src/infra/npm-managed-root.ts | 4 +- src/infra/npm-registry-spec.ts | 2 +- src/infra/numeric-options.ts | 2 +- src/infra/os-summary.ts | 2 +- src/infra/outbound/agent-delivery.ts | 2 +- src/infra/outbound/best-effort-delivery.ts | 2 +- src/infra/outbound/channel-target-prefix.ts | 2 +- src/infra/outbound/channel-target.ts | 2 +- src/infra/outbound/conversation-id.ts | 4 +- .../outbound/current-conversation-bindings.ts | 12 +- src/infra/outbound/delivery-queue-recovery.ts | 8 +- .../outbound/delivery-queue.recovery.test.ts | 2 +- src/infra/outbound/identity.ts | 2 +- .../outbound/message-action-normalization.ts | 2 +- .../outbound/message-action-param-keys.ts | 2 +- src/infra/outbound/message-action-params.ts | 2 +- src/infra/outbound/message-action-runner.ts | 8 +- src/infra/outbound/message-action-spec.ts | 6 +- src/infra/outbound/outbound-policy.ts | 2 +- .../outbound/outbound-session.test-helpers.ts | 8 +- src/infra/outbound/outbound-session.ts | 4 +- src/infra/outbound/reply-payload-normalize.ts | 2 +- .../outbound/session-binding-normalization.ts | 4 +- src/infra/outbound/session-binding-service.ts | 2 +- src/infra/outbound/session-context.ts | 2 +- src/infra/outbound/source-reply-mirror.ts | 10 +- src/infra/outbound/target-normalization.ts | 8 +- src/infra/outbound/target-resolver.ts | 2 +- src/infra/outbound/targets-loaded.ts | 2 +- src/infra/outbound/targets-session.ts | 10 +- src/infra/outbound/thread-id.ts | 2 +- src/infra/package-dist-inventory.ts | 2 +- src/infra/package-json.ts | 2 +- src/infra/package-tag.ts | 2 +- src/infra/package-update-utils.ts | 2 +- src/infra/parse-finite-number.ts | 2 +- src/infra/path-env.ts | 2 +- src/infra/path-prepend.ts | 2 +- src/infra/plugin-install-path-warnings.ts | 2 +- src/infra/ports-format.ts | 2 +- src/infra/ports-inspect.ts | 2 +- src/infra/process-respawn.ts | 2 +- src/infra/provider-usage.auth.ts | 2 +- src/infra/provider-usage.fetch.gemini.ts | 2 +- src/infra/provider-usage.fetch.minimax.ts | 2 +- src/infra/provider-usage.fetch.shared.test.ts | 2 +- src/infra/provider-usage.fetch.shared.ts | 2 +- src/infra/push-apns-http2.test.ts | 2 +- src/infra/push-apns-http2.ts | 2 +- src/infra/push-apns.relay.test.ts | 2 +- src/infra/push-apns.relay.ts | 6 +- src/infra/push-apns.test.ts | 2 +- src/infra/push-apns.ts | 6 +- src/infra/restart-handoff.ts | 2 +- src/infra/restart-sentinel.ts | 2 +- src/infra/restart-stale-pids.ts | 4 +- src/infra/retry.ts | 2 +- src/infra/runtime-status.ts | 2 +- src/infra/scp-host.ts | 2 +- src/infra/session-cost-usage.ts | 4 +- src/infra/session-delivery-queue-recovery.ts | 2 +- .../session-delivery-queue.recovery.test.ts | 2 +- src/infra/shell-env.test.ts | 2 +- src/infra/shell-env.ts | 2 +- src/infra/shell-inline-command.ts | 2 +- src/infra/shell-wrapper-resolution.ts | 2 +- src/infra/ssh-tunnel.ts | 2 +- src/infra/state-migrations.ts | 2 +- src/infra/system-events.ts | 8 +- src/infra/system-presence.ts | 2 +- src/infra/system-run-normalize.ts | 2 +- src/infra/tailnet.ts | 2 +- src/infra/tailscale.ts | 15 +- src/infra/tls/fingerprint.ts | 2 +- src/infra/transport-ready.test.ts | 2 +- src/infra/transport-ready.ts | 2 +- src/infra/unhandled-rejections.ts | 2 +- src/infra/update-channels.ts | 2 +- src/infra/update-control-plane-sentinel.ts | 2 +- src/infra/update-global.ts | 2 +- src/infra/update-runner.ts | 5 +- src/infra/update-startup.ts | 7 +- src/infra/voicewake-routing.ts | 4 +- src/infra/voicewake.ts | 2 +- src/infra/widearea-dns.ts | 2 +- src/infra/windows-encoding.ts | 2 +- src/infra/windows-install-roots.ts | 2 +- src/infra/windows-port-pids.ts | 4 +- src/infra/wsl.ts | 2 +- src/interactive/payload.ts | 4 +- src/link-understanding/format.ts | 2 +- .../openai-chatgpt-responses.test.ts | 2 +- src/llm/providers/openai-chatgpt-responses.ts | 5 +- .../anthropic-family-cache-semantics.ts | 2 +- .../anthropic-family-tool-payload-compat.ts | 2 +- .../stream-wrappers/moonshot-thinking.ts | 2 +- src/llm/providers/stream-wrappers/openai.ts | 8 +- src/llm/providers/stream-wrappers/proxy.ts | 8 +- src/llm/utils/oauth/abort.test.ts | 2 +- src/llm/utils/oauth/github-copilot.test.ts | 2 +- src/llm/utils/oauth/github-copilot.ts | 2 +- src/logging/config.ts | 2 +- src/logging/diagnostic-support-export.ts | 2 +- .../diagnostic-support-log-redaction.ts | 2 +- src/logging/diagnostic-support-redaction.ts | 2 +- src/logging/env-log-level.ts | 2 +- src/logging/parse-log-line.ts | 2 +- src/logging/redact-identifier.ts | 2 +- src/logging/subsystem.ts | 2 +- src/mcp/channel-bridge.ts | 8 +- src/mcp/channel-shared.ts | 4 +- src/media-generation/live-test-helpers.ts | 2 +- src/media-generation/runtime-shared.test.ts | 2 +- src/media-generation/runtime-shared.ts | 4 +- src/media-understanding/apply.ts | 8 +- .../attachments.normalize.ts | 2 +- src/media-understanding/defaults.ts | 4 +- src/media-understanding/echo-transcript.ts | 2 +- src/media-understanding/resolve.test.ts | 2 +- src/media-understanding/resolve.ts | 5 +- src/media-understanding/runner.entries.ts | 10 +- src/media-understanding/runner.ts | 15 +- src/media-understanding/runtime.test.ts | 2 +- src/media-understanding/scope.ts | 2 +- src/media-understanding/shared.test.ts | 5 +- src/media-understanding/shared.ts | 10 +- src/media/audio.ts | 2 +- src/media/channel-inbound-roots.ts | 2 +- src/media/document-extractors.runtime.ts | 2 +- src/media/ffmpeg-exec.ts | 2 +- src/media/file-context.ts | 2 +- src/media/input-files.ts | 8 +- src/media/local-roots.ts | 4 +- src/media/read-capability.ts | 2 +- src/media/store.ts | 2 +- src/media/web-media.ts | 2 +- src/memory-host-sdk/dreaming.ts | 8 +- src/model-catalog/manifest-planner.ts | 4 +- src/model-catalog/provider-index/normalize.ts | 6 +- src/music-generation/provider-assets.ts | 4 +- src/node-host/invoke-system-run-plan.ts | 8 +- src/node-host/invoke-system-run.ts | 2 +- src/node-host/invoke.ts | 4 +- src/node-host/with-timeout.test.ts | 2 +- src/node-host/with-timeout.ts | 2 +- src/pairing/allow-from-store-file.ts | 10 +- src/pairing/pairing-store.ts | 14 +- src/pairing/setup-code.ts | 8 +- src/param-key.ts | 2 +- src/plugin-sdk/access-groups.ts | 2 +- src/plugin-sdk/acp-runtime-backend.ts | 2 +- src/plugin-sdk/agent-harness-task-runtime.ts | 2 +- src/plugin-sdk/allow-from.ts | 4 +- .../anthropic-vertex-auth-presence.ts | 2 +- src/plugin-sdk/approval-approvers.ts | 2 +- src/plugin-sdk/approval-auth-helpers.ts | 2 +- src/plugin-sdk/approval-client-helpers.ts | 8 +- src/plugin-sdk/approval-handler-runtime.ts | 2 +- src/plugin-sdk/approval-native-helpers.ts | 8 +- src/plugin-sdk/approval-renderers.ts | 2 +- src/plugin-sdk/boolean-param.ts | 2 +- src/plugin-sdk/channel-config-helpers.ts | 4 +- src/plugin-sdk/channel-entry-contract.ts | 2 +- src/plugin-sdk/channel-ingress.ts | 2 +- src/plugin-sdk/channel-policy.ts | 5 +- src/plugin-sdk/channel-route.ts | 4 +- src/plugin-sdk/core.ts | 7 +- src/plugin-sdk/migration.ts | 2 +- src/plugin-sdk/number-runtime.ts | 2 +- src/plugin-sdk/provider-auth-result.test.ts | 2 +- src/plugin-sdk/provider-auth-result.ts | 2 +- src/plugin-sdk/provider-auth.ts | 12 +- src/plugin-sdk/provider-catalog-shared.ts | 2 +- src/plugin-sdk/provider-entry.ts | 2 +- src/plugin-sdk/provider-model-shared.ts | 2 +- src/plugin-sdk/provider-oauth-runtime.ts | 4 +- src/plugin-sdk/provider-onboard.ts | 2 +- .../provider-openai-chatgpt-auth.ts | 4 +- src/plugin-sdk/provider-selection-runtime.ts | 2 +- src/plugin-sdk/provider-stream-shared.ts | 2 +- src/plugin-sdk/qa-channel-protocol.ts | 2 +- src/plugin-sdk/reply-payload.ts | 4 +- src/plugin-sdk/session-transcript-hit.ts | 4 +- src/plugin-sdk/session-visibility.ts | 10 +- src/plugin-sdk/ssrf-policy.ts | 6 +- src/plugin-sdk/status-helpers.ts | 2 +- src/plugin-sdk/string-coerce-runtime.ts | 8 +- .../string-normalization-runtime.ts | 2 +- .../test-helpers/public-artifacts.ts | 2 +- src/plugin-sdk/test-helpers/string-utils.ts | 2 +- src/plugin-sdk/text-runtime.ts | 8 +- src/plugin-sdk/tool-send.ts | 2 +- src/plugin-sdk/webhook-request-guards.ts | 2 +- src/plugin-sdk/windows-spawn.ts | 4 +- src/plugin-state/plugin-state-store.sqlite.ts | 2 +- src/plugin-state/plugin-state-store.test.ts | 2 +- src/plugins/activation-planner.ts | 4 +- src/plugins/active-runtime-registry.ts | 2 +- src/plugins/agent-event-emission.ts | 2 +- src/plugins/bundle-commands.ts | 8 +- src/plugins/bundle-manifest.ts | 10 +- src/plugins/bundled-dir.ts | 4 +- src/plugins/bundled-plugin-metadata.ts | 2 +- src/plugins/bundled-plugin-scan.ts | 4 +- src/plugins/bundled-source-overlays.ts | 2 +- src/plugins/bundled-sources.ts | 4 +- src/plugins/capability-provider-runtime.ts | 2 +- src/plugins/captured-registration.ts | 2 +- src/plugins/channel-catalog-registry.ts | 2 +- src/plugins/channel-presence-policy.ts | 4 +- src/plugins/channel-validation.ts | 8 +- src/plugins/clawhub.ts | 2 +- src/plugins/cli-gateway-nodes-runtime.test.ts | 2 +- src/plugins/cli-gateway-nodes-runtime.ts | 2 +- src/plugins/cli-registry-loader.ts | 4 +- src/plugins/command-registration.ts | 6 +- src/plugins/command-registry-state.ts | 2 +- src/plugins/command-specs.ts | 2 +- src/plugins/commands.ts | 2 +- src/plugins/config-contract-matches.ts | 2 +- src/plugins/config-contracts.ts | 2 +- src/plugins/config-normalization-shared.ts | 8 +- src/plugins/config-state.ts | 4 +- ...tension-package-project-boundaries.test.ts | 1 + src/plugins/contracts/registry.ts | 2 +- .../scheduled-turns.contract.test.ts | 2 +- src/plugins/conversation-binding.ts | 8 +- src/plugins/dependency-denylist.ts | 2 +- src/plugins/discovery.ts | 8 +- src/plugins/doctor-contract-registry.ts | 4 +- .../document-extractor-public-artifacts.ts | 2 +- src/plugins/document-extractors.runtime.ts | 5 +- src/plugins/effective-plugin-ids.ts | 4 +- src/plugins/gateway-startup-plugin-ids.ts | 4 +- .../gateway-startup-speech-providers.ts | 4 +- src/plugins/git-install.ts | 2 +- src/plugins/hook-agent-context.ts | 2 +- src/plugins/hooks.test-helpers.ts | 2 +- src/plugins/host-hook-attachments.ts | 2 +- src/plugins/host-hook-cleanup.ts | 2 +- src/plugins/host-hook-runtime.ts | 2 +- src/plugins/host-hook-scheduled-turns.ts | 10 +- src/plugins/host-hook-state.ts | 8 +- src/plugins/http-path.ts | 2 +- src/plugins/install-security-scan.runtime.ts | 7 +- src/plugins/install-source-info.ts | 2 +- src/plugins/install.ts | 2 +- .../installed-plugin-index-record-builder.ts | 2 +- .../installed-plugin-index-record-reader.ts | 2 +- src/plugins/interactive-registry.ts | 2 +- src/plugins/interactive-shared.ts | 2 +- src/plugins/legacy-npm-declaration.ts | 2 +- src/plugins/loader-provenance.ts | 2 +- src/plugins/loader-records.ts | 2 +- src/plugins/loader.ts | 2 +- .../manifest-command-aliases.runtime.ts | 2 +- src/plugins/manifest-command-aliases.ts | 2 +- src/plugins/manifest-contract-eligibility.ts | 2 +- src/plugins/manifest-contract-runtime.ts | 2 +- src/plugins/manifest-metadata-scan.ts | 4 +- src/plugins/manifest-model-suppression.ts | 2 +- src/plugins/manifest-registry-installed.ts | 6 +- src/plugins/manifest-registry.ts | 10 +- src/plugins/manifest-tool-availability.ts | 4 +- src/plugins/manifest.ts | 4 +- src/plugins/marketplace.ts | 2 +- src/plugins/min-host-version.ts | 2 +- src/plugins/model-catalog-registration.ts | 4 +- .../official-external-plugin-catalog.ts | 4 +- src/plugins/package-compat.ts | 2 +- src/plugins/package-entry-resolution.ts | 2 +- src/plugins/package-entrypoints.ts | 2 +- src/plugins/plugin-config-trust.ts | 2 +- src/plugins/plugin-metadata-snapshot.ts | 2 +- src/plugins/plugin-module-loader-cache.ts | 2 + src/plugins/plugin-registry-contributions.ts | 2 +- src/plugins/plugin-scope.ts | 2 +- .../plugin-sdk-native-resolver.test.ts | 31 +++ src/plugins/plugin-sdk-native-resolver.ts | 61 +++++- src/plugins/provider-api-key-auth.ts | 4 +- src/plugins/provider-auth-choice-helpers.ts | 12 +- src/plugins/provider-auth-helpers.ts | 2 +- src/plugins/provider-auth-input.ts | 8 +- src/plugins/provider-auth-ref.ts | 8 +- src/plugins/provider-auth-token.ts | 2 +- src/plugins/provider-catalog.ts | 4 +- .../provider-contract-public-artifacts.ts | 4 +- src/plugins/provider-discovery.runtime.ts | 2 +- src/plugins/provider-discovery.ts | 2 +- src/plugins/provider-hook-runtime.ts | 6 +- src/plugins/provider-install-catalog.ts | 4 +- src/plugins/provider-model-compat.ts | 2 +- src/plugins/provider-model-helpers.ts | 4 +- .../provider-openai-chatgpt-oauth-tls.ts | 4 +- src/plugins/provider-registry-shared.ts | 2 +- src/plugins/provider-replay-helpers.ts | 2 +- src/plugins/provider-runtime.ts | 7 +- src/plugins/provider-self-hosted-setup.ts | 10 +- src/plugins/provider-validation.ts | 4 +- src/plugins/provider-wizard.ts | 8 +- src/plugins/providers.runtime.ts | 2 +- src/plugins/providers.test.ts | 2 +- src/plugins/providers.ts | 2 +- src/plugins/registry.ts | 18 +- src/plugins/roots.ts | 2 +- .../runtime/channel-runtime-contexts.ts | 2 +- src/plugins/runtime/runtime-llm.runtime.ts | 4 +- src/plugins/sdk-alias.ts | 2 +- src/plugins/setup-registry.ts | 4 +- src/plugins/tools.ts | 7 +- .../web-content-extractor-public-artifacts.ts | 2 +- .../web-provider-public-artifacts.explicit.ts | 4 +- src/plugins/web-provider-public-artifacts.ts | 2 +- src/plugins/web-search-install-catalog.ts | 4 +- src/poll-params.ts | 4 +- src/process/exec.ts | 2 +- src/process/supervisor/supervisor.ts | 2 +- src/process/windows-command.ts | 2 +- src/proxy-capture/store.sqlite.ts | 4 +- src/routing/account-id.ts | 2 +- src/routing/account-lookup.ts | 2 +- src/routing/binding-scope.ts | 2 +- src/routing/channel-route-targets.ts | 4 +- src/routing/resolve-route.ts | 2 +- src/routing/session-key.ts | 2 +- src/secrets/channel-env-vars.ts | 2 +- src/secrets/configure.ts | 10 +- src/secrets/json-pointer.ts | 2 +- src/secrets/model-provider-header-policy.ts | 2 +- src/secrets/plan.ts | 4 +- src/secrets/provider-env-vars.ts | 2 +- src/secrets/provider-integrations.ts | 2 +- src/secrets/resolve.ts | 2 +- src/secrets/runtime-command-secrets.ts | 4 +- src/secrets/runtime-config-collectors-core.ts | 2 +- .../runtime-config-collectors-plugins.ts | 2 +- src/secrets/runtime-fast-path.ts | 2 +- src/secrets/runtime-web-tools.shared.ts | 2 +- src/secrets/runtime-web-tools.ts | 4 +- src/secrets/runtime.ts | 2 +- src/secrets/storage-scan.ts | 2 +- src/security/audit-channel.ts | 2 +- src/security/audit-extra.async.ts | 18 +- src/security/audit-extra.sync.ts | 12 +- src/security/audit-gateway-config.ts | 10 +- src/security/audit-plugins-trust.ts | 2 +- src/security/audit.ts | 6 +- src/security/channel-metadata.ts | 2 +- src/security/dm-policy-shared.ts | 2 +- src/security/external-content-source.ts | 2 +- src/security/installed-plugin-dirs.ts | 2 +- src/sessions/input-provenance.ts | 2 +- src/sessions/model-overrides.ts | 2 +- src/sessions/send-policy.ts | 8 +- src/sessions/session-chat-type-shared.ts | 2 +- src/sessions/session-chat-type.ts | 2 +- src/sessions/session-id-resolution.ts | 2 +- src/sessions/session-key-utils.ts | 2 +- src/sessions/transcript-events.ts | 4 +- src/shared/assistant-identity-values.ts | 2 +- src/shared/avatar-policy.ts | 2 +- src/shared/chat-message-content.ts | 2 +- src/shared/custom-command-config.ts | 2 +- src/shared/device-auth-store.ts | 2 +- src/shared/entry-metadata.ts | 2 +- src/shared/frontmatter.ts | 7 +- src/shared/gateway-bind-url.ts | 2 +- src/shared/google-models.ts | 2 +- src/shared/model-param-b.ts | 2 +- src/shared/node-list-parse.ts | 2 +- src/shared/node-match.ts | 2 +- src/shared/node-presence.ts | 2 +- src/shared/node-resolve.ts | 2 +- src/shared/silent-reply-policy.ts | 2 +- src/shared/text/assistant-visible-text.ts | 2 +- src/shared/text/auto-linked-file-ref.ts | 2 +- src/shared/text/tool-call-shaped-text.ts | 4 +- src/skills/discovery/bins.ts | 2 +- .../discovery/chat-command-invocation.ts | 4 +- src/skills/discovery/chat-commands.ts | 10 +- src/skills/discovery/command-specs.ts | 8 +- src/skills/discovery/filter.ts | 5 +- src/skills/lifecycle/install-download.ts | 2 +- src/skills/lifecycle/install-extract.ts | 2 +- src/skills/lifecycle/install-output.ts | 2 +- src/skills/lifecycle/install-tar-verbose.ts | 2 +- src/skills/lifecycle/source-install.ts | 2 +- src/skills/lifecycle/upload-store.test.ts | 2 +- src/skills/lifecycle/upload-store.ts | 10 +- src/skills/loading/config.ts | 10 +- src/skills/loading/frontmatter.ts | 2 +- src/skills/loading/source.ts | 2 +- src/skills/loading/workspace.ts | 7 +- src/skills/runtime/refresh.ts | 2 +- src/skills/runtime/remote.ts | 10 +- src/skills/workshop/config.ts | 2 +- src/skills/workshop/policy.ts | 2 +- src/skills/workshop/service.ts | 2 +- src/skills/workshop/store.ts | 2 +- src/status/agent-runtime-label.ts | 8 +- src/status/fallback-notice-state.ts | 2 +- src/status/status-message.ts | 10 +- src/status/status-text.ts | 2 +- src/talk/agent-consult-tool.ts | 2 +- src/talk/agent-run-control-shared.ts | 2 +- src/talk/event-metrics.ts | 2 +- src/talk/fast-context-runtime.test.ts | 2 +- src/talk/fast-context-runtime.ts | 2 +- src/talk/session-log-runtime.ts | 2 +- src/talk/talk-session-controller.ts | 2 +- src/tasks/task-flow-owner-access.ts | 2 +- src/tasks/task-flow-registry.ts | 2 +- src/tasks/task-owner-access.ts | 2 +- src/tasks/task-registry.maintenance.ts | 8 +- src/tasks/task-registry.ts | 4 +- .../bundled-plugin-public-surface.ts | 2 +- src/test-utils/mock-http-response.ts | 2 +- src/test-utils/openclaw-test-state.ts | 7 +- src/trajectory/cleanup.ts | 2 +- src/trajectory/export.ts | 2 +- src/transcripts/config.ts | 2 +- src/transcripts/summary.ts | 2 +- src/tts/directive-number.ts | 2 +- src/tts/directives.ts | 2 +- src/tts/openai-compatible-speech-provider.ts | 2 +- src/tts/status-config.ts | 10 +- src/tts/tts-auto-mode.ts | 2 +- src/tts/tts-config.ts | 10 +- src/tts/tts-core.ts | 2 +- src/tts/tts-provider-helpers.ts | 2 +- src/tui/commands.ts | 2 +- src/tui/components/filterable-select-list.ts | 2 +- src/tui/components/fuzzy-filter.ts | 2 +- src/tui/components/searchable-select-list.ts | 4 +- src/tui/theme/theme.ts | 2 +- src/tui/tui-event-handlers.ts | 2 +- src/tui/tui-session-actions.ts | 2 +- src/tui/tui-submit.ts | 2 +- src/tui/tui.ts | 2 +- src/utils/boolean.ts | 2 +- src/utils/delivery-context.ts | 2 +- src/utils/directive-tags.ts | 2 +- src/utils/message-channel-core.ts | 2 +- src/utils/message-channel-normalize.ts | 2 +- src/utils/provider-utils.ts | 8 +- src/utils/transcript-tools.ts | 2 +- src/utils/usage-format.ts | 2 +- src/version.ts | 2 +- src/video-generation/dashscope-compatible.ts | 4 +- src/video-generation/duration-support.ts | 2 +- src/video-generation/live-test-helpers.ts | 2 +- src/web-fetch/runtime.ts | 2 +- src/web-search/runtime.ts | 10 +- src/wizard/clack-prompter.ts | 2 +- src/wizard/setup.plugin-config.ts | 2 +- test/scripts/changed-lanes.test.ts | 15 +- test/scripts/ci-workflow-guards.test.ts | 37 ++++ test/scripts/test-projects.test.ts | 15 +- test/vitest/vitest.shared.config.ts | 44 +++++ tsconfig.json | 14 ++ tsconfig.plugin-sdk.dts.json | 1 + tsdown.config.ts | 26 ++- ui/package.json | 1 + ui/src/ui/chat/export.ts | 2 +- .../slash-commands.browser-import.test.ts | 4 +- ui/src/ui/format.ts | 2 +- ui/src/ui/provider-quota-summary.ts | 2 +- ui/src/ui/string-coerce.ts | 4 +- ui/src/ui/views/overview-cards.ts | 2 +- ui/src/ui/views/usage-query.ts | 2 +- ui/vite.config.ts | 5 +- ui/vitest.config.ts | 12 ++ 1537 files changed, 3715 insertions(+), 2656 deletions(-) create mode 100644 packages/normalization-core/dist/index.d.mts create mode 100644 packages/normalization-core/dist/index.mjs create mode 100644 packages/normalization-core/dist/number-coercion.d.mts create mode 100644 packages/normalization-core/dist/number-coercion.mjs create mode 100644 packages/normalization-core/dist/record-coerce.d.mts create mode 100644 packages/normalization-core/dist/record-coerce.mjs create mode 100644 packages/normalization-core/dist/string-coerce.d.mts create mode 100644 packages/normalization-core/dist/string-coerce.mjs create mode 100644 packages/normalization-core/dist/string-normalization.d.mts create mode 100644 packages/normalization-core/dist/string-normalization.mjs create mode 100644 packages/normalization-core/package.json create mode 100644 packages/normalization-core/src/index.ts rename {src/shared => packages/normalization-core/src}/number-coercion.test.ts (100%) rename {src/shared => packages/normalization-core/src}/number-coercion.ts (100%) rename {src/shared => packages/normalization-core/src}/record-coerce.test.ts (86%) rename {src/shared => packages/normalization-core/src}/record-coerce.ts (100%) rename {src/shared => packages/normalization-core/src}/string-coerce.test.ts (88%) rename {src/shared => packages/normalization-core/src}/string-coerce.ts (100%) rename {src/shared => packages/normalization-core/src}/string-normalization.test.ts (98%) rename {src/shared => packages/normalization-core/src}/string-normalization.ts (100%) diff --git a/.github/codeql/codeql-network-runtime-boundary-critical-quality.yml b/.github/codeql/codeql-network-runtime-boundary-critical-quality.yml index 441a795b932..95fccf6cbb0 100644 --- a/.github/codeql/codeql-network-runtime-boundary-critical-quality.yml +++ b/.github/codeql/codeql-network-runtime-boundary-critical-quality.yml @@ -7,8 +7,16 @@ queries: - uses: ./.github/codeql/openclaw-boundary/queries/managed-proxy-runtime-mutation.ql paths: - - src - - extensions + - src/cli/gateway-cli/run-loop.ts + - src/infra/gateway-lock.ts + - src/infra/jsonl-socket.ts + - src/infra/net + - src/infra/push-apns-http2.ts + - src/infra/ssh-tunnel.ts + - src/proxy-capture + - extensions/codex-supervisor/src/json-rpc-client.ts + - extensions/irc/src + - extensions/qa-lab/src - packages/net-policy/src paths-ignore: diff --git a/.github/workflows/codeql-critical-quality.yml b/.github/workflows/codeql-critical-quality.yml index 864472c2acc..d883449e0b6 100644 --- a/.github/workflows/codeql-critical-quality.yml +++ b/.github/workflows/codeql-critical-quality.yml @@ -210,6 +210,9 @@ jobs: else while IFS= read -r file; do case "${file}" in + .github/codeql/codeql-network-runtime-boundary-critical-quality.yml|.github/codeql/openclaw-boundary/queries/raw-socket-callsite-classification.ql|.github/codeql/openclaw-boundary/queries/managed-proxy-runtime-mutation.ql) + network_runtime=true + ;; .github/codeql/*|.github/workflows/codeql-critical-quality.yml) agent=true channel=true @@ -222,7 +225,6 @@ jobs: plugin_sdk_package=true plugin_sdk_reply=true provider=true - network_runtime=true session_diagnostics=true ;; src/agents/sessions/tools/*) @@ -304,7 +306,7 @@ jobs: case "${file}" in src/**/*.test.ts|src/**/*.test.tsx|extensions/**/*.test.ts|extensions/**/*.test.tsx) ;; - src/*.ts|src/**/*.ts|extensions/*.ts|extensions/**/*.ts|packages/net-policy/src/*|packages/net-policy/src/**/*) + packages/net-policy/src/*|packages/net-policy/src/**/*|src/cli/gateway-cli/run-loop.ts|src/infra/net/*|src/infra/net/**/*|src/infra/ssh-tunnel.ts|src/infra/gateway-lock.ts|src/infra/jsonl-socket.ts|src/infra/push-apns-http2.ts|src/proxy-capture/*|src/proxy-capture/**/*|extensions/codex-supervisor/src/json-rpc-client.ts|extensions/irc/src/*|extensions/qa-lab/src/*) network_runtime=true ;; esac @@ -431,7 +433,33 @@ jobs: with: submodules: false + - name: Fast PR network boundary diff scan + if: ${{ github.event_name == 'pull_request' }} + env: + GH_TOKEN: ${{ github.token }} + PR_NUMBER: ${{ github.event.pull_request.number }} + REPOSITORY: ${{ github.repository }} + run: | + set -euo pipefail + + added_lines="$(mktemp)" + gh api --paginate "repos/${REPOSITORY}/pulls/${PR_NUMBER}/files" --jq ' + .[] + | select(.filename | test("^(src/cli/gateway-cli/run-loop\\.ts|src/infra/(gateway-lock|jsonl-socket|push-apns-http2|ssh-tunnel)\\.ts|src/infra/net/|src/proxy-capture/|extensions/codex-supervisor/src/json-rpc-client\\.ts|extensions/irc/src/|extensions/qa-lab/src/|packages/net-policy/src/)")) + | .filename as $file + | (.patch // "") + | split("\n")[] + | select(startswith("+") and (startswith("+++") | not)) + | "\($file): \(.)" + ' > "$added_lines" + + if grep -En '(from|require\().*["'\''](node:)?(net|tls|http2)["'\'']|\b(net|tls|http2)\.(connect|createConnection)\b|new Socket\(|HTTP_PROXY|HTTPS_PROXY|NO_PROXY|GLOBAL_AGENT_|OPENCLAW_PROXY_' "$added_lines"; then + echo "Network runtime boundary-sensitive added lines require full CodeQL review." >&2 + exit 1 + fi + - name: Initialize CodeQL + if: ${{ github.event_name != 'pull_request' }} uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 with: languages: javascript-typescript @@ -439,12 +467,14 @@ jobs: - name: Analyze id: analyze + if: ${{ github.event_name != 'pull_request' }} uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 with: output: sarif-results category: "/codeql-critical-quality/network-runtime-boundary" - name: Fail on network runtime boundary findings + if: ${{ github.event_name != 'pull_request' }} env: SARIF_OUTPUT: sarif-results run: | diff --git a/extensions/tsconfig.package-boundary.paths.json b/extensions/tsconfig.package-boundary.paths.json index e7f6cee30a9..ec6855772d3 100644 --- a/extensions/tsconfig.package-boundary.paths.json +++ b/extensions/tsconfig.package-boundary.paths.json @@ -2,9 +2,15 @@ "extends": "../tsconfig.json", "compilerOptions": { "paths": { - "openclaw/extension-api": ["../src/extensionAPI.ts"], - "openclaw/plugin-sdk": ["../dist/plugin-sdk/index.d.ts"], - "openclaw/plugin-sdk/*": ["../dist/plugin-sdk/*.d.ts"], + "openclaw/extension-api": [ + "../src/extensionAPI.ts" + ], + "openclaw/plugin-sdk": [ + "../dist/plugin-sdk/index.d.ts" + ], + "openclaw/plugin-sdk/*": [ + "../dist/plugin-sdk/*.d.ts" + ], "openclaw/plugin-sdk/reply-payload-testing": [ "../packages/plugin-sdk/dist/src/plugin-sdk/reply-payload-testing.d.ts" ], @@ -29,9 +35,6 @@ "openclaw/plugin-sdk/plugin-test-contracts": [ "../packages/plugin-sdk/dist/src/plugin-sdk/plugin-test-contracts.d.ts" ], - "openclaw/plugin-sdk/plugin-state-test-runtime": [ - "../packages/plugin-sdk/dist/src/plugin-sdk/plugin-state-test-runtime.d.ts" - ], "openclaw/plugin-sdk/plugin-test-runtime": [ "../packages/plugin-sdk/dist/src/plugin-sdk/plugin-test-runtime.d.ts" ], @@ -53,10 +56,15 @@ "openclaw/plugin-sdk/testing": [ "../packages/plugin-sdk/dist/src/plugin-sdk/testing.d.ts" ], + "openclaw/plugin-sdk/plugin-state-test-runtime": [ + "../packages/plugin-sdk/dist/src/plugin-sdk/plugin-state-test-runtime.d.ts" + ], "openclaw/plugin-sdk/channel-contract-testing": [ "../packages/plugin-sdk/dist/src/plugin-sdk/channel-contract-testing.d.ts" ], - "openclaw/plugin-sdk/account-id": ["../dist/plugin-sdk/account-id.d.ts"], + "openclaw/plugin-sdk/account-id": [ + "../dist/plugin-sdk/account-id.d.ts" + ], "openclaw/plugin-sdk/channel-entry-contract": [ "../dist/plugin-sdk/channel-entry-contract.d.ts" ], @@ -75,7 +83,9 @@ "openclaw/plugin-sdk/channel-streaming": [ "../dist/plugin-sdk/channel-streaming.d.ts" ], - "openclaw/plugin-sdk/error-runtime": ["../dist/plugin-sdk/error-runtime.d.ts"], + "openclaw/plugin-sdk/error-runtime": [ + "../dist/plugin-sdk/error-runtime.d.ts" + ], "openclaw/plugin-sdk/provider-catalog-shared": [ "../dist/plugin-sdk/provider-catalog-shared.d.ts" ], @@ -85,23 +95,39 @@ "openclaw/plugin-sdk/secret-ref-runtime": [ "../dist/plugin-sdk/secret-ref-runtime.d.ts" ], - "openclaw/plugin-sdk/ssrf-runtime": ["../dist/plugin-sdk/ssrf-runtime.d.ts"], - "@openclaw/qa-channel/api.js": ["../dist/plugin-sdk/extensions/qa-channel/api.d.ts"], - "@openclaw/discord/api.js": ["../dist/plugin-sdk/extensions/discord/api.d.ts"], - "@openclaw/slack/api.js": ["../dist/plugin-sdk/extensions/slack/api.d.ts"], - "@openclaw/whatsapp/api.js": ["../dist/plugin-sdk/extensions/whatsapp/api.d.ts"], - "@openclaw/llm-core": ["../dist/plugin-sdk/packages/llm-core/src/index.d.ts"], + "openclaw/plugin-sdk/ssrf-runtime": [ + "../dist/plugin-sdk/ssrf-runtime.d.ts" + ], + "@openclaw/qa-channel/api.js": [ + "../dist/plugin-sdk/extensions/qa-channel/api.d.ts" + ], + "@openclaw/discord/api.js": [ + "../dist/plugin-sdk/extensions/discord/api.d.ts" + ], + "@openclaw/slack/api.js": [ + "../dist/plugin-sdk/extensions/slack/api.d.ts" + ], + "@openclaw/whatsapp/api.js": [ + "../dist/plugin-sdk/extensions/whatsapp/api.d.ts" + ], + "@openclaw/llm-core": [ + "../dist/plugin-sdk/packages/llm-core/src/index.d.ts" + ], "@openclaw/llm-core/diagnostics": [ "../dist/plugin-sdk/packages/llm-core/src/utils/diagnostics.d.ts" ], "@openclaw/llm-core/event-stream": [ "../dist/plugin-sdk/packages/llm-core/src/utils/event-stream.d.ts" ], - "@openclaw/llm-core/types": ["../dist/plugin-sdk/packages/llm-core/src/types.d.ts"], + "@openclaw/llm-core/types": [ + "../dist/plugin-sdk/packages/llm-core/src/types.d.ts" + ], "@openclaw/llm-core/validation": [ "../dist/plugin-sdk/packages/llm-core/src/validation.d.ts" ], - "@openclaw/llm-core/*": ["../dist/plugin-sdk/packages/llm-core/src/*.d.ts"], + "@openclaw/llm-core/*": [ + "../dist/plugin-sdk/packages/llm-core/src/*.d.ts" + ], "@openclaw/model-catalog-core": [ "../dist/plugin-sdk/packages/model-catalog-core/src/index.d.ts" ], @@ -234,14 +260,26 @@ "@openclaw/terminal-core/*": [ "../dist/plugin-sdk/packages/terminal-core/src/*.d.ts" ], - "@openclaw/*.js": ["../packages/plugin-sdk/dist/extensions/*.d.ts", "../extensions/*"], - "@openclaw/*": ["../packages/plugin-sdk/dist/extensions/*", "../extensions/*"], - "openclaw/plugin-sdk/qa-channel": ["../dist/plugin-sdk/src/plugin-sdk/qa-channel.d.ts"], + "@openclaw/*.js": [ + "../packages/plugin-sdk/dist/extensions/*.d.ts", + "../extensions/*" + ], + "@openclaw/*": [ + "../packages/plugin-sdk/dist/extensions/*", + "../extensions/*" + ], + "openclaw/plugin-sdk/qa-channel": [ + "../dist/plugin-sdk/src/plugin-sdk/qa-channel.d.ts" + ], "openclaw/plugin-sdk/qa-channel-protocol": [ "../dist/plugin-sdk/src/plugin-sdk/qa-channel-protocol.d.ts" ], - "openclaw/plugin-sdk/qa-runtime": ["../dist/plugin-sdk/src/plugin-sdk/qa-runtime.d.ts"], - "@openclaw/plugin-sdk/*": ["../dist/plugin-sdk/*.d.ts"] + "openclaw/plugin-sdk/qa-runtime": [ + "../dist/plugin-sdk/src/plugin-sdk/qa-runtime.d.ts" + ], + "@openclaw/plugin-sdk/*": [ + "../dist/plugin-sdk/*.d.ts" + ] } } } diff --git a/extensions/xai/tsconfig.json b/extensions/xai/tsconfig.json index 62a0bf97e3d..c56d2289abd 100644 --- a/extensions/xai/tsconfig.json +++ b/extensions/xai/tsconfig.json @@ -3,9 +3,15 @@ "compilerOptions": { "rootDir": ".", "paths": { - "openclaw/extension-api": ["../../src/extensionAPI.ts"], - "openclaw/plugin-sdk": ["../../dist/plugin-sdk/index.d.ts"], - "openclaw/plugin-sdk/*": ["../../dist/plugin-sdk/*.d.ts"], + "openclaw/extension-api": [ + "../../src/extensionAPI.ts" + ], + "openclaw/plugin-sdk": [ + "../../dist/plugin-sdk/index.d.ts" + ], + "openclaw/plugin-sdk/*": [ + "../../dist/plugin-sdk/*.d.ts" + ], "openclaw/plugin-sdk/reply-payload-testing": [ "../../packages/plugin-sdk/dist/src/plugin-sdk/reply-payload-testing.d.ts" ], @@ -30,9 +36,6 @@ "openclaw/plugin-sdk/plugin-test-contracts": [ "../../packages/plugin-sdk/dist/src/plugin-sdk/plugin-test-contracts.d.ts" ], - "openclaw/plugin-sdk/plugin-state-test-runtime": [ - "../../packages/plugin-sdk/dist/src/plugin-sdk/plugin-state-test-runtime.d.ts" - ], "openclaw/plugin-sdk/plugin-test-runtime": [ "../../packages/plugin-sdk/dist/src/plugin-sdk/plugin-test-runtime.d.ts" ], @@ -54,10 +57,15 @@ "openclaw/plugin-sdk/testing": [ "../../packages/plugin-sdk/dist/src/plugin-sdk/testing.d.ts" ], + "openclaw/plugin-sdk/plugin-state-test-runtime": [ + "../../packages/plugin-sdk/dist/src/plugin-sdk/plugin-state-test-runtime.d.ts" + ], "openclaw/plugin-sdk/channel-contract-testing": [ "../../packages/plugin-sdk/dist/src/plugin-sdk/channel-contract-testing.d.ts" ], - "openclaw/plugin-sdk/account-id": ["../../dist/plugin-sdk/account-id.d.ts"], + "openclaw/plugin-sdk/account-id": [ + "../../dist/plugin-sdk/account-id.d.ts" + ], "openclaw/plugin-sdk/channel-entry-contract": [ "../../dist/plugin-sdk/channel-entry-contract.d.ts" ], @@ -70,29 +78,24 @@ "openclaw/plugin-sdk/channel-streaming": [ "../../dist/plugin-sdk/channel-streaming.d.ts" ], - "openclaw/plugin-sdk/cli-runtime": ["../../dist/plugin-sdk/cli-runtime.d.ts"], "openclaw/plugin-sdk/error-runtime": [ "../../dist/plugin-sdk/error-runtime.d.ts" ], "openclaw/plugin-sdk/provider-catalog-shared": [ "../../dist/plugin-sdk/provider-catalog-shared.d.ts" ], - "openclaw/plugin-sdk/provider-env-vars": [ - "../../dist/plugin-sdk/provider-env-vars.d.ts" - ], "openclaw/plugin-sdk/provider-entry": [ "../../dist/plugin-sdk/provider-entry.d.ts" ], - "openclaw/plugin-sdk/provider-web-search-contract": [ - "../../dist/plugin-sdk/provider-web-search-contract.d.ts" - ], "openclaw/plugin-sdk/secret-ref-runtime": [ "../../dist/plugin-sdk/secret-ref-runtime.d.ts" ], "openclaw/plugin-sdk/ssrf-runtime": [ "../../dist/plugin-sdk/ssrf-runtime.d.ts" ], - "@openclaw/qa-channel/api.js": ["../../dist/plugin-sdk/extensions/qa-channel/api.d.ts"], + "@openclaw/qa-channel/api.js": [ + "../../dist/plugin-sdk/extensions/qa-channel/api.d.ts" + ], "@openclaw/llm-core": [ "../../dist/plugin-sdk/packages/llm-core/src/index.d.ts" ], @@ -243,23 +246,52 @@ "@openclaw/terminal-core/*": [ "../../dist/plugin-sdk/packages/terminal-core/src/*.d.ts" ], - "@openclaw/*.js": ["../../packages/plugin-sdk/dist/extensions/*.d.ts", "../*"], - "@openclaw/*": ["../*"], + "@openclaw/*.js": [ + "../../packages/plugin-sdk/dist/extensions/*.d.ts", + "../*" + ], + "@openclaw/*": [ + "../*" + ], "openclaw/plugin-sdk/qa-channel": [ "../../dist/plugin-sdk/src/plugin-sdk/qa-channel.d.ts" ], "openclaw/plugin-sdk/qa-channel-protocol": [ "../../dist/plugin-sdk/src/plugin-sdk/qa-channel-protocol.d.ts" ], - "openclaw/plugin-sdk/qa-runtime": ["../../dist/plugin-sdk/src/plugin-sdk/qa-runtime.d.ts"], - "@openclaw/plugin-sdk/*": ["../../dist/plugin-sdk/*.d.ts"], - "@openclaw/anthropic-vertex/api.js": ["./.boundary-stubs/anthropic-vertex-api.d.ts"], - "@openclaw/ollama/api.js": ["./.boundary-stubs/ollama-api.d.ts"], - "@openclaw/ollama/runtime-api.js": ["./.boundary-stubs/ollama-runtime-api.d.ts"], - "@openclaw/speech-core/runtime-api.js": ["./.boundary-stubs/speech-core-runtime-api.d.ts"] + "openclaw/plugin-sdk/qa-runtime": [ + "../../dist/plugin-sdk/src/plugin-sdk/qa-runtime.d.ts" + ], + "@openclaw/plugin-sdk/*": [ + "../../dist/plugin-sdk/*.d.ts" + ], + "openclaw/plugin-sdk/cli-runtime": [ + "../../dist/plugin-sdk/cli-runtime.d.ts" + ], + "openclaw/plugin-sdk/provider-env-vars": [ + "../../dist/plugin-sdk/provider-env-vars.d.ts" + ], + "openclaw/plugin-sdk/provider-web-search-contract": [ + "../../dist/plugin-sdk/provider-web-search-contract.d.ts" + ], + "@openclaw/anthropic-vertex/api.js": [ + "./.boundary-stubs/anthropic-vertex-api.d.ts" + ], + "@openclaw/ollama/api.js": [ + "./.boundary-stubs/ollama-api.d.ts" + ], + "@openclaw/ollama/runtime-api.js": [ + "./.boundary-stubs/ollama-runtime-api.d.ts" + ], + "@openclaw/speech-core/runtime-api.js": [ + "./.boundary-stubs/speech-core-runtime-api.d.ts" + ] } }, - "include": ["./*.ts", "./src/**/*.ts"], + "include": [ + "./*.ts", + "./src/**/*.ts" + ], "exclude": [ "./**/*.test.ts", "./dist/**", diff --git a/packages/normalization-core/dist/index.d.mts b/packages/normalization-core/dist/index.d.mts new file mode 100644 index 00000000000..beff330c7b4 --- /dev/null +++ b/packages/normalization-core/dist/index.d.mts @@ -0,0 +1,5 @@ +import { MAX_DATE_TIMESTAMP_MS, MAX_TIMER_TIMEOUT_MS, MAX_TIMER_TIMEOUT_SECONDS, UNIX_EPOCH_ISO_STRING, addTimerTimeoutGraceMs, asDateTimestampMs, asFiniteNumber, asFiniteNumberInRange, asPositiveSafeInteger, asSafeIntegerInRange, clampPositiveTimerTimeoutMs, clampTimerTimeoutMs, finiteSecondsToTimerSafeMilliseconds, isFutureDateTimestampMs, nonNegativeSecondsToSafeMilliseconds, parseFiniteNumber, parseStrictFiniteNumber, parseStrictInteger, parseStrictNonNegativeInteger, parseStrictPositiveInteger, positiveSecondsToSafeMilliseconds, resolveDateTimestampMs, resolveExpiresAtMsFromDurationMs, resolveExpiresAtMsFromDurationOrEpoch, resolveExpiresAtMsFromDurationSeconds, resolveExpiresAtMsFromEpochSeconds, resolveIntegerOption, resolveNonNegativeIntegerOption, resolveOptionalIntegerOption, resolvePositiveTimerTimeoutMs, resolveTimerTimeoutMs, resolveTimestampMsToIsoString, timestampMsToIsoFileStamp, timestampMsToIsoString } from "./number-coercion.mjs"; +import { asNullableObjectRecord, asNullableRecord, asOptionalObjectRecord, asOptionalRecord, asRecord, isRecord, readStringField } from "./record-coerce.mjs"; +import { hasNonEmptyString, localeLowercasePreservingWhitespace, lowercasePreservingWhitespace, normalizeFastMode, normalizeLowercaseStringOrEmpty, normalizeNullableString, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeOptionalStringifiedId, normalizeOptionalThreadValue, normalizeStringifiedEntries, normalizeStringifiedOptionalString, readStringValue, resolvePrimaryStringValue } from "./string-coerce.mjs"; +import { normalizeArrayBackedTrimmedStringList, normalizeAtHashSlug, normalizeCsvOrLooseStringList, normalizeHyphenSlug, normalizeOptionalTrimmedStringList, normalizeSingleOrTrimmedStringList, normalizeSortedUniqueStringEntries, normalizeSortedUniqueTrimmedStringList, normalizeStringEntries, normalizeStringEntriesLower, normalizeTrimmedStringList, normalizeUniqueSingleOrTrimmedStringList, normalizeUniqueStringEntries, normalizeUniqueStringEntriesLower, normalizeUniqueTrimmedStringList, sortUniqueStrings, uniqueStrings, uniqueValues } from "./string-normalization.mjs"; +export { MAX_DATE_TIMESTAMP_MS, MAX_TIMER_TIMEOUT_MS, MAX_TIMER_TIMEOUT_SECONDS, UNIX_EPOCH_ISO_STRING, addTimerTimeoutGraceMs, asDateTimestampMs, asFiniteNumber, asFiniteNumberInRange, asNullableObjectRecord, asNullableRecord, asOptionalObjectRecord, asOptionalRecord, asPositiveSafeInteger, asRecord, asSafeIntegerInRange, clampPositiveTimerTimeoutMs, clampTimerTimeoutMs, finiteSecondsToTimerSafeMilliseconds, hasNonEmptyString, isFutureDateTimestampMs, isRecord, localeLowercasePreservingWhitespace, lowercasePreservingWhitespace, nonNegativeSecondsToSafeMilliseconds, normalizeArrayBackedTrimmedStringList, normalizeAtHashSlug, normalizeCsvOrLooseStringList, normalizeFastMode, normalizeHyphenSlug, normalizeLowercaseStringOrEmpty, normalizeNullableString, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeOptionalStringifiedId, normalizeOptionalThreadValue, normalizeOptionalTrimmedStringList, normalizeSingleOrTrimmedStringList, normalizeSortedUniqueStringEntries, normalizeSortedUniqueTrimmedStringList, normalizeStringEntries, normalizeStringEntriesLower, normalizeStringifiedEntries, normalizeStringifiedOptionalString, normalizeTrimmedStringList, normalizeUniqueSingleOrTrimmedStringList, normalizeUniqueStringEntries, normalizeUniqueStringEntriesLower, normalizeUniqueTrimmedStringList, parseFiniteNumber, parseStrictFiniteNumber, parseStrictInteger, parseStrictNonNegativeInteger, parseStrictPositiveInteger, positiveSecondsToSafeMilliseconds, readStringField, readStringValue, resolveDateTimestampMs, resolveExpiresAtMsFromDurationMs, resolveExpiresAtMsFromDurationOrEpoch, resolveExpiresAtMsFromDurationSeconds, resolveExpiresAtMsFromEpochSeconds, resolveIntegerOption, resolveNonNegativeIntegerOption, resolveOptionalIntegerOption, resolvePositiveTimerTimeoutMs, resolvePrimaryStringValue, resolveTimerTimeoutMs, resolveTimestampMsToIsoString, sortUniqueStrings, timestampMsToIsoFileStamp, timestampMsToIsoString, uniqueStrings, uniqueValues }; \ No newline at end of file diff --git a/packages/normalization-core/dist/index.mjs b/packages/normalization-core/dist/index.mjs new file mode 100644 index 00000000000..b870418850e --- /dev/null +++ b/packages/normalization-core/dist/index.mjs @@ -0,0 +1,5 @@ +import { MAX_DATE_TIMESTAMP_MS, MAX_TIMER_TIMEOUT_MS, MAX_TIMER_TIMEOUT_SECONDS, UNIX_EPOCH_ISO_STRING, addTimerTimeoutGraceMs, asDateTimestampMs, asFiniteNumber, asFiniteNumberInRange, asPositiveSafeInteger, asSafeIntegerInRange, clampPositiveTimerTimeoutMs, clampTimerTimeoutMs, finiteSecondsToTimerSafeMilliseconds, isFutureDateTimestampMs, nonNegativeSecondsToSafeMilliseconds, parseFiniteNumber, parseStrictFiniteNumber, parseStrictInteger, parseStrictNonNegativeInteger, parseStrictPositiveInteger, positiveSecondsToSafeMilliseconds, resolveDateTimestampMs, resolveExpiresAtMsFromDurationMs, resolveExpiresAtMsFromDurationOrEpoch, resolveExpiresAtMsFromDurationSeconds, resolveExpiresAtMsFromEpochSeconds, resolveIntegerOption, resolveNonNegativeIntegerOption, resolveOptionalIntegerOption, resolvePositiveTimerTimeoutMs, resolveTimerTimeoutMs, resolveTimestampMsToIsoString, timestampMsToIsoFileStamp, timestampMsToIsoString } from "./number-coercion.mjs"; +import { asNullableObjectRecord, asNullableRecord, asOptionalObjectRecord, asOptionalRecord, asRecord, isRecord, readStringField } from "./record-coerce.mjs"; +import { hasNonEmptyString, localeLowercasePreservingWhitespace, lowercasePreservingWhitespace, normalizeFastMode, normalizeLowercaseStringOrEmpty, normalizeNullableString, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeOptionalStringifiedId, normalizeOptionalThreadValue, normalizeStringifiedEntries, normalizeStringifiedOptionalString, readStringValue, resolvePrimaryStringValue } from "./string-coerce.mjs"; +import { normalizeArrayBackedTrimmedStringList, normalizeAtHashSlug, normalizeCsvOrLooseStringList, normalizeHyphenSlug, normalizeOptionalTrimmedStringList, normalizeSingleOrTrimmedStringList, normalizeSortedUniqueStringEntries, normalizeSortedUniqueTrimmedStringList, normalizeStringEntries, normalizeStringEntriesLower, normalizeTrimmedStringList, normalizeUniqueSingleOrTrimmedStringList, normalizeUniqueStringEntries, normalizeUniqueStringEntriesLower, normalizeUniqueTrimmedStringList, sortUniqueStrings, uniqueStrings, uniqueValues } from "./string-normalization.mjs"; +export { MAX_DATE_TIMESTAMP_MS, MAX_TIMER_TIMEOUT_MS, MAX_TIMER_TIMEOUT_SECONDS, UNIX_EPOCH_ISO_STRING, addTimerTimeoutGraceMs, asDateTimestampMs, asFiniteNumber, asFiniteNumberInRange, asNullableObjectRecord, asNullableRecord, asOptionalObjectRecord, asOptionalRecord, asPositiveSafeInteger, asRecord, asSafeIntegerInRange, clampPositiveTimerTimeoutMs, clampTimerTimeoutMs, finiteSecondsToTimerSafeMilliseconds, hasNonEmptyString, isFutureDateTimestampMs, isRecord, localeLowercasePreservingWhitespace, lowercasePreservingWhitespace, nonNegativeSecondsToSafeMilliseconds, normalizeArrayBackedTrimmedStringList, normalizeAtHashSlug, normalizeCsvOrLooseStringList, normalizeFastMode, normalizeHyphenSlug, normalizeLowercaseStringOrEmpty, normalizeNullableString, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeOptionalStringifiedId, normalizeOptionalThreadValue, normalizeOptionalTrimmedStringList, normalizeSingleOrTrimmedStringList, normalizeSortedUniqueStringEntries, normalizeSortedUniqueTrimmedStringList, normalizeStringEntries, normalizeStringEntriesLower, normalizeStringifiedEntries, normalizeStringifiedOptionalString, normalizeTrimmedStringList, normalizeUniqueSingleOrTrimmedStringList, normalizeUniqueStringEntries, normalizeUniqueStringEntriesLower, normalizeUniqueTrimmedStringList, parseFiniteNumber, parseStrictFiniteNumber, parseStrictInteger, parseStrictNonNegativeInteger, parseStrictPositiveInteger, positiveSecondsToSafeMilliseconds, readStringField, readStringValue, resolveDateTimestampMs, resolveExpiresAtMsFromDurationMs, resolveExpiresAtMsFromDurationOrEpoch, resolveExpiresAtMsFromDurationSeconds, resolveExpiresAtMsFromEpochSeconds, resolveIntegerOption, resolveNonNegativeIntegerOption, resolveOptionalIntegerOption, resolvePositiveTimerTimeoutMs, resolvePrimaryStringValue, resolveTimerTimeoutMs, resolveTimestampMsToIsoString, sortUniqueStrings, timestampMsToIsoFileStamp, timestampMsToIsoString, uniqueStrings, uniqueValues }; diff --git a/packages/normalization-core/dist/number-coercion.d.mts b/packages/normalization-core/dist/number-coercion.d.mts new file mode 100644 index 00000000000..34e6f647cc7 --- /dev/null +++ b/packages/normalization-core/dist/number-coercion.d.mts @@ -0,0 +1,70 @@ +//#region packages/normalization-core/src/number-coercion.d.ts +declare function asFiniteNumber(value: unknown): number | undefined; +declare function asFiniteNumberInRange(value: unknown, range: { + min?: number; + max?: number; + minExclusive?: boolean; + maxExclusive?: boolean; +}): number | undefined; +declare function asSafeIntegerInRange(value: unknown, range: { + min?: number; + max?: number; +}): number | undefined; +declare function parseFiniteNumber(value: unknown): number | undefined; +declare function parseStrictInteger(value: unknown): number | undefined; +declare function parseStrictFiniteNumber(value: unknown): number | undefined; +declare function asPositiveSafeInteger(value: unknown): number | undefined; +declare const MAX_TIMER_TIMEOUT_MS = 2147000000; +declare const MAX_TIMER_TIMEOUT_SECONDS: number; +declare const MAX_DATE_TIMESTAMP_MS = 8640000000000000; +declare const UNIX_EPOCH_ISO_STRING = "1970-01-01T00:00:00.000Z"; +declare function asDateTimestampMs(value: unknown): number | undefined; +declare function isFutureDateTimestampMs(value: unknown, opts?: { + nowMs?: number; +}): value is number; +declare function timestampMsToIsoString(value: unknown): string | undefined; +declare function resolveDateTimestampMs(value: unknown, fallbackValue?: unknown): number; +declare function resolveTimestampMsToIsoString(value: unknown, fallbackValue?: unknown): string; +declare function timestampMsToIsoFileStamp(value: unknown, fallbackValue?: unknown): string; +declare function clampTimerTimeoutMs(valueMs: unknown, minMs?: number): number | undefined; +declare function clampPositiveTimerTimeoutMs(valueMs: unknown): number | undefined; +declare function resolvePositiveTimerTimeoutMs(valueMs: unknown, fallbackMs: number): number; +declare function resolveTimerTimeoutMs(valueMs: unknown, fallbackMs: number, minMs?: number): number; +declare function addTimerTimeoutGraceMs(timeoutMs: unknown, graceMs?: number): number | undefined; +declare function finiteSecondsToTimerSafeMilliseconds(value: unknown, opts?: { + floorSeconds?: boolean; +}): number | undefined; +declare function resolveIntegerOption(value: unknown, fallback: number, range?: { + min?: number; + max?: number; +}): number; +declare function resolveOptionalIntegerOption(value: unknown, range?: { + min?: number; + max?: number; +}): number | undefined; +declare function resolveNonNegativeIntegerOption(value: unknown, fallback: number): number; +declare function parseStrictPositiveInteger(value: unknown): number | undefined; +declare function parseStrictNonNegativeInteger(value: unknown): number | undefined; +declare function positiveSecondsToSafeMilliseconds(value: unknown): number | undefined; +declare function nonNegativeSecondsToSafeMilliseconds(value: unknown): number | undefined; +declare function resolveExpiresAtMsFromDurationMs(value: unknown, opts?: { + nowMs?: number; + bufferMs?: number; + minRemainingMs?: number; +}): number | undefined; +declare function resolveExpiresAtMsFromDurationSeconds(value: unknown, opts?: { + nowMs?: number; + bufferMs?: number; + minRemainingMs?: number; +}): number | undefined; +declare function resolveExpiresAtMsFromEpochSeconds(value: unknown, opts?: { + bufferMs?: number; + maxMs?: number; +}): number | undefined; +declare function resolveExpiresAtMsFromDurationOrEpoch(value: unknown, opts?: { + nowMs?: number; + relativeSecondsThreshold?: number; + absoluteMillisecondsThreshold?: number; +}): number | undefined; +//#endregion +export { MAX_DATE_TIMESTAMP_MS, MAX_TIMER_TIMEOUT_MS, MAX_TIMER_TIMEOUT_SECONDS, UNIX_EPOCH_ISO_STRING, addTimerTimeoutGraceMs, asDateTimestampMs, asFiniteNumber, asFiniteNumberInRange, asPositiveSafeInteger, asSafeIntegerInRange, clampPositiveTimerTimeoutMs, clampTimerTimeoutMs, finiteSecondsToTimerSafeMilliseconds, isFutureDateTimestampMs, nonNegativeSecondsToSafeMilliseconds, parseFiniteNumber, parseStrictFiniteNumber, parseStrictInteger, parseStrictNonNegativeInteger, parseStrictPositiveInteger, positiveSecondsToSafeMilliseconds, resolveDateTimestampMs, resolveExpiresAtMsFromDurationMs, resolveExpiresAtMsFromDurationOrEpoch, resolveExpiresAtMsFromDurationSeconds, resolveExpiresAtMsFromEpochSeconds, resolveIntegerOption, resolveNonNegativeIntegerOption, resolveOptionalIntegerOption, resolvePositiveTimerTimeoutMs, resolveTimerTimeoutMs, resolveTimestampMsToIsoString, timestampMsToIsoFileStamp, timestampMsToIsoString }; \ No newline at end of file diff --git a/packages/normalization-core/dist/number-coercion.mjs b/packages/normalization-core/dist/number-coercion.mjs new file mode 100644 index 00000000000..de778fb27dd --- /dev/null +++ b/packages/normalization-core/dist/number-coercion.mjs @@ -0,0 +1,178 @@ +//#region packages/normalization-core/src/number-coercion.ts +function asFiniteNumber(value) { + return typeof value === "number" && Number.isFinite(value) ? value : void 0; +} +function asFiniteNumberInRange(value, range) { + const number = asFiniteNumber(value); + if (number === void 0) return; + if (range.min !== void 0) { + if (range.minExclusive ? number <= range.min : number < range.min) return; + } + if (range.max !== void 0) { + if (range.maxExclusive ? number >= range.max : number > range.max) return; + } + return number; +} +function asSafeIntegerInRange(value, range) { + if (typeof value !== "number" || !Number.isSafeInteger(value)) return; + if (range.min !== void 0 && value < range.min) return; + if (range.max !== void 0 && value > range.max) return; + return value; +} +function normalizeNumericString(value) { + const trimmed = value.trim(); + return trimmed ? trimmed : void 0; +} +function parseFiniteNumber(value) { + if (typeof value === "number") return Number.isFinite(value) ? value : void 0; + return parseStrictFiniteNumber(value); +} +function parseStrictInteger(value) { + if (typeof value === "number") return Number.isSafeInteger(value) ? value : void 0; + if (typeof value !== "string") return; + const normalized = normalizeNumericString(value); + if (!normalized || !/^[+-]?\d+$/.test(normalized)) return; + const parsed = Number(normalized); + return Number.isSafeInteger(parsed) ? parsed : void 0; +} +function parseStrictFiniteNumber(value) { + if (typeof value === "number") return Number.isFinite(value) ? value : void 0; + if (typeof value !== "string") return; + const normalized = normalizeNumericString(value); + if (!normalized || !/^[+-]?(?:(?:\d+\.?\d*)|(?:\.\d+))(?:e[+-]?\d+)?$/i.test(normalized)) return; + const parsed = Number(normalized); + return Number.isFinite(parsed) ? parsed : void 0; +} +function asPositiveSafeInteger(value) { + return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : void 0; +} +const MAX_TIMER_TIMEOUT_MS = 2147e6; +const MAX_TIMER_TIMEOUT_SECONDS = Math.floor(MAX_TIMER_TIMEOUT_MS / 1e3); +const MAX_DATE_TIMESTAMP_MS = 864e13; +const UNIX_EPOCH_ISO_STRING = "1970-01-01T00:00:00.000Z"; +function asDateTimestampMs(value) { + return asFiniteNumberInRange(value, { + min: -864e13, + max: MAX_DATE_TIMESTAMP_MS + }); +} +function isFutureDateTimestampMs(value, opts = {}) { + const timestampMs = asDateTimestampMs(value); + const nowMs = asDateTimestampMs(opts.nowMs ?? Date.now()); + return timestampMs !== void 0 && nowMs !== void 0 && timestampMs > nowMs; +} +function timestampMsToIsoString(value) { + const timestampMs = asDateTimestampMs(value); + return timestampMs === void 0 ? void 0 : new Date(timestampMs).toISOString(); +} +function resolveDateTimestampMs(value, fallbackValue = Date.now()) { + return asDateTimestampMs(value) ?? asDateTimestampMs(fallbackValue) ?? 0; +} +function resolveTimestampMsToIsoString(value, fallbackValue = Date.now()) { + return timestampMsToIsoString(value) ?? timestampMsToIsoString(fallbackValue) ?? "1970-01-01T00:00:00.000Z"; +} +function timestampMsToIsoFileStamp(value, fallbackValue = Date.now()) { + return resolveTimestampMsToIsoString(value, fallbackValue).replaceAll(":", "-"); +} +function clampTimerTimeoutMs(valueMs, minMs = 1) { + const value = asFiniteNumber(valueMs); + if (value === void 0) return; + return Math.min(Math.max(Math.floor(value), Math.max(1, Math.floor(minMs))), MAX_TIMER_TIMEOUT_MS); +} +function clampPositiveTimerTimeoutMs(valueMs) { + const value = asFiniteNumber(valueMs); + if (value === void 0 || value <= 0) return; + return clampTimerTimeoutMs(value); +} +function resolvePositiveTimerTimeoutMs(valueMs, fallbackMs) { + return clampPositiveTimerTimeoutMs(valueMs) ?? resolveTimerTimeoutMs(fallbackMs, 1); +} +function resolveTimerTimeoutMs(valueMs, fallbackMs, minMs = 1) { + const value = asFiniteNumber(valueMs) ?? asFiniteNumber(fallbackMs); + const min = Math.max(0, Math.floor(minMs)); + if (value === void 0) return min; + return Math.min(Math.max(Math.floor(value), min), MAX_TIMER_TIMEOUT_MS); +} +function addTimerTimeoutGraceMs(timeoutMs, graceMs = 5e3) { + const timeout = asFiniteNumber(timeoutMs); + const grace = asFiniteNumber(graceMs); + if (timeout === void 0 || grace === void 0) return; + const withGrace = timeout + grace; + return Number.isFinite(withGrace) ? clampTimerTimeoutMs(withGrace) : MAX_TIMER_TIMEOUT_MS; +} +function finiteSecondsToTimerSafeMilliseconds(value, opts = {}) { + const seconds = asFiniteNumber(value); + if (seconds === void 0 || seconds <= 0) return; + const boundedSeconds = opts.floorSeconds ? Math.floor(seconds) : seconds; + const milliseconds = Math.floor(boundedSeconds * 1e3); + if (!Number.isFinite(milliseconds) || milliseconds <= 0) return; + return Math.min(milliseconds, MAX_TIMER_TIMEOUT_MS); +} +function resolveIntegerOption(value, fallback, range = {}) { + const floored = Math.floor(typeof value === "number" && Number.isFinite(value) ? value : fallback); + const minBounded = range.min === void 0 ? floored : Math.max(range.min, floored); + return range.max === void 0 ? minBounded : Math.min(range.max, minBounded); +} +function resolveOptionalIntegerOption(value, range = {}) { + if (typeof value !== "number" || !Number.isFinite(value)) return; + return resolveIntegerOption(value, value, range); +} +function resolveNonNegativeIntegerOption(value, fallback) { + return resolveIntegerOption(value, fallback, { min: 0 }); +} +function parseStrictPositiveInteger(value) { + const parsed = parseStrictInteger(value); + return parsed !== void 0 && parsed > 0 ? parsed : void 0; +} +function parseStrictNonNegativeInteger(value) { + const parsed = parseStrictInteger(value); + return parsed !== void 0 && parsed >= 0 ? parsed : void 0; +} +function positiveSecondsToSafeMilliseconds(value) { + const seconds = parseStrictPositiveInteger(value); + if (seconds === void 0) return; + const milliseconds = seconds * 1e3; + return Number.isSafeInteger(milliseconds) ? milliseconds : void 0; +} +function nonNegativeSecondsToSafeMilliseconds(value) { + const seconds = parseStrictNonNegativeInteger(value); + if (seconds === void 0) return; + const milliseconds = seconds * 1e3; + return Number.isSafeInteger(milliseconds) ? milliseconds : void 0; +} +function resolveExpiresAtMsFromDurationMs(value, opts = {}) { + const durationMs = asPositiveSafeInteger(value); + if (durationMs === void 0) return; + const nowMs = asDateTimestampMs(opts.nowMs ?? Date.now()); + const bufferMs = asFiniteNumber(opts.bufferMs ?? 0); + if (nowMs === void 0 || bufferMs === void 0) return; + const expiresAt = nowMs + durationMs - bufferMs; + if (!Number.isSafeInteger(expiresAt) || timestampMsToIsoString(expiresAt) === void 0) return; + const minRemainingMs = opts.minRemainingMs; + if (minRemainingMs === void 0) return expiresAt; + const minExpiresAt = nowMs + minRemainingMs; + if (!Number.isSafeInteger(minExpiresAt) || timestampMsToIsoString(minExpiresAt) === void 0) return expiresAt; + return Math.max(expiresAt, minExpiresAt); +} +function resolveExpiresAtMsFromDurationSeconds(value, opts = {}) { + const durationMs = positiveSecondsToSafeMilliseconds(value); + return durationMs === void 0 ? void 0 : resolveExpiresAtMsFromDurationMs(durationMs, opts); +} +function resolveExpiresAtMsFromEpochSeconds(value, opts = {}) { + const epochMs = typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.trunc(value) * 1e3 : positiveSecondsToSafeMilliseconds(value); + if (epochMs === void 0) return; + const expiresAt = epochMs - (opts.bufferMs ?? 0); + if (!Number.isSafeInteger(expiresAt)) return; + if (timestampMsToIsoString(expiresAt) === void 0) return; + const maxMs = opts.maxMs; + return maxMs === void 0 || expiresAt <= maxMs ? expiresAt : void 0; +} +function resolveExpiresAtMsFromDurationOrEpoch(value, opts = {}) { + const parsed = parseStrictPositiveInteger(value); + if (parsed === void 0) return; + if (parsed < (opts.relativeSecondsThreshold ?? 1e9)) return resolveExpiresAtMsFromDurationSeconds(parsed, { nowMs: opts.nowMs }); + if (parsed < (opts.absoluteMillisecondsThreshold ?? 0xe8d4a51000)) return resolveExpiresAtMsFromEpochSeconds(parsed); + return asDateTimestampMs(parsed); +} +//#endregion +export { MAX_DATE_TIMESTAMP_MS, MAX_TIMER_TIMEOUT_MS, MAX_TIMER_TIMEOUT_SECONDS, UNIX_EPOCH_ISO_STRING, addTimerTimeoutGraceMs, asDateTimestampMs, asFiniteNumber, asFiniteNumberInRange, asPositiveSafeInteger, asSafeIntegerInRange, clampPositiveTimerTimeoutMs, clampTimerTimeoutMs, finiteSecondsToTimerSafeMilliseconds, isFutureDateTimestampMs, nonNegativeSecondsToSafeMilliseconds, parseFiniteNumber, parseStrictFiniteNumber, parseStrictInteger, parseStrictNonNegativeInteger, parseStrictPositiveInteger, positiveSecondsToSafeMilliseconds, resolveDateTimestampMs, resolveExpiresAtMsFromDurationMs, resolveExpiresAtMsFromDurationOrEpoch, resolveExpiresAtMsFromDurationSeconds, resolveExpiresAtMsFromEpochSeconds, resolveIntegerOption, resolveNonNegativeIntegerOption, resolveOptionalIntegerOption, resolvePositiveTimerTimeoutMs, resolveTimerTimeoutMs, resolveTimestampMsToIsoString, timestampMsToIsoFileStamp, timestampMsToIsoString }; diff --git a/packages/normalization-core/dist/record-coerce.d.mts b/packages/normalization-core/dist/record-coerce.d.mts new file mode 100644 index 00000000000..7b8181dae8a --- /dev/null +++ b/packages/normalization-core/dist/record-coerce.d.mts @@ -0,0 +1,10 @@ +//#region packages/normalization-core/src/record-coerce.d.ts +declare function isRecord(value: unknown): value is Record; +declare function asRecord(value: unknown): Record; +declare function readStringField(record: Record | null | undefined, key: string): string | undefined; +declare function asOptionalRecord(value: unknown): Record | undefined; +declare function asNullableRecord(value: unknown): Record | null; +declare function asOptionalObjectRecord(value: unknown): Record | undefined; +declare function asNullableObjectRecord(value: unknown): Record | null; +//#endregion +export { asNullableObjectRecord, asNullableRecord, asOptionalObjectRecord, asOptionalRecord, asRecord, isRecord, readStringField }; \ No newline at end of file diff --git a/packages/normalization-core/dist/record-coerce.mjs b/packages/normalization-core/dist/record-coerce.mjs new file mode 100644 index 00000000000..777678de1f3 --- /dev/null +++ b/packages/normalization-core/dist/record-coerce.mjs @@ -0,0 +1,25 @@ +//#region packages/normalization-core/src/record-coerce.ts +function isRecord(value) { + return value !== null && typeof value === "object" && !Array.isArray(value); +} +function asRecord(value) { + return typeof value === "object" && value !== null ? value : {}; +} +function readStringField(record, key) { + const value = record?.[key]; + return typeof value === "string" ? value : void 0; +} +function asOptionalRecord(value) { + return isRecord(value) ? value : void 0; +} +function asNullableRecord(value) { + return isRecord(value) ? value : null; +} +function asOptionalObjectRecord(value) { + return value && typeof value === "object" ? value : void 0; +} +function asNullableObjectRecord(value) { + return value && typeof value === "object" ? value : null; +} +//#endregion +export { asNullableObjectRecord, asNullableRecord, asOptionalObjectRecord, asOptionalRecord, asRecord, isRecord, readStringField }; diff --git a/packages/normalization-core/dist/string-coerce.d.mts b/packages/normalization-core/dist/string-coerce.d.mts new file mode 100644 index 00000000000..9ebebf2cdbf --- /dev/null +++ b/packages/normalization-core/dist/string-coerce.d.mts @@ -0,0 +1,17 @@ +//#region packages/normalization-core/src/string-coerce.d.ts +declare function readStringValue(value: unknown): string | undefined; +declare function normalizeNullableString(value: unknown): string | null; +declare function normalizeOptionalString(value: unknown): string | undefined; +declare function normalizeStringifiedOptionalString(value: unknown): string | undefined; +declare function normalizeStringifiedEntries(values?: ReadonlyArray): string[]; +declare function normalizeOptionalLowercaseString(value: unknown): string | undefined; +declare function normalizeLowercaseStringOrEmpty(value: unknown): string; +declare function normalizeFastMode(raw?: string | boolean | null): boolean | undefined; +declare function lowercasePreservingWhitespace(value: string): string; +declare function localeLowercasePreservingWhitespace(value: string): string; +declare function resolvePrimaryStringValue(value: unknown): string | undefined; +declare function normalizeOptionalThreadValue(value: unknown): string | number | undefined; +declare function normalizeOptionalStringifiedId(value: unknown): string | undefined; +declare function hasNonEmptyString(value: unknown): value is string; +//#endregion +export { hasNonEmptyString, localeLowercasePreservingWhitespace, lowercasePreservingWhitespace, normalizeFastMode, normalizeLowercaseStringOrEmpty, normalizeNullableString, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeOptionalStringifiedId, normalizeOptionalThreadValue, normalizeStringifiedEntries, normalizeStringifiedOptionalString, readStringValue, resolvePrimaryStringValue }; \ No newline at end of file diff --git a/packages/normalization-core/dist/string-coerce.mjs b/packages/normalization-core/dist/string-coerce.mjs new file mode 100644 index 00000000000..07d591ca70a --- /dev/null +++ b/packages/normalization-core/dist/string-coerce.mjs @@ -0,0 +1,72 @@ +//#region packages/normalization-core/src/string-coerce.ts +function readStringValue(value) { + return typeof value === "string" ? value : void 0; +} +function normalizeNullableString(value) { + if (typeof value !== "string") return null; + const trimmed = value.trim(); + return trimmed ? trimmed : null; +} +function normalizeOptionalString(value) { + return normalizeNullableString(value) ?? void 0; +} +function normalizeStringifiedOptionalString(value) { + if (typeof value === "string") return normalizeOptionalString(value); + if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return normalizeOptionalString(String(value)); +} +function normalizeStringifiedEntries(values) { + return (values ?? []).map((entry) => normalizeStringifiedOptionalString(entry)).filter((entry) => Boolean(entry)); +} +function normalizeOptionalLowercaseString(value) { + return normalizeOptionalString(value)?.toLowerCase(); +} +function normalizeLowercaseStringOrEmpty(value) { + return normalizeOptionalLowercaseString(value) ?? ""; +} +function normalizeFastMode(raw) { + if (typeof raw === "boolean") return raw; + if (!raw) return; + const key = normalizeLowercaseStringOrEmpty(raw); + if ([ + "off", + "false", + "no", + "0", + "disable", + "disabled", + "normal" + ].includes(key)) return false; + if ([ + "on", + "true", + "yes", + "1", + "enable", + "enabled", + "fast" + ].includes(key)) return true; +} +function lowercasePreservingWhitespace(value) { + return value.toLowerCase(); +} +function localeLowercasePreservingWhitespace(value) { + return value.toLocaleLowerCase(); +} +function resolvePrimaryStringValue(value) { + if (typeof value === "string") return normalizeOptionalString(value); + if (!value || typeof value !== "object") return; + return normalizeOptionalString(value.primary); +} +function normalizeOptionalThreadValue(value) { + if (typeof value === "number") return Number.isFinite(value) ? Math.trunc(value) : void 0; + return normalizeOptionalString(value); +} +function normalizeOptionalStringifiedId(value) { + const normalized = normalizeOptionalThreadValue(value); + return normalized == null ? void 0 : String(normalized); +} +function hasNonEmptyString(value) { + return normalizeOptionalString(value) !== void 0; +} +//#endregion +export { hasNonEmptyString, localeLowercasePreservingWhitespace, lowercasePreservingWhitespace, normalizeFastMode, normalizeLowercaseStringOrEmpty, normalizeNullableString, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeOptionalStringifiedId, normalizeOptionalThreadValue, normalizeStringifiedEntries, normalizeStringifiedOptionalString, readStringValue, resolvePrimaryStringValue }; diff --git a/packages/normalization-core/dist/string-normalization.d.mts b/packages/normalization-core/dist/string-normalization.d.mts new file mode 100644 index 00000000000..1131a019c0f --- /dev/null +++ b/packages/normalization-core/dist/string-normalization.d.mts @@ -0,0 +1,21 @@ +//#region packages/normalization-core/src/string-normalization.d.ts +declare function normalizeStringEntries(list?: ReadonlyArray): string[]; +declare function normalizeStringEntriesLower(list?: ReadonlyArray): string[]; +declare function uniqueValues(values: Iterable): T[]; +declare function uniqueStrings(values: Iterable): string[]; +declare function sortUniqueStrings(values: Iterable): string[]; +declare function normalizeUniqueStringEntries(values?: Iterable): string[]; +declare function normalizeUniqueStringEntriesLower(values?: Iterable): string[]; +declare function normalizeSortedUniqueStringEntries(values?: Iterable): string[]; +declare function normalizeTrimmedStringList(value: unknown): string[]; +declare function normalizeUniqueTrimmedStringList(value: unknown): string[]; +declare function normalizeSortedUniqueTrimmedStringList(value: unknown): string[]; +declare function normalizeOptionalTrimmedStringList(value: unknown): string[] | undefined; +declare function normalizeArrayBackedTrimmedStringList(value: unknown): string[] | undefined; +declare function normalizeSingleOrTrimmedStringList(value: unknown): string[]; +declare function normalizeUniqueSingleOrTrimmedStringList(value: unknown): string[]; +declare function normalizeCsvOrLooseStringList(value: unknown): string[]; +declare function normalizeHyphenSlug(raw?: string | null): string; +declare function normalizeAtHashSlug(raw?: string | null): string; +//#endregion +export { normalizeArrayBackedTrimmedStringList, normalizeAtHashSlug, normalizeCsvOrLooseStringList, normalizeHyphenSlug, normalizeOptionalTrimmedStringList, normalizeSingleOrTrimmedStringList, normalizeSortedUniqueStringEntries, normalizeSortedUniqueTrimmedStringList, normalizeStringEntries, normalizeStringEntriesLower, normalizeTrimmedStringList, normalizeUniqueSingleOrTrimmedStringList, normalizeUniqueStringEntries, normalizeUniqueStringEntriesLower, normalizeUniqueTrimmedStringList, sortUniqueStrings, uniqueStrings, uniqueValues }; \ No newline at end of file diff --git a/packages/normalization-core/dist/string-normalization.mjs b/packages/normalization-core/dist/string-normalization.mjs new file mode 100644 index 00000000000..6b25c91648f --- /dev/null +++ b/packages/normalization-core/dist/string-normalization.mjs @@ -0,0 +1,75 @@ +import { normalizeOptionalLowercaseString, normalizeOptionalString } from "./string-coerce.mjs"; +//#region packages/normalization-core/src/string-normalization.ts +function normalizeStringEntries(list) { + return (list ?? []).map((entry) => normalizeOptionalString(String(entry)) ?? "").filter(Boolean); +} +function normalizeStringEntriesLower(list) { + return normalizeStringEntries(list).map((entry) => normalizeOptionalLowercaseString(entry) ?? ""); +} +function uniqueValues(values) { + return [...new Set(values)]; +} +function uniqueStrings(values) { + return uniqueValues(values); +} +function sortUniqueStrings(values) { + return uniqueStrings(values).toSorted((left, right) => left < right ? -1 : left > right ? 1 : 0); +} +function normalizeUniqueStringEntries(values) { + return uniqueStrings(normalizeStringEntries(values ? [...values] : void 0)); +} +function normalizeUniqueStringEntriesLower(values) { + return uniqueStrings(normalizeStringEntriesLower(values ? [...values] : void 0).filter(Boolean)); +} +function normalizeSortedUniqueStringEntries(values) { + return sortUniqueStrings(normalizeUniqueStringEntries(values)); +} +function normalizeTrimmedStringList(value) { + if (!Array.isArray(value)) return []; + return value.flatMap((entry) => { + const normalized = normalizeOptionalString(entry); + return normalized ? [normalized] : []; + }); +} +function normalizeUniqueTrimmedStringList(value) { + return uniqueStrings(normalizeTrimmedStringList(value)); +} +function normalizeSortedUniqueTrimmedStringList(value) { + return sortUniqueStrings(normalizeTrimmedStringList(value)); +} +function normalizeOptionalTrimmedStringList(value) { + const normalized = normalizeTrimmedStringList(value); + return normalized.length > 0 ? normalized : void 0; +} +function normalizeArrayBackedTrimmedStringList(value) { + if (!Array.isArray(value)) return; + return normalizeTrimmedStringList(value); +} +function normalizeSingleOrTrimmedStringList(value) { + if (Array.isArray(value)) return normalizeTrimmedStringList(value); + const normalized = normalizeOptionalString(value); + return normalized ? [normalized] : []; +} +function normalizeUniqueSingleOrTrimmedStringList(value) { + return uniqueStrings(normalizeSingleOrTrimmedStringList(value)); +} +function normalizeCsvOrLooseStringList(value) { + if (Array.isArray(value)) return normalizeStringEntries(value); + if (typeof value === "string") return value.split(",").map((entry) => entry.trim()).filter(Boolean); + return []; +} +function normalizeSlugInput(raw) { + return (normalizeOptionalLowercaseString(raw) ?? "").normalize("NFC"); +} +function normalizeHyphenSlug(raw) { + const trimmed = normalizeSlugInput(raw); + if (!trimmed) return ""; + return trimmed.replace(/\s+/g, "-").replace(/[^\p{L}\p{M}\p{N}#@._+-]+/gu, "-").replace(/-{2,}/g, "-").replace(/^[-.]+|[-.]+$/g, ""); +} +function normalizeAtHashSlug(raw) { + const trimmed = normalizeSlugInput(raw); + if (!trimmed) return ""; + return trimmed.replace(/^[@#]+/, "").replace(/[\s_]+/g, "-").replace(/[^\p{L}\p{M}\p{N}-]+/gu, "-").replace(/-{2,}/g, "-").replace(/^-+|-+$/g, ""); +} +//#endregion +export { normalizeArrayBackedTrimmedStringList, normalizeAtHashSlug, normalizeCsvOrLooseStringList, normalizeHyphenSlug, normalizeOptionalTrimmedStringList, normalizeSingleOrTrimmedStringList, normalizeSortedUniqueStringEntries, normalizeSortedUniqueTrimmedStringList, normalizeStringEntries, normalizeStringEntriesLower, normalizeTrimmedStringList, normalizeUniqueSingleOrTrimmedStringList, normalizeUniqueStringEntries, normalizeUniqueStringEntriesLower, normalizeUniqueTrimmedStringList, sortUniqueStrings, uniqueStrings, uniqueValues }; diff --git a/packages/normalization-core/package.json b/packages/normalization-core/package.json new file mode 100644 index 00000000000..a2025ea6ab2 --- /dev/null +++ b/packages/normalization-core/package.json @@ -0,0 +1,41 @@ +{ + "name": "@openclaw/normalization-core", + "version": "0.0.0-private", + "private": true, + "files": [ + "dist" + ], + "type": "module", + "main": "./dist/index.mjs", + "types": "./dist/index.d.mts", + "exports": { + ".": { + "types": "./dist/index.d.mts", + "import": "./dist/index.mjs", + "default": "./dist/index.mjs" + }, + "./number-coercion": { + "types": "./dist/number-coercion.d.mts", + "import": "./dist/number-coercion.mjs", + "default": "./dist/number-coercion.mjs" + }, + "./record-coerce": { + "types": "./dist/record-coerce.d.mts", + "import": "./dist/record-coerce.mjs", + "default": "./dist/record-coerce.mjs" + }, + "./string-coerce": { + "types": "./dist/string-coerce.d.mts", + "import": "./dist/string-coerce.mjs", + "default": "./dist/string-coerce.mjs" + }, + "./string-normalization": { + "types": "./dist/string-normalization.d.mts", + "import": "./dist/string-normalization.mjs", + "default": "./dist/string-normalization.mjs" + } + }, + "scripts": { + "build": "tsdown src/index.ts src/number-coercion.ts src/record-coerce.ts src/string-coerce.ts src/string-normalization.ts --no-config --platform node --format esm --dts --out-dir dist --clean" + } +} diff --git a/packages/normalization-core/src/index.ts b/packages/normalization-core/src/index.ts new file mode 100644 index 00000000000..dfae88b2012 --- /dev/null +++ b/packages/normalization-core/src/index.ts @@ -0,0 +1,4 @@ +export * from "./number-coercion.js"; +export * from "./record-coerce.js"; +export * from "./string-coerce.js"; +export * from "./string-normalization.js"; diff --git a/src/shared/number-coercion.test.ts b/packages/normalization-core/src/number-coercion.test.ts similarity index 100% rename from src/shared/number-coercion.test.ts rename to packages/normalization-core/src/number-coercion.test.ts diff --git a/src/shared/number-coercion.ts b/packages/normalization-core/src/number-coercion.ts similarity index 100% rename from src/shared/number-coercion.ts rename to packages/normalization-core/src/number-coercion.ts diff --git a/src/shared/record-coerce.test.ts b/packages/normalization-core/src/record-coerce.test.ts similarity index 86% rename from src/shared/record-coerce.test.ts rename to packages/normalization-core/src/record-coerce.test.ts index 7f22cae78e4..166e5660b40 100644 --- a/src/shared/record-coerce.test.ts +++ b/packages/normalization-core/src/record-coerce.test.ts @@ -14,7 +14,10 @@ describe("record-coerce", () => { }); it("stays isolated from utils.ts so browser bundles stay Node-free", () => { - const source = readFileSync(path.resolve("src/shared/record-coerce.ts"), "utf8"); + const source = readFileSync( + path.resolve("packages/normalization-core/src/record-coerce.ts"), + "utf8", + ); expect(source).not.toContain("../utils.js"); }); diff --git a/src/shared/record-coerce.ts b/packages/normalization-core/src/record-coerce.ts similarity index 100% rename from src/shared/record-coerce.ts rename to packages/normalization-core/src/record-coerce.ts diff --git a/src/shared/string-coerce.test.ts b/packages/normalization-core/src/string-coerce.test.ts similarity index 88% rename from src/shared/string-coerce.test.ts rename to packages/normalization-core/src/string-coerce.test.ts index b78e02deb46..1f13a6581c9 100644 --- a/src/shared/string-coerce.test.ts +++ b/packages/normalization-core/src/string-coerce.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from "vitest"; import { normalizeStringifiedEntries } from "./string-coerce.js"; -describe("shared/string-coerce", () => { +describe("normalization-core/string-coerce", () => { it("normalizes primitive stringified entries", () => { expect(normalizeStringifiedEntries([" a ", 42, true, 0n, "", " ", null, {}])).toEqual([ "a", diff --git a/src/shared/string-coerce.ts b/packages/normalization-core/src/string-coerce.ts similarity index 100% rename from src/shared/string-coerce.ts rename to packages/normalization-core/src/string-coerce.ts diff --git a/src/shared/string-normalization.test.ts b/packages/normalization-core/src/string-normalization.test.ts similarity index 98% rename from src/shared/string-normalization.test.ts rename to packages/normalization-core/src/string-normalization.test.ts index da5ae18df40..f1aa05c8b14 100644 --- a/src/shared/string-normalization.test.ts +++ b/packages/normalization-core/src/string-normalization.test.ts @@ -14,7 +14,7 @@ import { uniqueStrings, } from "./string-normalization.js"; -describe("shared/string-normalization", () => { +describe("normalization-core/string-normalization", () => { it("normalizes mixed allow-list entries", () => { expect(normalizeStringEntries([" a ", 42, "", " ", "z"])).toEqual(["a", "42", "z"]); expect(normalizeStringEntries([" ok ", null, { toString: () => " obj " }])).toEqual([ diff --git a/src/shared/string-normalization.ts b/packages/normalization-core/src/string-normalization.ts similarity index 100% rename from src/shared/string-normalization.ts rename to packages/normalization-core/src/string-normalization.ts diff --git a/packages/plugin-sdk/tsconfig.json b/packages/plugin-sdk/tsconfig.json index c9c3894c33b..69cb87f1149 100644 --- a/packages/plugin-sdk/tsconfig.json +++ b/packages/plugin-sdk/tsconfig.json @@ -16,6 +16,7 @@ "../../packages/markdown-core/src/**/*.ts", "../../packages/media-generation-core/src/**/*.ts", "../../packages/model-catalog-core/src/**/*.ts", + "../../packages/normalization-core/src/**/*.ts", "../../packages/terminal-core/src/**/*.ts", "../../src/plugin-sdk/**/*.ts", "../../src/video-generation/dashscope-compatible.ts", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5a95660c753..c3def781345 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1828,6 +1828,8 @@ importers: specifier: 2.4.0 version: 2.4.0 + packages/normalization-core: {} + packages/plugin-package-contract: {} packages/plugin-sdk: {} @@ -1853,10 +1855,10 @@ importers: specifier: 5.6.2 version: 5.6.2 - packages/web-content-core: {} - packages/tool-call-repair: {} + packages/web-content-core: {} + ui: dependencies: '@create-markdown/preview': @@ -1865,6 +1867,9 @@ importers: '@noble/ed25519': specifier: 3.1.0 version: 3.1.0 + '@openclaw/normalization-core': + specifier: workspace:* + version: link:../packages/normalization-core dompurify: specifier: 3.4.6 version: 3.4.6 diff --git a/scripts/build-all.mjs b/scripts/build-all.mjs index 0143545cf0e..084c08ea9f6 100644 --- a/scripts/build-all.mjs +++ b/scripts/build-all.mjs @@ -51,6 +51,7 @@ export const BUILD_ALL_STEPS = [ "packages/media-understanding-common/package.json", "packages/terminal-core/package.json", "packages/model-catalog-core/package.json", + "packages/normalization-core/package.json", "packages/web-content-core/package.json", "packages/memory-host-sdk/package.json", "tsconfig.json", @@ -61,6 +62,7 @@ export const BUILD_ALL_STEPS = [ "packages/model-catalog-core/src", "packages/memory-host-sdk/src", "packages/media-generation-core/src", + "packages/normalization-core/src", "packages/media-understanding-common/src", "packages/terminal-core/src", "packages/web-content-core/src", diff --git a/scripts/debug-claude-usage.ts b/scripts/debug-claude-usage.ts index 4280b5000a9..3d4d0e9204b 100644 --- a/scripts/debug-claude-usage.ts +++ b/scripts/debug-claude-usage.ts @@ -4,7 +4,7 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import { pathToFileURL } from "node:url"; -import { normalizeOptionalString } from "../src/shared/string-coerce.ts"; +import { normalizeOptionalString } from "../packages/normalization-core/src/string-coerce.js"; import { readBoundedResponseText as readBoundedResponseTextWithLimit } from "./lib/bounded-response.ts"; import { maskIdentifier, diff --git a/scripts/e2e/mcp-channels-harness.ts b/scripts/e2e/mcp-channels-harness.ts index c365ebda169..259d6e35d73 100644 --- a/scripts/e2e/mcp-channels-harness.ts +++ b/scripts/e2e/mcp-channels-harness.ts @@ -12,7 +12,7 @@ import { z } from "zod"; import { PROTOCOL_VERSION } from "../../dist/gateway/protocol/index.js"; import { formatErrorMessage } from "../../dist/infra/errors.js"; import { rawDataToString } from "../../dist/infra/ws.js"; -import { readStringValue } from "../../dist/shared/string-coerce.js"; +import { readStringValue } from "../../dist/normalization-core/string-coerce.js"; import { readMcpChannelLimits } from "./mcp-channel-limits.ts"; import { connectMcpWithTimeout } from "./mcp-connect-timeout.ts"; import { waitForWebSocketOpen } from "./mcp-websocket-open.ts"; diff --git a/scripts/lib/plugin-npm-release.ts b/scripts/lib/plugin-npm-release.ts index c811e9e9cba..6390d680fef 100644 --- a/scripts/lib/plugin-npm-release.ts +++ b/scripts/lib/plugin-npm-release.ts @@ -2,8 +2,8 @@ import { execFileSync } from "node:child_process"; import { mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join, resolve } from "node:path"; +import { normalizeOptionalString } from "../../packages/normalization-core/src/string-coerce.js"; import { validateExternalCodePluginPackageJson } from "../../packages/plugin-package-contract/src/index.ts"; -import { normalizeOptionalString } from "../../src/shared/string-coerce.ts"; import { parseReleaseVersion } from "../openclaw-npm-release-check.ts"; import { resolveNpmPublishPlan } from "./npm-publish-plan.mjs"; diff --git a/scripts/lib/tsdown-output-roots.mjs b/scripts/lib/tsdown-output-roots.mjs index e58d9967a80..aac28dfe445 100644 --- a/scripts/lib/tsdown-output-roots.mjs +++ b/scripts/lib/tsdown-output-roots.mjs @@ -9,6 +9,7 @@ const TSDOWN_PACKAGE_NAMES = [ "media-understanding-common", "model-catalog-core", "net-policy", + "normalization-core", "speech-core", "terminal-core", ]; diff --git a/scripts/prepare-extension-package-boundary-artifacts.mjs b/scripts/prepare-extension-package-boundary-artifacts.mjs index c2feea15178..c123084d036 100644 --- a/scripts/prepare-extension-package-boundary-artifacts.mjs +++ b/scripts/prepare-extension-package-boundary-artifacts.mjs @@ -21,6 +21,7 @@ const PLUGIN_SDK_TYPE_INPUTS = [ "packages/memory-host-sdk/src", "packages/media-generation-core/src", "packages/media-understanding-common/src", + "packages/normalization-core/src", "packages/terminal-core/src", "src/video-generation/dashscope-compatible.ts", "src/video-generation/types.ts", @@ -105,6 +106,11 @@ const PACKAGE_DTS_REQUIRED_OUTPUTS = [ "packages/plugin-sdk/dist/packages/model-catalog-core/src/provider-id.d.ts", "packages/plugin-sdk/dist/packages/model-catalog-core/src/provider-model-id-normalization.d.ts", "packages/plugin-sdk/dist/packages/model-catalog-core/src/provider-model-id-normalize.d.ts", + "packages/plugin-sdk/dist/packages/normalization-core/src/index.d.ts", + "packages/plugin-sdk/dist/packages/normalization-core/src/number-coercion.d.ts", + "packages/plugin-sdk/dist/packages/normalization-core/src/record-coerce.d.ts", + "packages/plugin-sdk/dist/packages/normalization-core/src/string-coerce.d.ts", + "packages/plugin-sdk/dist/packages/normalization-core/src/string-normalization.d.ts", "packages/plugin-sdk/dist/packages/terminal-core/src/ansi.d.ts", "packages/plugin-sdk/dist/packages/terminal-core/src/decorative-emoji.d.ts", "packages/plugin-sdk/dist/packages/terminal-core/src/health-style.d.ts", diff --git a/scripts/run-node-watch-paths.mjs b/scripts/run-node-watch-paths.mjs index 50d3314277c..17d946c77ae 100644 --- a/scripts/run-node-watch-paths.mjs +++ b/scripts/run-node-watch-paths.mjs @@ -13,6 +13,7 @@ const RUN_NODE_PACKAGE_SOURCE_ROOTS = [ "packages/markdown-core/src", "packages/media-generation-core/src", "packages/media-understanding-common/src", + "packages/normalization-core/src", "packages/terminal-core/src", "packages/web-content-core/src", "packages/net-policy/src", diff --git a/scripts/write-plugin-sdk-entry-dts.ts b/scripts/write-plugin-sdk-entry-dts.ts index 6d593bdd151..2a4f44f2ba3 100644 --- a/scripts/write-plugin-sdk-entry-dts.ts +++ b/scripts/write-plugin-sdk-entry-dts.ts @@ -44,7 +44,10 @@ const RUNTIME_SHIMS: Partial> = { }; function isBareImportSpecifier(id: string): boolean { - if (id === "@openclaw/model-catalog-core/model-catalog-types") { + if ( + id === "@openclaw/model-catalog-core/model-catalog-types" || + id.startsWith("@openclaw/normalization-core/") + ) { return false; } return !id.startsWith(".") && !id.startsWith("/") && !/^[A-Za-z]:[\\/]/u.test(id); diff --git a/src/acp/approval-classifier.ts b/src/acp/approval-classifier.ts index e1bbf9481ae..1af263fdc7e 100644 --- a/src/acp/approval-classifier.ts +++ b/src/acp/approval-classifier.ts @@ -1,12 +1,12 @@ import { homedir } from "node:os"; import path from "node:path"; -import { isKnownCoreToolId } from "../agents/tool-catalog.js"; -import { isMutatingToolCall } from "../agents/tool-mutation.js"; -import { isPathInside } from "../infra/path-guards.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { isKnownCoreToolId } from "../agents/tool-catalog.js"; +import { isMutatingToolCall } from "../agents/tool-mutation.js"; +import { isPathInside } from "../infra/path-guards.js"; import { asRecord } from "./record-shared.js"; const SAFE_SEARCH_TOOL_IDS = new Set(["search", "web_search", "memory_search"]); diff --git a/src/acp/client-helpers.ts b/src/acp/client-helpers.ts index d076ca5bc10..a48bb29dee5 100644 --- a/src/acp/client-helpers.ts +++ b/src/acp/client-helpers.ts @@ -1,5 +1,9 @@ import * as readline from "node:readline"; import type { RequestPermissionRequest, RequestPermissionResponse } from "@agentclientprotocol/sdk"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { sanitizeTerminalText } from "../../packages/terminal-core/src/safe-text.js"; import { materializeWindowsSpawnProgram, @@ -9,10 +13,6 @@ import { listKnownProviderAuthEnvVarNames, omitEnvKeysCaseInsensitive, } from "../secrets/provider-env-vars.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { classifyAcpToolApproval, type AcpApprovalClass } from "./approval-classifier.js"; type PermissionOption = RequestPermissionRequest["options"][number]; diff --git a/src/acp/client.ts b/src/acp/client.ts index 3460d284582..fa03bf4ec46 100644 --- a/src/acp/client.ts +++ b/src/acp/client.ts @@ -11,8 +11,8 @@ import { type RequestPermissionRequest, type SessionNotification, } from "@agentclientprotocol/sdk"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { ensureOpenClawCliOnPath } from "../infra/path-env.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { buildAcpClientStripKeys, resolveAcpClientSpawnEnv, diff --git a/src/acp/control-plane/manager.core.ts b/src/acp/control-plane/manager.core.ts index d271fc3d33c..c3e36099b3f 100644 --- a/src/acp/control-plane/manager.core.ts +++ b/src/acp/control-plane/manager.core.ts @@ -1,3 +1,5 @@ +import { clampTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { resolveAgentTimeoutMs } from "../../agents/timeout.js"; import { resolveRuntimeConfigCacheKey } from "../../config/runtime-snapshot.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; @@ -5,8 +7,6 @@ import { logVerbose } from "../../globals.js"; import { formatErrorMessage } from "../../infra/errors.js"; import { normalizeAgentId } from "../../routing/session-key.js"; import { isAcpSessionKey } from "../../sessions/session-key-utils.js"; -import { clampTimerTimeoutMs } from "../../shared/number-coercion.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { createRunningTaskRun, completeTaskRunByRunId, diff --git a/src/acp/control-plane/manager.runtime-controls.ts b/src/acp/control-plane/manager.runtime-controls.ts index ff3faf791e1..fcbd37b325e 100644 --- a/src/acp/control-plane/manager.runtime-controls.ts +++ b/src/acp/control-plane/manager.runtime-controls.ts @@ -1,5 +1,5 @@ -import { asNullableRecord } from "../../shared/record-coerce.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +import { asNullableRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { AcpRuntimeError, withAcpRuntimeErrorBoundary } from "../runtime/errors.js"; import type { AcpRuntime, diff --git a/src/acp/control-plane/manager.test.ts b/src/acp/control-plane/manager.test.ts index 4f5c106ea24..b9f5e2bcd16 100644 --- a/src/acp/control-plane/manager.test.ts +++ b/src/acp/control-plane/manager.test.ts @@ -1,10 +1,10 @@ import { setTimeout as scheduleNativeTimeout } from "node:timers"; import { setTimeout as sleep } from "node:timers/promises"; +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../../config/config.js"; import type { AcpSessionRuntimeOptions, SessionAcpMeta } from "../../config/sessions/types.js"; import { resetHeartbeatWakeStateForTests } from "../../infra/heartbeat-wake.js"; -import { MAX_TIMER_TIMEOUT_MS } from "../../shared/number-coercion.js"; import { withTempDir } from "../../test-helpers/temp-dir.js"; import type { AcpRuntime, AcpRuntimeCapabilities } from "../runtime/types.js"; diff --git a/src/acp/control-plane/manager.utils.ts b/src/acp/control-plane/manager.utils.ts index 77174f6e404..b51d064b344 100644 --- a/src/acp/control-plane/manager.utils.ts +++ b/src/acp/control-plane/manager.utils.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { canonicalizeMainSessionAlias, resolveMainSessionKey, @@ -9,7 +10,6 @@ import { normalizeMainKey, parseAgentSessionKey, } from "../../routing/session-key.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { ACP_ERROR_CODES, AcpRuntimeError } from "../runtime/errors.js"; import type { AcpSessionResolution } from "./manager.types.js"; diff --git a/src/acp/control-plane/runtime-options.ts b/src/acp/control-plane/runtime-options.ts index 287ccdcd3af..516977882ee 100644 --- a/src/acp/control-plane/runtime-options.ts +++ b/src/acp/control-plane/runtime-options.ts @@ -1,7 +1,7 @@ import { isAbsolute } from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { AcpSessionRuntimeOptions, SessionAcpMeta } from "../../config/sessions/types.js"; import { parseStrictPositiveInteger } from "../../infra/parse-finite-number.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { normalizeText } from "../normalize-text.js"; import { AcpRuntimeError } from "../runtime/errors.js"; diff --git a/src/acp/event-mapper.ts b/src/acp/event-mapper.ts index 93a3ba85bc8..cddfa427f3d 100644 --- a/src/acp/event-mapper.ts +++ b/src/acp/event-mapper.ts @@ -10,7 +10,7 @@ import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, readStringValue, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; import { asRecord } from "./record-shared.js"; type GatewayAttachment = { diff --git a/src/acp/meta.ts b/src/acp/meta.ts index 4a2b8824614..5415869d3b6 100644 --- a/src/acp/meta.ts +++ b/src/acp/meta.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; function readMetaValue( meta: Record | null | undefined, diff --git a/src/acp/normalize-text.ts b/src/acp/normalize-text.ts index 3c4e58d56c3..94ddf937474 100644 --- a/src/acp/normalize-text.ts +++ b/src/acp/normalize-text.ts @@ -1 +1 @@ -export { normalizeOptionalString as normalizeText } from "../shared/string-coerce.js"; +export { normalizeOptionalString as normalizeText } from "../../packages/normalization-core/src/string-coerce.js"; diff --git a/src/acp/numeric-options.ts b/src/acp/numeric-options.ts index 421d91eb26a..2d8bf7507af 100644 --- a/src/acp/numeric-options.ts +++ b/src/acp/numeric-options.ts @@ -1,4 +1,4 @@ -import { resolveIntegerOption as resolveSharedIntegerOption } from "../shared/number-coercion.js"; +import { resolveIntegerOption as resolveSharedIntegerOption } from "@openclaw/normalization-core/number-coercion"; export function resolveIntegerOption( value: number | undefined, diff --git a/src/acp/permission-relay.ts b/src/acp/permission-relay.ts index 2d54b5d2627..5da122221c3 100644 --- a/src/acp/permission-relay.ts +++ b/src/acp/permission-relay.ts @@ -3,7 +3,7 @@ import type { RequestPermissionRequest, RequestPermissionResponse, } from "@agentclientprotocol/sdk"; -import { normalizeOptionalString as readNonEmptyString } from "../shared/string-coerce.js"; +import { normalizeOptionalString as readNonEmptyString } from "@openclaw/normalization-core/string-coerce"; export type GatewayExecApprovalDecision = "allow-once" | "allow-always" | "deny"; diff --git a/src/acp/persistent-bindings.lifecycle.ts b/src/acp/persistent-bindings.lifecycle.ts index f2abf5030c8..4727a49defc 100644 --- a/src/acp/persistent-bindings.lifecycle.ts +++ b/src/acp/persistent-bindings.lifecycle.ts @@ -1,8 +1,8 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { SessionAcpMeta } from "../config/sessions/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { logVerbose } from "../globals.js"; import { formatErrorMessage } from "../infra/errors.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { getAcpSessionManager } from "./control-plane/manager.js"; import { resolveConfiguredAcpBindingSpecBySessionKey } from "./persistent-bindings.resolve.js"; import { diff --git a/src/acp/persistent-bindings.types.ts b/src/acp/persistent-bindings.types.ts index 345394ac92f..3a1ffb9fd84 100644 --- a/src/acp/persistent-bindings.types.ts +++ b/src/acp/persistent-bindings.types.ts @@ -1,9 +1,9 @@ import { createHash } from "node:crypto"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { ChannelId } from "../channels/plugins/types.public.js"; import type { SessionBindingRecord } from "../infra/outbound/session-binding-service.js"; import { normalizeAccountId, resolveAgentIdFromSessionKey } from "../routing/session-key.js"; import { sanitizeAgentId } from "../routing/session-key.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import { normalizeText } from "./normalize-text.js"; import type { AcpRuntimeSessionMode } from "./runtime/types.js"; diff --git a/src/acp/record-shared.ts b/src/acp/record-shared.ts index a167128c008..981b6fbfb62 100644 --- a/src/acp/record-shared.ts +++ b/src/acp/record-shared.ts @@ -1 +1 @@ -export { asOptionalRecord as asRecord } from "../shared/record-coerce.js"; +export { asOptionalRecord as asRecord } from "@openclaw/normalization-core/record-coerce"; diff --git a/src/acp/runtime/adapter-contract.testkit.ts b/src/acp/runtime/adapter-contract.testkit.ts index 662defa3228..b7f8db301ec 100644 --- a/src/acp/runtime/adapter-contract.testkit.ts +++ b/src/acp/runtime/adapter-contract.testkit.ts @@ -1,6 +1,6 @@ import { randomUUID } from "node:crypto"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { expect } from "vitest"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { toAcpRuntimeError } from "./errors.js"; import type { AcpRuntime, AcpRuntimeEvent } from "./types.js"; diff --git a/src/acp/runtime/registry.ts b/src/acp/runtime/registry.ts index 7a675f5ac2b..1e77b799e4e 100644 --- a/src/acp/runtime/registry.ts +++ b/src/acp/runtime/registry.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { resolveGlobalSingleton } from "../../shared/global-singleton.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { AcpRuntimeError } from "./errors.js"; import type { AcpRuntime } from "./types.js"; diff --git a/src/acp/runtime/session-identifiers.ts b/src/acp/runtime/session-identifiers.ts index 2634e49cbd5..82181e3c25f 100644 --- a/src/acp/runtime/session-identifiers.ts +++ b/src/acp/runtime/session-identifiers.ts @@ -1,5 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { SessionAcpIdentity, SessionAcpMeta } from "../../config/sessions/types.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { normalizeText } from "../normalize-text.js"; import { isSessionIdentityPending, resolveSessionIdentityFromMeta } from "./session-identity.js"; diff --git a/src/acp/runtime/session-meta.ts b/src/acp/runtime/session-meta.ts index f45e6de5650..c9d1388f5c8 100644 --- a/src/acp/runtime/session-meta.ts +++ b/src/acp/runtime/session-meta.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { getRuntimeConfig } from "../../config/config.js"; import { resolveStorePath } from "../../config/sessions/paths.js"; import { loadSessionStore } from "../../config/sessions/store-load.js"; @@ -9,7 +10,6 @@ import { } from "../../config/sessions/types.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { parseAgentSessionKey } from "../../routing/session-key.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; let sessionStoreRuntimePromise: | Promise diff --git a/src/acp/server.ts b/src/acp/server.ts index 4453e3c9829..3bd63b887a9 100644 --- a/src/acp/server.ts +++ b/src/acp/server.ts @@ -2,6 +2,7 @@ import { Readable, Writable } from "node:stream"; import { fileURLToPath } from "node:url"; import { AgentSideConnection, ndJsonStream } from "@agentclientprotocol/sdk"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { GATEWAY_CLIENT_CAPS, GATEWAY_CLIENT_MODES, @@ -13,7 +14,6 @@ import { startGatewayClientWhenEventLoopReady } from "../gateway/client-start-re import { GatewayClient } from "../gateway/client.js"; import { isMainModule } from "../infra/is-main.js"; import { routeLogsToStderr } from "../logging/console.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { createFileAcpEventLedger, resolveDefaultAcpEventLedgerPath } from "./event-ledger.js"; import { readSecretFromFile } from "./secret-file.js"; import { AcpGatewayAgent } from "./translator.js"; diff --git a/src/acp/session-interaction-mode.ts b/src/acp/session-interaction-mode.ts index 071a576a39e..21d6f3d17a9 100644 --- a/src/acp/session-interaction-mode.ts +++ b/src/acp/session-interaction-mode.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { SessionEntry } from "../config/sessions/types.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; type AcpSessionInteractionMode = "interactive" | "parent-owned-background"; diff --git a/src/acp/session-lineage-meta.ts b/src/acp/session-lineage-meta.ts index 8f13dec558e..bcde134719f 100644 --- a/src/acp/session-lineage-meta.ts +++ b/src/acp/session-lineage-meta.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { GatewaySessionRow } from "../gateway/session-utils.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; const SUBAGENT_ROLES = ["orchestrator", "leaf"] as const; const SUBAGENT_CONTROL_SCOPES = ["children", "none"] as const; diff --git a/src/acp/translator.ts b/src/acp/translator.ts index 230894663f6..bd5c3526c8f 100644 --- a/src/acp/translator.ts +++ b/src/acp/translator.ts @@ -33,6 +33,8 @@ import type { ToolCallLocation, ToolKind, } from "@agentclientprotocol/sdk"; +import { timestampMsToIsoString } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { EventFrame } from "../../packages/gateway-protocol/src/index.js"; import { BASE_THINKING_LEVELS } from "../auto-reply/thinking.shared.js"; import type { GatewayClient } from "../gateway/client.js"; @@ -42,8 +44,6 @@ import { resolveFixedWindowRateLimitInteger, type FixedWindowRateLimiter, } from "../infra/fixed-window-rate-limit.js"; -import { timestampMsToIsoString } from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { shortenHomePath } from "../utils.js"; import { createInMemoryAcpEventLedger, diff --git a/src/acp/types.ts b/src/acp/types.ts index 126bf0e9eb1..a48fc9a0a90 100644 --- a/src/acp/types.ts +++ b/src/acp/types.ts @@ -1,5 +1,5 @@ import type { SessionId } from "@agentclientprotocol/sdk"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { VERSION } from "../version.js"; const ACP_PROVENANCE_MODE_VALUES = ["off", "meta", "meta+receipt"] as const; diff --git a/src/agents/accepted-session-spawn.ts b/src/agents/accepted-session-spawn.ts index 22d1565db7e..3ee92083819 100644 --- a/src/agents/accepted-session-spawn.ts +++ b/src/agents/accepted-session-spawn.ts @@ -1,5 +1,5 @@ -import { asOptionalRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { asOptionalRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export type AcceptedSessionSpawn = { runId: string; diff --git a/src/agents/acp-spawn-parent-stream.ts b/src/agents/acp-spawn-parent-stream.ts index b7cb5823568..4f605bbe79b 100644 --- a/src/agents/acp-spawn-parent-stream.ts +++ b/src/agents/acp-spawn-parent-stream.ts @@ -1,5 +1,7 @@ import { mkdir } from "node:fs/promises"; import path from "node:path"; +import { asFiniteNumber } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { readAcpSessionEntry } from "../acp/runtime/session-meta.js"; import { resolveSessionFilePath, resolveSessionFilePathOptions } from "../config/sessions/paths.js"; import { onAgentEvent } from "../infra/agent-events.js"; @@ -12,8 +14,6 @@ import { requestHeartbeat } from "../infra/heartbeat-wake.js"; import { appendRegularFile } from "../infra/regular-file.js"; import { enqueueSystemEvent } from "../infra/system-events.js"; import { normalizeAssistantPhase } from "../shared/chat-message-content.js"; -import { asFiniteNumber } from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { recordTaskRunProgressByRunId } from "../tasks/detached-task-runtime.js"; import type { DeliveryContext } from "../utils/delivery-context.types.js"; diff --git a/src/agents/acp-spawn.ts b/src/agents/acp-spawn.ts index 4ceb9d05ee9..60560d23d50 100644 --- a/src/agents/acp-spawn.ts +++ b/src/agents/acp-spawn.ts @@ -1,5 +1,9 @@ import crypto from "node:crypto"; import fs from "node:fs/promises"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { getAcpSessionManager } from "../acp/control-plane/manager.js"; import type { AcpTurnAttachment } from "../acp/control-plane/manager.types.js"; import { @@ -56,10 +60,6 @@ import { parseAgentSessionKey, resolveAgentIdFromSessionKey, } from "../routing/session-key.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { createRunningTaskRun } from "../tasks/detached-task-runtime.js"; import { listTasksForOwnerKey } from "../tasks/runtime-internal.js"; import { diff --git a/src/agents/agent-auth-credentials.ts b/src/agents/agent-auth-credentials.ts index 75fe61a1ec1..d9d6aa761a5 100644 --- a/src/agents/agent-auth-credentials.ts +++ b/src/agents/agent-auth-credentials.ts @@ -1,7 +1,7 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { asDateTimestampMs } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { coerceSecretRef } from "../config/types.secrets.js"; -import { asDateTimestampMs } from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { AuthProfileCredential, AuthProfileStore } from "./auth-profiles.js"; type AgentApiKeyCredential = { type: "api_key"; key: string }; diff --git a/src/agents/agent-bundle-lsp-runtime.ts b/src/agents/agent-bundle-lsp-runtime.ts index 26e893cab50..e5bae653f61 100644 --- a/src/agents/agent-bundle-lsp-runtime.ts +++ b/src/agents/agent-bundle-lsp-runtime.ts @@ -1,4 +1,5 @@ import { spawn, type ChildProcess } from "node:child_process"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { sanitizeHostExecEnv } from "../infra/host-env-security.js"; import { logDebug, logWarn } from "../logger.js"; @@ -8,7 +9,6 @@ import { } from "../plugin-sdk/windows-spawn.js"; import { setPluginToolMeta } from "../plugins/tools.js"; import { killProcessTree } from "../process/kill-tree.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import { loadEmbeddedAgentLspConfig } from "./embedded-agent-lsp.js"; import { resolveStdioMcpServerLaunchConfig, diff --git a/src/agents/agent-bundle-mcp-materialize.ts b/src/agents/agent-bundle-mcp-materialize.ts index cd5f6f8be40..37a21279860 100644 --- a/src/agents/agent-bundle-mcp-materialize.ts +++ b/src/agents/agent-bundle-mcp-materialize.ts @@ -1,9 +1,9 @@ import crypto from "node:crypto"; import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { logWarn } from "../logger.js"; import { setPluginToolMeta } from "../plugins/tools.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { buildSafeToolName, normalizeReservedToolNames, diff --git a/src/agents/agent-bundle-mcp-names.ts b/src/agents/agent-bundle-mcp-names.ts index c938429d4c4..ddef7978814 100644 --- a/src/agents/agent-bundle-mcp-names.ts +++ b/src/agents/agent-bundle-mcp-names.ts @@ -1,7 +1,7 @@ import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; const TOOL_NAME_SAFE_RE = /[^A-Za-z0-9_-]/g; export const TOOL_NAME_SEPARATOR = "__"; diff --git a/src/agents/agent-bundle-mcp-runtime.ts b/src/agents/agent-bundle-mcp-runtime.ts index e8f93c2bb4c..b3e9c2308a8 100644 --- a/src/agents/agent-bundle-mcp-runtime.ts +++ b/src/agents/agent-bundle-mcp-runtime.ts @@ -11,6 +11,7 @@ import type { jsonSchemaValidator, } from "@modelcontextprotocol/sdk/validation/types.js"; import { redactSensitiveUrlLikeString } from "@openclaw/net-policy/redact-sensitive-url"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { Compile } from "typebox/compile"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { logWarn } from "../logger.js"; @@ -20,7 +21,6 @@ import { findJsonSchemaShapeError, normalizeJsonSchemaForTypeBox, } from "../shared/json-schema-defaults.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { sanitizeServerName } from "./agent-bundle-mcp-names.js"; import type { McpCatalogTool, diff --git a/src/agents/agent-command.ts b/src/agents/agent-command.ts index 2161d965ccb..d9a2fc5b306 100644 --- a/src/agents/agent-command.ts +++ b/src/agents/agent-command.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { sanitizeForLog } from "../../packages/terminal-core/src/ansi.js"; import { resolveInlineAgentImageAttachments } from "../auto-reply/reply/agent-turn-attachments.js"; import { sanitizePendingFinalDeliveryText } from "../auto-reply/reply/pending-final-delivery.js"; @@ -46,7 +47,6 @@ import { } from "../sessions/model-overrides.js"; import { resolveSendPolicy } from "../sessions/send-policy.js"; import { createLazyImportLoader } from "../shared/lazy-promise.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resolveEffectiveAgentSkillFilter } from "../skills/discovery/agent-filter.js"; import type { getRemoteSkillEligibility } from "../skills/runtime/remote.js"; import type { resolveReusableWorkspaceSkillSnapshot } from "../skills/runtime/session-snapshot.js"; diff --git a/src/agents/agent-delete-safety.ts b/src/agents/agent-delete-safety.ts index 29cda1f4720..03147dad1b6 100644 --- a/src/agents/agent-delete-safety.ts +++ b/src/agents/agent-delete-safety.ts @@ -1,9 +1,9 @@ import fs from "node:fs"; import path from "node:path"; +import { lowercasePreservingWhitespace } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { isPathInside } from "../infra/path-guards.js"; import { normalizeAgentId } from "../routing/session-key.js"; -import { lowercasePreservingWhitespace } from "../shared/string-coerce.js"; import { listAgentEntries, resolveAgentWorkspaceDir } from "./agent-scope.js"; function normalizeWorkspacePathForComparison(input: string): string { diff --git a/src/agents/agent-hooks/compaction-safeguard-quality.ts b/src/agents/agent-hooks/compaction-safeguard-quality.ts index 820b0c59ca4..9f780ef5466 100644 --- a/src/agents/agent-hooks/compaction-safeguard-quality.ts +++ b/src/agents/agent-hooks/compaction-safeguard-quality.ts @@ -1,6 +1,6 @@ +import { localeLowercasePreservingWhitespace } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { extractKeywords, isQueryStopWordToken } from "../../memory-host-sdk/query.js"; -import { localeLowercasePreservingWhitespace } from "../../shared/string-coerce.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; import type { CompactionSummarizationInstructions } from "../compaction.js"; import { wrapUntrustedPromptDataBlock } from "../sanitize-for-prompt.js"; diff --git a/src/agents/agent-hooks/context-pruning/tools.ts b/src/agents/agent-hooks/context-pruning/tools.ts index 43c9032a432..536c60e439b 100644 --- a/src/agents/agent-hooks/context-pruning/tools.ts +++ b/src/agents/agent-hooks/context-pruning/tools.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { compileGlobPatterns, matchesAnyGlobPattern } from "../../glob-pattern.js"; import type { ContextPruningToolMatch } from "./settings.js"; diff --git a/src/agents/agent-model-discovery.auth.test.ts b/src/agents/agent-model-discovery.auth.test.ts index 246cb2100cb..a5e63eb9d5e 100644 --- a/src/agents/agent-model-discovery.auth.test.ts +++ b/src/agents/agent-model-discovery.auth.test.ts @@ -1,8 +1,8 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; +import { MAX_DATE_TIMESTAMP_MS } from "@openclaw/normalization-core/number-coercion"; import { describe, expect, it, vi } from "vitest"; -import { MAX_DATE_TIMESTAMP_MS } from "../shared/number-coercion.js"; import { resolveAgentCredentialMapFromStore } from "./agent-auth-credentials.js"; import { addEnvBackedAgentCredentials, diff --git a/src/agents/agent-scope-config.ts b/src/agents/agent-scope-config.ts index 0324dc3e068..0941771560a 100644 --- a/src/agents/agent-scope-config.ts +++ b/src/agents/agent-scope-config.ts @@ -1,4 +1,5 @@ import path from "node:path"; +import { readStringValue } from "@openclaw/normalization-core/string-coerce"; import { resolveStateDir } from "../config/paths.js"; import type { AgentContextLimitsConfig, @@ -6,7 +7,6 @@ import type { } from "../config/types.agent-defaults.js"; import type { OpenClawConfig } from "../config/types.js"; import { DEFAULT_AGENT_ID, normalizeAgentId } from "../routing/session-key.js"; -import { readStringValue } from "../shared/string-coerce.js"; import { resolveUserPath } from "../utils.js"; import { resolveDefaultAgentWorkspaceDir } from "./workspace-default.js"; diff --git a/src/agents/agent-scope.ts b/src/agents/agent-scope.ts index bc0a161021d..658976744d0 100644 --- a/src/agents/agent-scope.ts +++ b/src/agents/agent-scope.ts @@ -3,6 +3,12 @@ import path from "node:path"; import { resolveAgentModelFallbackValues } from "../config/model-input.js"; import { hasSessionAutoModelFallbackProvenance } from "../config/sessions/model-override-provenance.js"; export { hasSessionAutoModelFallbackProvenance } from "../config/sessions/model-override-provenance.js"; +import { + lowercasePreservingWhitespace, + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, + resolvePrimaryStringValue, +} from "@openclaw/normalization-core/string-coerce"; import type { SessionEntry } from "../config/sessions/types.js"; import type { AgentDefaultsConfig } from "../config/types.agent-defaults.js"; import type { AgentModelConfig } from "../config/types.agents-shared.js"; @@ -15,12 +21,6 @@ import { parseAgentSessionKey, resolveAgentIdFromSessionKey, } from "../routing/session-key.js"; -import { - lowercasePreservingWhitespace, - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, - resolvePrimaryStringValue, -} from "../shared/string-coerce.js"; import { resolveEffectiveAgentSkillFilter } from "../skills/discovery/agent-filter.js"; import { resolveUserPath } from "../utils.js"; import { diff --git a/src/agents/agent-tools-parameter-schema.ts b/src/agents/agent-tools-parameter-schema.ts index 2b700388eb9..f6517b17c8c 100644 --- a/src/agents/agent-tools-parameter-schema.ts +++ b/src/agents/agent-tools-parameter-schema.ts @@ -1,13 +1,13 @@ +import { isRecord as isSchemaRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { uniqueValues } from "@openclaw/normalization-core/string-normalization"; import type { TSchema } from "typebox"; import type { ModelCompatConfig } from "../config/types.models.js"; import { resolveUnsupportedToolSchemaKeywords, shouldOmitEmptyArrayItems, } from "../plugins/provider-model-compat.js"; -import { isRecord as isSchemaRecord } from "../shared/record-coerce.js"; import { stripUnsupportedSchemaKeywords } from "../shared/schema-keyword-strip.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { uniqueValues } from "../shared/string-normalization.js"; import { cleanSchemaForGemini } from "./schema/clean-for-gemini.js"; export type ToolParameterSchemaOptions = { diff --git a/src/agents/agent-tools.before-tool-call.ts b/src/agents/agent-tools.before-tool-call.ts index 810c34da914..36f8ed25454 100644 --- a/src/agents/agent-tools.before-tool-call.ts +++ b/src/agents/agent-tools.before-tool-call.ts @@ -1,5 +1,6 @@ import os from "node:os"; import path from "node:path"; +import { addTimerTimeoutGraceMs } from "@openclaw/normalization-core/number-coercion"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { ToolLoopDetectionConfig } from "../config/types.tools.js"; import { @@ -35,7 +36,6 @@ import { type PluginHookToolKind, } from "../plugins/types.js"; import { createLazyRuntimeSurface } from "../shared/lazy-runtime.js"; -import { addTimerTimeoutGraceMs } from "../shared/number-coercion.js"; import { resolveSkillTelemetrySource, resolveSkillTelemetrySourceValue, diff --git a/src/agents/agent-tools.message-provider-policy.ts b/src/agents/agent-tools.message-provider-policy.ts index 9c565a09053..0e225fe7e35 100644 --- a/src/agents/agent-tools.message-provider-policy.ts +++ b/src/agents/agent-tools.message-provider-policy.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; const TOOL_DENY_BY_MESSAGE_PROVIDER: Readonly> = { "discord-voice": ["tts"], diff --git a/src/agents/agent-tools.policy.ts b/src/agents/agent-tools.policy.ts index 04d175b670c..578c6256520 100644 --- a/src/agents/agent-tools.policy.ts +++ b/src/agents/agent-tools.policy.ts @@ -1,4 +1,12 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, +} from "@openclaw/normalization-core/string-coerce"; +import { + normalizeUniqueSingleOrTrimmedStringList, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { getLoadedChannelPlugin } from "../channels/plugins/index.js"; import { resolveSessionConversation } from "../channels/plugins/session-conversation.js"; import { DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH } from "../config/agent-limits.js"; @@ -11,14 +19,6 @@ import { parseRawSessionConversationRef, parseThreadSessionSuffix, } from "../sessions/session-key-utils.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; -import { - normalizeUniqueSingleOrTrimmedStringList, - uniqueStrings, -} from "../shared/string-normalization.js"; import { normalizeMessageChannel } from "../utils/message-channel.js"; import { resolveAgentConfig, resolveAgentIdFromSessionKey } from "./agent-scope.js"; import type { AnyAgentTool } from "./agent-tools.types.js"; diff --git a/src/agents/agent-tools.ts b/src/agents/agent-tools.ts index 197a24c2a31..b76f856be08 100644 --- a/src/agents/agent-tools.ts +++ b/src/agents/agent-tools.ts @@ -1,4 +1,8 @@ import path from "node:path"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, +} from "@openclaw/normalization-core/string-coerce"; import type { SourceReplyDeliveryMode } from "../auto-reply/get-reply-options.types.js"; import { HEARTBEAT_RESPONSE_TOOL_NAME } from "../auto-reply/heartbeat-tool-response.js"; import type { InboundEventKind } from "../channels/inbound-event/kind.js"; @@ -17,10 +21,6 @@ import { resolveMergedSafeBinProfileFixtures } from "../infra/exec-safe-bin-runt import { logWarn } from "../logger.js"; import { getPluginToolMeta } from "../plugins/tools.js"; import { createLazyImportLoader } from "../shared/lazy-promise.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; import type { SkillSnapshot } from "../skills/types.js"; import { resolveGatewayMessageChannel } from "../utils/message-channel.js"; import { resolveAgentConfig } from "./agent-scope.js"; diff --git a/src/agents/anthropic-transport-stream.ts b/src/agents/anthropic-transport-stream.ts index d320fa36d0b..fc0968242ac 100644 --- a/src/agents/anthropic-transport-stream.ts +++ b/src/agents/anthropic-transport-stream.ts @@ -1,10 +1,10 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { getEnvApiKey } from "../llm/env-api-keys.js"; import { calculateCost } from "../llm/model-utils.js"; import type { AnthropicOptions } from "../llm/providers/anthropic.js"; import type { Context, Model, SimpleStreamOptions, ThinkingLevel } from "../llm/types.js"; import { parseStreamingJson } from "../llm/utils/json-parse.js"; import { MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE } from "../shared/assistant-error-format.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { applyAnthropicPayloadPolicyToParams, resolveAnthropicPayloadPolicy, diff --git a/src/agents/api-key-rotation.ts b/src/agents/api-key-rotation.ts index ef7ef74a9a9..09fce0c97f0 100644 --- a/src/agents/api-key-rotation.ts +++ b/src/agents/api-key-rotation.ts @@ -1,3 +1,4 @@ +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import { sleepWithAbort } from "../infra/backoff.js"; import { formatErrorMessage } from "../infra/errors.js"; import { @@ -7,7 +8,6 @@ import { shouldRetrySameKeyProviderOperation, type TransientProviderRetryConfig, } from "../provider-runtime/operation-retry.js"; -import { normalizeUniqueStringEntries } from "../shared/string-normalization.js"; import { collectProviderApiKeys, isApiKeyRateLimitError } from "./live-auth-keys.js"; type ApiKeyRetryParams = { diff --git a/src/agents/auth-health.test.ts b/src/agents/auth-health.test.ts index 591bff4ef68..fb96cfcfa84 100644 --- a/src/agents/auth-health.test.ts +++ b/src/agents/auth-health.test.ts @@ -1,5 +1,5 @@ +import { MAX_DATE_TIMESTAMP_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { MAX_DATE_TIMESTAMP_MS } from "../shared/number-coercion.js"; import type { OAuthCredential } from "./auth-profiles/types.js"; const { readCodexCliCredentialsCachedMock } = vi.hoisted(() => ({ diff --git a/src/agents/auth-health.ts b/src/agents/auth-health.ts index ef655f1cf78..3beeebcd6f0 100644 --- a/src/agents/auth-health.ts +++ b/src/agents/auth-health.ts @@ -2,9 +2,9 @@ import { findNormalizedProviderValue, normalizeProviderId, } from "@openclaw/model-catalog-core/provider-id"; +import { asDateTimestampMs } from "@openclaw/normalization-core/number-coercion"; +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { asDateTimestampMs } from "../shared/number-coercion.js"; -import { normalizeUniqueStringEntries } from "../shared/string-normalization.js"; import { DEFAULT_OAUTH_REFRESH_MARGIN_MS, type AuthCredentialReasonCode, diff --git a/src/agents/auth-profiles/credential-state.ts b/src/agents/auth-profiles/credential-state.ts index 3dc1c9d4b6f..ff5bc47dd3a 100644 --- a/src/agents/auth-profiles/credential-state.ts +++ b/src/agents/auth-profiles/credential-state.ts @@ -1,5 +1,5 @@ +import { MAX_DATE_TIMESTAMP_MS } from "@openclaw/normalization-core/number-coercion"; import { coerceSecretRef, normalizeSecretInputString } from "../../config/types.secrets.js"; -import { MAX_DATE_TIMESTAMP_MS } from "../../shared/number-coercion.js"; import type { AuthProfileCredential, OAuthCredential } from "./types.js"; export type AuthCredentialReasonCode = diff --git a/src/agents/auth-profiles/external-cli-discovery.ts b/src/agents/auth-profiles/external-cli-discovery.ts index 5f990d9eb4a..4a159d02b61 100644 --- a/src/agents/auth-profiles/external-cli-discovery.ts +++ b/src/agents/auth-profiles/external-cli-discovery.ts @@ -1,5 +1,5 @@ +import { normalizeTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { normalizeTrimmedStringList } from "../../shared/string-normalization.js"; import { resolveExternalCliAuthScopeFromConfig, type ExternalCliAuthScope, diff --git a/src/agents/auth-profiles/identity.ts b/src/agents/auth-profiles/identity.ts index fdeee2482c4..622c85d42fc 100644 --- a/src/agents/auth-profiles/identity.ts +++ b/src/agents/auth-profiles/identity.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { AuthProfileStore } from "./types.js"; function resolveStoredMetadata(store: AuthProfileStore | undefined, profileId: string) { diff --git a/src/agents/auth-profiles/oauth-identity.test.ts b/src/agents/auth-profiles/oauth-identity.test.ts index a5598612193..3a6a94ffa28 100644 --- a/src/agents/auth-profiles/oauth-identity.test.ts +++ b/src/agents/auth-profiles/oauth-identity.test.ts @@ -1,5 +1,5 @@ +import { MAX_DATE_TIMESTAMP_MS } from "@openclaw/normalization-core/number-coercion"; import { describe, expect, it } from "vitest"; -import { MAX_DATE_TIMESTAMP_MS } from "../../shared/number-coercion.js"; import { isSafeToCopyOAuthIdentity, isSameOAuthIdentity, diff --git a/src/agents/auth-profiles/oauth-identity.ts b/src/agents/auth-profiles/oauth-identity.ts index d4d552eca86..70fcc7cdad0 100644 --- a/src/agents/auth-profiles/oauth-identity.ts +++ b/src/agents/auth-profiles/oauth-identity.ts @@ -1,4 +1,4 @@ -import { asDateTimestampMs } from "../../shared/number-coercion.js"; +import { asDateTimestampMs } from "@openclaw/normalization-core/number-coercion"; import type { AuthProfileCredential, OAuthCredential } from "./types.js"; export function normalizeAuthIdentityToken(value: string | undefined): string | undefined { diff --git a/src/agents/auth-profiles/oauth.ts b/src/agents/auth-profiles/oauth.ts index a81e882003d..45139cb6776 100644 --- a/src/agents/auth-profiles/oauth.ts +++ b/src/agents/auth-profiles/oauth.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { getRuntimeConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { coerceSecretRef } from "../../config/types.secrets.js"; @@ -13,7 +14,6 @@ import { refreshProviderOAuthCredentialWithPlugin, } from "../../plugins/provider-runtime.runtime.js"; import { resolveSecretRefString, type SecretRefResolveCache } from "../../secrets/resolve.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { normalizeOptionalSecretInput } from "../../utils/normalize-secret-input.js"; import { refreshChutesTokens } from "../chutes-oauth.js"; import { resolveProviderIdForAuth } from "../provider-auth-aliases.js"; diff --git a/src/agents/auth-profiles/persisted.ts b/src/agents/auth-profiles/persisted.ts index da996e49dd2..50ea2c5d1de 100644 --- a/src/agents/auth-profiles/persisted.ts +++ b/src/agents/auth-profiles/persisted.ts @@ -1,9 +1,9 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { resolveOAuthPath } from "../../config/paths.js"; import { coerceSecretRef } from "../../config/types.secrets.js"; import { loadJsonFile } from "../../infra/json-file.js"; -import { isRecord } from "../../shared/record-coerce.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; import { asBoolean } from "../../utils/boolean.js"; import { AUTH_STORE_VERSION, log } from "./constants.js"; import { diff --git a/src/agents/auth-profiles/profile-list.ts b/src/agents/auth-profiles/profile-list.ts index c91519db01b..f68af5dcdfa 100644 --- a/src/agents/auth-profiles/profile-list.ts +++ b/src/agents/auth-profiles/profile-list.ts @@ -1,4 +1,4 @@ -import { uniqueStrings } from "../../shared/string-normalization.js"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { resolveProviderIdForAuth } from "../provider-auth-aliases.js"; import type { AuthProfileStore } from "./types.js"; diff --git a/src/agents/auth-profiles/profiles.ts b/src/agents/auth-profiles/profiles.ts index 3f089acbb89..39d5c17a3ab 100644 --- a/src/agents/auth-profiles/profiles.ts +++ b/src/agents/auth-profiles/profiles.ts @@ -2,7 +2,7 @@ import { findNormalizedProviderKey, normalizeProviderId, } from "@openclaw/model-catalog-core/provider-id"; -import { normalizeStringEntries } from "../../shared/string-normalization.js"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { normalizeSecretInput } from "../../utils/normalize-secret-input.js"; import { resolveProviderIdForAuth } from "../provider-auth-aliases.js"; import { dedupeProfileIds, listProfilesForProvider } from "./profile-list.js"; diff --git a/src/agents/auth-profiles/state.ts b/src/agents/auth-profiles/state.ts index 3087edc22ee..76f1f6fa372 100644 --- a/src/agents/auth-profiles/state.ts +++ b/src/agents/auth-profiles/state.ts @@ -1,11 +1,11 @@ import fs from "node:fs"; import { isDeepStrictEqual } from "node:util"; import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { asFiniteNumber } from "@openclaw/normalization-core/number-coercion"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import { loadJsonFile, repairJsonFilePermissions, saveJsonFile } from "../../infra/json-file.js"; -import { asFiniteNumber } from "../../shared/number-coercion.js"; -import { isRecord } from "../../shared/record-coerce.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; -import { normalizeTrimmedStringList } from "../../shared/string-normalization.js"; import { AUTH_STORE_VERSION } from "./constants.js"; import { resolveAuthStatePath } from "./paths.js"; import type { diff --git a/src/agents/auth-profiles/usage.ts b/src/agents/auth-profiles/usage.ts index b5fba31781e..3768e2bbfe4 100644 --- a/src/agents/auth-profiles/usage.ts +++ b/src/agents/auth-profiles/usage.ts @@ -1,12 +1,12 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; -import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { createSubsystemLogger } from "../../logging/subsystem.js"; import { asDateTimestampMs, isFutureDateTimestampMs, positiveSecondsToSafeMilliseconds, resolveExpiresAtMsFromEpochSeconds, -} from "../../shared/number-coercion.js"; +} from "@openclaw/normalization-core/number-coercion"; +import type { OpenClawConfig } from "../../config/types.openclaw.js"; +import { createSubsystemLogger } from "../../logging/subsystem.js"; import { resolveProviderRequestHeaders } from "../provider-request-config.js"; import { logAuthProfileFailureStateChange } from "./state-observation.js"; diff --git a/src/agents/bash-tools.exec-approval-followup-state.ts b/src/agents/bash-tools.exec-approval-followup-state.ts index 3aeb2f268ee..542a5a79a4f 100644 --- a/src/agents/bash-tools.exec-approval-followup-state.ts +++ b/src/agents/bash-tools.exec-approval-followup-state.ts @@ -2,8 +2,8 @@ import { randomUUID } from "node:crypto"; import { isFutureDateTimestampMs, resolveExpiresAtMsFromDurationMs, -} from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { ExecElevatedDefaults } from "./bash-tools.exec-types.js"; const EXEC_APPROVAL_FOLLOWUP_IDEMPOTENCY_PREFIX = "exec-approval-followup:"; diff --git a/src/agents/bash-tools.exec-approval-followup.ts b/src/agents/bash-tools.exec-approval-followup.ts index 5982c011035..71652e78f62 100644 --- a/src/agents/bash-tools.exec-approval-followup.ts +++ b/src/agents/bash-tools.exec-approval-followup.ts @@ -1,13 +1,13 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveExternalBestEffortDeliveryTarget, type ExternalBestEffortDeliveryTarget, } from "../infra/outbound/best-effort-delivery.js"; import { sendMessage } from "../infra/outbound/message.js"; import { isCronSessionKey, isSubagentSessionKey } from "../sessions/session-key-utils.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { isGatewayMessageChannel, normalizeMessageChannel } from "../utils/message-channel.js"; import { buildExecApprovalFollowupIdempotencyKey } from "./bash-tools.exec-approval-followup-state.js"; import { sanitizeUserFacingText } from "./embedded-agent-helpers/sanitize-user-facing-text.js"; diff --git a/src/agents/bash-tools.exec-approval-request.ts b/src/agents/bash-tools.exec-approval-request.ts index 9591c292366..a456ffb074b 100644 --- a/src/agents/bash-tools.exec-approval-request.ts +++ b/src/agents/bash-tools.exec-approval-request.ts @@ -1,3 +1,11 @@ +import { + asDateTimestampMs, + resolveExpiresAtMsFromDurationMs, +} from "@openclaw/normalization-core/number-coercion"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString as parseString, +} from "@openclaw/normalization-core/string-coerce"; import type { ExecApprovalCommandSpan, ExecAsk, @@ -10,11 +18,6 @@ import { POSIX_SHELL_WRAPPERS, resolveShellWrapperTransportArgv, } from "../infra/shell-wrapper-resolution.js"; -import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "../shared/number-coercion.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString as parseString, -} from "../shared/string-coerce.js"; import { DEFAULT_APPROVAL_REQUEST_TIMEOUT_MS, DEFAULT_APPROVAL_TIMEOUT_MS, diff --git a/src/agents/bash-tools.exec-host-gateway.ts b/src/agents/bash-tools.exec-host-gateway.ts index 9079f623ee8..ebae9bb8f8e 100644 --- a/src/agents/bash-tools.exec-host-gateway.ts +++ b/src/agents/bash-tools.exec-host-gateway.ts @@ -1,3 +1,5 @@ +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { describeInterpreterInlineEval } from "../infra/command-analysis/inline-eval.js"; import { detectPolicyInlineEval } from "../infra/command-analysis/policy.js"; import { @@ -20,8 +22,6 @@ import { type ExecAutoReviewInput, } from "../infra/exec-auto-review.js"; import type { SafeBinProfile } from "../infra/exec-safe-bin-policy.js"; -import { isRecord } from "../shared/record-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { INTERNAL_MESSAGE_CHANNEL, normalizeMessageChannel } from "../utils/message-channel.js"; import { markBackgrounded, tail } from "./bash-process-registry.js"; import { diff --git a/src/agents/bash-tools.exec-host-node-phases.ts b/src/agents/bash-tools.exec-host-node-phases.ts index 34b84c3b515..69fb5f5bfc9 100644 --- a/src/agents/bash-tools.exec-host-node-phases.ts +++ b/src/agents/bash-tools.exec-host-node-phases.ts @@ -1,4 +1,5 @@ import crypto from "node:crypto"; +import { normalizeNullableString } from "@openclaw/normalization-core/string-coerce"; import { describeInterpreterInlineEval, type InterpreterInlineEvalHit, @@ -25,7 +26,6 @@ import { formatExecCommand, resolveSystemRunCommandRequest, } from "../infra/system-run-command.js"; -import { normalizeNullableString } from "../shared/string-coerce.js"; import { addSafeTimeoutDelayGraceMs } from "../utils/timer-delay.js"; import type { ExecuteNodeHostCommandParams } from "./bash-tools.exec-host-node.types.js"; import { renderExecOutputText } from "./bash-tools.exec-output.js"; diff --git a/src/agents/bash-tools.exec-host-shared.test.ts b/src/agents/bash-tools.exec-host-shared.test.ts index 77efcd3cb31..050f68e4f6b 100644 --- a/src/agents/bash-tools.exec-host-shared.test.ts +++ b/src/agents/bash-tools.exec-host-shared.test.ts @@ -1,5 +1,5 @@ +import { MAX_DATE_TIMESTAMP_MS } from "@openclaw/normalization-core/number-coercion"; import { beforeEach, describe, expect, it, vi } from "vitest"; -import { MAX_DATE_TIMESTAMP_MS } from "../shared/number-coercion.js"; import { consumeExecApprovalFollowupRuntimeHandoff, registerExecApprovalFollowupRuntimeHandoff, diff --git a/src/agents/bash-tools.exec-host-shared.ts b/src/agents/bash-tools.exec-host-shared.ts index 93dd4f3b094..2ba21aa4004 100644 --- a/src/agents/bash-tools.exec-host-shared.ts +++ b/src/agents/bash-tools.exec-host-shared.ts @@ -1,4 +1,5 @@ import crypto from "node:crypto"; +import { resolveExpiresAtMsFromDurationMs } from "@openclaw/normalization-core/number-coercion"; import { formatErrorMessage } from "../infra/errors.js"; import { buildExecApprovalUnavailableReplyPayload } from "../infra/exec-approval-reply.js"; import { @@ -15,7 +16,6 @@ import { type ExecSecurity, } from "../infra/exec-approvals.js"; import { logWarn } from "../logger.js"; -import { resolveExpiresAtMsFromDurationMs } from "../shared/number-coercion.js"; import { registerExecApprovalFollowupRuntimeHandoff } from "./bash-tools.exec-approval-followup-state.js"; import { sendExecApprovalFollowup } from "./bash-tools.exec-approval-followup.js"; import { diff --git a/src/agents/bash-tools.exec-runtime.ts b/src/agents/bash-tools.exec-runtime.ts index 239f52f90b3..fbcec8ec806 100644 --- a/src/agents/bash-tools.exec-runtime.ts +++ b/src/agents/bash-tools.exec-runtime.ts @@ -1,4 +1,5 @@ import path from "node:path"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { emitDiagnosticEvent } from "../infra/diagnostic-events.js"; import { type EventSessionRoutingPolicy, @@ -17,7 +18,6 @@ import { isDangerousHostInheritedEnvVarName } from "../infra/host-env-security.j import { findPathKey, mergePathPrepend, removePathPrepend } from "../infra/path-prepend.js"; import { enqueueSystemEvent } from "../infra/system-events.js"; import { isSubagentSessionKey } from "../sessions/session-key-utils.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import type { ProcessSession } from "./bash-process-registry.js"; import type { ExecToolDetails } from "./bash-tools.exec-types.js"; import type { BashSandboxConfig } from "./bash-tools.shared.js"; diff --git a/src/agents/bash-tools.exec.ts b/src/agents/bash-tools.exec.ts index 5d9460f9633..87a75eb0604 100644 --- a/src/agents/bash-tools.exec.ts +++ b/src/agents/bash-tools.exec.ts @@ -1,6 +1,12 @@ import { constants as fsConstants } from "node:fs"; import fs from "node:fs/promises"; import path from "node:path"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { buildCommandPayloadCandidates } from "../infra/command-analysis/risks.js"; import { analyzeShellCommand } from "../infra/exec-approvals-analysis.js"; import { @@ -27,12 +33,6 @@ import { resolveAgentIdFromSessionKey, } from "../routing/session-key.js"; import { createLazyImportLoader } from "../shared/lazy-promise.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { normalizeDeliveryContext } from "../utils/delivery-context.js"; import { splitShellArgs } from "../utils/shell-argv.js"; import { markBackgrounded } from "./bash-process-registry.js"; diff --git a/src/agents/bash-tools.shared.ts b/src/agents/bash-tools.shared.ts index be0eedb52a7..feae9f24121 100644 --- a/src/agents/bash-tools.shared.ts +++ b/src/agents/bash-tools.shared.ts @@ -2,7 +2,7 @@ import { existsSync, statSync } from "node:fs"; import fs from "node:fs/promises"; import { homedir } from "node:os"; import path from "node:path"; -import { parseStrictInteger } from "../shared/number-coercion.js"; +import { parseStrictInteger } from "@openclaw/normalization-core/number-coercion"; import { sliceUtf16Safe } from "../utils.js"; import { assertSandboxPath } from "./sandbox-paths.js"; import type { SandboxBackendExecSpec } from "./sandbox/backend-handle.types.js"; diff --git a/src/agents/bootstrap-budget.ts b/src/agents/bootstrap-budget.ts index 3f8c8c907d1..e42fc652311 100644 --- a/src/agents/bootstrap-budget.ts +++ b/src/agents/bootstrap-budget.ts @@ -1,5 +1,5 @@ import path from "node:path"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { EmbeddedContextFile } from "./embedded-agent-helpers.js"; import type { WorkspaceBootstrapFile } from "./workspace.js"; diff --git a/src/agents/bootstrap-files.ts b/src/agents/bootstrap-files.ts index d273e522ce3..99362fab098 100644 --- a/src/agents/bootstrap-files.ts +++ b/src/agents/bootstrap-files.ts @@ -1,8 +1,8 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { AgentContextInjection } from "../config/types.agent-defaults.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resolveUserPath } from "../utils.js"; import { resolveAgentConfig, resolveSessionAgentIds } from "./agent-scope.js"; import { getOrLoadBootstrapFiles } from "./bootstrap-cache.js"; diff --git a/src/agents/btw.ts b/src/agents/btw.ts index 291038633c4..90489b2a4e7 100644 --- a/src/agents/btw.ts +++ b/src/agents/btw.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { GetReplyOptions } from "../auto-reply/get-reply-options.types.js"; import type { ReplyPayload } from "../auto-reply/reply-payload.js"; import type { ReasoningLevel, ThinkLevel } from "../auto-reply/thinking.js"; @@ -13,7 +14,6 @@ import { type TextContent, } from "../llm/types.js"; import { prepareProviderRuntimeAuth } from "../plugins/provider-runtime.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { discoverAuthStorage, discoverModels } from "./agent-model-discovery.js"; import { resolveAgentWorkspaceDir, resolveSessionAgentId } from "./agent-scope.js"; import { resolveExternalCliAuthOverlayScopeFromSelection } from "./auth-profiles/external-cli-auth-selection.js"; diff --git a/src/agents/cache/agent-cache-store.sqlite.test.ts b/src/agents/cache/agent-cache-store.sqlite.test.ts index 86ad7df31a5..00e63b27137 100644 --- a/src/agents/cache/agent-cache-store.sqlite.test.ts +++ b/src/agents/cache/agent-cache-store.sqlite.test.ts @@ -1,8 +1,8 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; +import { MAX_DATE_TIMESTAMP_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, describe, expect, it } from "vitest"; -import { MAX_DATE_TIMESTAMP_MS } from "../../shared/number-coercion.js"; import { closeOpenClawAgentDatabasesForTest, listOpenClawRegisteredAgentDatabases, diff --git a/src/agents/cache/agent-cache-store.sqlite.ts b/src/agents/cache/agent-cache-store.sqlite.ts index 05abd8d002f..42d70518e1f 100644 --- a/src/agents/cache/agent-cache-store.sqlite.ts +++ b/src/agents/cache/agent-cache-store.sqlite.ts @@ -1,3 +1,10 @@ +import { + MAX_DATE_TIMESTAMP_MS, + asDateTimestampMs, + isFutureDateTimestampMs, + resolveDateTimestampMs, + resolveExpiresAtMsFromDurationMs, +} from "@openclaw/normalization-core/number-coercion"; import type { Selectable } from "kysely"; import { executeSqliteQuerySync, @@ -5,13 +12,6 @@ import { getNodeSqliteKysely, } from "../../infra/kysely-sync.js"; import { normalizeAgentId } from "../../routing/session-key.js"; -import { - MAX_DATE_TIMESTAMP_MS, - asDateTimestampMs, - isFutureDateTimestampMs, - resolveDateTimestampMs, - resolveExpiresAtMsFromDurationMs, -} from "../../shared/number-coercion.js"; import type { DB as OpenClawAgentKyselyDatabase } from "../../state/openclaw-agent-db.generated.js"; import { openOpenClawAgentDatabase, diff --git a/src/agents/channel-tools.ts b/src/agents/channel-tools.ts index 3f2b5bbe006..0ad3394cab0 100644 --- a/src/agents/channel-tools.ts +++ b/src/agents/channel-tools.ts @@ -1,3 +1,4 @@ +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { getChannelPlugin, listChannelPlugins } from "../channels/plugins/index.js"; import { createMessageActionDiscoveryContext, @@ -16,7 +17,6 @@ import type { } from "../channels/plugins/types.public.js"; import { normalizeAnyChannelId } from "../channels/registry.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; type ChannelAgentToolMeta = { channelId: string; diff --git a/src/agents/chutes-oauth.ts b/src/agents/chutes-oauth.ts index bced416a19c..1bf7caa0f6c 100644 --- a/src/agents/chutes-oauth.ts +++ b/src/agents/chutes-oauth.ts @@ -1,7 +1,7 @@ import { createHash, randomBytes } from "node:crypto"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveExpiresAtMsFromDurationSeconds } from "../infra/parse-finite-number.js"; import type { OAuthCredentials } from "../llm/oauth.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; const CHUTES_OAUTH_ISSUER = "https://api.chutes.ai"; export const CHUTES_AUTHORIZE_ENDPOINT = `${CHUTES_OAUTH_ISSUER}/idp/authorize`; diff --git a/src/agents/cli-auth-epoch.ts b/src/agents/cli-auth-epoch.ts index 56cdb5db1ae..86e41c3e670 100644 --- a/src/agents/cli-auth-epoch.ts +++ b/src/agents/cli-auth-epoch.ts @@ -1,5 +1,5 @@ import crypto from "node:crypto"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { loadAuthProfileStoreForRuntime } from "./auth-profiles/store.js"; import type { AuthProfileCredential, AuthProfileStore } from "./auth-profiles/types.js"; import { diff --git a/src/agents/cli-backends.ts b/src/agents/cli-backends.ts index 735372d6f00..d018b2a7a3a 100644 --- a/src/agents/cli-backends.ts +++ b/src/agents/cli-backends.ts @@ -1,4 +1,6 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { CliBackendConfig } from "../config/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { ContextEngineHostCapability } from "../context-engine/types.js"; @@ -16,8 +18,6 @@ import type { CliBackendNativeToolMode, PluginTextTransforms, } from "../plugins/types.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { mergePluginTextTransforms } from "./plugin-text-transforms.js"; type CliBackendsDeps = { diff --git a/src/agents/cli-credentials.ts b/src/agents/cli-credentials.ts index e7f87f56454..06c649ec50d 100644 --- a/src/agents/cli-credentials.ts +++ b/src/agents/cli-credentials.ts @@ -2,14 +2,14 @@ import { execFileSync, execSync } from "node:child_process"; import { createHash } from "node:crypto"; import fs from "node:fs"; import path from "node:path"; -import { formatErrorMessage } from "../infra/errors.js"; -import { loadJsonFile, saveJsonFile } from "../infra/json-file.js"; -import { createSubsystemLogger } from "../logging/subsystem.js"; import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs, timestampMsToIsoString, -} from "../shared/number-coercion.js"; +} from "@openclaw/normalization-core/number-coercion"; +import { formatErrorMessage } from "../infra/errors.js"; +import { loadJsonFile, saveJsonFile } from "../infra/json-file.js"; +import { createSubsystemLogger } from "../logging/subsystem.js"; import { resolveUserPath } from "../utils.js"; import type { OAuthCredentials, OAuthProvider } from "./auth-profiles/types.js"; diff --git a/src/agents/cli-output.ts b/src/agents/cli-output.ts index ce900456004..d733c4de1ad 100644 --- a/src/agents/cli-output.ts +++ b/src/agents/cli-output.ts @@ -1,7 +1,7 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { CliBackendConfig } from "../config/types.js"; import { extractBalancedJsonFragments } from "../shared/balanced-json.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { isRecord } from "../utils.js"; type CliUsage = { diff --git a/src/agents/cli-runner/bundle-mcp-adapter-shared.ts b/src/agents/cli-runner/bundle-mcp-adapter-shared.ts index dfb923f3ccb..9cea63b71cd 100644 --- a/src/agents/cli-runner/bundle-mcp-adapter-shared.ts +++ b/src/agents/cli-runner/bundle-mcp-adapter-shared.ts @@ -1,6 +1,6 @@ +import { isRecord } from "../../../packages/normalization-core/src/record-coerce.js"; import type { BundleMcpServerConfig } from "../../plugins/bundle-mcp.js"; -import { isRecord } from "../../shared/record-coerce.js"; -export { isRecord } from "../../shared/record-coerce.js"; +export { isRecord } from "../../../packages/normalization-core/src/record-coerce.js"; function normalizeStringArray(value: unknown): string[] | undefined { return Array.isArray(value) && value.every((entry) => typeof entry === "string") diff --git a/src/agents/cli-runner/bundle-mcp-claude.ts b/src/agents/cli-runner/bundle-mcp-claude.ts index abd7461ce0c..f078552fc38 100644 --- a/src/agents/cli-runner/bundle-mcp-claude.ts +++ b/src/agents/cli-runner/bundle-mcp-claude.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export function findClaudeMcpConfigPath(args?: string[]): string | undefined { if (!args?.length) { diff --git a/src/agents/cli-runner/claude-skills-plugin.ts b/src/agents/cli-runner/claude-skills-plugin.ts index dc77fe00105..6215abfa409 100644 --- a/src/agents/cli-runner/claude-skills-plugin.ts +++ b/src/agents/cli-runner/claude-skills-plugin.ts @@ -1,8 +1,8 @@ import { accessSync } from "node:fs"; import fs from "node:fs/promises"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { resolvePreferredOpenClawTmpDir } from "../../infra/tmp-openclaw-dir.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import type { SkillSnapshot } from "../../skills/types.js"; import { cliBackendLog } from "./log.js"; diff --git a/src/agents/cli-runner/helpers.ts b/src/agents/cli-runner/helpers.ts index 0d31ce46ea0..bfd0c3e0c86 100644 --- a/src/agents/cli-runner/helpers.ts +++ b/src/agents/cli-runner/helpers.ts @@ -2,6 +2,10 @@ import crypto from "node:crypto"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, +} from "@openclaw/normalization-core/string-coerce"; import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue"; import { isAcpRuntimeSpawnAvailable } from "../../acp/runtime/availability.js"; import type { SourceReplyDeliveryMode } from "../../auto-reply/get-reply-options.types.js"; @@ -15,10 +19,6 @@ import type { ImageContent } from "../../llm/types.js"; import { MAX_IMAGE_BYTES } from "../../media/constants.js"; import { extensionForMime } from "../../media/mime.js"; import { listRegisteredPluginAgentPromptGuidance } from "../../plugins/command-registry-state.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, -} from "../../shared/string-coerce.js"; import type { EmbeddedContextFile } from "../embedded-agent-helpers.js"; import { detectImageReferences, loadImageFromRef } from "../embedded-agent-runner/run/images.js"; import { resolveDefaultModelForAgent } from "../model-selection.js"; diff --git a/src/agents/cli-runner/prepare.ts b/src/agents/cli-runner/prepare.ts index 6c9e5be8afb..40cade857e6 100644 --- a/src/agents/cli-runner/prepare.ts +++ b/src/agents/cli-runner/prepare.ts @@ -1,3 +1,4 @@ +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { getRuntimeConfig } from "../../config/config.js"; import { assertContextEngineHostSupport, @@ -20,7 +21,6 @@ import type { import { buildAgentHookContextChannelFields } from "../../plugins/hook-agent-context.js"; import { getGlobalHookRunner } from "../../plugins/hook-runner-global.js"; import { annotateInterSessionPromptText } from "../../sessions/input-provenance.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; import { resolveSkillsPromptForRun } from "../../skills/loading/workspace.js"; import { resolveUserPath } from "../../utils.js"; import { resolveAgentDir, resolveSessionAgentIds } from "../agent-scope.js"; diff --git a/src/agents/cli-runner/reliability.ts b/src/agents/cli-runner/reliability.ts index ff9c373f157..0c50db96074 100644 --- a/src/agents/cli-runner/reliability.ts +++ b/src/agents/cli-runner/reliability.ts @@ -1,6 +1,6 @@ import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { CliBackendConfig } from "../../config/types.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { CLI_FRESH_WATCHDOG_DEFAULTS, CLI_RESUME_WATCHDOG_DEFAULTS, diff --git a/src/agents/cli-runner/toml-inline.ts b/src/agents/cli-runner/toml-inline.ts index ac7d5fec234..cec3366ddd8 100644 --- a/src/agents/cli-runner/toml-inline.ts +++ b/src/agents/cli-runner/toml-inline.ts @@ -1,4 +1,4 @@ -import { isRecord } from "../../shared/record-coerce.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; function escapeTomlString(value: string): string { return value.replaceAll("\\", "\\\\").replaceAll('"', '\\"'); diff --git a/src/agents/cli-session.ts b/src/agents/cli-session.ts index 20a95ae971b..4267887868b 100644 --- a/src/agents/cli-session.ts +++ b/src/agents/cli-session.ts @@ -1,6 +1,6 @@ import crypto from "node:crypto"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { CliSessionBinding, SessionEntry } from "../config/sessions.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { normalizeProviderId } from "./model-selection.js"; const CLAUDE_CLI_BACKEND_ID = "claude-cli"; diff --git a/src/agents/code-mode-namespaces.ts b/src/agents/code-mode-namespaces.ts index a85099741da..e7006ee9ff6 100644 --- a/src/agents/code-mode-namespaces.ts +++ b/src/agents/code-mode-namespaces.ts @@ -1,4 +1,4 @@ -import { isRecord } from "../shared/record-coerce.js"; +import { isRecord } from "../../packages/normalization-core/src/record-coerce.js"; const FORBIDDEN_NAMESPACE_PATH_SEGMENTS = new Set(["__proto__", "constructor", "prototype"]); const NAMESPACE_PATH_KEY_SEPARATOR = "\u0000"; diff --git a/src/agents/code-mode.test.ts b/src/agents/code-mode.test.ts index d963cb93244..dd9cfbe22d3 100644 --- a/src/agents/code-mode.test.ts +++ b/src/agents/code-mode.test.ts @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { setPluginToolMeta } from "../plugins/tools.js"; -import { isRecord } from "../shared/record-coerce.js"; +import { isRecord } from "../../packages/normalization-core/src/record-coerce.js"; import { clearCodeModeNamespacesForPlugin, clearCodeModeNamespacesForTest, diff --git a/src/agents/code-mode.ts b/src/agents/code-mode.ts index 4abd524e1f4..af6c9df9b96 100644 --- a/src/agents/code-mode.ts +++ b/src/agents/code-mode.ts @@ -2,14 +2,14 @@ import { randomUUID } from "node:crypto"; import path from "node:path"; import { fileURLToPath, pathToFileURL } from "node:url"; import { Worker } from "node:worker_threads"; -import { Type } from "typebox"; -import type { OpenClawConfig } from "../config/types.openclaw.js"; import { isFutureDateTimestampMs, resolveExpiresAtMsFromDurationSeconds, -} from "../shared/number-coercion.js"; -import { isRecord } from "../shared/record-coerce.js"; -import { uniqueValues } from "../shared/string-normalization.js"; +} from "@openclaw/normalization-core/number-coercion"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { uniqueValues } from "@openclaw/normalization-core/string-normalization"; +import { Type } from "typebox"; +import type { OpenClawConfig } from "../config/types.openclaw.js"; import { resolveAgentConfig } from "./agent-scope-config.js"; import type { HookContext } from "./agent-tools.before-tool-call.js"; import { diff --git a/src/agents/codex-mcp-config.ts b/src/agents/codex-mcp-config.ts index 5292342b640..c2883f4c04a 100644 --- a/src/agents/codex-mcp-config.ts +++ b/src/agents/codex-mcp-config.ts @@ -1,10 +1,10 @@ import crypto from "node:crypto"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { loadEnabledBundleMcpConfig, type BundleMcpConfig, type BundleMcpServerConfig, } from "../plugins/bundle-mcp.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import { isRecord } from "../utils.js"; import { applyCommonServerConfig, diff --git a/src/agents/codex-native-web-search.shared.ts b/src/agents/codex-native-web-search.shared.ts index 77a4ce3f8ea..527610e774c 100644 --- a/src/agents/codex-native-web-search.shared.ts +++ b/src/agents/codex-native-web-search.shared.ts @@ -1,5 +1,5 @@ +import { normalizeUniqueTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeUniqueTrimmedStringList } from "../shared/string-normalization.js"; import { isRecord } from "../utils.js"; export type CodexNativeSearchMode = "cached" | "live"; diff --git a/src/agents/command/claude-cli-project-dir.ts b/src/agents/command/claude-cli-project-dir.ts index 40ac1552f05..ec22f295d3f 100644 --- a/src/agents/command/claude-cli-project-dir.ts +++ b/src/agents/command/claude-cli-project-dir.ts @@ -1,7 +1,7 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; const CLAUDE_PROJECTS_DIRNAME = path.join(".claude", "projects"); const MAX_SANITIZED_PROJECT_LENGTH = 200; diff --git a/src/agents/command/session-store.ts b/src/agents/command/session-store.ts index 9575417a662..4a1858e554d 100644 --- a/src/agents/command/session-store.ts +++ b/src/agents/command/session-store.ts @@ -1,4 +1,5 @@ import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { canonicalizeAbsoluteSessionFilePath, mergeSessionEntry, @@ -13,7 +14,6 @@ import { resolveMaintenanceConfigFromInput } from "../../config/sessions/store-m import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { resolveAgentIdFromSessionKey } from "../../routing/session-key.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { clearCliSession, setCliSessionBinding, setCliSessionId } from "../cli-session.js"; import { DEFAULT_CONTEXT_TOKENS } from "../defaults.js"; import { isCliProvider } from "../model-selection.js"; diff --git a/src/agents/context.ts b/src/agents/context.ts index 8e0a50b9789..e3ad2ec5d94 100644 --- a/src/agents/context.ts +++ b/src/agents/context.ts @@ -1,10 +1,10 @@ // Load session runtime model metadata so we can infer context windows when the // agent reports a model id. This includes custom models.json entries. +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { getRuntimeConfig } from "../config/config.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { computeBackoff, type BackoffPolicy } from "../infra/backoff.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { discoverAuthStorage, discoverModels } from "./agent-model-discovery.js"; import { resolveAgentWorkspaceDir, diff --git a/src/agents/current-time.ts b/src/agents/current-time.ts index 81d98216135..99322bb888b 100644 --- a/src/agents/current-time.ts +++ b/src/agents/current-time.ts @@ -1,4 +1,4 @@ -import { resolveDateTimestampMs } from "../shared/number-coercion.js"; +import { resolveDateTimestampMs } from "@openclaw/normalization-core/number-coercion"; import { type TimeFormatPreference, formatUserTime, diff --git a/src/agents/date-time.ts b/src/agents/date-time.ts index 4390e2f8418..af4f9424767 100644 --- a/src/agents/date-time.ts +++ b/src/agents/date-time.ts @@ -1,5 +1,5 @@ import { execFileSync } from "node:child_process"; -import { resolveDateTimestampMs } from "../shared/number-coercion.js"; +import { resolveDateTimestampMs } from "@openclaw/normalization-core/number-coercion"; export type TimeFormatPreference = "auto" | "12" | "24"; export type ResolvedTimeFormat = "12" | "24"; diff --git a/src/agents/embedded-agent-error-observation.ts b/src/agents/embedded-agent-error-observation.ts index f8948318cbf..01e5678c16a 100644 --- a/src/agents/embedded-agent-error-observation.ts +++ b/src/agents/embedded-agent-error-observation.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { readLoggingConfig } from "../logging/config.js"; import { redactIdentifier } from "../logging/redact-identifier.js"; import { getDefaultRedactPatterns, redactSensitiveText } from "../logging/redact.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { classifyProviderRuntimeFailureKind, getApiErrorPayloadFingerprint, diff --git a/src/agents/embedded-agent-helpers/bootstrap.ts b/src/agents/embedded-agent-helpers/bootstrap.ts index d0c28f28a0e..eaa9f616360 100644 --- a/src/agents/embedded-agent-helpers/bootstrap.ts +++ b/src/agents/embedded-agent-helpers/bootstrap.ts @@ -1,8 +1,8 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { sanitizeGoogleAssistantFirstOrdering } from "../../shared/google-turn-ordering.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { truncateUtf16Safe } from "../../utils.js"; import { resolveAgentConfig } from "../agent-scope.js"; import type { AgentMessage } from "../runtime/index.js"; diff --git a/src/agents/embedded-agent-helpers/errors.ts b/src/agents/embedded-agent-helpers/errors.ts index 93fac4902f1..43166614022 100644 --- a/src/agents/embedded-agent-helpers/errors.ts +++ b/src/agents/embedded-agent-helpers/errors.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, +} from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { AssistantMessage } from "../../llm/types.js"; import { createSubsystemLogger } from "../../logging/subsystem.js"; @@ -7,10 +11,6 @@ import { isGenericProviderInternalError, parseApiErrorInfo, } from "../../shared/assistant-error-format.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, -} from "../../shared/string-coerce.js"; export { extractLeadingHttpStatus, formatRawAssistantErrorForUi, diff --git a/src/agents/embedded-agent-helpers/failover-matches.ts b/src/agents/embedded-agent-helpers/failover-matches.ts index ad314cb5197..49952e3e1b2 100644 --- a/src/agents/embedded-agent-helpers/failover-matches.ts +++ b/src/agents/embedded-agent-helpers/failover-matches.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; type ErrorPattern = RegExp | string; diff --git a/src/agents/embedded-agent-helpers/messaging-dedupe.ts b/src/agents/embedded-agent-helpers/messaging-dedupe.ts index 6435c6e9fe9..efdc39f47e7 100644 --- a/src/agents/embedded-agent-helpers/messaging-dedupe.ts +++ b/src/agents/embedded-agent-helpers/messaging-dedupe.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; const MIN_DUPLICATE_TEXT_LENGTH = 10; const MIN_REVERSE_SUBSTRING_DUPLICATE_RATIO = 0.5; diff --git a/src/agents/embedded-agent-helpers/sanitize-user-facing-text.ts b/src/agents/embedded-agent-helpers/sanitize-user-facing-text.ts index 963d4b7dfe9..2d8da4be50f 100644 --- a/src/agents/embedded-agent-helpers/sanitize-user-facing-text.ts +++ b/src/agents/embedded-agent-helpers/sanitize-user-facing-text.ts @@ -13,7 +13,7 @@ import { coerceChatContentText } from "../../shared/chat-content.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, -} from "../../shared/string-coerce.js"; +} from "../../../packages/normalization-core/src/string-coerce.js"; import { stripLegacyBracketToolCallBlocks, stripMinimaxToolCallXml, diff --git a/src/agents/embedded-agent-helpers/thinking.ts b/src/agents/embedded-agent-helpers/thinking.ts index 367e1f038cd..87478d111e0 100644 --- a/src/agents/embedded-agent-helpers/thinking.ts +++ b/src/agents/embedded-agent-helpers/thinking.ts @@ -1,5 +1,5 @@ +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { normalizeThinkLevel, type ThinkLevel } from "../../auto-reply/thinking.js"; -import { normalizeStringEntries } from "../../shared/string-normalization.js"; import { isReasoningConstraintErrorMessage } from "./errors.js"; function extractSupportedValues(raw: string): string[] { diff --git a/src/agents/embedded-agent-helpers/turns.ts b/src/agents/embedded-agent-helpers/turns.ts index dca2215b2c1..599a8735763 100644 --- a/src/agents/embedded-agent-helpers/turns.ts +++ b/src/agents/embedded-agent-helpers/turns.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { AgentMessage } from "../runtime/index.js"; import { extractToolCallsFromAssistant, extractToolResultId } from "../tool-call-id.js"; diff --git a/src/agents/embedded-agent-messaging.ts b/src/agents/embedded-agent-messaging.ts index d511668f3eb..818678b89f6 100644 --- a/src/agents/embedded-agent-messaging.ts +++ b/src/agents/embedded-agent-messaging.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { getChannelPlugin, normalizeChannelId } from "../channels/plugins/index.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; const CORE_MESSAGING_TOOLS = new Set(["sessions_send", "message"]); const MESSAGE_TOOL_SEND_ACTIONS = new Set([ diff --git a/src/agents/embedded-agent-runner/abort.ts b/src/agents/embedded-agent-runner/abort.ts index c81f87bbc93..fe1aed3531a 100644 --- a/src/agents/embedded-agent-runner/abort.ts +++ b/src/agents/embedded-agent-runner/abort.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; /** * Runner abort check. Catches any abort-related message for embedded runners. diff --git a/src/agents/embedded-agent-runner/cache-ttl.ts b/src/agents/embedded-agent-runner/cache-ttl.ts index 4885bb2fb8c..04a94758fc7 100644 --- a/src/agents/embedded-agent-runner/cache-ttl.ts +++ b/src/agents/embedded-agent-runner/cache-ttl.ts @@ -1,12 +1,12 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, +} from "@openclaw/normalization-core/string-coerce"; import { isAnthropicFamilyCacheTtlEligible, isAnthropicModelRef, } from "../../llm/providers/stream-wrappers/anthropic-family-cache-semantics.js"; import { resolveProviderCacheTtlEligibility } from "../../plugins/provider-runtime.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, -} from "../../shared/string-coerce.js"; import { isGooglePromptCacheEligible } from "./prompt-cache-retention.js"; type CustomEntryLike = { type?: unknown; customType?: unknown; data?: unknown }; diff --git a/src/agents/embedded-agent-runner/compact-reasons.ts b/src/agents/embedded-agent-runner/compact-reasons.ts index 201ec361bdc..2ed42218aa8 100644 --- a/src/agents/embedded-agent-runner/compact-reasons.ts +++ b/src/agents/embedded-agent-runner/compact-reasons.ts @@ -1,5 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { sanitizeForLog } from "../../../packages/terminal-core/src/ansi.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; const MAX_COMPACTION_REASON_DETAIL_CHARS = 100; diff --git a/src/agents/embedded-agent-runner/compaction-duplicate-user-messages.ts b/src/agents/embedded-agent-runner/compaction-duplicate-user-messages.ts index da5fdf9a42e..5c39ba7bded 100644 --- a/src/agents/embedded-agent-runner/compaction-duplicate-user-messages.ts +++ b/src/agents/embedded-agent-runner/compaction-duplicate-user-messages.ts @@ -1,4 +1,4 @@ -import { isRecord } from "../../shared/record-coerce.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; const DEFAULT_DUPLICATE_USER_MESSAGE_WINDOW_MS = 60_000; const MIN_DUPLICATE_USER_MESSAGE_CHARS = 24; diff --git a/src/agents/embedded-agent-runner/compaction-safety-timeout.ts b/src/agents/embedded-agent-runner/compaction-safety-timeout.ts index 775df87416d..24060db03b7 100644 --- a/src/agents/embedded-agent-runner/compaction-safety-timeout.ts +++ b/src/agents/embedded-agent-runner/compaction-safety-timeout.ts @@ -1,7 +1,7 @@ +import { finiteSecondsToTimerSafeMilliseconds } from "@openclaw/normalization-core/number-coercion"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { CompactResult, ContextEngine } from "../../context-engine/types.js"; import { withTimeout } from "../../node-host/with-timeout.js"; -import { finiteSecondsToTimerSafeMilliseconds } from "../../shared/number-coercion.js"; export const EMBEDDED_COMPACTION_TIMEOUT_MS = 900_000; diff --git a/src/agents/embedded-agent-runner/compaction-successor-transcript.ts b/src/agents/embedded-agent-runner/compaction-successor-transcript.ts index 7efb2d8bdeb..4260db4e567 100644 --- a/src/agents/embedded-agent-runner/compaction-successor-transcript.ts +++ b/src/agents/embedded-agent-runner/compaction-successor-transcript.ts @@ -1,8 +1,8 @@ import { randomUUID } from "node:crypto"; import path from "node:path"; +import { resolveTimestampMsToIsoString } from "@openclaw/normalization-core/number-coercion"; import { CURRENT_SESSION_VERSION } from "../../config/sessions/version.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { resolveTimestampMsToIsoString } from "../../shared/number-coercion.js"; import { type CompactionEntry, type SessionEntry, type SessionHeader } from "../sessions/index.js"; import { collectDuplicateUserMessageEntryIdsForCompaction } from "./compaction-duplicate-user-messages.js"; import { diff --git a/src/agents/embedded-agent-runner/context-engine-capabilities.ts b/src/agents/embedded-agent-runner/context-engine-capabilities.ts index 2b55e1ced8e..c041806cc21 100644 --- a/src/agents/embedded-agent-runner/context-engine-capabilities.ts +++ b/src/agents/embedded-agent-runner/context-engine-capabilities.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { ContextEngineRuntimeContext } from "../../context-engine/types.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { resolveBoundAgentIdForSession } from "../session-agent-binding.js"; export type ResolveContextEngineCapabilitiesParams = { diff --git a/src/agents/embedded-agent-runner/context-engine-maintenance.ts b/src/agents/embedded-agent-runner/context-engine-maintenance.ts index e3d5b992ea9..d0f41b6fd77 100644 --- a/src/agents/embedded-agent-runner/context-engine-maintenance.ts +++ b/src/agents/embedded-agent-runner/context-engine-maintenance.ts @@ -1,4 +1,5 @@ import { randomUUID } from "node:crypto"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { resolveContextEngineOwnerPluginId } from "../../context-engine/registry.js"; import type { @@ -14,7 +15,6 @@ import { getQueueSize, isGatewayDraining, } from "../../process/command-queue.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { completeTaskRunByRunId, createQueuedTaskRun, diff --git a/src/agents/embedded-agent-runner/empty-assistant-turn.ts b/src/agents/embedded-agent-runner/empty-assistant-turn.ts index 5b1d7d65db5..8465dc12681 100644 --- a/src/agents/embedded-agent-runner/empty-assistant-turn.ts +++ b/src/agents/embedded-agent-runner/empty-assistant-turn.ts @@ -1,4 +1,4 @@ -import { asFiniteNumber } from "../../shared/number-coercion.js"; +import { asFiniteNumber } from "@openclaw/normalization-core/number-coercion"; type EmptyAssistantTurnLike = { content?: unknown; diff --git a/src/agents/embedded-agent-runner/extensions.ts b/src/agents/embedded-agent-runner/extensions.ts index 38743383888..02c45c0ba52 100644 --- a/src/agents/embedded-agent-runner/extensions.ts +++ b/src/agents/embedded-agent-runner/extensions.ts @@ -1,7 +1,7 @@ import { randomUUID } from "node:crypto"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { ProviderRuntimeModel } from "../../plugins/provider-runtime-model.types.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { setCompactionSafeguardRuntime } from "../agent-hooks/compaction-safeguard-runtime.js"; import compactionSafeguardExtension from "../agent-hooks/compaction-safeguard.js"; import contextPruningExtension from "../agent-hooks/context-pruning.js"; diff --git a/src/agents/embedded-agent-runner/failure-signal.ts b/src/agents/embedded-agent-runner/failure-signal.ts index 5422fac9847..417b03a3d30 100644 --- a/src/agents/embedded-agent-runner/failure-signal.ts +++ b/src/agents/embedded-agent-runner/failure-signal.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { isExecLikeToolName, type ToolErrorSummary } from "../tool-error-summary.js"; import type { EmbeddedRunFailureSignal } from "./types.js"; diff --git a/src/agents/embedded-agent-runner/google-prompt-cache.ts b/src/agents/embedded-agent-runner/google-prompt-cache.ts index 273f6ef67c4..03eaf72ae81 100644 --- a/src/agents/embedded-agent-runner/google-prompt-cache.ts +++ b/src/agents/embedded-agent-runner/google-prompt-cache.ts @@ -1,14 +1,14 @@ import crypto from "node:crypto"; -import { parseGeminiAuth } from "../../infra/gemini-auth.js"; -import { normalizeGoogleApiBaseUrl } from "../../infra/google-api-base-url.js"; -import { streamWithPayloadPatch } from "../../llm/providers/stream-wrappers/stream-payload-utils.js"; -import type { Model } from "../../llm/types.js"; import { asDateTimestampMs, isFutureDateTimestampMs, resolveExpiresAtMsFromDurationMs, -} from "../../shared/number-coercion.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { parseGeminiAuth } from "../../infra/gemini-auth.js"; +import { normalizeGoogleApiBaseUrl } from "../../infra/google-api-base-url.js"; +import { streamWithPayloadPatch } from "../../llm/providers/stream-wrappers/stream-payload-utils.js"; +import type { Model } from "../../llm/types.js"; import { buildGuardedModelFetch } from "../provider-transport-fetch.js"; import type { StreamFn } from "../runtime/index.js"; import { isSessionWriteLockTimeoutError } from "../session-write-lock-error.js"; diff --git a/src/agents/embedded-agent-runner/history.ts b/src/agents/embedded-agent-runner/history.ts index 88d161bc704..c6308daa5f9 100644 --- a/src/agents/embedded-agent-runner/history.ts +++ b/src/agents/embedded-agent-runner/history.ts @@ -1,6 +1,6 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import type { AgentMessage } from "../runtime/index.js"; const THREAD_SUFFIX_REGEX = /^(.*)(?::(?:thread|topic):\d+)$/i; diff --git a/src/agents/embedded-agent-runner/model.inline-provider.ts b/src/agents/embedded-agent-runner/model.inline-provider.ts index 2ad2e5e2c59..3c447314e55 100644 --- a/src/agents/embedded-agent-runner/model.inline-provider.ts +++ b/src/agents/embedded-agent-runner/model.inline-provider.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { ModelDefinitionConfig, ModelProviderConfig } from "../../config/types.js"; import { normalizeGoogleApiBaseUrl } from "../../infra/google-api-base-url.js"; import type { Api } from "../../llm/types.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { isSecretRefHeaderValueMarker } from "../model-auth-markers.js"; import { attachModelProviderLocalService } from "../provider-local-service.js"; import { diff --git a/src/agents/embedded-agent-runner/model.provider-runtime.test-support.ts b/src/agents/embedded-agent-runner/model.provider-runtime.test-support.ts index 58bfe25f54a..100cd81c147 100644 --- a/src/agents/embedded-agent-runner/model.provider-runtime.test-support.ts +++ b/src/agents/embedded-agent-runner/model.provider-runtime.test-support.ts @@ -1,4 +1,4 @@ -import { lowercasePreservingWhitespace } from "../../shared/string-coerce.js"; +import { lowercasePreservingWhitespace } from "@openclaw/normalization-core/string-coerce"; import type { OpenRouterModelCapabilities } from "./openrouter-model-capabilities.js"; const OPENAI_BASE_URL = "https://api.openai.com/v1"; diff --git a/src/agents/embedded-agent-runner/model.test.ts b/src/agents/embedded-agent-runner/model.test.ts index 16cc4443c07..4590ed20845 100644 --- a/src/agents/embedded-agent-runner/model.test.ts +++ b/src/agents/embedded-agent-runner/model.test.ts @@ -1,8 +1,8 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../../shared/number-coercion.js"; import { discoverAuthStorage, discoverModels } from "../agent-model-discovery.js"; import { clearRuntimeAuthProfileStoreSnapshots, diff --git a/src/agents/embedded-agent-runner/model.ts b/src/agents/embedded-agent-runner/model.ts index 570766aa87d..3ffb7c4d0f0 100644 --- a/src/agents/embedded-agent-runner/model.ts +++ b/src/agents/embedded-agent-runner/model.ts @@ -1,3 +1,4 @@ +import { finiteSecondsToTimerSafeMilliseconds } from "@openclaw/normalization-core/number-coercion"; import type { ModelCompatConfig, ModelMediaInputConfig } from "../../config/types.models.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { ModelRegistry as CoreModelRegistry } from "../../llm/model-registry.js"; @@ -12,7 +13,6 @@ import { normalizeProviderResolvedModelWithPlugin, shouldPreferProviderRuntimeResolvedModel, } from "../../plugins/provider-runtime.js"; -import { finiteSecondsToTimerSafeMilliseconds } from "../../shared/number-coercion.js"; import { discoverAuthStorage, discoverModels } from "../agent-model-discovery.js"; import { resolveDefaultAgentDir } from "../agent-scope.js"; import { ensureAuthProfileStore, resolveAuthProfileOrder } from "../auth-profiles.js"; diff --git a/src/agents/embedded-agent-runner/prompt-cache-retention.ts b/src/agents/embedded-agent-runner/prompt-cache-retention.ts index 0745ba698bb..91253263abe 100644 --- a/src/agents/embedded-agent-runner/prompt-cache-retention.ts +++ b/src/agents/embedded-agent-runner/prompt-cache-retention.ts @@ -1,5 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { resolveAnthropicCacheRetentionFamily } from "../../llm/providers/stream-wrappers/anthropic-family-cache-semantics.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; type CacheRetention = "none" | "short" | "long"; diff --git a/src/agents/embedded-agent-runner/run.overflow-compaction.harness.ts b/src/agents/embedded-agent-runner/run.overflow-compaction.harness.ts index 017bee9a0e5..d8c7017f1e3 100644 --- a/src/agents/embedded-agent-runner/run.overflow-compaction.harness.ts +++ b/src/agents/embedded-agent-runner/run.overflow-compaction.harness.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { type Mock, vi } from "vitest"; import type { ThinkLevel } from "../../auto-reply/thinking.js"; import { formatErrorMessage } from "../../infra/errors.js"; @@ -8,7 +9,6 @@ import type { PluginHookBeforeModelResolveResult, PluginHookBeforePromptBuildResult, } from "../../plugins/types.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import type { FailoverReason } from "../embedded-agent-helpers/types.js"; import { clearAgentHarnesses, registerAgentHarness } from "../harness/registry.js"; import type { buildEmbeddedRunPayloads } from "./run/payloads.js"; diff --git a/src/agents/embedded-agent-runner/run.ts b/src/agents/embedded-agent-runner/run.ts index 09e2685be9a..b62e757f1b2 100644 --- a/src/agents/embedded-agent-runner/run.ts +++ b/src/agents/embedded-agent-runner/run.ts @@ -1,5 +1,6 @@ import { randomBytes } from "node:crypto"; import fs from "node:fs/promises"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { sanitizeForLog } from "../../../packages/terminal-core/src/ansi.js"; import type { ReplyPayload } from "../../auto-reply/reply-payload.js"; import type { ThinkLevel } from "../../auto-reply/thinking.js"; @@ -19,7 +20,6 @@ import { getGlobalHookRunner } from "../../plugins/hook-runner-global.js"; import { resolveProviderAuthProfileId } from "../../plugins/provider-runtime.js"; import { enqueueCommandInLane } from "../../process/command-queue.js"; import type { CommandQueueEnqueueOptions } from "../../process/command-queue.types.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { createAgentHarnessTaskRuntimeScope } from "../../tasks/agent-harness-task-runtime-scope.js"; import { resolveUserPath } from "../../utils.js"; import { isMarkdownCapableMessageChannel } from "../../utils/message-channel.js"; diff --git a/src/agents/embedded-agent-runner/run/attempt.session-lock.ts b/src/agents/embedded-agent-runner/run/attempt.session-lock.ts index 7889800728c..90bcdc1fd81 100644 --- a/src/agents/embedded-agent-runner/run/attempt.session-lock.ts +++ b/src/agents/embedded-agent-runner/run/attempt.session-lock.ts @@ -2,9 +2,9 @@ import { AsyncLocalStorage } from "node:async_hooks"; import { statSync } from "node:fs"; import fs from "node:fs/promises"; import { isDeepStrictEqual } from "node:util"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { withOwnedSessionTranscriptWrites } from "../../../config/sessions/transcript-write-context.js"; import { resolveGlobalSingleton } from "../../../shared/global-singleton.js"; -import { normalizeStringEntries } from "../../../shared/string-normalization.js"; import { isSessionWriteLockTimeoutError } from "../../session-write-lock-error.js"; import type { acquireSessionWriteLock } from "../../session-write-lock.js"; import { resolveEmbeddedSessionFileKey } from "../session-file-key.js"; diff --git a/src/agents/embedded-agent-runner/run/attempt.spawn-workspace.test-support.ts b/src/agents/embedded-agent-runner/run/attempt.spawn-workspace.test-support.ts index 21c3e537284..aa9e2db5882 100644 --- a/src/agents/embedded-agent-runner/run/attempt.spawn-workspace.test-support.ts +++ b/src/agents/embedded-agent-runner/run/attempt.spawn-workspace.test-support.ts @@ -1,6 +1,10 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, +} from "@openclaw/normalization-core/string-coerce"; import { expect, vi, type Mock } from "vitest"; import type { AssembleResult, @@ -14,10 +18,6 @@ import type { import { formatErrorMessage } from "../../../infra/errors.js"; import type { Model } from "../../../llm/types.js"; import type { PluginMetadataSnapshot } from "../../../plugins/plugin-metadata-snapshot.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, -} from "../../../shared/string-coerce.js"; import type { EmbeddedContextFile } from "../../embedded-agent-helpers.js"; import type { MessagingToolSend, diff --git a/src/agents/embedded-agent-runner/run/attempt.tool-call-normalization.ts b/src/agents/embedded-agent-runner/run/attempt.tool-call-normalization.ts index f69421afa3a..9012eecff5c 100644 --- a/src/agents/embedded-agent-runner/run/attempt.tool-call-normalization.ts +++ b/src/agents/embedded-agent-runner/run/attempt.tool-call-normalization.ts @@ -8,8 +8,8 @@ import { type PlainTextToolCallNameMatcher, } from "../../../../packages/tool-call-repair/src/index.js"; import { visitObjectContentBlocks } from "../../../shared/message-content-blocks.js"; -import { normalizeLowercaseStringOrEmpty } from "../../../shared/string-coerce.js"; -import { normalizeStringEntries } from "../../../shared/string-normalization.js"; +import { normalizeLowercaseStringOrEmpty } from "../../../../packages/normalization-core/src/string-coerce.js"; +import { normalizeStringEntries } from "../../../../packages/normalization-core/src/string-normalization.js"; import { downgradeOpenAIFunctionCallReasoningPairs, downgradeOpenAIReasoningBlocks, diff --git a/src/agents/embedded-agent-runner/run/attempt.ts b/src/agents/embedded-agent-runner/run/attempt.ts index bda9c30cf5d..701585b24f2 100644 --- a/src/agents/embedded-agent-runner/run/attempt.ts +++ b/src/agents/embedded-agent-runner/run/attempt.ts @@ -1,5 +1,6 @@ import fs from "node:fs/promises"; import os from "node:os"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { isAcpRuntimeSpawnAvailable } from "../../../acp/runtime/availability.js"; import { buildHierarchyReinforcementMessage } from "../../../auto-reply/handoff-summarizer.js"; import { filterHeartbeatTranscriptArtifacts } from "../../../auto-reply/heartbeat-filter.js"; @@ -56,7 +57,6 @@ import { import { getPluginToolMeta } from "../../../plugins/tools.js"; import { isSubagentSessionKey } from "../../../routing/session-key.js"; import { annotateInterSessionPromptText } from "../../../sessions/input-provenance.js"; -import { normalizeOptionalString } from "../../../shared/string-coerce.js"; import { resolveSkillsPromptForRun } from "../../../skills/loading/workspace.js"; import { resolveEmbeddedRunSkillEntries } from "../../../skills/runtime/embedded-run-entries.js"; import { diff --git a/src/agents/embedded-agent-runner/run/compaction-retry-aggregate-timeout.test.ts b/src/agents/embedded-agent-runner/run/compaction-retry-aggregate-timeout.test.ts index e1f3254b9fe..08c6d855f33 100644 --- a/src/agents/embedded-agent-runner/run/compaction-retry-aggregate-timeout.test.ts +++ b/src/agents/embedded-agent-runner/run/compaction-retry-aggregate-timeout.test.ts @@ -1,5 +1,5 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../../../shared/number-coercion.js"; import { waitForCompactionRetryWithAggregateTimeout } from "./compaction-retry-aggregate-timeout.js"; type AggregateTimeoutParams = Parameters[0]; diff --git a/src/agents/embedded-agent-runner/run/compaction-retry-aggregate-timeout.ts b/src/agents/embedded-agent-runner/run/compaction-retry-aggregate-timeout.ts index d912ff88a75..ed6b5d054c3 100644 --- a/src/agents/embedded-agent-runner/run/compaction-retry-aggregate-timeout.ts +++ b/src/agents/embedded-agent-runner/run/compaction-retry-aggregate-timeout.ts @@ -2,7 +2,7 @@ * Wait for compaction retry completion with an aggregate timeout to avoid * holding a session lane indefinitely when retry resolution is lost. */ -import { resolveTimerTimeoutMs } from "../../../shared/number-coercion.js"; +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; export async function waitForCompactionRetryWithAggregateTimeout(params: { waitForCompactionRetry: () => Promise; diff --git a/src/agents/embedded-agent-runner/run/images.ts b/src/agents/embedded-agent-runner/run/images.ts index 4975fd50e63..a8d6a1d867c 100644 --- a/src/agents/embedded-agent-runner/run/images.ts +++ b/src/agents/embedded-agent-runner/run/images.ts @@ -1,11 +1,11 @@ import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { formatErrorMessage } from "../../../infra/errors.js"; import { assertNoWindowsNetworkPath, safeFileURLToPath } from "../../../infra/local-file-access.js"; import type { ImageContent } from "../../../llm/types.js"; import { resolveMediaReferenceLocalPath } from "../../../media/media-reference.js"; import type { PromptImageOrderEntry } from "../../../media/prompt-image-order.js"; import { loadWebMedia } from "../../../media/web-media.js"; -import { normalizeLowercaseStringOrEmpty } from "../../../shared/string-coerce.js"; import { resolveUserPath } from "../../../utils.js"; import type { ImageSanitizationLimits } from "../../image-sanitization.js"; import { diff --git a/src/agents/embedded-agent-runner/run/incomplete-turn.ts b/src/agents/embedded-agent-runner/run/incomplete-turn.ts index b1b5109a051..9d296b8c7c2 100644 --- a/src/agents/embedded-agent-runner/run/incomplete-turn.ts +++ b/src/agents/embedded-agent-runner/run/incomplete-turn.ts @@ -1,11 +1,11 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { isSilentReplyPayloadText, isSilentReplyText, SILENT_REPLY_TOKEN, } from "../../../auto-reply/tokens.js"; import type { EmbeddedAgentExecutionContract } from "../../../config/types.agent-defaults.js"; -import { normalizeLowercaseStringOrEmpty } from "../../../shared/string-coerce.js"; -import { normalizeStringEntries } from "../../../shared/string-normalization.js"; import { hasAcceptedSessionSpawn } from "../../accepted-session-spawn.js"; import { collectTextContentBlocks } from "../../content-blocks.js"; import { diff --git a/src/agents/embedded-agent-runner/run/llm-idle-timeout.test.ts b/src/agents/embedded-agent-runner/run/llm-idle-timeout.test.ts index 615256800b9..93e0393f0ef 100644 --- a/src/agents/embedded-agent-runner/run/llm-idle-timeout.test.ts +++ b/src/agents/embedded-agent-runner/run/llm-idle-timeout.test.ts @@ -1,7 +1,7 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import type { AssistantMessageEventStream } from "openclaw/plugin-sdk/llm"; import { afterEach, describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../../../config/config.js"; -import { MAX_TIMER_TIMEOUT_MS } from "../../../shared/number-coercion.js"; import { DEFAULT_LLM_IDLE_TIMEOUT_MS, resolveLlmIdleTimeoutMs, diff --git a/src/agents/embedded-agent-runner/run/llm-idle-timeout.ts b/src/agents/embedded-agent-runner/run/llm-idle-timeout.ts index 65f59abedab..74f2ecd5f0c 100644 --- a/src/agents/embedded-agent-runner/run/llm-idle-timeout.ts +++ b/src/agents/embedded-agent-runner/run/llm-idle-timeout.ts @@ -1,10 +1,10 @@ -import { DEFAULT_LLM_IDLE_TIMEOUT_SECONDS } from "../../../config/agent-timeout-defaults.js"; -import type { OpenClawConfig } from "../../../config/types.openclaw.js"; import { finiteSecondsToTimerSafeMilliseconds, clampTimerTimeoutMs, MAX_TIMER_TIMEOUT_MS, -} from "../../../shared/number-coercion.js"; +} from "@openclaw/normalization-core/number-coercion"; +import { DEFAULT_LLM_IDLE_TIMEOUT_SECONDS } from "../../../config/agent-timeout-defaults.js"; +import type { OpenClawConfig } from "../../../config/types.openclaw.js"; import type { StreamFn } from "../../runtime/index.js"; import type { MutableAssistantMessageEventStream } from "../../stream-compat.js"; import { createStreamIteratorWrapper } from "../../stream-iterator-wrapper.js"; diff --git a/src/agents/embedded-agent-runner/run/payloads.ts b/src/agents/embedded-agent-runner/run/payloads.ts index 0afc29a7f46..e57b5260a80 100644 --- a/src/agents/embedded-agent-runner/run/payloads.ts +++ b/src/agents/embedded-agent-runner/run/payloads.ts @@ -1,3 +1,7 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { SourceReplyDeliveryMode } from "../../../auto-reply/get-reply-options.types.js"; import { createHeartbeatToolResponsePayload, @@ -18,10 +22,6 @@ import { hasReplyPayloadContent } from "../../../interactive/payload.js"; import type { AssistantMessage } from "../../../llm/types.js"; import { isCronSessionKey } from "../../../routing/session-key.js"; import { extractAssistantTextForPhase } from "../../../shared/chat-message-content.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../../shared/string-coerce.js"; import { parseInlineDirectives } from "../../../utils/directive-tags.js"; import { BILLING_ERROR_USER_MESSAGE, diff --git a/src/agents/embedded-agent-runner/run/preemptive-compaction.ts b/src/agents/embedded-agent-runner/run/preemptive-compaction.ts index 7029818e982..3d9fff5cba9 100644 --- a/src/agents/embedded-agent-runner/run/preemptive-compaction.ts +++ b/src/agents/embedded-agent-runner/run/preemptive-compaction.ts @@ -1,5 +1,5 @@ +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import type { SessionContextBudgetStatus } from "../../../config/sessions.js"; -import { isRecord } from "../../../shared/record-coerce.js"; import { estimateStringChars } from "../../../utils/cjk-chars.js"; import { MIN_PROMPT_BUDGET_RATIO, diff --git a/src/agents/embedded-agent-runner/runs.ts b/src/agents/embedded-agent-runner/runs.ts index 90ed2aa349d..6276b44a419 100644 --- a/src/agents/embedded-agent-runner/runs.ts +++ b/src/agents/embedded-agent-runner/runs.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { abortActiveReplyRuns, abortReplyRunBySessionId, @@ -18,7 +19,6 @@ import { logSessionStateChange, updateDiagnosticSessionFile, } from "../../logging/diagnostic.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { ACTIVE_EMBEDDED_RUNS, ACTIVE_EMBEDDED_RUN_SESSION_IDS_BY_FILE, diff --git a/src/agents/embedded-agent-runner/tool-result-truncation.ts b/src/agents/embedded-agent-runner/tool-result-truncation.ts index 742c842dbbe..320e392fd58 100644 --- a/src/agents/embedded-agent-runner/tool-result-truncation.ts +++ b/src/agents/embedded-agent-runner/tool-result-truncation.ts @@ -1,8 +1,8 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { formatErrorMessage } from "../../infra/errors.js"; import type { TextContent } from "../../llm/types.js"; import { emitSessionTranscriptUpdate } from "../../sessions/transcript-events.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { resolveAgentContextLimits } from "../agent-scope.js"; import type { AgentMessage } from "../runtime/index.js"; import { diff --git a/src/agents/embedded-agent-subscribe.handlers.messages.ts b/src/agents/embedded-agent-subscribe.handlers.messages.ts index 91c963172da..94597bc3623 100644 --- a/src/agents/embedded-agent-subscribe.handlers.messages.ts +++ b/src/agents/embedded-agent-subscribe.handlers.messages.ts @@ -1,3 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload"; import { createInlineCodeState } from "../../packages/markdown-core/src/code-spans.js"; import { @@ -14,8 +16,6 @@ import { resolveAssistantMessagePhase, type AssistantPhase, } from "../shared/chat-message-content.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { isMessagingToolDuplicateNormalized, normalizeTextForComparison, diff --git a/src/agents/embedded-agent-subscribe.handlers.tools.ts b/src/agents/embedded-agent-subscribe.handlers.tools.ts index 896398ea5bc..e90bf354f0b 100644 --- a/src/agents/embedded-agent-subscribe.handlers.tools.ts +++ b/src/agents/embedded-agent-subscribe.handlers.tools.ts @@ -1,3 +1,11 @@ +import { + asOptionalObjectRecord, + asOptionalRecord as readRecordField, +} from "@openclaw/normalization-core/record-coerce"; +import { + normalizeOptionalLowercaseString, + readStringValue, +} from "@openclaw/normalization-core/string-coerce"; import { HEARTBEAT_RESPONSE_TOOL_NAME, normalizeHeartbeatToolResponse, @@ -19,11 +27,6 @@ import type { ExecApprovalDecision } from "../infra/exec-approvals.js"; import { normalizeInteractiveReply, normalizeMessagePresentation } from "../interactive/payload.js"; import type { PluginHookAfterToolCallEvent } from "../plugins/types.js"; import { createLazyImportLoader } from "../shared/lazy-promise.js"; -import { - asOptionalObjectRecord, - asOptionalRecord as readRecordField, -} from "../shared/record-coerce.js"; -import { normalizeOptionalLowercaseString, readStringValue } from "../shared/string-coerce.js"; import { truncateUtf16Safe } from "../utils.js"; import { normalizeAcceptedSessionSpawnResult } from "./accepted-session-spawn.js"; import { REQUIRED_PARAM_GROUPS, type RequiredParamGroup } from "./agent-tools.params.js"; diff --git a/src/agents/embedded-agent-subscribe.tool-text-diagnostics.ts b/src/agents/embedded-agent-subscribe.tool-text-diagnostics.ts index 1086a1f7e24..a2024299108 100644 --- a/src/agents/embedded-agent-subscribe.tool-text-diagnostics.ts +++ b/src/agents/embedded-agent-subscribe.tool-text-diagnostics.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { AssistantMessage } from "../llm/types.js"; import { extractTextFromChatContent } from "../shared/chat-content.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { detectToolCallShapedText } from "../shared/text/tool-call-shaped-text.js"; import type { EmbeddedAgentSubscribeContext } from "./embedded-agent-subscribe.handlers.types.js"; import { normalizeToolName } from "./tool-policy.js"; diff --git a/src/agents/embedded-agent-subscribe.tools.ts b/src/agents/embedded-agent-subscribe.tools.ts index 76cdbe15761..94df3e46ddf 100644 --- a/src/agents/embedded-agent-subscribe.tools.ts +++ b/src/agents/embedded-agent-subscribe.tools.ts @@ -1,13 +1,13 @@ -import { getChannelPlugin, normalizeChannelId } from "../channels/plugins/index.js"; -import { normalizeTargetForProvider } from "../infra/outbound/target-normalization.js"; -import { redactSensitiveFieldValue, redactToolPayloadText } from "../logging/redact.js"; -import { asOptionalRecord as readRecord } from "../shared/record-coerce.js"; +import { asOptionalRecord as readRecord } from "@openclaw/normalization-core/record-coerce"; import { normalizeOptionalLowercaseString, normalizeOptionalString, readStringValue, -} from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; +import { getChannelPlugin, normalizeChannelId } from "../channels/plugins/index.js"; +import { normalizeTargetForProvider } from "../infra/outbound/target-normalization.js"; +import { redactSensitiveFieldValue, redactToolPayloadText } from "../logging/redact.js"; import { truncateUtf16Safe } from "../utils.js"; import { collectTextContentBlocks } from "./content-blocks.js"; import { isMessageToolSendActionName } from "./embedded-agent-messaging.js"; diff --git a/src/agents/embedded-agent-subscribe.ts b/src/agents/embedded-agent-subscribe.ts index 5a05d26dd6b..62039769e4a 100644 --- a/src/agents/embedded-agent-subscribe.ts +++ b/src/agents/embedded-agent-subscribe.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { InlineCodeState } from "../../packages/markdown-core/src/code-spans.js"; import { buildCodeSpanIndex, @@ -10,7 +11,6 @@ import { isSilentReplyText, SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js"; import { formatToolAggregate } from "../auto-reply/tool-meta.js"; import { emitAgentEvent } from "../infra/agent-events.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { findFinalTagMatches } from "../shared/text/final-tags.js"; import { hasOrphanReasoningCloseBoundary } from "../shared/text/reasoning-tags.js"; import { parseInlineDirectives } from "../utils/directive-tags.js"; diff --git a/src/agents/exec-approval-result.ts b/src/agents/exec-approval-result.ts index 9522e0c611c..0efcecb3298 100644 --- a/src/agents/exec-approval-result.ts +++ b/src/agents/exec-approval-result.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; type ExecApprovalResult = | { diff --git a/src/agents/exec-auto-reviewer.test.ts b/src/agents/exec-auto-reviewer.test.ts index b3a99d24ad8..38b7ae33e2d 100644 --- a/src/agents/exec-auto-reviewer.test.ts +++ b/src/agents/exec-auto-reviewer.test.ts @@ -1,5 +1,5 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { createModelExecAutoReviewer, parseExecAutoReviewResponse, diff --git a/src/agents/exec-auto-reviewer.ts b/src/agents/exec-auto-reviewer.ts index 9980e124a66..3d1e8947796 100644 --- a/src/agents/exec-auto-reviewer.ts +++ b/src/agents/exec-auto-reviewer.ts @@ -1,3 +1,5 @@ +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { z } from "zod"; import type { AgentModelConfig } from "../config/types.agents-shared.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; @@ -8,8 +10,6 @@ import { type ExecAutoReviewInput, type ExecAutoReviewer, } from "../infra/exec-auto-review.js"; -import { resolveTimerTimeoutMs } from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { DEFAULT_EXEC_REVIEWER_SYSTEM_PROMPT } from "./exec-auto-reviewer.prompt.js"; import { completeWithPreparedSimpleCompletionModel, diff --git a/src/agents/execution-contract.ts b/src/agents/execution-contract.ts index 722ece6a830..b6a27c5bd8a 100644 --- a/src/agents/execution-contract.ts +++ b/src/agents/execution-contract.ts @@ -1,5 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { resolveAgentExecutionContract, resolveSessionAgentIds } from "./agent-scope.js"; /** diff --git a/src/agents/failover-error.ts b/src/agents/failover-error.ts index 2a99def6682..8b80330b754 100644 --- a/src/agents/failover-error.ts +++ b/src/agents/failover-error.ts @@ -1,5 +1,5 @@ +import { parseStrictNonNegativeInteger } from "@openclaw/normalization-core/number-coercion"; import { readErrorName } from "../infra/errors.js"; -import { parseStrictNonNegativeInteger } from "../shared/number-coercion.js"; import { classifyFailoverSignal, inferSignalStatus, diff --git a/src/agents/generated-attachments.ts b/src/agents/generated-attachments.ts index 467af70d3f6..fb8b7128414 100644 --- a/src/agents/generated-attachments.ts +++ b/src/agents/generated-attachments.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { basenameFromAnyPath } from "../media/file-name.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; export type AgentGeneratedAttachment = { type?: "image" | "audio" | "video" | "file"; diff --git a/src/agents/gpt5-prompt-overlay.ts b/src/agents/gpt5-prompt-overlay.ts index 63678dbbef6..a58495ee6b5 100644 --- a/src/agents/gpt5-prompt-overlay.ts +++ b/src/agents/gpt5-prompt-overlay.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import type { ProviderSystemPromptContribution } from "./system-prompt-contribution.js"; const GPT5_MODEL_ID_PATTERN = /(?:^|[/:])gpt-5(?:[.-]|$)/i; diff --git a/src/agents/harness/lifecycle-hook-helpers.ts b/src/agents/harness/lifecycle-hook-helpers.ts index b3c4da61938..1ac092b74e2 100644 --- a/src/agents/harness/lifecycle-hook-helpers.ts +++ b/src/agents/harness/lifecycle-hook-helpers.ts @@ -1,4 +1,5 @@ import { createHash } from "node:crypto"; +import { normalizeOptionalString as normalizeTrimmedString } from "@openclaw/normalization-core/string-coerce"; import { createSubsystemLogger } from "../../logging/subsystem.js"; import { getGlobalHookRunner } from "../../plugins/hook-runner-global.js"; import type { @@ -10,7 +11,6 @@ import type { } from "../../plugins/hook-types.js"; import type { VoidHookRunOptions } from "../../plugins/hooks.js"; import { resolveGlobalSingleton } from "../../shared/global-singleton.js"; -import { normalizeOptionalString as normalizeTrimmedString } from "../../shared/string-coerce.js"; import { buildAgentHookContext, type AgentHarnessHookContext } from "./hook-context.js"; const log = createSubsystemLogger("agents/harness"); diff --git a/src/agents/harness/native-hook-relay.ts b/src/agents/harness/native-hook-relay.ts index 5c88cc26e5e..a6c4f8454ed 100644 --- a/src/agents/harness/native-hook-relay.ts +++ b/src/agents/harness/native-hook-relay.ts @@ -17,16 +17,16 @@ import { } from "node:http"; import { tmpdir } from "node:os"; import path from "node:path"; +import { + asDateTimestampMs, + resolveExpiresAtMsFromDurationMs, +} from "@openclaw/normalization-core/number-coercion"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { resolveOpenClawPackageRootSync } from "../../infra/openclaw-root.js"; import { privateFileStoreSync } from "../../infra/private-file-store.js"; import { createSubsystemLogger } from "../../logging/subsystem.js"; import { hasGlobalHooks } from "../../plugins/hook-runner-global.js"; import { PluginApprovalResolutions } from "../../plugins/types.js"; -import { - asDateTimestampMs, - resolveExpiresAtMsFromDurationMs, -} from "../../shared/number-coercion.js"; import { cancelDeferredPluginToolApproval, hasBeforeToolCallPolicy, diff --git a/src/agents/harness/tool-result-middleware.ts b/src/agents/harness/tool-result-middleware.ts index e181a5e9563..f5c2b4ea9cc 100644 --- a/src/agents/harness/tool-result-middleware.ts +++ b/src/agents/harness/tool-result-middleware.ts @@ -1,3 +1,4 @@ +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { createSubsystemLogger } from "../../logging/subsystem.js"; import type { AgentToolResultMiddleware, @@ -6,7 +7,6 @@ import type { OpenClawAgentToolResult, } from "../../plugins/agent-tool-result-middleware-types.js"; import { createLazyPromiseLoader } from "../../shared/lazy-promise.js"; -import { isRecord } from "../../shared/record-coerce.js"; import { truncateUtf16Safe } from "../../utils.js"; const log = createSubsystemLogger("agents/harness"); diff --git a/src/agents/heartbeat-system-prompt.ts b/src/agents/heartbeat-system-prompt.ts index b65c721eeec..3423aaa78f0 100644 --- a/src/agents/heartbeat-system-prompt.ts +++ b/src/agents/heartbeat-system-prompt.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { DEFAULT_HEARTBEAT_EVERY, resolveHeartbeatPrompt as resolveHeartbeatPromptText, @@ -6,7 +7,6 @@ import { parseDurationMs } from "../cli/parse-duration.js"; import type { AgentDefaultsConfig } from "../config/types.agent-defaults.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeAgentId } from "../routing/session-key.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { listAgentEntries, resolveAgentConfig, resolveDefaultAgentId } from "./agent-scope.js"; type HeartbeatConfig = AgentDefaultsConfig["heartbeat"]; diff --git a/src/agents/identity-avatar.ts b/src/agents/identity-avatar.ts index 2eb3df6d066..4179e160ab3 100644 --- a/src/agents/identity-avatar.ts +++ b/src/agents/identity-avatar.ts @@ -1,5 +1,6 @@ import fs from "node:fs"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeAgentId } from "../routing/session-key.js"; import { @@ -11,7 +12,6 @@ import { isPathWithinRoot, isSupportedLocalAvatarExtension, } from "../shared/avatar-policy.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resolveUserPath } from "../utils.js"; import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "./agent-scope.js"; import { loadAgentIdentityFromWorkspace } from "./identity-file.js"; diff --git a/src/agents/identity-file.ts b/src/agents/identity-file.ts index bafd2022411..b23e48836ed 100644 --- a/src/agents/identity-file.ts +++ b/src/agents/identity-file.ts @@ -1,6 +1,6 @@ import fs from "node:fs"; import path from "node:path"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { DEFAULT_IDENTITY_FILENAME } from "./workspace.js"; export type AgentIdentityFile = { diff --git a/src/agents/inherited-tool-deny.ts b/src/agents/inherited-tool-deny.ts index 8ecffe23328..afd3f2f1dfe 100644 --- a/src/agents/inherited-tool-deny.ts +++ b/src/agents/inherited-tool-deny.ts @@ -1,4 +1,4 @@ -import { uniqueStrings } from "../shared/string-normalization.js"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { isToolAllowedByPolicyName } from "./tool-policy-match.js"; import { normalizeToolName } from "./tool-policy-shared.js"; diff --git a/src/agents/live-auth-keys.ts b/src/agents/live-auth-keys.ts index a1f0dea35f9..cc6b7e93ceb 100644 --- a/src/agents/live-auth-keys.ts +++ b/src/agents/live-auth-keys.ts @@ -1,9 +1,9 @@ -import { getProviderEnvVars } from "../secrets/provider-env-vars.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; +import { getProviderEnvVars } from "../secrets/provider-env-vars.js"; import { normalizeProviderId } from "./model-selection.js"; const KEY_SPLIT_RE = /[\s,;]+/g; diff --git a/src/agents/live-cache-regression-runner.ts b/src/agents/live-cache-regression-runner.ts index 7cdedadaf36..de3a83565a5 100644 --- a/src/agents/live-cache-regression-runner.ts +++ b/src/agents/live-cache-regression-runner.ts @@ -1,8 +1,8 @@ import { randomUUID } from "node:crypto"; import fs from "node:fs/promises"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { Type } from "typebox"; import type { AssistantMessage, Message, Tool } from "../llm/types.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { LIVE_CACHE_REGRESSION_BASELINE, type LiveCacheFloor, diff --git a/src/agents/live-model-dynamic-candidates.ts b/src/agents/live-model-dynamic-candidates.ts index 25b2bff103b..5407b965788 100644 --- a/src/agents/live-model-dynamic-candidates.ts +++ b/src/agents/live-model-dynamic-candidates.ts @@ -2,6 +2,7 @@ import { findNormalizedProviderValue, normalizeProviderId, } from "@openclaw/model-catalog-core/provider-id"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { Model } from "../llm/types.js"; import type { @@ -10,7 +11,6 @@ import type { } from "../plugins/provider-runtime.js"; import type { ProviderResolveDynamicModelContext } from "../plugins/types.js"; import { createLazyImportLoader } from "../shared/lazy-promise.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { listPrioritizedHighSignalLiveModelRefs } from "./live-model-filter.js"; type ProviderRuntimeModule = typeof import("../plugins/provider-runtime.js"); diff --git a/src/agents/live-model-filter.ts b/src/agents/live-model-filter.ts index 6b31c01a44a..4542d1614df 100644 --- a/src/agents/live-model-filter.ts +++ b/src/agents/live-model-filter.ts @@ -1,8 +1,8 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { parseStrictNonNegativeInteger } from "@openclaw/normalization-core/number-coercion"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { resolveProviderModernModelRef } from "../plugins/provider-runtime.js"; -import { parseStrictNonNegativeInteger } from "../shared/number-coercion.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { liveProvidersShareOwningPlugin } from "./live-provider-owner.js"; type ModelRef = { diff --git a/src/agents/live-model-switch.ts b/src/agents/live-model-switch.ts index 6e6d88ca6bd..18ae0795cc6 100644 --- a/src/agents/live-model-switch.ts +++ b/src/agents/live-model-switch.ts @@ -15,7 +15,7 @@ import { export { LiveSessionModelSwitchError } from "./live-model-switch-error.js"; export type LiveSessionModelSelection = EmbeddedRunModelSwitchRequest; import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; const OPENAI_PROVIDER_ID = "openai"; const OPENAI_CODEX_PROVIDER_ID = "openai"; diff --git a/src/agents/live-target-matcher.ts b/src/agents/live-target-matcher.ts index 13d07325c5a..7c7d468306a 100644 --- a/src/agents/live-target-matcher.ts +++ b/src/agents/live-target-matcher.ts @@ -1,10 +1,10 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; import { normalizeGooglePreviewModelId } from "@openclaw/model-catalog-core/provider-model-id-normalize"; -import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { OpenClawConfig } from "../config/types.openclaw.js"; import { liveProvidersShareOwningPlugin } from "./live-provider-owner.js"; type ModelTarget = { diff --git a/src/agents/live-test-provider-drift.ts b/src/agents/live-test-provider-drift.ts index dd0553ed195..c3e7cbf28a9 100644 --- a/src/agents/live-test-provider-drift.ts +++ b/src/agents/live-test-provider-drift.ts @@ -1,5 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { isCloudflareOrHtmlErrorPage } from "../shared/assistant-error-format.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { isAuthErrorMessage, isBillingErrorMessage, diff --git a/src/agents/main-session-restart-recovery.ts b/src/agents/main-session-restart-recovery.ts index ae3f9aa1445..92479eb6568 100644 --- a/src/agents/main-session-restart-recovery.ts +++ b/src/agents/main-session-restart-recovery.ts @@ -5,6 +5,7 @@ import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { sanitizePendingFinalDeliveryText } from "../auto-reply/reply/pending-final-delivery.js"; import { resolveStateDir } from "../config/paths.js"; import { @@ -23,7 +24,6 @@ import { createSubsystemLogger } from "../logging/subsystem.js"; import { CommandLane } from "../process/lanes.js"; import { isAcpSessionKey, isCronSessionKey, isSubagentSessionKey } from "../routing/session-key.js"; import { resolveSendPolicy } from "../sessions/send-policy.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { deliveryContextFromSession, normalizeDeliveryContext, diff --git a/src/agents/mcp-oauth.ts b/src/agents/mcp-oauth.ts index 2e5ad3ba7ab..87f4c8dbdd4 100644 --- a/src/agents/mcp-oauth.ts +++ b/src/agents/mcp-oauth.ts @@ -12,8 +12,8 @@ import type { OAuthTokens, } from "@modelcontextprotocol/sdk/shared/auth.js"; import type { FetchLike } from "@modelcontextprotocol/sdk/shared/transport.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveStateDir } from "../config/paths.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { sanitizeServerName } from "./agent-bundle-mcp-names.js"; type McpOAuthStore = { diff --git a/src/agents/mcp-transport-config.ts b/src/agents/mcp-transport-config.ts index d759de16712..d658a819305 100644 --- a/src/agents/mcp-transport-config.ts +++ b/src/agents/mcp-transport-config.ts @@ -1,7 +1,7 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { sanitizeForLog } from "../../packages/terminal-core/src/ansi.js"; import { resolveOpenClawMcpTransportAlias } from "../config/mcp-config-normalize.js"; import { logWarn } from "../logger.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { describeHttpMcpServerLaunchConfig, resolveHttpMcpServerLaunchConfig, diff --git a/src/agents/mcp-transport.ts b/src/agents/mcp-transport.ts index 2e44f21733f..ce483a63fdd 100644 --- a/src/agents/mcp-transport.ts +++ b/src/agents/mcp-transport.ts @@ -4,10 +4,10 @@ import { } from "@modelcontextprotocol/sdk/client/sse.js"; import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; import type { FetchLike, Transport } from "@modelcontextprotocol/sdk/shared/transport.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { normalizeHeadersInitForFetch } from "../infra/fetch-headers.js"; import { retainSafeHeadersForCrossOriginRedirect } from "../infra/net/redirect-headers.js"; import { logDebug } from "../logger.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { buildMcpHttpFetch, withoutMcpAuthorizationHeader, diff --git a/src/agents/media-generation-task-status-shared.ts b/src/agents/media-generation-task-status-shared.ts index d8614f19aaf..86ca4ccbf0c 100644 --- a/src/agents/media-generation-task-status-shared.ts +++ b/src/agents/media-generation-task-status-shared.ts @@ -1,8 +1,8 @@ -import { resolveNonNegativeIntegerOption } from "../shared/number-coercion.js"; +import { resolveNonNegativeIntegerOption } from "@openclaw/normalization-core/number-coercion"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; import { listFreshTasksForOwnerKey } from "../tasks/runtime-internal.js"; import type { TaskRecord } from "../tasks/task-registry.types.js"; import { buildSessionAsyncTaskStatusDetails } from "./session-async-task-status.js"; diff --git a/src/agents/memory-search.ts b/src/agents/memory-search.ts index c9357be7e44..38ebbe2bdee 100644 --- a/src/agents/memory-search.ts +++ b/src/agents/memory-search.ts @@ -4,6 +4,10 @@ import { findNormalizedProviderValue, normalizeProviderId, } from "@openclaw/model-catalog-core/provider-id"; +import { + normalizeStringEntries, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig, MemorySearchConfig } from "../config/config.js"; import { resolveStateDir } from "../config/paths.js"; import type { SecretInput } from "../config/types.secrets.js"; @@ -14,7 +18,6 @@ import { } from "../memory-host-sdk/multimodal.js"; import { getEmbeddingProvider } from "../plugins/embedding-provider-runtime.js"; import { getMemoryEmbeddingProvider } from "../plugins/memory-embedding-providers.js"; -import { normalizeStringEntries, uniqueStrings } from "../shared/string-normalization.js"; import { clampInt, clampNumber, resolveUserPath } from "../utils.js"; import { resolveAgentConfig } from "./agent-scope.js"; diff --git a/src/agents/model-alias-lines.ts b/src/agents/model-alias-lines.ts index 0f8c56d5be5..f612395ac00 100644 --- a/src/agents/model-alias-lines.ts +++ b/src/agents/model-alias-lines.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; export function buildModelAliasLines(cfg?: OpenClawConfig) { const models = cfg?.agents?.defaults?.models ?? {}; diff --git a/src/agents/model-auth-env.ts b/src/agents/model-auth-env.ts index 32028f5f09e..f7e4de0e305 100644 --- a/src/agents/model-auth-env.ts +++ b/src/agents/model-auth-env.ts @@ -1,11 +1,11 @@ import fs from "node:fs"; import os from "node:os"; import { normalizeProviderIdForAuth } from "@openclaw/model-catalog-core/provider-id"; +import { normalizeOptionalString as normalizeOptionalPathInput } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { getShellEnvAppliedKeys } from "../infra/shell-env.js"; import { resolvePluginSetupProvider } from "../plugins/setup-registry.js"; import type { ProviderAuthEvidence } from "../secrets/provider-env-vars.js"; -import { normalizeOptionalString as normalizeOptionalPathInput } from "../shared/string-coerce.js"; import { normalizeOptionalSecretInput } from "../utils/normalize-secret-input.js"; import { resolveProviderEnvAuthLookupMaps } from "./model-auth-env-vars.js"; import { GCP_VERTEX_CREDENTIALS_MARKER } from "./model-auth-markers.js"; diff --git a/src/agents/model-auth-label.ts b/src/agents/model-auth-label.ts index d82c1ce47d6..3ca591b011e 100644 --- a/src/agents/model-auth-label.ts +++ b/src/agents/model-auth-label.ts @@ -1,6 +1,6 @@ +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { SessionEntry } from "../config/sessions.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { externalCliDiscoveryForProviderAuth, ensureAuthProfileStore, diff --git a/src/agents/model-auth-markers.ts b/src/agents/model-auth-markers.ts index 9884b83d99d..db0754ac059 100644 --- a/src/agents/model-auth-markers.ts +++ b/src/agents/model-auth-markers.ts @@ -1,6 +1,9 @@ +import { + normalizeTrimmedStringList, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import type { SecretRefSource } from "../config/types.secrets.js"; import { listOpenClawPluginManifestMetadata } from "../plugins/manifest-metadata-scan.js"; -import { normalizeTrimmedStringList, uniqueStrings } from "../shared/string-normalization.js"; import { listKnownProviderEnvApiKeyNames } from "./model-auth-env-vars.js"; /** @deprecated MiniMax provider-owned marker; do not use from third-party plugins. */ diff --git a/src/agents/model-auth.ts b/src/agents/model-auth.ts index d848d622e98..355c83ab3d0 100644 --- a/src/agents/model-auth.ts +++ b/src/agents/model-auth.ts @@ -1,4 +1,9 @@ import path from "node:path"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import { formatCliCommand } from "../cli/command-format.js"; import { getRuntimeConfigSnapshot } from "../config/config.js"; import type { ModelProviderAuthMode, ModelProviderConfig } from "../config/types.js"; @@ -15,11 +20,6 @@ import { import { resolveOwningPluginIdsForProviderRef } from "../plugins/providers.js"; import { resolveRuntimeSyntheticAuthProviderRefState } from "../plugins/synthetic-auth.runtime.js"; import { resolveDefaultSecretProviderAlias } from "../secrets/ref-contract.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; -import { normalizeUniqueStringEntries } from "../shared/string-normalization.js"; import { normalizeOptionalSecretInput } from "../utils/normalize-secret-input.js"; import { resolveDefaultAgentDir } from "./agent-scope-config.js"; import { diff --git a/src/agents/model-catalog-browse.ts b/src/agents/model-catalog-browse.ts index 81f1e298851..4fe854d0106 100644 --- a/src/agents/model-catalog-browse.ts +++ b/src/agents/model-catalog-browse.ts @@ -1,5 +1,5 @@ +import { parseFiniteNumber } from "@openclaw/normalization-core/number-coercion"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { parseFiniteNumber } from "../shared/number-coercion.js"; import type { ModelCatalogEntry } from "./model-catalog.types.js"; import { parseConfiguredModelVisibilityEntries } from "./model-selection-shared.js"; diff --git a/src/agents/model-catalog-lookup.ts b/src/agents/model-catalog-lookup.ts index a1036a6085d..be0b0ae5ad3 100644 --- a/src/agents/model-catalog-lookup.ts +++ b/src/agents/model-catalog-lookup.ts @@ -2,7 +2,7 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; import type { ModelCatalogEntry, ModelInputType } from "./model-catalog.types.js"; export function modelSupportsInput( diff --git a/src/agents/model-catalog-scope.ts b/src/agents/model-catalog-scope.ts index 6880af1963d..f56dfddb0aa 100644 --- a/src/agents/model-catalog-scope.ts +++ b/src/agents/model-catalog-scope.ts @@ -2,8 +2,8 @@ import { findNormalizedProviderValue, normalizeProviderId, } from "@openclaw/model-catalog-core/provider-id"; +import { normalizeUniqueSingleOrTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeUniqueSingleOrTrimmedStringList } from "../shared/string-normalization.js"; function dedupeCatalogScopeRefs(values: Array): string[] { return normalizeUniqueSingleOrTrimmedStringList(values); diff --git a/src/agents/model-catalog.ts b/src/agents/model-catalog.ts index c5a735fe1e9..0fcf16a2d72 100644 --- a/src/agents/model-catalog.ts +++ b/src/agents/model-catalog.ts @@ -1,6 +1,10 @@ import { readFile } from "node:fs/promises"; import { join } from "node:path"; import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { getRuntimeConfig } from "../config/config.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; @@ -14,10 +18,6 @@ import { resolvePluginMetadataSnapshot } from "../plugins/plugin-metadata-snapsh import type { PluginMetadataSnapshot } from "../plugins/plugin-metadata-snapshot.types.js"; import { augmentModelCatalogWithProviderPlugins } from "../plugins/provider-runtime.runtime.js"; import { createLazyImportLoader } from "../shared/lazy-promise.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { resolveDefaultAgentDir } from "./agent-scope.js"; import { ensureAuthProfileStoreWithoutExternalProfiles } from "./auth-profiles.js"; import { modelSupportsInput as modelCatalogEntrySupportsInput } from "./model-catalog-lookup.js"; diff --git a/src/agents/model-fallback.ts b/src/agents/model-fallback.ts index f564281a54a..bc4f0e5734c 100644 --- a/src/agents/model-fallback.ts +++ b/src/agents/model-fallback.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { sanitizeForLog } from "../../packages/terminal-core/src/ansi.js"; import { resolveAgentModelFallbackValues, @@ -16,7 +17,6 @@ import { } from "../plugins/runtime-state.js"; import { isCommandLaneTaskTimeoutError } from "../process/command-queue.js"; import { createLazyImportLoader } from "../shared/lazy-promise.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { isDefaultAgentRuntimeId } from "./agent-runtime-id.js"; import { normalizeOptionalAgentRuntimeId } from "./agent-runtime-id.js"; import { externalCliDiscoveryForProviders } from "./auth-profiles/external-cli-discovery.js"; diff --git a/src/agents/model-ref-shared.ts b/src/agents/model-ref-shared.ts index b215d2351b8..abe21bff42e 100644 --- a/src/agents/model-ref-shared.ts +++ b/src/agents/model-ref-shared.ts @@ -6,8 +6,8 @@ import { normalizeConfiguredProviderCatalogModelId as normalizeConfiguredProviderCatalogModelIdShared, normalizeStaticProviderModelIdWithPolicies, } from "@openclaw/model-catalog-core/provider-model-id-normalization"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { normalizeProviderModelIdWithManifest } from "../plugins/manifest-model-id-normalization.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; type StaticModelRef = { provider: string; diff --git a/src/agents/model-runtime-aliases.ts b/src/agents/model-runtime-aliases.ts index 78352e30617..252bd6de50b 100644 --- a/src/agents/model-runtime-aliases.ts +++ b/src/agents/model-runtime-aliases.ts @@ -1,6 +1,6 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import { isCliRuntimeModelBackendForProvider, listCliRuntimeModelBackendBindings, diff --git a/src/agents/model-scan.test.ts b/src/agents/model-scan.test.ts index b473ef50fa2..023e0434211 100644 --- a/src/agents/model-scan.test.ts +++ b/src/agents/model-scan.test.ts @@ -1,5 +1,5 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { withEnvAsync } from "../test-utils/env.js"; import { withFetchPreconnect } from "../test-utils/fetch-mock.js"; import { scanOpenRouterModels } from "./model-scan.js"; diff --git a/src/agents/model-scan.ts b/src/agents/model-scan.ts index 25d99524265..99d6c087669 100644 --- a/src/agents/model-scan.ts +++ b/src/agents/model-scan.ts @@ -1,4 +1,13 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { + normalizeStringEntries, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { Type } from "typebox"; import { formatErrorMessage } from "../infra/errors.js"; import { getEnvApiKey } from "../llm/env-api-keys.js"; @@ -6,12 +15,6 @@ import type { OpenAICompletionsOptions } from "../llm/providers/openai-completio import { complete } from "../llm/stream.js"; import { type Context, type Model, type Tool } from "../llm/types.js"; import { inferParamBFromIdOrName } from "../shared/model-param-b.js"; -import { resolveTimerTimeoutMs } from "../shared/number-coercion.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; -import { normalizeStringEntries, uniqueStrings } from "../shared/string-normalization.js"; const OPENROUTER_MODELS_URL = "https://openrouter.ai/api/v1/models"; const DEFAULT_TIMEOUT_MS = 12_000; diff --git a/src/agents/model-selection-display.ts b/src/agents/model-selection-display.ts index 3c13e3dc948..13df50e6f64 100644 --- a/src/agents/model-selection-display.ts +++ b/src/agents/model-selection-display.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; type ModelDisplaySelectionParams = { runtimeProvider?: unknown; diff --git a/src/agents/model-selection-normalize.ts b/src/agents/model-selection-normalize.ts index a05268348bf..39b2899a072 100644 --- a/src/agents/model-selection-normalize.ts +++ b/src/agents/model-selection-normalize.ts @@ -4,8 +4,8 @@ import { normalizeProviderId as normalizeProviderIdCore, normalizeProviderIdForAuth as normalizeProviderIdForAuthCore, } from "@openclaw/model-catalog-core/provider-id"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { PluginManifestRecord } from "../plugins/manifest-registry.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { modelKey as sharedModelKey, normalizeStaticProviderModelId } from "./model-ref-shared.js"; import { normalizeProviderModelIdWithRuntime } from "./provider-model-normalization.runtime.js"; diff --git a/src/agents/model-selection-shared.ts b/src/agents/model-selection-shared.ts index daeb7a84813..d80ef08f788 100644 --- a/src/agents/model-selection-shared.ts +++ b/src/agents/model-selection-shared.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { sanitizeForLog, stripAnsi } from "../../packages/terminal-core/src/ansi.js"; import { resolveAgentModelPrimaryValue } from "../config/model-input.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; @@ -5,10 +9,6 @@ import { createSubsystemLogger } from "../logging/subsystem.js"; import { getCurrentPluginMetadataSnapshot } from "../plugins/current-plugin-metadata-snapshot.js"; import { loadManifestMetadataSnapshot } from "../plugins/manifest-contract-eligibility.js"; import { getActivePluginRegistryWorkspaceDirFromState } from "../plugins/runtime-state.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { resolveConfiguredProviderFallback } from "./configured-provider-fallback.js"; import { DEFAULT_PROVIDER } from "./defaults.js"; import { findModelCatalogEntry } from "./model-catalog-lookup.js"; diff --git a/src/agents/model-selection.ts b/src/agents/model-selection.ts index 455685c30af..826b1141ca2 100644 --- a/src/agents/model-selection.ts +++ b/src/agents/model-selection.ts @@ -1,13 +1,13 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveAgentModelFallbackValues, resolveAgentModelPrimaryValue, toAgentModelListLike, } from "../config/model-input.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { resolveAgentConfig, resolveAgentEffectiveModelPrimary, diff --git a/src/agents/model-suppression.ts b/src/agents/model-suppression.ts index 4230ebd22a7..83af440dade 100644 --- a/src/agents/model-suppression.ts +++ b/src/agents/model-suppression.ts @@ -5,7 +5,7 @@ import { buildManifestBuiltInModelSuppressionResolver } from "../plugins/manifes import { resolvePluginControlPlaneFingerprint } from "../plugins/plugin-control-plane-context.js"; import { registerPluginMetadataProcessMemoLifecycleClear } from "../plugins/plugin-metadata-lifecycle.js"; import { resolvePluginMetadataSnapshotMemoEnvFingerprint } from "../plugins/plugin-metadata-snapshot.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "../../packages/normalization-core/src/string-coerce.js"; type ManifestSuppressionResolver = ReturnType; diff --git a/src/agents/model-thinking-default.ts b/src/agents/model-thinking-default.ts index 33bb8b12bb8..e3cbb766a52 100644 --- a/src/agents/model-thinking-default.ts +++ b/src/agents/model-thinking-default.ts @@ -1,9 +1,9 @@ -import { resolveThinkingDefaultForModel } from "../auto-reply/thinking.js"; -import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { resolveThinkingDefaultForModel } from "../auto-reply/thinking.js"; +import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { ModelCatalogEntry } from "./model-catalog.types.js"; import { legacyModelKey, modelKey, normalizeProviderId } from "./model-selection-normalize.js"; import { normalizeModelSelection } from "./model-selection-resolve.js"; diff --git a/src/agents/models-config.merge.ts b/src/agents/models-config.merge.ts index 139d04040f8..5008778dfb1 100644 --- a/src/agents/models-config.merge.ts +++ b/src/agents/models-config.merge.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { isNonSecretApiKeyMarker } from "./model-auth-markers.js"; import type { ProviderConfig } from "./models-config.providers.secrets.js"; diff --git a/src/agents/models-config.providers.implicit.ts b/src/agents/models-config.providers.implicit.ts index 68416294e2b..9b06e0ce47a 100644 --- a/src/agents/models-config.providers.implicit.ts +++ b/src/agents/models-config.providers.implicit.ts @@ -2,6 +2,10 @@ import { findNormalizedProviderValue, normalizeProviderId, } from "@openclaw/model-catalog-core/provider-id"; +import { + normalizeStringEntries, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { formatErrorMessage } from "../infra/errors.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; @@ -14,7 +18,6 @@ import { runProviderStaticCatalog, } from "../plugins/provider-discovery.js"; import { resolveOwningPluginIdsForProviderRef } from "../plugins/providers.js"; -import { normalizeStringEntries, uniqueStrings } from "../shared/string-normalization.js"; import { ensureAuthProfileStore } from "./auth-profiles/store.js"; import { isNonSecretApiKeyMarker, diff --git a/src/agents/models-config.providers.policy.lookup.ts b/src/agents/models-config.providers.policy.lookup.ts index 342599bdf90..d716b4aca76 100644 --- a/src/agents/models-config.providers.policy.lookup.ts +++ b/src/agents/models-config.providers.policy.lookup.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { MODEL_APIS } from "../config/types.models.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { ProviderConfig } from "./models-config.providers.secrets.js"; const GENERIC_PROVIDER_APIS = new Set([ diff --git a/src/agents/models-config.providers.secret-helpers.ts b/src/agents/models-config.providers.secret-helpers.ts index 3beb405cb6d..f6588899748 100644 --- a/src/agents/models-config.providers.secret-helpers.ts +++ b/src/agents/models-config.providers.secret-helpers.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { coerceSecretRef, resolveSecretInputRef } from "../config/types.secrets.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { normalizeOptionalSecretInput } from "../utils/normalize-secret-input.js"; import type { AuthProfileStore } from "./auth-profiles/types.js"; import { resolveEnvApiKey, type EnvApiKeyLookupOptions } from "./model-auth-env.js"; diff --git a/src/agents/openai-reasoning-compat.ts b/src/agents/openai-reasoning-compat.ts index 0e796b20c48..91629cd4b77 100644 --- a/src/agents/openai-reasoning-compat.ts +++ b/src/agents/openai-reasoning-compat.ts @@ -1,4 +1,5 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; + type OpenAIReasoningCompatModel = { provider?: string | null; id?: string | null; diff --git a/src/agents/openai-reasoning-effort.ts b/src/agents/openai-reasoning-effort.ts index fe80a27f44c..5f7e341a938 100644 --- a/src/agents/openai-reasoning-effort.ts +++ b/src/agents/openai-reasoning-effort.ts @@ -1,5 +1,8 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { normalizeStringEntries, uniqueStrings } from "../shared/string-normalization.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { + normalizeStringEntries, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; export type OpenAIReasoningEffort = "none" | "minimal" | "low" | "medium" | "high" | "xhigh"; diff --git a/src/agents/openai-responses-payload-policy.ts b/src/agents/openai-responses-payload-policy.ts index c51a54c7ca5..76564ccb49b 100644 --- a/src/agents/openai-responses-payload-policy.ts +++ b/src/agents/openai-responses-payload-policy.ts @@ -1,5 +1,5 @@ +import { readStringValue } from "@openclaw/normalization-core/string-coerce"; import { parseStrictPositiveInteger } from "../infra/parse-finite-number.js"; -import { readStringValue } from "../shared/string-coerce.js"; import { asBoolean } from "../utils/boolean.js"; import { supportsOpenAIReasoningEffort } from "./openai-reasoning-effort.js"; diff --git a/src/agents/openai-strict-tool-setting.ts b/src/agents/openai-strict-tool-setting.ts index 44623a7a476..6f276309c2d 100644 --- a/src/agents/openai-strict-tool-setting.ts +++ b/src/agents/openai-strict-tool-setting.ts @@ -1,4 +1,4 @@ -import { readStringValue } from "../shared/string-coerce.js"; +import { readStringValue } from "@openclaw/normalization-core/string-coerce"; import { resolveProviderRequestCapabilities } from "./provider-attribution.js"; type OpenAITransportKind = "stream" | "websocket"; diff --git a/src/agents/openai-text-verbosity.ts b/src/agents/openai-text-verbosity.ts index e39598323d1..2a71f19bedc 100644 --- a/src/agents/openai-text-verbosity.ts +++ b/src/agents/openai-text-verbosity.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { log } from "./embedded-agent-runner/logger.js"; /** @deprecated OpenAI provider-owned stream helper; do not use from third-party plugins. */ diff --git a/src/agents/openai-transport-stream.ts b/src/agents/openai-transport-stream.ts index 964cab66d84..a2afe022c97 100644 --- a/src/agents/openai-transport-stream.ts +++ b/src/agents/openai-transport-stream.ts @@ -1,4 +1,6 @@ import { createHash, randomUUID } from "node:crypto"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import OpenAI, { AzureOpenAI } from "openai"; import type { ChatCompletionChunk } from "openai/resources/chat/completions.js"; import type { @@ -26,8 +28,6 @@ import { redactSensitiveText } from "../logging/redact.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import type { ProviderRuntimeModel } from "../plugins/provider-runtime-model.types.js"; import { resolveProviderTransportTurnStateWithPlugin } from "../plugins/provider-runtime.js"; -import { isRecord } from "../shared/record-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { CHARS_PER_TOKEN_ESTIMATE, estimateStringChars } from "../utils/cjk-chars.js"; import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./copilot-dynamic-headers.js"; import { createDeepSeekTextFilter } from "./deepseek-text-filter.js"; diff --git a/src/agents/openclaw-tools.media-factory-plan.ts b/src/agents/openclaw-tools.media-factory-plan.ts index 9690fe9e02f..88a30c537c1 100644 --- a/src/agents/openclaw-tools.media-factory-plan.ts +++ b/src/agents/openclaw-tools.media-factory-plan.ts @@ -1,3 +1,4 @@ +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { resolveAgentModelFallbackValues, resolveAgentModelPrimaryValue, @@ -5,7 +6,6 @@ import { import type { AgentModelConfig } from "../config/types.agents-shared.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { PluginMetadataSnapshot } from "../plugins/plugin-metadata-snapshot.types.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { listProfilesForProvider } from "./auth-profiles/profile-list.js"; import type { AuthProfileStore } from "./auth-profiles/types.js"; import { isToolAllowedByPolicyName } from "./tool-policy-match.js"; diff --git a/src/agents/openclaw-tools.registration.ts b/src/agents/openclaw-tools.registration.ts index 35c421c23db..654266271a8 100644 --- a/src/agents/openclaw-tools.registration.ts +++ b/src/agents/openclaw-tools.registration.ts @@ -1,5 +1,5 @@ +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { isStrictAgenticExecutionContractActive } from "./execution-contract.js"; import { isToolAllowedByPolicyName } from "./tool-policy-match.js"; import type { AnyAgentTool } from "./tools/common.js"; diff --git a/src/agents/owner-display.ts b/src/agents/owner-display.ts index 0ce8feb3d0a..275ddcddf55 100644 --- a/src/agents/owner-display.ts +++ b/src/agents/owner-display.ts @@ -1,6 +1,6 @@ import crypto from "node:crypto"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; type OwnerDisplaySetting = { ownerDisplay?: "raw" | "hash"; diff --git a/src/agents/payload-redaction.ts b/src/agents/payload-redaction.ts index 830cbc16976..0b0847c9089 100644 --- a/src/agents/payload-redaction.ts +++ b/src/agents/payload-redaction.ts @@ -1,6 +1,6 @@ import crypto from "node:crypto"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { estimateBase64DecodedBytes } from "../media/base64.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; const REDACTED_IMAGE_DATA = ""; diff --git a/src/agents/prompt-cache-stability.ts b/src/agents/prompt-cache-stability.ts index ed265ecd5a0..be5311d4b0d 100644 --- a/src/agents/prompt-cache-stability.ts +++ b/src/agents/prompt-cache-stability.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export function normalizeStructuredPromptSection(text: string): string { return text diff --git a/src/agents/provider-attribution.ts b/src/agents/provider-attribution.ts index fb58a797fdd..5ab0b45c02f 100644 --- a/src/agents/provider-attribution.ts +++ b/src/agents/provider-attribution.ts @@ -1,12 +1,12 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; -import { listOpenClawPluginManifestMetadata } from "../plugins/manifest-metadata-scan.js"; -import { isRecord } from "../shared/record-coerce.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; -import { normalizeTrimmedStringList } from "../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; +import { listOpenClawPluginManifestMetadata } from "../plugins/manifest-metadata-scan.js"; import { asBoolean } from "../utils/boolean.js"; import type { RuntimeVersionEnv } from "../version.js"; import { resolveRuntimeServiceVersion } from "../version.js"; diff --git a/src/agents/provider-http-errors.ts b/src/agents/provider-http-errors.ts index 9661f26a269..58dfa2fd832 100644 --- a/src/agents/provider-http-errors.ts +++ b/src/agents/provider-http-errors.ts @@ -1,9 +1,9 @@ -export { asFiniteNumber } from "../shared/number-coercion.js"; +export { asFiniteNumber } from "../../packages/normalization-core/src/number-coercion.js"; +import { normalizeOptionalString as trimToUndefined } from "../../packages/normalization-core/src/string-coerce.js"; import { redactSensitiveText } from "../logging/redact.js"; import { readResponseWithLimit } from "../media/read-response-with-limit.js"; -import { normalizeOptionalString as trimToUndefined } from "../shared/string-coerce.js"; export { asBoolean } from "../utils/boolean.js"; -export { normalizeOptionalString as trimToUndefined } from "../shared/string-coerce.js"; +export { normalizeOptionalString as trimToUndefined } from "../../packages/normalization-core/src/string-coerce.js"; const ERROR_BODY_METADATA_LIMIT = 500; const PROVIDER_BINARY_RESPONSE_MAX_BYTES = 16 * 1024 * 1024; diff --git a/src/agents/provider-local-service.test.ts b/src/agents/provider-local-service.test.ts index 9b53616cfd1..bf2cc0778f9 100644 --- a/src/agents/provider-local-service.test.ts +++ b/src/agents/provider-local-service.test.ts @@ -2,9 +2,9 @@ import fs from "node:fs/promises"; import net from "node:net"; import os from "node:os"; import path from "node:path"; +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import type { Model } from "openclaw/plugin-sdk/llm"; import { afterEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { attachModelProviderLocalService, ensureModelProviderLocalService, diff --git a/src/agents/provider-local-service.ts b/src/agents/provider-local-service.ts index 4722348861e..565e7163b9a 100644 --- a/src/agents/provider-local-service.ts +++ b/src/agents/provider-local-service.ts @@ -1,12 +1,12 @@ import { spawn, type ChildProcess } from "node:child_process"; import path from "node:path"; -import type { ModelProviderLocalServiceConfig } from "../config/types.models.js"; -import type { Model } from "../llm/types.js"; -import { createSubsystemLogger } from "../logging/subsystem.js"; import { clampPositiveTimerTimeoutMs, resolvePositiveTimerTimeoutMs, -} from "../shared/number-coercion.js"; +} from "@openclaw/normalization-core/number-coercion"; +import type { ModelProviderLocalServiceConfig } from "../config/types.models.js"; +import type { Model } from "../llm/types.js"; +import { createSubsystemLogger } from "../logging/subsystem.js"; const log = createSubsystemLogger("provider-local-service"); const DEFAULT_READY_TIMEOUT_MS = 120_000; diff --git a/src/agents/provider-request-config.ts b/src/agents/provider-request-config.ts index 047c57cf61a..70f296b9efe 100644 --- a/src/agents/provider-request-config.ts +++ b/src/agents/provider-request-config.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { ModelDefinitionConfig } from "../config/types.js"; import type { ConfiguredModelProviderRequest, @@ -6,7 +7,6 @@ import type { import { assertSecretInputResolved } from "../config/types.secrets.js"; import type { PinnedDispatcherPolicy } from "../infra/net/ssrf.js"; import type { Api } from "../llm/types.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { COPILOT_INTEGRATION_ID, buildCopilotIdeHeaders } from "./copilot-dynamic-headers.js"; import type { ProviderRequestCapabilities, diff --git a/src/agents/provider-transport-fetch.test.ts b/src/agents/provider-transport-fetch.test.ts index 02a0224e57d..66e9542feab 100644 --- a/src/agents/provider-transport-fetch.test.ts +++ b/src/agents/provider-transport-fetch.test.ts @@ -1,7 +1,7 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { Stream } from "openai/streaming"; import type { Model } from "openclaw/plugin-sdk/llm"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { buildGuardedModelFetch } from "./provider-transport-fetch.js"; type ProviderRequestPolicyConfigMockResult = { diff --git a/src/agents/provider-transport-fetch.ts b/src/agents/provider-transport-fetch.ts index 8693ee6e72c..ebb45120812 100644 --- a/src/agents/provider-transport-fetch.ts +++ b/src/agents/provider-transport-fetch.ts @@ -3,6 +3,12 @@ import { isLinkLocalIpAddress, parseCanonicalIpAddress, } from "@openclaw/net-policy/ip"; +import { + asFiniteNumberInRange, + clampTimerTimeoutMs, + parseStrictFiniteNumber, + parseStrictNonNegativeInteger, +} from "@openclaw/normalization-core/number-coercion"; import { fetchWithSsrFGuard, withTrustedEnvProxyGuardedFetchMode, @@ -17,12 +23,6 @@ import { import type { Model } from "../llm/types.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { resolveDebugProxySettings } from "../proxy-capture/env.js"; -import { - asFiniteNumberInRange, - clampTimerTimeoutMs, - parseStrictFiniteNumber, - parseStrictNonNegativeInteger, -} from "../shared/number-coercion.js"; import { emitModelTransportDebug } from "./model-transport-debug.js"; import { formatModelTransportDebugUrl } from "./model-transport-url.js"; import { diff --git a/src/agents/pty-keys.ts b/src/agents/pty-keys.ts index 1b9d237d45c..7424fe7cf9b 100644 --- a/src/agents/pty-keys.ts +++ b/src/agents/pty-keys.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { escapeRegExp } from "../utils.js"; const ESC = "\x1b"; diff --git a/src/agents/responses-image-payload-sanitizer.ts b/src/agents/responses-image-payload-sanitizer.ts index f64fe83ad62..0349a622894 100644 --- a/src/agents/responses-image-payload-sanitizer.ts +++ b/src/agents/responses-image-payload-sanitizer.ts @@ -1,5 +1,5 @@ +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { sanitizeInlineImageDataUrl as sanitizeSharedInlineImageDataUrl } from "../media/inline-image-data-url.js"; -import { isRecord } from "../shared/record-coerce.js"; const IMAGE_OMITTED_TEXT = "omitted image payload: invalid inline image data"; diff --git a/src/agents/run-wait.test.ts b/src/agents/run-wait.test.ts index 451f903e7a0..3d9d2ee0c98 100644 --- a/src/agents/run-wait.test.ts +++ b/src/agents/run-wait.test.ts @@ -1,9 +1,9 @@ -import { beforeEach, describe, expect, it, vi } from "vitest"; import { addTimerTimeoutGraceMs, MAX_DATE_TIMESTAMP_MS, MAX_TIMER_TIMEOUT_MS, -} from "../shared/number-coercion.js"; +} from "@openclaw/normalization-core/number-coercion"; +import { beforeEach, describe, expect, it, vi } from "vitest"; const callGatewayMock = vi.fn(); vi.mock("../gateway/call.js", () => ({ diff --git a/src/agents/run-wait.ts b/src/agents/run-wait.ts index a93ae8b738d..1bfe3fbb524 100644 --- a/src/agents/run-wait.ts +++ b/src/agents/run-wait.ts @@ -1,6 +1,3 @@ -import { callGateway } from "../gateway/call.js"; -import { formatErrorMessage } from "../infra/errors.js"; -import { normalizeBlockedLivenessWaitStatus } from "../shared/agent-liveness.js"; import { addTimerTimeoutGraceMs, asDateTimestampMs, @@ -8,7 +5,10 @@ import { parseFiniteNumber, resolveDateTimestampMs, resolveExpiresAtMsFromDurationMs, -} from "../shared/number-coercion.js"; +} from "@openclaw/normalization-core/number-coercion"; +import { callGateway } from "../gateway/call.js"; +import { formatErrorMessage } from "../infra/errors.js"; +import { normalizeBlockedLivenessWaitStatus } from "../shared/agent-liveness.js"; import { buildAgentRunTerminalOutcomeFromWaitResult, type AgentRunTerminalOutcome, diff --git a/src/agents/runtime-capabilities.ts b/src/agents/runtime-capabilities.ts index dfdab840b8c..9bfcb1f85b6 100644 --- a/src/agents/runtime-capabilities.ts +++ b/src/agents/runtime-capabilities.ts @@ -1,11 +1,11 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntriesLower } from "@openclaw/normalization-core/string-normalization"; import { resolveThreadBindingSpawnPolicy, supportsAutomaticThreadBindingSpawn, } from "../channels/thread-bindings-policy.js"; import { resolveChannelCapabilities } from "../config/channel-capabilities.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { normalizeStringEntriesLower } from "../shared/string-normalization.js"; import { resolveChannelPromptCapabilities } from "./channel-tools.js"; const THREAD_BOUND_SUBAGENT_SPAWN_CAPABILITY = "threadbound-subagent-spawn"; diff --git a/src/agents/sandbox-tool-policy.ts b/src/agents/sandbox-tool-policy.ts index 80509014230..b507337dd78 100644 --- a/src/agents/sandbox-tool-policy.ts +++ b/src/agents/sandbox-tool-policy.ts @@ -1,4 +1,4 @@ -import { uniqueStrings } from "../shared/string-normalization.js"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { SandboxToolPolicy } from "./sandbox/types.js"; export const IMPLICIT_ALLOW_ALL_FROM_ALSO_ALLOW = Symbol.for( diff --git a/src/agents/sandbox/backend.ts b/src/agents/sandbox/backend.ts index 6d5642f371f..82755c828e3 100644 --- a/src/agents/sandbox/backend.ts +++ b/src/agents/sandbox/backend.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { RegisteredSandboxBackend, SandboxBackendFactory, diff --git a/src/agents/sandbox/browser.ts b/src/agents/sandbox/browser.ts index 5ad9e9def82..eaf8dacea6f 100644 --- a/src/agents/sandbox/browser.ts +++ b/src/agents/sandbox/browser.ts @@ -1,4 +1,8 @@ import crypto from "node:crypto"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { deriveDefaultBrowserCdpPortRange } from "../../config/port-defaults.js"; import { isSameSsrFPolicy, type SsrFPolicy } from "../../infra/net/ssrf.js"; import { @@ -14,10 +18,6 @@ import { type ResolvedBrowserConfig, } from "../../plugin-sdk/browser-profiles.js"; import { defaultRuntime } from "../../runtime.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { BROWSER_BRIDGES } from "./browser-bridges.js"; import { computeSandboxBrowserConfigHash } from "./config-hash.js"; import { resolveSandboxBrowserDockerCreateConfig } from "./config.js"; diff --git a/src/agents/sandbox/config.test.ts b/src/agents/sandbox/config.test.ts index 0810808dd8f..f47a8df5ce1 100644 --- a/src/agents/sandbox/config.test.ts +++ b/src/agents/sandbox/config.test.ts @@ -1,6 +1,6 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../../config/config.js"; -import { MAX_TIMER_TIMEOUT_MS } from "../../shared/number-coercion.js"; import { resolveSandboxConfigForAgent } from "./config.js"; describe("sandbox config", () => { diff --git a/src/agents/sandbox/config.ts b/src/agents/sandbox/config.ts index 7556afea7a0..181258695b7 100644 --- a/src/agents/sandbox/config.ts +++ b/src/agents/sandbox/config.ts @@ -1,8 +1,8 @@ +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { SandboxSshSettings } from "../../config/types.sandbox.js"; import { normalizeSecretInputString } from "../../config/types.secrets.js"; -import { resolveTimerTimeoutMs } from "../../shared/number-coercion.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { resolveAgentConfig } from "../agent-scope.js"; import { DEFAULT_SANDBOX_BROWSER_AUTOSTART_TIMEOUT_MS, diff --git a/src/agents/sandbox/fs-bridge.ts b/src/agents/sandbox/fs-bridge.ts index 451e49bf8fa..94bfa42c287 100644 --- a/src/agents/sandbox/fs-bridge.ts +++ b/src/agents/sandbox/fs-bridge.ts @@ -1,5 +1,5 @@ import fs from "node:fs"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { SandboxBackendCommandResult, SandboxFsBridgeContext, diff --git a/src/agents/sandbox/fs-paths.ts b/src/agents/sandbox/fs-paths.ts index eeeeb11f4a5..65b92b278ef 100644 --- a/src/agents/sandbox/fs-paths.ts +++ b/src/agents/sandbox/fs-paths.ts @@ -1,8 +1,8 @@ import os from "node:os"; import path from "node:path"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { isPathInside } from "../../infra/path-guards.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; -import { normalizeStringEntries } from "../../shared/string-normalization.js"; import { resolveSandboxInputPath, resolveSandboxPath } from "../sandbox-paths.js"; import type { SandboxFsBridgeContext } from "./backend-handle.types.js"; import { splitSandboxBindSpec } from "./bind-spec.js"; diff --git a/src/agents/sandbox/network-mode.ts b/src/agents/sandbox/network-mode.ts index c7f53960b5e..636f2e5713a 100644 --- a/src/agents/sandbox/network-mode.ts +++ b/src/agents/sandbox/network-mode.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; export type NetworkModeBlockReason = "host" | "container_namespace_join"; diff --git a/src/agents/sandbox/novnc-auth.ts b/src/agents/sandbox/novnc-auth.ts index 0f0594c2a1b..f6216bc3c12 100644 --- a/src/agents/sandbox/novnc-auth.ts +++ b/src/agents/sandbox/novnc-auth.ts @@ -2,8 +2,8 @@ import crypto from "node:crypto"; import { isFutureDateTimestampMs, resolveExpiresAtMsFromDurationMs, -} from "../../shared/number-coercion.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export const NOVNC_PASSWORD_ENV_KEY = "OPENCLAW_BROWSER_NOVNC_PASSWORD"; // pragma: allowlist secret const NOVNC_TOKEN_TTL_MS = 60 * 1000; diff --git a/src/agents/sandbox/runtime-status.ts b/src/agents/sandbox/runtime-status.ts index 7473b5ff2c4..2f82beec8cf 100644 --- a/src/agents/sandbox/runtime-status.ts +++ b/src/agents/sandbox/runtime-status.ts @@ -1,10 +1,10 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { formatCliCommand } from "../../cli/command-format.js"; import { canonicalizeMainSessionAlias, resolveAgentMainSessionKey, } from "../../config/sessions/main-session.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { resolveSessionAgentId } from "../agent-scope.js"; import { auditSandboxToolPolicyBlock } from "../tool-policy-audit.js"; import { resolveSandboxConfigForAgent } from "./config.js"; diff --git a/src/agents/sandbox/shared.ts b/src/agents/sandbox/shared.ts index 5b68fa63585..295e22f40f6 100644 --- a/src/agents/sandbox/shared.ts +++ b/src/agents/sandbox/shared.ts @@ -1,6 +1,6 @@ import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { normalizeAgentId } from "../../routing/session-key.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { resolveUserPath } from "../../utils.js"; import { resolveAgentIdFromSessionKey } from "../agent-scope.js"; import { hashTextSha256 } from "./hash.js"; diff --git a/src/agents/sandbox/ssh-backend.ts b/src/agents/sandbox/ssh-backend.ts index d3908f6e59e..af63d5152ee 100644 --- a/src/agents/sandbox/ssh-backend.ts +++ b/src/agents/sandbox/ssh-backend.ts @@ -1,5 +1,5 @@ import path from "node:path"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { SandboxBackendCommandParams, SandboxBackendCommandResult, diff --git a/src/agents/sandbox/tool-policy.ts b/src/agents/sandbox/tool-policy.ts index 8ff9edd27b1..1eb05a21387 100644 --- a/src/agents/sandbox/tool-policy.ts +++ b/src/agents/sandbox/tool-policy.ts @@ -1,6 +1,6 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; import { resolveAgentConfig } from "../agent-scope.js"; import { compileGlobPatterns, matchesAnyGlobPattern } from "../glob-pattern.js"; import { expandToolGroups, normalizeToolName } from "../tool-policy.js"; diff --git a/src/agents/sandbox/validate-sandbox-security.ts b/src/agents/sandbox/validate-sandbox-security.ts index 587888a30dc..2996cd6e2b9 100644 --- a/src/agents/sandbox/validate-sandbox-security.ts +++ b/src/agents/sandbox/validate-sandbox-security.ts @@ -7,8 +7,8 @@ import os from "node:os"; import path from "node:path"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { resolveRequiredHomeDir, resolveRequiredOsHomeDir } from "../../infra/home-dir.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { splitSandboxBindSpec } from "./bind-spec.js"; import { SANDBOX_AGENT_WORKSPACE_MOUNT } from "./constants.js"; import { diff --git a/src/agents/session-agent-binding.ts b/src/agents/session-agent-binding.ts index 20ba29665b5..6b0ff47f006 100644 --- a/src/agents/session-agent-binding.ts +++ b/src/agents/session-agent-binding.ts @@ -1,13 +1,13 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { parseAgentSessionKey, normalizeAgentId, normalizeMainKey, } from "../routing/session-key.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { resolveDefaultAgentId } from "./agent-scope.js"; /** diff --git a/src/agents/session-async-task-status.ts b/src/agents/session-async-task-status.ts index 4ba830a0e48..a0b1fc32121 100644 --- a/src/agents/session-async-task-status.ts +++ b/src/agents/session-async-task-status.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { listTasksForOwnerKey } from "../tasks/runtime-internal.js"; import type { TaskRecord, TaskRuntime, TaskStatus } from "../tasks/task-registry.types.js"; diff --git a/src/agents/session-runtime-compat.ts b/src/agents/session-runtime-compat.ts index ac7004d2bea..f760b88b1dd 100644 --- a/src/agents/session-runtime-compat.ts +++ b/src/agents/session-runtime-compat.ts @@ -1,5 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { SessionEntry } from "../config/sessions.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { isDefaultAgentRuntimeId } from "./agent-runtime-id.js"; import { normalizeOptionalAgentRuntimeId } from "./agent-runtime-id.js"; import { resolveCliRuntimeModelBackendBinding } from "./cli-backends.js"; diff --git a/src/agents/session-tool-result-guard.ts b/src/agents/session-tool-result-guard.ts index 1042205bd80..b0244844b26 100644 --- a/src/agents/session-tool-result-guard.ts +++ b/src/agents/session-tool-result-guard.ts @@ -1,3 +1,5 @@ +import { resolveIntegerOption } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { boundedJsonUtf8Bytes, firstEnumerableOwnKeys, @@ -14,8 +16,6 @@ import type { PluginHookBeforeMessageWriteResult, } from "../plugins/types.js"; import { emitSessionTranscriptUpdate } from "../sessions/transcript-events.js"; -import { resolveIntegerOption } from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { formatContextLimitTruncationNotice } from "./embedded-agent-runner/context-truncation-notice.js"; import { DEFAULT_MAX_LIVE_TOOL_RESULT_CHARS, diff --git a/src/agents/session-transcript-repair.ts b/src/agents/session-transcript-repair.ts index 53c0b325bca..c5ac94e62c0 100644 --- a/src/agents/session-transcript-repair.ts +++ b/src/agents/session-transcript-repair.ts @@ -2,7 +2,7 @@ import { hasNonEmptyString as hasNonEmptyStringField, normalizeOptionalString, readStringValue, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; import type { AgentMessage } from "./runtime/index.js"; import { extractToolCallsFromAssistant, diff --git a/src/agents/session-write-lock.test.ts b/src/agents/session-write-lock.test.ts index 316d4609b7c..f7b39ef89c3 100644 --- a/src/agents/session-write-lock.test.ts +++ b/src/agents/session-write-lock.test.ts @@ -2,8 +2,8 @@ import fsSync from "node:fs"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, beforeAll, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; const FAKE_STARTTIME = 12345; let testing: typeof import("./session-write-lock.js").testing; diff --git a/src/agents/session-write-lock.ts b/src/agents/session-write-lock.ts index c100a36fb15..b2645f242e2 100644 --- a/src/agents/session-write-lock.ts +++ b/src/agents/session-write-lock.ts @@ -2,9 +2,9 @@ import "../infra/fs-safe-defaults.js"; import type fsSync from "node:fs"; import fs from "node:fs/promises"; import path from "node:path"; +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { createFileLockManager } from "../infra/file-lock-manager.js"; import { readGatewayProcessArgsSync as readProcessArgsSync } from "../infra/gateway-processes.js"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { getProcessStartTime, isPidAlive } from "../shared/pid-alive.js"; import { SessionWriteLockTimeoutError } from "./session-write-lock-error.js"; diff --git a/src/agents/sessions/extensions/loader.ts b/src/agents/sessions/extensions/loader.ts index ba0457d0289..156dce7b2c5 100644 --- a/src/agents/sessions/extensions/loader.ts +++ b/src/agents/sessions/extensions/loader.ts @@ -17,6 +17,7 @@ import * as bundledTypebox from "typebox"; import * as bundledTypeboxCompile from "typebox/compile"; import * as bundledTypeboxFormat from "typebox/format"; import * as bundledTypeboxValue from "typebox/value"; +import { installOpenClawInternalCorePackageNativeResolver } from "../../../plugins/plugin-sdk-native-resolver.js"; import { buildPluginLoaderAliasMap, buildPluginLoaderJitiOptions, @@ -429,6 +430,7 @@ async function loadExtensionSourceTransformModule( extensionPath: string, ): Promise { if (!extensionSourceTransformLoader) { + installOpenClawInternalCorePackageNativeResolver({ moduleUrl: import.meta.url }); const createJitiLoader = await loadCreateJitiLoaderFactory(); extensionSourceTransformLoader = createJitiLoader(import.meta.url, { ...(isBunBinary diff --git a/src/agents/sessions/tools/bash.test.ts b/src/agents/sessions/tools/bash.test.ts index 2c3ce37ce0b..cc86be1fcfb 100644 --- a/src/agents/sessions/tools/bash.test.ts +++ b/src/agents/sessions/tools/bash.test.ts @@ -1,5 +1,5 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { describe, expect, it } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../../../shared/number-coercion.js"; import { resolveBashTimeoutMs } from "./bash.js"; describe("bash tool timeout helpers", () => { diff --git a/src/agents/sessions/tools/bash.ts b/src/agents/sessions/tools/bash.ts index 15775277c28..d70414a9b23 100644 --- a/src/agents/sessions/tools/bash.ts +++ b/src/agents/sessions/tools/bash.ts @@ -1,8 +1,8 @@ import { spawn } from "node:child_process"; import { existsSync } from "node:fs"; import { Container, Text, truncateToWidth } from "@earendil-works/pi-tui"; +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; import { Type } from "typebox"; -import { resolveTimerTimeoutMs } from "../../../shared/number-coercion.js"; import { keyHint } from "../../modes/interactive/components/keybinding-hints.js"; import { truncateToVisualLines } from "../../modes/interactive/components/visual-truncate.js"; import { theme } from "../../modes/interactive/theme/theme.js"; diff --git a/src/agents/spawned-context.ts b/src/agents/spawned-context.ts index 23dc4d10dd2..a71f7e69c70 100644 --- a/src/agents/spawned-context.ts +++ b/src/agents/spawned-context.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeAgentId, parseAgentSessionKey } from "../routing/session-key.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resolveAgentWorkspaceDir } from "./agent-scope.js"; export type SpawnedRunMetadata = { diff --git a/src/agents/subagent-announce-delivery.ts b/src/agents/subagent-announce-delivery.ts index cd8e4c1b837..924bfa547e5 100644 --- a/src/agents/subagent-announce-delivery.ts +++ b/src/agents/subagent-announce-delivery.ts @@ -1,3 +1,9 @@ +import { clampTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; +import { + normalizeStringEntries, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { completionRequiresMessageToolDelivery } from "../auto-reply/reply/completion-delivery-policy.js"; import { isSilentReplyPayloadText, SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js"; import { getLoadedChannelPluginForRead } from "../channels/plugins/registry-loaded-read.js"; @@ -17,9 +23,6 @@ import { import { deriveSessionChatTypeFromKey } from "../sessions/session-chat-type-shared.js"; import { isCronRunSessionKey, isCronSessionKey } from "../sessions/session-key-utils.js"; import { isNonTerminalAgentRunStatus } from "../shared/agent-run-status.js"; -import { clampTimerTimeoutMs } from "../shared/number-coercion.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { normalizeStringEntries, uniqueStrings } from "../shared/string-normalization.js"; import { mergeDeliveryContext, normalizeDeliveryContext } from "../utils/delivery-context.js"; import { INTERNAL_MESSAGE_CHANNEL, diff --git a/src/agents/subagent-announce-origin.ts b/src/agents/subagent-announce-origin.ts index a44e1b9f29a..e2953faa433 100644 --- a/src/agents/subagent-announce-origin.ts +++ b/src/agents/subagent-announce-origin.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { getLoadedChannelPluginForRead } from "../channels/plugins/registry-loaded-read.js"; import type { ChannelId } from "../channels/plugins/types.public.js"; import { @@ -5,7 +6,6 @@ import { stripTargetProviderPrefix, stripTargetTopicSuffix, } from "../infra/outbound/channel-target-prefix.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { deliveryContextFromSession, mergeDeliveryContext, diff --git a/src/agents/subagent-announce-output.ts b/src/agents/subagent-announce-output.ts index ecf596d6fa2..db0bcca2a2c 100644 --- a/src/agents/subagent-announce-output.ts +++ b/src/agents/subagent-announce-output.ts @@ -1,5 +1,5 @@ +import { asFiniteNumber } from "@openclaw/normalization-core/number-coercion"; import { isSilentReplyText, SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js"; -import { asFiniteNumber } from "../shared/number-coercion.js"; import { buildAgentRunTerminalOutcomeFromWaitResult } from "./agent-run-terminal-outcome.js"; import { wrapPromptDataBlock } from "./sanitize-for-prompt.js"; import { diff --git a/src/agents/subagent-announce.timeout.test.ts b/src/agents/subagent-announce.timeout.test.ts index c9b19f0524b..efaefe23a00 100644 --- a/src/agents/subagent-announce.timeout.test.ts +++ b/src/agents/subagent-announce.timeout.test.ts @@ -1,5 +1,5 @@ +import { clampTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; import { beforeEach, describe, expect, it, vi } from "vitest"; -import { clampTimerTimeoutMs } from "../shared/number-coercion.js"; import { createSubagentAnnounceDeliveryRuntimeMock } from "./subagent-announce.test-support.js"; type GatewayCall = { diff --git a/src/agents/subagent-announce.ts b/src/agents/subagent-announce.ts index caf48097d36..acb22bca884 100644 --- a/src/agents/subagent-announce.ts +++ b/src/agents/subagent-announce.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { isSilentReplyText, SILENT_REPLY_TOKEN, @@ -8,7 +9,6 @@ import { import { defaultRuntime } from "../runtime.js"; import { isCronSessionKey } from "../sessions/session-key-utils.js"; import { createLazyImportLoader } from "../shared/lazy-promise.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { type DeliveryContext, normalizeDeliveryContext } from "../utils/delivery-context.js"; import { INTERNAL_MESSAGE_CHANNEL } from "../utils/message-channel.js"; import { diff --git a/src/agents/subagent-attachments.ts b/src/agents/subagent-attachments.ts index 76a78a0bfa5..9d87a066b06 100644 --- a/src/agents/subagent-attachments.ts +++ b/src/agents/subagent-attachments.ts @@ -1,9 +1,9 @@ import crypto from "node:crypto"; import { promises as fs } from "node:fs"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { privateFileStore } from "../infra/private-file-store.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resolveAgentWorkspaceDir } from "./agent-scope.js"; export function decodeStrictBase64(value: string, maxDecodedBytes: number): Buffer | null { diff --git a/src/agents/subagent-capabilities.ts b/src/agents/subagent-capabilities.ts index 829c37b987d..797349925a9 100644 --- a/src/agents/subagent-capabilities.ts +++ b/src/agents/subagent-capabilities.ts @@ -1,3 +1,8 @@ +import { + resolveIntegerOption, + resolveNonNegativeIntegerOption, +} from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH } from "../config/agent-limits.js"; import { loadSessionStore, resolveStorePath } from "../config/sessions.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; @@ -6,11 +11,6 @@ import { isSubagentSessionKey, parseAgentSessionKey, } from "../routing/session-key.js"; -import { - resolveIntegerOption, - resolveNonNegativeIntegerOption, -} from "../shared/number-coercion.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import { normalizeInheritedToolAllowlist, normalizeInheritedToolDenylist, diff --git a/src/agents/subagent-depth.test.ts b/src/agents/subagent-depth.test.ts index 812eb95703a..d1f75dc1834 100644 --- a/src/agents/subagent-depth.test.ts +++ b/src/agents/subagent-depth.test.ts @@ -1,8 +1,8 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { describe, expect, it } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { getSubagentDepthFromSessionStore } from "./subagent-depth.js"; import { resolveAgentTimeoutMs, resolveAgentTimeoutSeconds } from "./timeout.js"; diff --git a/src/agents/subagent-list.ts b/src/agents/subagent-list.ts index b067e840a8c..374c37ed141 100644 --- a/src/agents/subagent-list.ts +++ b/src/agents/subagent-list.ts @@ -1,10 +1,10 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { resolveSubagentLabel, sortSubagentRuns } from "../auto-reply/reply/subagents-utils.js"; import { resolveStorePath } from "../config/sessions/paths.js"; import { loadSessionStore } from "../config/sessions/store-load.js"; import type { SessionEntry } from "../config/sessions/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { parseAgentSessionKey, type ParsedAgentSessionKey } from "../routing/session-key.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { formatDurationCompact, formatTokenUsageDisplay, diff --git a/src/agents/subagent-registry-helpers.ts b/src/agents/subagent-registry-helpers.ts index cbbcec1f6bf..cd9dcb35c14 100644 --- a/src/agents/subagent-registry-helpers.ts +++ b/src/agents/subagent-registry-helpers.ts @@ -1,5 +1,6 @@ import fsSync, { promises as fs } from "node:fs"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { DEFAULT_SUBAGENT_ARCHIVE_AFTER_MINUTES } from "../config/agent-limits.js"; import { getRuntimeConfig } from "../config/config.js"; import { @@ -11,7 +12,6 @@ import { } from "../config/sessions.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { defaultRuntime } from "../runtime.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { withSubagentOutcomeTiming } from "./subagent-announce-output.js"; import { getDeliveryAttemptCount, getDeliveryLastError } from "./subagent-delivery-state.js"; import { SUBAGENT_ENDED_REASON_ERROR } from "./subagent-lifecycle-events.js"; diff --git a/src/agents/subagent-registry-lifecycle.ts b/src/agents/subagent-registry-lifecycle.ts index 2e490a639fc..f574e46cd6d 100644 --- a/src/agents/subagent-registry-lifecycle.ts +++ b/src/agents/subagent-registry-lifecycle.ts @@ -1,3 +1,4 @@ +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { isSilentReplyText, SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js"; import type { cleanupBrowserSessionsForLifecycleEnd } from "../browser-lifecycle-cleanup.js"; import type { callGateway as defaultCallGateway } from "../gateway/call.js"; @@ -6,7 +7,6 @@ import { defaultRuntime } from "../runtime.js"; import { emitSessionLifecycleEvent } from "../sessions/session-lifecycle-events.js"; import { extractTextFromChatContent } from "../shared/chat-content.js"; import { createLazyImportLoader } from "../shared/lazy-promise.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { completeTaskRunByRunId, failTaskRunByRunId, diff --git a/src/agents/subagent-registry.store.ts b/src/agents/subagent-registry.store.ts index 3e3c3679a72..fce9e7a31c8 100644 --- a/src/agents/subagent-registry.store.ts +++ b/src/agents/subagent-registry.store.ts @@ -1,9 +1,9 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; +import { readStringValue } from "@openclaw/normalization-core/string-coerce"; import { resolveStateDir } from "../config/paths.js"; import { loadJsonFile, saveJsonFile } from "../infra/json-file.js"; -import { readStringValue } from "../shared/string-coerce.js"; import { normalizeDeliveryContext } from "../utils/delivery-context.shared.js"; import { normalizeSubagentRunState } from "./subagent-delivery-state.js"; import type { SubagentRunRecord } from "./subagent-registry.types.js"; diff --git a/src/agents/subagent-session-key.ts b/src/agents/subagent-session-key.ts index 7108ff199f6..ae87948a5e4 100644 --- a/src/agents/subagent-session-key.ts +++ b/src/agents/subagent-session-key.ts @@ -1,3 +1,3 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "../../packages/normalization-core/src/string-coerce.js"; export const normalizeSubagentSessionKey = normalizeOptionalString; diff --git a/src/agents/subagent-session-reconciliation.ts b/src/agents/subagent-session-reconciliation.ts index 947dc976720..872892b45d2 100644 --- a/src/agents/subagent-session-reconciliation.ts +++ b/src/agents/subagent-session-reconciliation.ts @@ -1,3 +1,4 @@ +import { asFiniteNumber } from "@openclaw/normalization-core/number-coercion"; import { getRuntimeConfig } from "../config/config.js"; import { loadSessionStore, @@ -6,7 +7,6 @@ import { type SessionEntry, } from "../config/sessions.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { asFiniteNumber } from "../shared/number-coercion.js"; import type { SubagentRunOutcome } from "./subagent-announce-output.js"; import { SUBAGENT_ENDED_REASON_COMPLETE, diff --git a/src/agents/subagent-spawn-thinking.ts b/src/agents/subagent-spawn-thinking.ts index 8e665ae5e89..03b37d19eb6 100644 --- a/src/agents/subagent-spawn-thinking.ts +++ b/src/agents/subagent-spawn-thinking.ts @@ -1,6 +1,6 @@ +import { asOptionalObjectRecord } from "@openclaw/normalization-core/record-coerce"; import { normalizeThinkLevel } from "../auto-reply/thinking.shared.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { asOptionalObjectRecord } from "../shared/record-coerce.js"; function readString(value: Record, key: string): string | undefined { const raw = value[key]; diff --git a/src/agents/subagent-spawn.context.test.ts b/src/agents/subagent-spawn.context.test.ts index b0eb128749b..373083cf7fa 100644 --- a/src/agents/subagent-spawn.context.test.ts +++ b/src/agents/subagent-spawn.context.test.ts @@ -1,6 +1,6 @@ import path from "node:path"; +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { loadSubagentSpawnModuleForTest, setupAcceptedSubagentGatewayMock, diff --git a/src/agents/subagent-spawn.test-helpers.ts b/src/agents/subagent-spawn.test-helpers.ts index 098b6a3db75..d7ddff98d7a 100644 --- a/src/agents/subagent-spawn.test-helpers.ts +++ b/src/agents/subagent-spawn.test-helpers.ts @@ -1,7 +1,7 @@ import os from "node:os"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { expect, vi } from "vitest"; import type { SubagentLifecycleHookRunner } from "../plugins/hooks.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; type MockFn = (...args: unknown[]) => unknown; type MockImplementationTarget = { diff --git a/src/agents/subagent-spawn.ts b/src/agents/subagent-spawn.ts index 5123b45991f..5a0ae8f0da1 100644 --- a/src/agents/subagent-spawn.ts +++ b/src/agents/subagent-spawn.ts @@ -1,6 +1,11 @@ import crypto from "node:crypto"; import { promises as fs } from "node:fs"; import path from "node:path"; +import { finiteSecondsToTimerSafeMilliseconds } from "@openclaw/normalization-core/number-coercion"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { isAcpRuntimeSpawnAvailable } from "../acp/runtime/availability.js"; import { resolveChannelDefaultBindingPlacement, @@ -25,11 +30,6 @@ import { stringifyRouteThreadId } from "../plugin-sdk/channel-route.js"; import { listRegisteredPluginAgentPromptGuidance } from "../plugins/command-registry-state.js"; import type { SubagentLifecycleHookRunner } from "../plugins/hooks.js"; import { isValidAgentId, normalizeAgentId, parseAgentSessionKey } from "../routing/session-key.js"; -import { finiteSecondsToTimerSafeMilliseconds } from "../shared/number-coercion.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { resolveUserPath } from "../utils.js"; import type { DeliveryContext } from "../utils/delivery-context.types.js"; import { listAgentIds, resolveAgentDir } from "./agent-scope-config.js"; diff --git a/src/agents/subagent-system-prompt.ts b/src/agents/subagent-system-prompt.ts index 234ff1bfaa5..945dd2a4920 100644 --- a/src/agents/subagent-system-prompt.ts +++ b/src/agents/subagent-system-prompt.ts @@ -1,5 +1,5 @@ +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import { DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH } from "../config/agent-limits.js"; -import { normalizeUniqueStringEntries } from "../shared/string-normalization.js"; import type { DeliveryContext } from "../utils/delivery-context.types.js"; export function buildSubagentSystemPrompt(params: { diff --git a/src/agents/subagent-target-policy.ts b/src/agents/subagent-target-policy.ts index ef4f5fb2c81..7156393d2f2 100644 --- a/src/agents/subagent-target-policy.ts +++ b/src/agents/subagent-target-policy.ts @@ -1,5 +1,8 @@ +import { + normalizeUniqueStringEntries, + sortUniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { normalizeAgentId } from "../routing/session-key.js"; -import { normalizeUniqueStringEntries, sortUniqueStrings } from "../shared/string-normalization.js"; type SubagentTargetPolicyResult = { ok: true } | { ok: false; allowedText: string; error: string }; diff --git a/src/agents/subagent-task-name.ts b/src/agents/subagent-task-name.ts index d008cc2b517..dba65672c72 100644 --- a/src/agents/subagent-task-name.ts +++ b/src/agents/subagent-task-name.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; const SUBAGENT_TASK_NAME_RE = /^[a-z][a-z0-9_-]{0,63}$/; const RESERVED_SUBAGENT_TASK_NAMES = new Set(["all", "last"]); diff --git a/src/agents/subagent-yield-output.ts b/src/agents/subagent-yield-output.ts index 7078e151a15..d20429120e0 100644 --- a/src/agents/subagent-yield-output.ts +++ b/src/agents/subagent-yield-output.ts @@ -1,4 +1,4 @@ -import { asOptionalRecord } from "../shared/record-coerce.js"; +import { asOptionalRecord } from "@openclaw/normalization-core/record-coerce"; function readToolName(value: unknown): string | undefined { const record = asOptionalRecord(value); diff --git a/src/agents/system-prompt-params.ts b/src/agents/system-prompt-params.ts index 392c98643d6..2ad5c98c971 100644 --- a/src/agents/system-prompt-params.ts +++ b/src/agents/system-prompt-params.ts @@ -1,8 +1,8 @@ import fs from "node:fs"; import path from "node:path"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { findGitRoot } from "../infra/git-root.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import type { ActiveProcessSessionReference } from "./bash-process-references.js"; import { formatUserTime, diff --git a/src/agents/system-prompt.ts b/src/agents/system-prompt.ts index fca4a9b983c..89366ebd371 100644 --- a/src/agents/system-prompt.ts +++ b/src/agents/system-prompt.ts @@ -1,4 +1,13 @@ import { createHmac, createHash } from "node:crypto"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, +} from "@openclaw/normalization-core/string-coerce"; +import { + normalizeStringEntries, + normalizeStringEntriesLower, + normalizeUniqueStringEntries, +} from "@openclaw/normalization-core/string-normalization"; import type { SourceReplyDeliveryMode } from "../auto-reply/get-reply-options.types.js"; import type { ReasoningLevel, ThinkLevel } from "../auto-reply/thinking.js"; import { SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js"; @@ -10,15 +19,6 @@ import type { SubagentDelegationMode } from "../config/types.agent-defaults.js"; import type { MemoryCitationsMode } from "../config/types.memory.js"; import { buildMemoryPromptSection } from "../plugins/memory-state.js"; import type { AgentPromptSurfaceKind } from "../plugins/types.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; -import { - normalizeStringEntries, - normalizeStringEntriesLower, - normalizeUniqueStringEntries, -} from "../shared/string-normalization.js"; import { listDeliverableMessageChannels } from "../utils/message-channel.js"; import type { ActiveProcessSessionReference } from "./bash-process-references.js"; import type { BootstrapMode } from "./bootstrap-mode.js"; diff --git a/src/agents/test-helpers/fast-openclaw-tools-sessions.ts b/src/agents/test-helpers/fast-openclaw-tools-sessions.ts index 039b29bb524..8a176a3b459 100644 --- a/src/agents/test-helpers/fast-openclaw-tools-sessions.ts +++ b/src/agents/test-helpers/fast-openclaw-tools-sessions.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { vi } from "vitest"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { stubTool } from "./fast-tool-stubs.js"; // Sessions-tool tests only exercise sessions/subagent registrations. diff --git a/src/agents/timeout.ts b/src/agents/timeout.ts index 9f89dc0b280..8d0998397ef 100644 --- a/src/agents/timeout.ts +++ b/src/agents/timeout.ts @@ -1,5 +1,8 @@ +import { + clampTimerTimeoutMs, + MAX_TIMER_TIMEOUT_MS, +} from "@openclaw/normalization-core/number-coercion"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { clampTimerTimeoutMs, MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; const DEFAULT_AGENT_TIMEOUT_SECONDS = 48 * 60 * 60; diff --git a/src/agents/tool-allowlist-guard.ts b/src/agents/tool-allowlist-guard.ts index 5919a74a6b5..d6ea2ae801a 100644 --- a/src/agents/tool-allowlist-guard.ts +++ b/src/agents/tool-allowlist-guard.ts @@ -1,4 +1,4 @@ -import { normalizeStringEntries } from "../shared/string-normalization.js"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { normalizeToolList, normalizeToolName } from "./tool-policy.js"; type ExplicitToolAllowlistSource = { diff --git a/src/agents/tool-call-shared.ts b/src/agents/tool-call-shared.ts index 1c397e7f14a..efaf8d611c9 100644 --- a/src/agents/tool-call-shared.ts +++ b/src/agents/tool-call-shared.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; const TOOL_CALL_NAME_MAX_CHARS = 64; const TOOL_CALL_NAME_RE = /^[A-Za-z0-9_:.-]+$/; diff --git a/src/agents/tool-description-summary.ts b/src/agents/tool-description-summary.ts index 42c313d6077..11bbd28a930 100644 --- a/src/agents/tool-description-summary.ts +++ b/src/agents/tool-description-summary.ts @@ -1,5 +1,5 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; function normalizeSummaryWhitespace(value: string): string { return value.replace(/\s+/g, " ").trim(); diff --git a/src/agents/tool-display-common.ts b/src/agents/tool-display-common.ts index 5a69e16c5dd..d3a49920c54 100644 --- a/src/agents/tool-display-common.ts +++ b/src/agents/tool-display-common.ts @@ -1,8 +1,8 @@ -import { parseStrictFiniteNumber } from "../infra/parse-finite-number.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { parseStrictFiniteNumber } from "../infra/parse-finite-number.js"; import { resolveExecDetail, type ToolDetailMode } from "./tool-display-exec.js"; import { asRecord } from "./tool-display-record.js"; diff --git a/src/agents/tool-display-exec-shell.ts b/src/agents/tool-display-exec-shell.ts index 8d386290840..df02252013b 100644 --- a/src/agents/tool-display-exec-shell.ts +++ b/src/agents/tool-display-exec-shell.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; type PreambleResult = { command: string; diff --git a/src/agents/tool-display-record.ts b/src/agents/tool-display-record.ts index c29ff4abd0d..e1fcdf96584 100644 --- a/src/agents/tool-display-record.ts +++ b/src/agents/tool-display-record.ts @@ -1 +1 @@ -export { asOptionalObjectRecord as asRecord } from "../shared/record-coerce.js"; +export { asOptionalObjectRecord as asRecord } from "../../packages/normalization-core/src/record-coerce.js"; diff --git a/src/agents/tool-display.ts b/src/agents/tool-display.ts index 259c100b4d0..4dba454f381 100644 --- a/src/agents/tool-display.ts +++ b/src/agents/tool-display.ts @@ -1,5 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { redactToolDetail } from "../logging/redact.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { shortenHomeInString } from "../utils.js"; import { defaultTitle, diff --git a/src/agents/tool-error-summary.ts b/src/agents/tool-error-summary.ts index 1acfbc3936c..8eac6fef852 100644 --- a/src/agents/tool-error-summary.ts +++ b/src/agents/tool-error-summary.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { FileTarget } from "./tool-mutation.js"; export type ToolErrorSummary = { diff --git a/src/agents/tool-images.ts b/src/agents/tool-images.ts index 5e10cb0ccef..62ce9e98010 100644 --- a/src/agents/tool-images.ts +++ b/src/agents/tool-images.ts @@ -1,3 +1,4 @@ +import { resolveIntegerOption } from "@openclaw/normalization-core/number-coercion"; import type { ImageContent } from "../llm/types.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { canonicalizeBase64 } from "../media/base64.js"; @@ -8,7 +9,6 @@ import { isImageProcessorUnavailableError, resizeToJpeg, } from "../media/media-services.js"; -import { resolveIntegerOption } from "../shared/number-coercion.js"; import { DEFAULT_IMAGE_MAX_BYTES, DEFAULT_IMAGE_MAX_DIMENSION_PX, diff --git a/src/agents/tool-loop-detection.ts b/src/agents/tool-loop-detection.ts index 33659b7e880..0069ee8de49 100644 --- a/src/agents/tool-loop-detection.ts +++ b/src/agents/tool-loop-detection.ts @@ -1,11 +1,11 @@ import { createHash } from "node:crypto"; -import type { ToolLoopDetectionConfig } from "../config/types.tools.js"; -import type { SessionState, ToolCallRecord } from "../logging/diagnostic-session-state.js"; -import { createSubsystemLogger } from "../logging/subsystem.js"; import { normalizeNullableString as nonEmptyStringField, normalizeOptionalString as normalizeRunId, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { ToolLoopDetectionConfig } from "../config/types.tools.js"; +import type { SessionState, ToolCallRecord } from "../logging/diagnostic-session-state.js"; +import { createSubsystemLogger } from "../logging/subsystem.js"; import { isPlainObject } from "../utils.js"; import { stableStringify } from "./stable-stringify.js"; diff --git a/src/agents/tool-mutation.ts b/src/agents/tool-mutation.ts index c12e601b24a..c51957af460 100644 --- a/src/agents/tool-mutation.ts +++ b/src/agents/tool-mutation.ts @@ -1,7 +1,7 @@ import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; import { asRecord } from "./tool-display-record.js"; const MUTATING_TOOL_NAMES = new Set([ diff --git a/src/agents/tool-policy-shared.ts b/src/agents/tool-policy-shared.ts index 8645e3191b9..f472547fdd4 100644 --- a/src/agents/tool-policy-shared.ts +++ b/src/agents/tool-policy-shared.ts @@ -1,5 +1,5 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { CORE_TOOL_GROUPS, resolveCoreToolProfilePolicy, diff --git a/src/agents/tool-policy.ts b/src/agents/tool-policy.ts index 4db3ad743d9..691af11e0c0 100644 --- a/src/agents/tool-policy.ts +++ b/src/agents/tool-policy.ts @@ -1,5 +1,5 @@ -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { IMPLICIT_ALLOW_ALL_FROM_ALSO_ALLOW } from "./sandbox-tool-policy.js"; import { expandToolGroups, normalizeToolList, normalizeToolName } from "./tool-policy-shared.js"; export { diff --git a/src/agents/tool-search.ts b/src/agents/tool-search.ts index 3399f720df8..197baf6034b 100644 --- a/src/agents/tool-search.ts +++ b/src/agents/tool-search.ts @@ -1,14 +1,14 @@ import { spawn } from "node:child_process"; import os from "node:os"; -import { Type } from "typebox"; -import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { getPluginToolMeta } from "../plugins/tools.js"; -import { isRecord } from "../shared/record-coerce.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { normalizeStringEntries, uniqueStrings, uniqueValues, -} from "../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-normalization"; +import { Type } from "typebox"; +import type { OpenClawConfig } from "../config/types.openclaw.js"; +import { getPluginToolMeta } from "../plugins/tools.js"; import { isToolWrappedWithBeforeToolCallHook, type HookContext, diff --git a/src/agents/tools-effective-inventory-build.ts b/src/agents/tools-effective-inventory-build.ts index 7b8682bbe10..aeb79114a28 100644 --- a/src/agents/tools-effective-inventory-build.ts +++ b/src/agents/tools-effective-inventory-build.ts @@ -1,11 +1,11 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { ProviderRuntimeModel } from "../plugins/provider-runtime-model.types.js"; import { getActivePluginRegistry } from "../plugins/runtime.js"; import { buildPluginToolMetadataKey, getPluginToolMeta } from "../plugins/tools.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { getChannelAgentToolMeta } from "./channel-tools.js"; import { normalizeAgentRuntimeTools } from "./runtime-plan/tools.js"; import { summarizeToolDescriptionText } from "./tool-description-summary.js"; diff --git a/src/agents/tools-effective-inventory.ts b/src/agents/tools-effective-inventory.ts index c8b28df3484..f5e47af7dbb 100644 --- a/src/agents/tools-effective-inventory.ts +++ b/src/agents/tools-effective-inventory.ts @@ -2,14 +2,14 @@ import { findNormalizedProviderValue, normalizeProviderId, } from "@openclaw/model-catalog-core/provider-id"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/config.js"; import { extractModelCompat } from "../plugins/provider-model-compat.js"; import type { ProviderRuntimeModel } from "../plugins/provider-runtime-model.types.js"; import { normalizeProviderTransportWithPlugin } from "../plugins/provider-runtime.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { resolveAgentDir, resolveAgentWorkspaceDir, resolveSessionAgentId } from "./agent-scope.js"; import { createOpenClawCodingTools } from "./agent-tools.js"; import { resolveEffectiveToolPolicy } from "./agent-tools.policy.js"; diff --git a/src/agents/tools-effective-mcp-inventory.ts b/src/agents/tools-effective-mcp-inventory.ts index 0cc44103fc7..730738a23e1 100644 --- a/src/agents/tools-effective-mcp-inventory.ts +++ b/src/agents/tools-effective-mcp-inventory.ts @@ -1,9 +1,9 @@ -import type { OpenClawConfig } from "../config/types.openclaw.js"; -import type { ProviderRuntimeModel } from "../plugins/provider-runtime-model.types.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { OpenClawConfig } from "../config/types.openclaw.js"; +import type { ProviderRuntimeModel } from "../plugins/provider-runtime-model.types.js"; import { normalizeAgentRuntimeTools } from "./runtime-plan/tools.js"; import { summarizeToolDescriptionText } from "./tool-description-summary.js"; import { resolveToolDisplay } from "./tool-display.js"; @@ -69,14 +69,17 @@ function buildMcpToolInventoryEntries( ): EffectiveToolInventoryEntry[] { return disambiguateLabels( tools - .map((tool) => ({ - id: tool.name, - label: resolveMcpToolLabel(tool), - description: summarizeToolDescription(tool), - rawDescription: resolveRawToolDescription(tool) || summarizeToolDescription(tool), - source: "mcp", - pluginId: BUNDLE_MCP_PLUGIN_ID, - }) satisfies EffectiveToolInventoryEntry) + .map( + (tool) => + ({ + id: tool.name, + label: resolveMcpToolLabel(tool), + description: summarizeToolDescription(tool), + rawDescription: resolveRawToolDescription(tool) || summarizeToolDescription(tool), + source: "mcp", + pluginId: BUNDLE_MCP_PLUGIN_ID, + }) satisfies EffectiveToolInventoryEntry, + ) .toSorted((a, b) => a.label.localeCompare(b.label)), ); } diff --git a/src/agents/tools/common.ts b/src/agents/tools/common.ts index db5980b631e..97690210421 100644 --- a/src/agents/tools/common.ts +++ b/src/agents/tools/common.ts @@ -1,13 +1,13 @@ -import type { TSchema } from "typebox"; -import { readLocalFileSafely } from "../../infra/fs-safe.js"; -import { detectMime } from "../../media/mime.js"; -import { readSnakeCaseParamRaw } from "../../param-key.js"; import { asPositiveSafeInteger, asSafeIntegerInRange, parseStrictFiniteNumber, -} from "../../shared/number-coercion.js"; -import { normalizeStringEntries } from "../../shared/string-normalization.js"; +} from "@openclaw/normalization-core/number-coercion"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; +import type { TSchema } from "typebox"; +import { readLocalFileSafely } from "../../infra/fs-safe.js"; +import { detectMime } from "../../media/mime.js"; +import { readSnakeCaseParamRaw } from "../../param-key.js"; import type { ImageSanitizationLimits } from "../image-sanitization.js"; import type { AgentTool, diff --git a/src/agents/tools/cron-tool.ts b/src/agents/tools/cron-tool.ts index 85124657676..70b1262eb02 100644 --- a/src/agents/tools/cron-tool.ts +++ b/src/agents/tools/cron-tool.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { Type, type TSchema } from "typebox"; import { getRuntimeConfig } from "../../config/config.js"; import { resolveCronCreationDelivery } from "../../cron/delivery-context.js"; @@ -5,7 +6,6 @@ import { normalizeCronJobCreate, normalizeCronJobPatch } from "../../cron/normal import type { CronDelivery } from "../../cron/types.js"; import { normalizeHttpWebhookUrl } from "../../cron/webhook-url.js"; import { extractTextFromChatContent } from "../../shared/chat-content.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { isRecord, truncateUtf16Safe } from "../../utils.js"; import type { DeliveryContext } from "../../utils/delivery-context.shared.js"; import { resolveSessionAgentId } from "../agent-scope.js"; diff --git a/src/agents/tools/gateway-tool.ts b/src/agents/tools/gateway-tool.ts index 8e9b03a6f84..8ed4c45c31b 100644 --- a/src/agents/tools/gateway-tool.ts +++ b/src/agents/tools/gateway-tool.ts @@ -1,4 +1,9 @@ import { isDeepStrictEqual } from "node:util"; +import { isRecord as isPlainObject } from "@openclaw/normalization-core/record-coerce"; +import { + normalizeOptionalString, + readStringValue, +} from "@openclaw/normalization-core/string-coerce"; import { Type } from "typebox"; import { isRestartEnabled } from "../../config/commands.flags.js"; import { parseConfigJson5, resolveConfigSnapshotHash } from "../../config/io.js"; @@ -15,8 +20,6 @@ import { import { scheduleGatewaySigusr1Restart } from "../../infra/restart.js"; import { createSubsystemLogger } from "../../logging/subsystem.js"; import { collectEnabledInsecureOrDangerousFlags } from "../../security/dangerous-config-flags.js"; -import { isRecord as isPlainObject } from "../../shared/record-coerce.js"; -import { normalizeOptionalString, readStringValue } from "../../shared/string-coerce.js"; import { optionalNonNegativeIntegerSchema, stringEnum } from "../schema/typebox.js"; import { type AnyAgentTool, diff --git a/src/agents/tools/gateway.ts b/src/agents/tools/gateway.ts index c0cac975fd4..123b3728726 100644 --- a/src/agents/tools/gateway.ts +++ b/src/agents/tools/gateway.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES, @@ -12,10 +16,6 @@ import { } from "../../gateway/method-scopes.js"; import { getOperatorApprovalRuntimeToken } from "../../gateway/operator-approval-runtime-token.js"; import { formatErrorMessage } from "../../infra/errors.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { readPositiveIntegerParam, readStringParam } from "./common.js"; export const DEFAULT_GATEWAY_URL = "ws://127.0.0.1:18789"; diff --git a/src/agents/tools/heartbeat-response-tool.ts b/src/agents/tools/heartbeat-response-tool.ts index 577b8a9b017..e1d6cee79ec 100644 --- a/src/agents/tools/heartbeat-response-tool.ts +++ b/src/agents/tools/heartbeat-response-tool.ts @@ -1,3 +1,4 @@ +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { Type } from "typebox"; import { HEARTBEAT_RESPONSE_TOOL_NAME, @@ -6,7 +7,6 @@ import { normalizeHeartbeatToolResponse, } from "../../auto-reply/heartbeat-tool-response.js"; import { readSnakeCaseParamRaw } from "../../param-key.js"; -import { isRecord } from "../../shared/record-coerce.js"; import { optionalStringEnum, stringEnum } from "../schema/string-enum.js"; import type { AnyAgentTool } from "./common.js"; import { jsonResult, ToolInputError } from "./common.js"; diff --git a/src/agents/tools/image-tool.helpers.ts b/src/agents/tools/image-tool.helpers.ts index e670d6d7983..dd396a2a38d 100644 --- a/src/agents/tools/image-tool.helpers.ts +++ b/src/agents/tools/image-tool.helpers.ts @@ -1,7 +1,7 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { AssistantMessage } from "../../llm/types.js"; import { estimateBase64DecodedBytes } from "../../media/base64.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { extractAssistantText } from "../embedded-agent-utils.js"; import { isMinimaxVlmProvider } from "../minimax-vlm.js"; import { findNormalizedProviderValue, normalizeProviderId } from "../model-selection.js"; diff --git a/src/agents/tools/media-tool-shared.ts b/src/agents/tools/media-tool-shared.ts index 0e47e44a55d..35a8fc34149 100644 --- a/src/agents/tools/media-tool-shared.ts +++ b/src/agents/tools/media-tool-shared.ts @@ -1,4 +1,9 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { findCapabilityProviderById, resolveCapabilityModelRefForProviders, @@ -13,11 +18,6 @@ import { getDefaultLocalRoots } from "../../media/local-media-access.js"; import { readSnakeCaseParamRaw } from "../../param-key.js"; import { loadCapabilityManifestSnapshot } from "../../plugins/capability-provider-runtime.js"; import { listAvailableManifestContractValues } from "../../plugins/manifest-contract-eligibility.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; import type { AuthProfileStore } from "../auth-profiles/types.js"; import { normalizeModelRef } from "../model-selection.js"; import { diff --git a/src/agents/tools/message-tool.ts b/src/agents/tools/message-tool.ts index 983a5ab6c5c..550edd0aad2 100644 --- a/src/agents/tools/message-tool.ts +++ b/src/agents/tools/message-tool.ts @@ -1,3 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { sortUniqueStrings, uniqueValues } from "@openclaw/normalization-core/string-normalization"; import { Type, type TSchema } from "typebox"; import { GATEWAY_CLIENT_IDS, @@ -34,8 +36,6 @@ import { parseAgentSessionKey, parseThreadSessionSuffix, } from "../../routing/session-key.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; -import { sortUniqueStrings, uniqueValues } from "../../shared/string-normalization.js"; import { stripFormattedReasoningMessage } from "../../shared/text/formatted-reasoning-message.js"; import { normalizeMessageChannel } from "../../utils/message-channel.js"; import { resolveSessionAgentId } from "../agent-scope.js"; diff --git a/src/agents/tools/music-generate-tool.ts b/src/agents/tools/music-generate-tool.ts index 3db0f17c033..2c42e9cfeb7 100644 --- a/src/agents/tools/music-generate-tool.ts +++ b/src/agents/tools/music-generate-tool.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { Type } from "typebox"; import { getRuntimeConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; @@ -22,7 +23,6 @@ import type { MusicGenerationSourceImage, } from "../../music-generation/types.js"; import { readSnakeCaseParamRaw } from "../../param-key.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { resolveUserPath } from "../../utils.js"; import type { DeliveryContext } from "../../utils/delivery-context.js"; import { buildTimeoutAbortSignal } from "../../utils/fetch-timeout.js"; diff --git a/src/agents/tools/nodes-tool-commands.ts b/src/agents/tools/nodes-tool-commands.ts index 3b9c64565ec..5d615b53035 100644 --- a/src/agents/tools/nodes-tool-commands.ts +++ b/src/agents/tools/nodes-tool-commands.ts @@ -1,6 +1,6 @@ import crypto from "node:crypto"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { formatErrorMessage } from "../../infra/errors.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { jsonResult, readNonNegativeIntegerParam, diff --git a/src/agents/tools/nodes-tool-media.ts b/src/agents/tools/nodes-tool-media.ts index 125c1ed1433..efba2d3f0dd 100644 --- a/src/agents/tools/nodes-tool-media.ts +++ b/src/agents/tools/nodes-tool-media.ts @@ -1,4 +1,5 @@ import crypto from "node:crypto"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { type CameraFacing, cameraTempPath, @@ -14,7 +15,6 @@ import { } from "../../cli/nodes-screen.js"; import { parseDurationMs } from "../../cli/parse-duration.js"; import { imageMimeFromFormat } from "../../media/mime.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import type { ImageSanitizationLimits } from "../image-sanitization.js"; import type { AgentToolResult } from "../runtime/index.js"; import { sanitizeToolResultImages } from "../tool-images.js"; diff --git a/src/agents/tools/nodes-utils.ts b/src/agents/tools/nodes-utils.ts index b67915706be..2a0a0032d12 100644 --- a/src/agents/tools/nodes-utils.ts +++ b/src/agents/tools/nodes-utils.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { parseNodeList, parsePairingList } from "../../shared/node-list-parse.js"; import type { NodeListNode } from "../../shared/node-list-types.js"; import { resolveNodeFromNodeList, resolveNodeIdFromNodeList } from "../../shared/node-resolve.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { callGatewayTool, type GatewayCallOptions } from "./gateway.js"; export type { NodeListNode }; diff --git a/src/agents/tools/pdf-tool.ts b/src/agents/tools/pdf-tool.ts index 1807c5f35fb..133a3369230 100644 --- a/src/agents/tools/pdf-tool.ts +++ b/src/agents/tools/pdf-tool.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { Type } from "typebox"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { complete } from "../../llm/stream.js"; @@ -8,10 +12,6 @@ import { } from "../../media/media-reference.js"; import { extractPdfContent, type PdfExtractedContent } from "../../media/pdf-extract.js"; import { loadWebMediaRaw } from "../../media/web-media.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { resolveUserPath } from "../../utils.js"; import type { AuthProfileStore } from "../auth-profiles/types.js"; import { optionalFiniteNumberSchema } from "../schema/typebox.js"; diff --git a/src/agents/tools/session-status-tool.ts b/src/agents/tools/session-status-tool.ts index b19a47b3c8d..c33ed6455e5 100644 --- a/src/agents/tools/session-status-tool.ts +++ b/src/agents/tools/session-status-tool.ts @@ -1,3 +1,4 @@ +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { Type } from "typebox"; import type { ElevatedLevel, @@ -25,7 +26,6 @@ import { } from "../../routing/session-key.js"; import { applyModelOverrideToSessionEntry } from "../../sessions/model-overrides.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; import type { BuildStatusTextParams } from "../../status/status-text.types.js"; import { buildTaskStatusSnapshotForRelatedSessionKeyForOwner } from "../../tasks/task-owner-access.js"; import { formatTaskStatusDetail, formatTaskStatusTitle } from "../../tasks/task-status.js"; diff --git a/src/agents/tools/sessions-access.ts b/src/agents/tools/sessions-access.ts index dcab1a1e66a..0f92c078929 100644 --- a/src/agents/tools/sessions-access.ts +++ b/src/agents/tools/sessions-access.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { resolveSandboxSessionToolsVisibility } from "../../plugin-sdk/session-visibility.js"; import { isSubagentSessionKey } from "../../routing/session-key.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { resolveInternalSessionKey, resolveMainSessionAlias } from "./sessions-resolution.js"; export { diff --git a/src/agents/tools/sessions-announce-target.ts b/src/agents/tools/sessions-announce-target.ts index 095bb39c5c9..6ab0e5bfed0 100644 --- a/src/agents/tools/sessions-announce-target.ts +++ b/src/agents/tools/sessions-announce-target.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalStringifiedId } from "@openclaw/normalization-core/string-coerce"; import { getChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js"; import type { CallGatewayOptions } from "../../gateway/call.js"; import { parseThreadSessionSuffix } from "../../sessions/session-key-utils.js"; -import { normalizeOptionalStringifiedId } from "../../shared/string-coerce.js"; import { deliveryContextFromSession } from "../../utils/delivery-context.shared.js"; import type { SessionListRow } from "./sessions-helpers.js"; import type { AnnounceTarget } from "./sessions-send-helpers.js"; diff --git a/src/agents/tools/sessions-helpers.ts b/src/agents/tools/sessions-helpers.ts index f05e5d4e5f7..8aca55ffc6f 100644 --- a/src/agents/tools/sessions-helpers.ts +++ b/src/agents/tools/sessions-helpers.ts @@ -20,9 +20,9 @@ export { sanitizeTextContent, stripToolMessages, } from "./chat-history-text.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { getRuntimeConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; export type SessionKind = "main" | "group" | "cron" | "hook" | "node" | "other"; diff --git a/src/agents/tools/sessions-history-tool.ts b/src/agents/tools/sessions-history-tool.ts index a66c709e277..8f85ef42df6 100644 --- a/src/agents/tools/sessions-history-tool.ts +++ b/src/agents/tools/sessions-history-tool.ts @@ -1,3 +1,4 @@ +import { readStringValue } from "@openclaw/normalization-core/string-coerce"; import { Type } from "typebox"; import { getRuntimeConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; @@ -5,7 +6,6 @@ import { callGateway } from "../../gateway/call.js"; import { capArrayByJsonBytes } from "../../gateway/session-utils.fs.js"; import { jsonUtf8Bytes } from "../../infra/json-utf8-bytes.js"; import { redactToolPayloadText } from "../../logging/redact.js"; -import { readStringValue } from "../../shared/string-coerce.js"; import { truncateUtf16Safe } from "../../utils.js"; import { optionalPositiveIntegerSchema } from "../schema/typebox.js"; import { diff --git a/src/agents/tools/sessions-list-tool.ts b/src/agents/tools/sessions-list-tool.ts index 40241b11367..10bf58ccea4 100644 --- a/src/agents/tools/sessions-list-tool.ts +++ b/src/agents/tools/sessions-list-tool.ts @@ -1,4 +1,8 @@ import path from "node:path"; +import { + normalizeOptionalLowercaseString, + readStringValue, +} from "@openclaw/normalization-core/string-coerce"; import { Type } from "typebox"; import { getRuntimeConfig } from "../../config/config.js"; import { @@ -14,7 +18,6 @@ import { readSessionTitleFieldsFromTranscriptAsync, } from "../../gateway/session-utils.js"; import { resolveAgentIdFromSessionKey } from "../../routing/session-key.js"; -import { normalizeOptionalLowercaseString, readStringValue } from "../../shared/string-coerce.js"; import { deliveryContextFromSession } from "../../utils/delivery-context.shared.js"; import { optionalNonNegativeIntegerSchema, diff --git a/src/agents/tools/sessions-resolution.ts b/src/agents/tools/sessions-resolution.ts index c3176697db7..ebd5c453caa 100644 --- a/src/agents/tools/sessions-resolution.ts +++ b/src/agents/tools/sessions-resolution.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { GATEWAY_CLIENT_IDS, normalizeGatewayClientId, @@ -11,7 +12,6 @@ import { } from "../../plugin-sdk/session-visibility.js"; import { isAcpSessionKey, normalizeMainKey } from "../../routing/session-key.js"; import { looksLikeSessionId } from "../../sessions/session-id.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; type GatewayCaller = typeof callGateway; diff --git a/src/agents/tools/sessions-send-tool.ts b/src/agents/tools/sessions-send-tool.ts index 65eb695ba10..c0082de6397 100644 --- a/src/agents/tools/sessions-send-tool.ts +++ b/src/agents/tools/sessions-send-tool.ts @@ -1,4 +1,6 @@ import crypto from "node:crypto"; +import { finiteSecondsToTimerSafeMilliseconds } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { Type } from "typebox"; import { isRequesterParentOfBackgroundAcpSession } from "../../acp/session-interaction-mode.js"; import { parseSessionThreadInfoFast } from "../../config/sessions/thread-info.js"; @@ -14,8 +16,6 @@ import { } from "../../routing/session-key.js"; import { annotateInterSessionPromptText } from "../../sessions/input-provenance.js"; import { SESSION_LABEL_MAX_LENGTH } from "../../sessions/session-label.js"; -import { finiteSecondsToTimerSafeMilliseconds } from "../../shared/number-coercion.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { stripFormattedReasoningMessage } from "../../shared/text/formatted-reasoning-message.js"; import { type GatewayMessageChannel, diff --git a/src/agents/tools/sessions.test.ts b/src/agents/tools/sessions.test.ts index cf0ccb6ad4f..408207f2343 100644 --- a/src/agents/tools/sessions.test.ts +++ b/src/agents/tools/sessions.test.ts @@ -1,8 +1,8 @@ import os from "node:os"; import path from "node:path"; +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import type { ChannelMessagingAdapter } from "../../channels/plugins/types.js"; -import { MAX_TIMER_TIMEOUT_MS } from "../../shared/number-coercion.js"; import { createTestRegistry } from "../../test-utils/channel-plugins.js"; import { extractAssistantText, sanitizeTextContent } from "./sessions-helpers.js"; diff --git a/src/agents/tools/transcripts-tool.ts b/src/agents/tools/transcripts-tool.ts index 20e96f65930..a3952d6abaa 100644 --- a/src/agents/tools/transcripts-tool.ts +++ b/src/agents/tools/transcripts-tool.ts @@ -1,9 +1,9 @@ import { randomUUID } from "node:crypto"; import path from "node:path"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { Type } from "typebox"; import { resolveStateDir } from "../../config/paths.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; import { type ResolvedTranscriptsAutoStartConfig, resolveTranscriptsConfig, diff --git a/src/agents/tools/web-fetch-visibility.ts b/src/agents/tools/web-fetch-visibility.ts index 45350644299..9af428fa5df 100644 --- a/src/agents/tools/web-fetch-visibility.ts +++ b/src/agents/tools/web-fetch-visibility.ts @@ -1,7 +1,7 @@ import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; // CSS property values that indicate an element is hidden const HIDDEN_STYLE_PATTERNS: Array<[string, RegExp]> = [ diff --git a/src/agents/tools/web-fetch.test-harness.ts b/src/agents/tools/web-fetch.test-harness.ts index 86ba6301982..c0e54c0acf5 100644 --- a/src/agents/tools/web-fetch.test-harness.ts +++ b/src/agents/tools/web-fetch.test-harness.ts @@ -1,5 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { LookupFn } from "../../infra/net/ssrf.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; export function makeFetchHeaders(map: Record): { get: (key: string) => string | null; diff --git a/src/agents/tools/web-fetch.ts b/src/agents/tools/web-fetch.ts index 55b1c48c1fb..b4de1b90d9b 100644 --- a/src/agents/tools/web-fetch.ts +++ b/src/agents/tools/web-fetch.ts @@ -1,3 +1,8 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { Type } from "typebox"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { SsrFBlockedError, type LookupFn, type SsrFPolicy } from "../../infra/net/ssrf.js"; @@ -5,11 +10,6 @@ import { logDebug } from "../../logger.js"; import type { RuntimeWebFetchMetadata } from "../../secrets/runtime-web-tools.types.js"; import { wrapExternalContent, wrapWebContent } from "../../security/external-content.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { isRecord } from "../../utils.js"; import { extractReadableContent } from "../../web-fetch/content-extractors.runtime.js"; import { resolveWebProviderConfig } from "../../web/provider-runtime-shared.js"; diff --git a/src/agents/tools/web-guarded-fetch.test.ts b/src/agents/tools/web-guarded-fetch.test.ts index f1ed2ecf4a6..85167aec293 100644 --- a/src/agents/tools/web-guarded-fetch.test.ts +++ b/src/agents/tools/web-guarded-fetch.test.ts @@ -1,6 +1,6 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, describe, expect, it, vi } from "vitest"; import { fetchWithSsrFGuard, GUARDED_FETCH_MODE } from "../../infra/net/fetch-guard.js"; -import { MAX_TIMER_TIMEOUT_MS } from "../../shared/number-coercion.js"; import { withSelfHostedWebToolsEndpoint, withStrictWebToolsEndpoint, diff --git a/src/agents/tools/web-guarded-fetch.ts b/src/agents/tools/web-guarded-fetch.ts index c9a15a567dd..d6cb1e7f059 100644 --- a/src/agents/tools/web-guarded-fetch.ts +++ b/src/agents/tools/web-guarded-fetch.ts @@ -1,3 +1,4 @@ +import { finiteSecondsToTimerSafeMilliseconds } from "@openclaw/normalization-core/number-coercion"; import { fetchWithSsrFGuard, type GuardedFetchOptions, @@ -9,7 +10,6 @@ import { ssrfPolicyFromHttpBaseUrlFakeIpHostnameAllowlist, type SsrFPolicy, } from "../../infra/net/ssrf.js"; -import { finiteSecondsToTimerSafeMilliseconds } from "../../shared/number-coercion.js"; import { readPositiveIntegerParam } from "./common.js"; const WEB_TOOLS_SELF_HOSTED_NETWORK_SSRF_POLICY: SsrFPolicy = { diff --git a/src/agents/tools/web-search-provider-common.ts b/src/agents/tools/web-search-provider-common.ts index 0bf1bce39dc..1db030bd997 100644 --- a/src/agents/tools/web-search-provider-common.ts +++ b/src/agents/tools/web-search-provider-common.ts @@ -1,7 +1,7 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { normalizeResolvedSecretInputString } from "../../config/types.secrets.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { normalizeSecretInput } from "../../utils/normalize-secret-input.js"; import { DEFAULT_CACHE_TTL_MINUTES, diff --git a/src/agents/tools/web-shared.test.ts b/src/agents/tools/web-shared.test.ts index af6902c85fc..b78c1b2a515 100644 --- a/src/agents/tools/web-shared.test.ts +++ b/src/agents/tools/web-shared.test.ts @@ -1,5 +1,5 @@ +import { MAX_TIMER_TIMEOUT_SECONDS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_SECONDS } from "../../shared/number-coercion.js"; import { readCache, resolvePositiveTimeoutSeconds, diff --git a/src/agents/tools/web-shared.ts b/src/agents/tools/web-shared.ts index e732910d0b1..f73d6a906d1 100644 --- a/src/agents/tools/web-shared.ts +++ b/src/agents/tools/web-shared.ts @@ -2,8 +2,8 @@ import { asDateTimestampMs, MAX_TIMER_TIMEOUT_SECONDS, resolveExpiresAtMsFromDurationMs, -} from "../../shared/number-coercion.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/number-coercion"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export type CacheEntry = { value: T; diff --git a/src/agents/transcript-policy.ts b/src/agents/transcript-policy.ts index 912ed0cefe2..5cabe2bba74 100644 --- a/src/agents/transcript-policy.ts +++ b/src/agents/transcript-policy.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { resolvePluginControlPlaneFingerprint } from "../plugins/plugin-control-plane-context.js"; import type { ProviderRuntimePluginHandle } from "../plugins/provider-hook-runtime.js"; @@ -5,7 +6,6 @@ import { resolveProviderRuntimePlugin } from "../plugins/provider-hook-runtime.j import { shouldPreserveThinkingBlocks } from "../plugins/provider-replay-helpers.js"; import type { ProviderRuntimeModel } from "../plugins/provider-runtime-model.types.js"; import type { ProviderReplayPolicy } from "../plugins/types.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { isGoogleModelApi } from "./embedded-agent-helpers/google.js"; import { normalizeProviderId } from "./model-selection.js"; import type { ToolCallIdMode } from "./tool-call-id.js"; diff --git a/src/agents/usage.ts b/src/agents/usage.ts index bfeec32a839..b0a32e6961d 100644 --- a/src/agents/usage.ts +++ b/src/agents/usage.ts @@ -1,4 +1,4 @@ -import { asFiniteNumber } from "../shared/number-coercion.js"; +import { asFiniteNumber } from "@openclaw/normalization-core/number-coercion"; export type UsageLike = { input?: number; diff --git a/src/agents/workspace-default.ts b/src/agents/workspace-default.ts index 2b0632afad9..881e77b9572 100644 --- a/src/agents/workspace-default.ts +++ b/src/agents/workspace-default.ts @@ -1,7 +1,7 @@ import os from "node:os"; import path from "node:path"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { resolveRequiredHomeDir } from "../infra/home-dir.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; export function resolveDefaultAgentWorkspaceDir( env: NodeJS.ProcessEnv = process.env, diff --git a/src/agents/workspace.ts b/src/agents/workspace.ts index 780dd4d7903..d7e0027a2e7 100644 --- a/src/agents/workspace.ts +++ b/src/agents/workspace.ts @@ -1,6 +1,7 @@ import syncFs from "node:fs"; import fs from "node:fs/promises"; import path from "node:path"; +import { readStringValue } from "@openclaw/normalization-core/string-coerce"; import { openRootFile } from "../infra/boundary-file-read.js"; import { pathExists } from "../infra/fs-safe.js"; import { replaceFileAtomic } from "../infra/replace-file.js"; @@ -10,7 +11,6 @@ import { } from "../memory/root-memory-files.js"; import { runCommandWithTimeout } from "../process/exec.js"; import { isCronSessionKey, isSubagentSessionKey } from "../routing/session-key.js"; -import { readStringValue } from "../shared/string-coerce.js"; import { resolveUserPath } from "../utils.js"; import { DEFAULT_AGENT_WORKSPACE_DIR } from "./workspace-default.js"; import { diff --git a/src/auto-reply/command-auth.ts b/src/auto-reply/command-auth.ts index 68dd263c270..462126bc29c 100644 --- a/src/auto-reply/command-auth.ts +++ b/src/auto-reply/command-auth.ts @@ -1,3 +1,9 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { getLoadedChannelPluginById, listLoadedChannelPlugins, @@ -6,12 +12,6 @@ import type { ChannelPlugin } from "../channels/plugins/types.plugin.js"; import type { ChannelId } from "../channels/plugins/types.public.js"; import { normalizeAnyChannelId } from "../channels/registry.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { INTERNAL_MESSAGE_CHANNEL, isInternalMessageChannel, diff --git a/src/auto-reply/command-detection.ts b/src/auto-reply/command-detection.ts index d64d8cc1569..11f3894120d 100644 --- a/src/auto-reply/command-detection.ts +++ b/src/auto-reply/command-detection.ts @@ -1,8 +1,8 @@ -import type { OpenClawConfig } from "../config/types.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { OpenClawConfig } from "../config/types.js"; import { listChatCommands, listChatCommandsForConfig } from "./commands-registry-list.js"; import { normalizeCommandBody } from "./commands-registry-normalize.js"; import type { CommandNormalizeOptions } from "./commands-registry.types.js"; diff --git a/src/auto-reply/command-status-builders.ts b/src/auto-reply/command-status-builders.ts index 19deef24f6c..fb19db4c337 100644 --- a/src/auto-reply/command-status-builders.ts +++ b/src/auto-reply/command-status-builders.ts @@ -1,12 +1,12 @@ -import { getChannelPlugin } from "../channels/plugins/index.js"; -import { isCommandFlagEnabled } from "../config/commands.flags.js"; -import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { listPluginCommands } from "../plugins/commands.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { getChannelPlugin } from "../channels/plugins/index.js"; +import { isCommandFlagEnabled } from "../config/commands.flags.js"; +import type { OpenClawConfig } from "../config/types.openclaw.js"; +import { listPluginCommands } from "../plugins/commands.js"; import type { SkillCommandSpec } from "../skills/types.js"; import { listChatCommands, diff --git a/src/auto-reply/command-turn-context.ts b/src/auto-reply/command-turn-context.ts index 6352a30d1db..497184f7549 100644 --- a/src/auto-reply/command-turn-context.ts +++ b/src/auto-reply/command-turn-context.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export type CommandTurnKind = "native" | "text-slash" | "normal"; export type CommandTurnSource = "native" | "text" | "message"; diff --git a/src/auto-reply/command-turn-detection.ts b/src/auto-reply/command-turn-detection.ts index 9490acdc57f..ac6b993bb87 100644 --- a/src/auto-reply/command-turn-detection.ts +++ b/src/auto-reply/command-turn-detection.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { isControlCommandMessage } from "./command-detection.js"; import { isExplicitCommandTurn, diff --git a/src/auto-reply/commands-args.ts b/src/auto-reply/commands-args.ts index c4032eeef8a..6e412d6444d 100644 --- a/src/auto-reply/commands-args.ts +++ b/src/auto-reply/commands-args.ts @@ -1,7 +1,7 @@ import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "../../packages/normalization-core/src/string-coerce.js"; import type { CommandArgValues } from "./commands-registry.types.js"; type CommandArgsFormatter = (values: CommandArgValues) => string | undefined; diff --git a/src/auto-reply/commands-registry-normalize.ts b/src/auto-reply/commands-registry-normalize.ts index eb3f0b94d28..628f914fd40 100644 --- a/src/auto-reply/commands-registry-normalize.ts +++ b/src/auto-reply/commands-registry-normalize.ts @@ -1,9 +1,9 @@ -import type { OpenClawConfig } from "../config/types.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { OpenClawConfig } from "../config/types.js"; import { escapeRegExp } from "../utils.js"; import { getChatCommands } from "./commands-registry.data.js"; import type { diff --git a/src/auto-reply/commands-registry.shared.ts b/src/auto-reply/commands-registry.shared.ts index 75d8ed10bd6..5cb93e79eea 100644 --- a/src/auto-reply/commands-registry.shared.ts +++ b/src/auto-reply/commands-registry.shared.ts @@ -1,5 +1,5 @@ -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; +import { normalizeOptionalLowercaseString } from "../../packages/normalization-core/src/string-coerce.js"; +import { normalizeStringEntries } from "../../packages/normalization-core/src/string-normalization.js"; import { COMMAND_ARG_FORMATTERS } from "./commands-args.js"; import type { ChatCommandDefinition, diff --git a/src/auto-reply/commands-registry.ts b/src/auto-reply/commands-registry.ts index 42cd53c9777..4cddcedd97f 100644 --- a/src/auto-reply/commands-registry.ts +++ b/src/auto-reply/commands-registry.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../agents/defaults.js"; import { buildConfiguredModelCatalog, @@ -5,7 +6,6 @@ import { } from "../agents/model-selection.js"; import { getChannelPlugin, getLoadedChannelPlugin } from "../channels/plugins/index.js"; import type { OpenClawConfig } from "../config/types.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import type { SkillCommandSpec } from "../skills/types.js"; import { listChatCommands, listChatCommandsForConfig } from "./commands-registry-list.js"; import { normalizeCommandBody } from "./commands-registry-normalize.js"; diff --git a/src/auto-reply/commands-text-routing.ts b/src/auto-reply/commands-text-routing.ts index 250cbd20ae1..889f79e344e 100644 --- a/src/auto-reply/commands-text-routing.ts +++ b/src/auto-reply/commands-text-routing.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { listChannelPlugins } from "../channels/plugins/index.js"; import { getActivePluginChannelRegistryVersion, requireActivePluginChannelRegistry, } from "../plugins/runtime.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import type { ShouldHandleTextCommandsParams } from "./commands-registry.types.js"; let cachedNativeCommandSurfaces: Set | null = null; diff --git a/src/auto-reply/envelope.ts b/src/auto-reply/envelope.ts index fbac44885a5..8feeef7c17a 100644 --- a/src/auto-reply/envelope.ts +++ b/src/auto-reply/envelope.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveUserTimezone } from "../agents/date-time.js"; import { normalizeChatType } from "../channels/chat-type.js"; import { resolveSenderLabel, type SenderLabelParams } from "../channels/sender-label.js"; @@ -8,10 +12,6 @@ import { formatZonedTimestamp, } from "../infra/format-time/format-datetime.ts"; import { formatTimeAgo } from "../infra/format-time/format-relative.ts"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; type AgentEnvelopeParams = { channel: string; diff --git a/src/auto-reply/fallback-state.ts b/src/auto-reply/fallback-state.ts index 19924bedcc1..f8f8a3a50e0 100644 --- a/src/auto-reply/fallback-state.ts +++ b/src/auto-reply/fallback-state.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { formatRawAssistantErrorForUi } from "../agents/embedded-agent-helpers.js"; import { areRuntimeModelRefsEquivalent } from "../agents/model-runtime-aliases.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { FallbackNoticeState } from "../status/fallback-notice-state.js"; import { formatProviderModelRef } from "./model-runtime.js"; import type { RuntimeFallbackAttempt } from "./reply/agent-runner-execution.js"; diff --git a/src/auto-reply/group-activation.ts b/src/auto-reply/group-activation.ts index 8fb7a77b15b..75dc810067b 100644 --- a/src/auto-reply/group-activation.ts +++ b/src/auto-reply/group-activation.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; export type GroupActivationMode = "mention" | "always"; diff --git a/src/auto-reply/heartbeat-filter.ts b/src/auto-reply/heartbeat-filter.ts index 85ecec5189e..8477fafcc90 100644 --- a/src/auto-reply/heartbeat-filter.ts +++ b/src/auto-reply/heartbeat-filter.ts @@ -1,6 +1,6 @@ -import { isRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalString as readString } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString as readString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { HEARTBEAT_RESPONSE_TOOL_NAME } from "./heartbeat-tool-response.js"; import { HEARTBEAT_RESPONSE_TOOL_PROMPT, diff --git a/src/auto-reply/heartbeat-tool-response.ts b/src/auto-reply/heartbeat-tool-response.ts index d95f2f2a353..cdfab82ec93 100644 --- a/src/auto-reply/heartbeat-tool-response.ts +++ b/src/auto-reply/heartbeat-tool-response.ts @@ -1,5 +1,5 @@ -import { isRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalString as readString } from "../shared/string-coerce.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString as readString } from "@openclaw/normalization-core/string-coerce"; import type { ReplyPayload } from "./reply-payload.js"; import { HEARTBEAT_TOKEN } from "./tokens.js"; diff --git a/src/auto-reply/heartbeat.ts b/src/auto-reply/heartbeat.ts index e26e5cc5057..cf8499f09ed 100644 --- a/src/auto-reply/heartbeat.ts +++ b/src/auto-reply/heartbeat.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { parseDurationMs } from "../cli/parse-duration.js"; import { escapeRegExp } from "../shared/regexp.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { HEARTBEAT_TOKEN } from "./tokens.js"; export type HeartbeatTask = { diff --git a/src/auto-reply/media-note.ts b/src/auto-reply/media-note.ts index 5efc0efa961..6c8950a964f 100644 --- a/src/auto-reply/media-note.ts +++ b/src/auto-reply/media-note.ts @@ -1,6 +1,6 @@ import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { getMediaDir } from "../media/store.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import type { MsgContext } from "./templating.js"; function stripDarwinPrivatePrefix(value: string): string { diff --git a/src/auto-reply/model-runtime.ts b/src/auto-reply/model-runtime.ts index f12b07b3cd9..1c65a4d96a9 100644 --- a/src/auto-reply/model-runtime.ts +++ b/src/auto-reply/model-runtime.ts @@ -1,8 +1,8 @@ -import type { SessionEntry } from "../config/sessions.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { SessionEntry } from "../config/sessions.js"; export function formatProviderModelRef(providerRaw: string, modelRaw: string): string { const provider = normalizeOptionalString(providerRaw) ?? ""; diff --git a/src/auto-reply/model.ts b/src/auto-reply/model.ts index 41d27c584a5..77ee029331c 100644 --- a/src/auto-reply/model.ts +++ b/src/auto-reply/model.ts @@ -1,5 +1,5 @@ +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { splitTrailingAuthProfile } from "../agents/model-ref-profile.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { escapeRegExp } from "../utils.js"; export function extractModelDirective( diff --git a/src/auto-reply/reply.directive.directive-behavior.e2e-harness.ts b/src/auto-reply/reply.directive.directive-behavior.e2e-harness.ts index a5feffc1908..387bf2ac755 100644 --- a/src/auto-reply/reply.directive.directive-behavior.e2e-harness.ts +++ b/src/auto-reply/reply.directive.directive-behavior.e2e-harness.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { afterEach, beforeEach, vi } from "vitest"; import { clearRuntimeAuthProfileStoreSnapshots } from "../agents/auth-profiles.js"; import { clearSessionStoreCacheForTest } from "../config/sessions.js"; @@ -6,7 +7,6 @@ import { createEmptyPluginRegistry } from "../plugins/registry-empty.js"; import type { PluginProviderRegistration } from "../plugins/registry.js"; import { resetPluginRuntimeStateForTest, setActivePluginRegistry } from "../plugins/runtime.js"; import type { ProviderPlugin } from "../plugins/types.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { resetSkillsRefreshForTest } from "../skills/runtime/refresh.js"; import { clearSessionAuthProfileOverrideMock, diff --git a/src/auto-reply/reply/abort-cutoff.ts b/src/auto-reply/reply/abort-cutoff.ts index ff29cd5805b..2b5a425cbdf 100644 --- a/src/auto-reply/reply/abort-cutoff.ts +++ b/src/auto-reply/reply/abort-cutoff.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { SessionEntry } from "../../config/sessions/types.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { MsgContext } from "../templating.js"; export type AbortCutoff = { diff --git a/src/auto-reply/reply/abort-primitives.ts b/src/auto-reply/reply/abort-primitives.ts index 496580de692..b89ce63ca0c 100644 --- a/src/auto-reply/reply/abort-primitives.ts +++ b/src/auto-reply/reply/abort-primitives.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { normalizeCommandBody } from "../commands-registry-normalize.js"; import type { CommandNormalizeOptions } from "../commands-registry.types.js"; diff --git a/src/auto-reply/reply/abort.ts b/src/auto-reply/reply/abort.ts index 38814477a6e..d6dcc0423fd 100644 --- a/src/auto-reply/reply/abort.ts +++ b/src/auto-reply/reply/abort.ts @@ -1,3 +1,7 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { getAcpSessionManager } from "../../acp/control-plane/manager.js"; import { resolveSessionAgentId } from "../../agents/agent-scope.js"; import { @@ -25,10 +29,6 @@ import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { logVerbose } from "../../globals.js"; import { formatErrorMessage } from "../../infra/errors.js"; import { isAcpSessionKey, parseAgentSessionKey } from "../../routing/session-key.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { resolveCommandAuthorization } from "../command-auth.js"; import type { FinalizedMsgContext } from "../templating.js"; import { diff --git a/src/auto-reply/reply/acp-projector.ts b/src/auto-reply/reply/acp-projector.ts index 8de6488e78d..44735084fe6 100644 --- a/src/auto-reply/reply/acp-projector.ts +++ b/src/auto-reply/reply/acp-projector.ts @@ -1,12 +1,12 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { AcpRuntimeEvent, AcpSessionUpdateTag } from "../../acp/runtime/types.js"; import { EmbeddedBlockChunker } from "../../agents/embedded-agent-block-chunker.js"; import { formatToolSummary, resolveToolDisplay } from "../../agents/tool-display.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { prefixSystemMessage } from "../../infra/system-message.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import type { ReplyPayload } from "../types.js"; import { type AcpHiddenBoundarySeparator, diff --git a/src/auto-reply/reply/acp-reset-target.ts b/src/auto-reply/reply/acp-reset-target.ts index bd6658836dd..86ba04238b9 100644 --- a/src/auto-reply/reply/acp-reset-target.ts +++ b/src/auto-reply/reply/acp-reset-target.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { buildConfiguredAcpSessionKey, normalizeBindingConfig, @@ -8,10 +12,6 @@ import { listAcpBindings } from "../../config/bindings.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { getSessionBindingService } from "../../infra/outbound/session-binding-service.js"; import { DEFAULT_ACCOUNT_ID, isAcpSessionKey } from "../../routing/session-key.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; const acpResetTargetDeps = { getSessionBindingService, diff --git a/src/auto-reply/reply/agent-runner-cli-dispatch.ts b/src/auto-reply/reply/agent-runner-cli-dispatch.ts index 5b9e25a708f..75a45d7de4d 100644 --- a/src/auto-reply/reply/agent-runner-cli-dispatch.ts +++ b/src/auto-reply/reply/agent-runner-cli-dispatch.ts @@ -1,3 +1,8 @@ +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { runCliAgent } from "../../agents/cli-runner.js"; import type { RunCliAgentParams } from "../../agents/cli-runner/types.js"; import { clearCliSession } from "../../agents/cli-session.js"; @@ -5,11 +10,6 @@ import type { EmbeddedAgentRunResult } from "../../agents/embedded-agent.js"; import { updateSessionStore, type SessionEntry } from "../../config/sessions.js"; import type { AgentEventPayload } from "../../infra/agent-events.js"; import { emitAgentEvent, onAgentEvent } from "../../infra/agent-events.js"; -import { isRecord } from "../../shared/record-coerce.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; function shouldBridgeCliAssistantTextToReasoning(provider: string): boolean { return normalizeLowercaseStringOrEmpty(provider) === "claude-cli"; diff --git a/src/auto-reply/reply/agent-runner-execution.ts b/src/auto-reply/reply/agent-runner-execution.ts index 9f5862c312d..c7146e8a901 100644 --- a/src/auto-reply/reply/agent-runner-execution.ts +++ b/src/auto-reply/reply/agent-runner-execution.ts @@ -1,4 +1,10 @@ import crypto from "node:crypto"; +import { + hasNonEmptyString, + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, + readStringValue, +} from "@openclaw/normalization-core/string-coerce"; import { hasOutboundReplyContent, resolveSendableOutboundReplyParts, @@ -61,12 +67,6 @@ import { CommandLaneClearedError, GatewayDrainingError } from "../../process/com import { CommandLane } from "../../process/lanes.js"; import { defaultRuntime } from "../../runtime.js"; import { shouldPreserveUserFacingSessionStateForInputProvenance } from "../../sessions/input-provenance.js"; -import { - hasNonEmptyString, - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, - readStringValue, -} from "../../shared/string-coerce.js"; import { isMarkdownCapableMessageChannel, resolveMessageChannel, diff --git a/src/auto-reply/reply/agent-runner-memory.ts b/src/auto-reply/reply/agent-runner-memory.ts index 6efebc56c23..2fd8038797d 100644 --- a/src/auto-reply/reply/agent-runner-memory.ts +++ b/src/auto-reply/reply/agent-runner-memory.ts @@ -1,6 +1,10 @@ import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveBootstrapWarningSignaturesSeen } from "../../agents/bootstrap-budget.js"; import { estimateMessagesTokens } from "../../agents/compaction.js"; import { @@ -39,10 +43,6 @@ import { isAbortError } from "../../infra/unhandled-rejections.js"; import { resolveMemoryFlushPlan } from "../../plugins/memory-state.js"; import { CommandLane } from "../../process/lanes.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import type { TemplateContext } from "../templating.js"; import type { VerboseLevel } from "../thinking.js"; import type { GetReplyOptions, ReplyPayload } from "../types.js"; diff --git a/src/auto-reply/reply/agent-runner-reminder-guard.ts b/src/auto-reply/reply/agent-runner-reminder-guard.ts index b861c920813..d219e9ef8db 100644 --- a/src/auto-reply/reply/agent-runner-reminder-guard.ts +++ b/src/auto-reply/reply/agent-runner-reminder-guard.ts @@ -1,5 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { loadCronStore, resolveCronStorePath } from "../../cron/store.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import type { ReplyPayload } from "../types.js"; const UNSCHEDULED_REMINDER_NOTE = diff --git a/src/auto-reply/reply/agent-runner-utils.ts b/src/auto-reply/reply/agent-runner-utils.ts index 6b3e83fd0b7..bde9793a347 100644 --- a/src/auto-reply/reply/agent-runner-utils.ts +++ b/src/auto-reply/reply/agent-runner-utils.ts @@ -1,3 +1,7 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { getChannelPlugin } from "../../channels/plugins/index.js"; import type { ChannelId, @@ -16,10 +20,6 @@ import { selectApplicableRuntimeConfig, type OpenClawConfig, } from "../../config/config.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { isReasoningTagProvider } from "../../utils/provider-utils.js"; import type { TemplateContext } from "../templating.js"; import { diff --git a/src/auto-reply/reply/agent-runner.ts b/src/auto-reply/reply/agent-runner.ts index dde4d52ec4c..188b63fd933 100644 --- a/src/auto-reply/reply/agent-runner.ts +++ b/src/auto-reply/reply/agent-runner.ts @@ -1,5 +1,6 @@ import crypto from "node:crypto"; import fs from "node:fs/promises"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { hasSessionAutoModelFallbackProvenance, hasConfiguredModelFallbacks, @@ -40,7 +41,6 @@ import { enqueueSystemEvent } from "../../infra/system-events.js"; import { CommandLaneClearedError, GatewayDrainingError } from "../../process/command-queue.js"; import { shouldPreserveUserFacingSessionStateForInputProvenance } from "../../sessions/input-provenance.js"; import { resolveSendPolicy } from "../../sessions/send-policy.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { normalizeDeliveryContext, type DeliveryContext, diff --git a/src/auto-reply/reply/agent-turn-attachments.ts b/src/auto-reply/reply/agent-turn-attachments.ts index 5d49a24a541..2386903c38b 100644 --- a/src/auto-reply/reply/agent-turn-attachments.ts +++ b/src/auto-reply/reply/agent-turn-attachments.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { AcpTurnAttachment as AgentTurnAttachment } from "../../acp/control-plane/manager.types.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { logVerbose } from "../../globals.js"; import type { MediaAttachment } from "../../media-understanding/types.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { MsgContext } from "../templating.js"; import { type RecentInboundHistoryImage, diff --git a/src/auto-reply/reply/bash-command.ts b/src/auto-reply/reply/bash-command.ts index c81d3c4b1a5..0cac05c10f6 100644 --- a/src/auto-reply/reply/bash-command.ts +++ b/src/auto-reply/reply/bash-command.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveSessionAgentId } from "../../agents/agent-scope.js"; import { getFinishedSession, getSession } from "../../agents/bash-process-registry.js"; import { createExecTool } from "../../agents/bash-tools.js"; @@ -6,10 +10,6 @@ import { isCommandFlagEnabled } from "../../config/commands.flags.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { logVerbose } from "../../globals.js"; import { formatErrorMessage } from "../../infra/errors.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { clampInt } from "../../utils.js"; import type { MsgContext } from "../templating.js"; import type { ReplyPayload } from "../types.js"; diff --git a/src/auto-reply/reply/btw-command.ts b/src/auto-reply/reply/btw-command.ts index 07f9ec9801f..603675c4850 100644 --- a/src/auto-reply/reply/btw-command.ts +++ b/src/auto-reply/reply/btw-command.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { normalizeCommandBody, type CommandNormalizeOptions } from "../commands-registry.js"; const BTW_COMMAND_RE = /^\/btw(?::|\s|$)/i; diff --git a/src/auto-reply/reply/channel-context.ts b/src/auto-reply/reply/channel-context.ts index fd0a80558c0..133264e2d6a 100644 --- a/src/auto-reply/reply/channel-context.ts +++ b/src/auto-reply/reply/channel-context.ts @@ -1,9 +1,9 @@ -import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { getActivePluginChannelRegistry } from "../../plugins/runtime.js"; import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { OpenClawConfig } from "../../config/types.openclaw.js"; +import { getActivePluginChannelRegistry } from "../../plugins/runtime.js"; type CommandSurfaceParams = { ctx: { diff --git a/src/auto-reply/reply/commands-acp/context.ts b/src/auto-reply/reply/commands-acp/context.ts index 5a3b9515580..20ced764b31 100644 --- a/src/auto-reply/reply/commands-acp/context.ts +++ b/src/auto-reply/reply/commands-acp/context.ts @@ -1,6 +1,6 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { normalizeConversationText } from "../../../acp/conversation-id.js"; import { normalizeConversationTargetRef } from "../../../infra/outbound/session-binding-normalization.js"; -import { normalizeLowercaseStringOrEmpty } from "../../../shared/string-coerce.js"; import type { HandleCommandsParams } from "../commands-types.js"; import { resolveConversationBindingAccountIdFromMessage, diff --git a/src/auto-reply/reply/commands-acp/diagnostics.ts b/src/auto-reply/reply/commands-acp/diagnostics.ts index a6e1daeae9e..cc3062b9dea 100644 --- a/src/auto-reply/reply/commands-acp/diagnostics.ts +++ b/src/auto-reply/reply/commands-acp/diagnostics.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { getAcpSessionManager } from "../../../acp/control-plane/manager.js"; import { formatAcpRuntimeErrorText } from "../../../acp/runtime/error-text.js"; import { toAcpRuntimeError } from "../../../acp/runtime/errors.js"; @@ -6,10 +10,6 @@ import { resolveSessionStorePathForAcp } from "../../../acp/runtime/session-meta import { loadSessionStore } from "../../../config/sessions.js"; import type { SessionEntry } from "../../../config/sessions/types.js"; import { getSessionBindingService } from "../../../infra/outbound/session-binding-service.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../../shared/string-coerce.js"; import type { CommandHandlerResult, HandleCommandsParams } from "../commands-types.js"; import { resolveAcpCommandBindingContext } from "./context.js"; import { resolveAcpInstallCommandHint } from "./install-hints.js"; diff --git a/src/auto-reply/reply/commands-acp/install-hints.ts b/src/auto-reply/reply/commands-acp/install-hints.ts index c1e4b6cd65c..d05f299326a 100644 --- a/src/auto-reply/reply/commands-acp/install-hints.ts +++ b/src/auto-reply/reply/commands-acp/install-hints.ts @@ -1,11 +1,11 @@ import { existsSync } from "node:fs"; import path from "node:path"; -import type { OpenClawConfig } from "../../../config/types.openclaw.js"; -import { resolveBundledPluginInstallCommandHint } from "../../../plugins/bundled-sources.js"; import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { OpenClawConfig } from "../../../config/types.openclaw.js"; +import { resolveBundledPluginInstallCommandHint } from "../../../plugins/bundled-sources.js"; export function resolveAcpInstallCommandHint(cfg: OpenClawConfig): string { const configured = normalizeOptionalString(cfg.acp?.runtime?.installCommand); diff --git a/src/auto-reply/reply/commands-acp/lifecycle.ts b/src/auto-reply/reply/commands-acp/lifecycle.ts index d29256acfe0..565c9e2764d 100644 --- a/src/auto-reply/reply/commands-acp/lifecycle.ts +++ b/src/auto-reply/reply/commands-acp/lifecycle.ts @@ -1,4 +1,5 @@ import { randomUUID } from "node:crypto"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { getAcpSessionManager } from "../../../acp/control-plane/manager.js"; import { resolveAcpSessionResolutionError } from "../../../acp/control-plane/manager.utils.js"; import { @@ -46,7 +47,6 @@ import { type SessionBindingRecord, type SessionBindingService, } from "../../../infra/outbound/session-binding-service.js"; -import { normalizeOptionalString } from "../../../shared/string-coerce.js"; import type { ReplyPayload } from "../../types.js"; import type { CommandHandlerResult, HandleCommandsParams } from "../commands-types.js"; import { diff --git a/src/auto-reply/reply/commands-acp/runtime-options.ts b/src/auto-reply/reply/commands-acp/runtime-options.ts index 66dee1c1d9c..4be41083065 100644 --- a/src/auto-reply/reply/commands-acp/runtime-options.ts +++ b/src/auto-reply/reply/commands-acp/runtime-options.ts @@ -1,3 +1,5 @@ +import { timestampMsToIsoString } from "@openclaw/normalization-core/number-coercion"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { getAcpSessionManager } from "../../../acp/control-plane/manager.js"; import { parseRuntimeTimeoutSecondsInput, @@ -8,8 +10,6 @@ import { validateRuntimePermissionProfileInput, } from "../../../acp/control-plane/runtime-options.js"; import { resolveAcpSessionIdentifierLinesFromIdentity } from "../../../acp/runtime/session-identifiers.js"; -import { timestampMsToIsoString } from "../../../shared/number-coercion.js"; -import { normalizeLowercaseStringOrEmpty } from "../../../shared/string-coerce.js"; import { findLatestTaskForRelatedSessionKeyForOwner } from "../../../tasks/task-owner-access.js"; import { sanitizeTaskStatusText } from "../../../tasks/task-status.js"; import type { CommandHandlerResult, HandleCommandsParams } from "../commands-types.js"; diff --git a/src/auto-reply/reply/commands-acp/shared.ts b/src/auto-reply/reply/commands-acp/shared.ts index 4a0b3cc4e8e..bea2b3f74a6 100644 --- a/src/auto-reply/reply/commands-acp/shared.ts +++ b/src/auto-reply/reply/commands-acp/shared.ts @@ -1,14 +1,14 @@ import { randomUUID } from "node:crypto"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { toAcpRuntimeErrorText } from "../../../acp/runtime/error-text.js"; import type { AcpRuntimeError } from "../../../acp/runtime/errors.js"; import type { AcpRuntimeSessionMode } from "../../../acp/runtime/types.js"; import { supportsAutomaticThreadBindingSpawn } from "../../../channels/thread-bindings-policy.js"; import type { AcpSessionRuntimeOptions } from "../../../config/sessions/types.js"; import { normalizeAgentId } from "../../../routing/session-key.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../../shared/string-coerce.js"; import type { CommandHandlerResult, HandleCommandsParams } from "../commands-types.js"; import { resolveAcpCommandChannel, resolveAcpCommandThreadId } from "./context.js"; diff --git a/src/auto-reply/reply/commands-acp/targets.ts b/src/auto-reply/reply/commands-acp/targets.ts index 5ecc2ed8c75..e4705882c0d 100644 --- a/src/auto-reply/reply/commands-acp/targets.ts +++ b/src/auto-reply/reply/commands-acp/targets.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { callGateway } from "../../../gateway/call.js"; -import { normalizeOptionalString } from "../../../shared/string-coerce.js"; import { resolveEffectiveResetTargetSessionKey } from "../acp-reset-target.js"; import { resolveRequesterSessionKey } from "../commands-subagents/shared.js"; import type { HandleCommandsParams } from "../commands-types.js"; diff --git a/src/auto-reply/reply/commands-allowlist.ts b/src/auto-reply/reply/commands-allowlist.ts index e005049a77a..f0fc78fc77a 100644 --- a/src/auto-reply/reply/commands-allowlist.ts +++ b/src/auto-reply/reply/commands-allowlist.ts @@ -1,3 +1,8 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { resolveExplicitConfigWriteTarget } from "../../channels/plugins/config-writes.js"; import { getChannelPlugin } from "../../channels/plugins/index.js"; import type { ChannelId } from "../../channels/plugins/types.public.js"; @@ -10,11 +15,6 @@ import { removeChannelAllowFromStoreEntry, } from "../../pairing/pairing-store.js"; import { DEFAULT_ACCOUNT_ID, normalizeOptionalAccountId } from "../../routing/session-key.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; -import { normalizeStringEntries } from "../../shared/string-normalization.js"; import { resolveChannelAccountId, resolveCommandSurfaceChannel } from "./channel-context.js"; import { rejectNonOwnerCommand, diff --git a/src/auto-reply/reply/commands-approve.ts b/src/auto-reply/reply/commands-approve.ts index 882adb5aa10..fb67d79deb7 100644 --- a/src/auto-reply/reply/commands-approve.ts +++ b/src/auto-reply/reply/commands-approve.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { getChannelPlugin, resolveChannelApprovalCapability, @@ -7,7 +8,6 @@ import { isApprovalNotFoundError } from "../../infra/approval-errors.js"; import { resolveApprovalOverGateway } from "../../infra/approval-gateway-resolver.js"; import { resolveApprovalCommandAuthorization } from "../../infra/channel-approval-auth.js"; import { formatErrorMessage } from "../../infra/errors.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { resolveChannelAccountId } from "./channel-context.js"; import { requireGatewayClientScope } from "./command-gates.js"; import type { CommandHandler } from "./commands-types.js"; diff --git a/src/auto-reply/reply/commands-compact.ts b/src/auto-reply/reply/commands-compact.ts index 952e4e5d317..646dcc5e73c 100644 --- a/src/auto-reply/reply/commands-compact.ts +++ b/src/auto-reply/reply/commands-compact.ts @@ -1,4 +1,9 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveAgentDir, resolveSessionAgentId } from "../../agents/agent-scope.js"; import { resolveContextTokensForModel } from "../../agents/context.js"; import { resolveAgentHarnessPolicy } from "../../agents/harness/selection.js"; @@ -10,11 +15,6 @@ import { import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { logVerbose } from "../../globals.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import type { CommandHandler } from "./commands-types.js"; import { stripMentions, stripStructuralPrefixes } from "./mentions.js"; diff --git a/src/auto-reply/reply/commands-config.ts b/src/auto-reply/reply/commands-config.ts index 8bb8ba0900d..79388dcfd87 100644 --- a/src/auto-reply/reply/commands-config.ts +++ b/src/auto-reply/reply/commands-config.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveConfigWriteTargetFromPath } from "../../channels/plugins/config-writes.js"; import { normalizeChannelId } from "../../channels/registry.js"; import { getConfigValueAtPath, parseConfigPath } from "../../config/config-paths.js"; @@ -8,7 +9,6 @@ import { setConfigOverride, unsetConfigOverride, } from "../../config/runtime-overrides.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { isInternalMessageChannel } from "../../utils/message-channel.js"; import { resolveChannelAccountId } from "./channel-context.js"; import { diff --git a/src/auto-reply/reply/commands-context-report.ts b/src/auto-reply/reply/commands-context-report.ts index 41db4fe980c..576df847998 100644 --- a/src/auto-reply/reply/commands-context-report.ts +++ b/src/auto-reply/reply/commands-context-report.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { resolveSessionAgentIds } from "../../agents/agent-scope.js"; import { analyzeBootstrapBudget } from "../../agents/bootstrap-budget.js"; import { @@ -9,7 +10,6 @@ import { resolveFreshSessionTotalTokens, type SessionSystemPromptReport, } from "../../config/sessions/types.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { estimateTokensFromChars } from "../../utils/cjk-chars.js"; import type { ReplyPayload } from "../types.js"; import type { HandleCommandsParams } from "./commands-types.js"; diff --git a/src/auto-reply/reply/commands-context.ts b/src/auto-reply/reply/commands-context.ts index 1322301eaf2..c678bc5ec5d 100644 --- a/src/auto-reply/reply/commands-context.ts +++ b/src/auto-reply/reply/commands-context.ts @@ -1,9 +1,9 @@ -import { normalizeAnyChannelId } from "../../channels/registry.js"; -import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeAnyChannelId } from "../../channels/registry.js"; +import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { resolveCommandAuthorization } from "../command-auth.js"; import { normalizeCommandBody } from "../commands-registry-normalize.js"; import type { MsgContext } from "../templating.js"; diff --git a/src/auto-reply/reply/commands-diagnostics.ts b/src/auto-reply/reply/commands-diagnostics.ts index 4a91d077558..09bb989f0fd 100644 --- a/src/auto-reply/reply/commands-diagnostics.ts +++ b/src/auto-reply/reply/commands-diagnostics.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveSessionAgentId } from "../../agents/agent-scope.js"; import { createExecTool } from "../../agents/bash-tools.js"; import type { ExecToolDetails } from "../../agents/bash-tools.js"; @@ -8,7 +9,6 @@ import type { ExecApprovalRequest } from "../../infra/exec-approvals.js"; import type { InteractiveReply } from "../../interactive/payload.js"; import { executePluginCommand, matchPluginCommand } from "../../plugins/commands.js"; import type { PluginCommandDiagnosticsSession, PluginCommandResult } from "../../plugins/types.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { ReplyPayload } from "../types.js"; import { buildCurrentOpenClawCliCommand } from "./commands-openclaw-cli.js"; import { diff --git a/src/auto-reply/reply/commands-dock.ts b/src/auto-reply/reply/commands-dock.ts index 382e277f2e9..e676f01c652 100644 --- a/src/auto-reply/reply/commands-dock.ts +++ b/src/auto-reply/reply/commands-dock.ts @@ -1,9 +1,9 @@ -import { getActivePluginChannelRegistry } from "../../plugins/runtime.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../../shared/string-coerce.js"; -import { normalizeTrimmedStringList } from "../../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; +import { getActivePluginChannelRegistry } from "../../plugins/runtime.js"; import { resolveTextCommand } from "../commands-registry.js"; import { resolveCommandSurfaceChannel } from "./channel-context.js"; import { persistSessionEntry } from "./commands-session-store.js"; diff --git a/src/auto-reply/reply/commands-export-session.ts b/src/auto-reply/reply/commands-export-session.ts index 9ca8f31ff37..a4ba640838f 100644 --- a/src/auto-reply/reply/commands-export-session.ts +++ b/src/auto-reply/reply/commands-export-session.ts @@ -1,6 +1,7 @@ import fsp from "node:fs/promises"; import path from "node:path"; import { fileURLToPath } from "node:url"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { migrateSessionEntries, type FileEntry as SessionFileEntry, @@ -8,7 +9,6 @@ import { type SessionHeader, } from "../../agents/sessions/session-manager.js"; import { pathExists } from "../../infra/fs-safe.js"; -import { isRecord } from "../../shared/record-coerce.js"; import type { ReplyPayload } from "../types.js"; import { isReplyPayload, @@ -246,7 +246,9 @@ async function readSessionDataFromTranscript(sessionFile: string): Promise<{ migrateSessionEntries(fileEntries); const header = fileEntries.find((entry): entry is SessionHeader => entry.type === "session") ?? null; - const entries = fileEntries.filter((entry): entry is AgentSessionEntry => entry.type !== "session"); + const entries = fileEntries.filter( + (entry): entry is AgentSessionEntry => entry.type !== "session", + ); const lastEntry = entries.at(-1); const leafId = typeof lastEntry?.id === "string" ? lastEntry.id : null; return { header, entries, leafId, warnings: summarizeSessionExportWarnings(warnings) }; diff --git a/src/auto-reply/reply/commands-goal.ts b/src/auto-reply/reply/commands-goal.ts index 3f7b598e918..7f9743a577d 100644 --- a/src/auto-reply/reply/commands-goal.ts +++ b/src/auto-reply/reply/commands-goal.ts @@ -1,3 +1,7 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { clearSessionGoal, createSessionGoal, @@ -6,10 +10,6 @@ import { getSessionGoal, updateSessionGoalStatus, } from "../../config/sessions.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { rejectUnauthorizedCommand } from "./command-gates.js"; import type { CommandHandler, diff --git a/src/auto-reply/reply/commands-models.ts b/src/auto-reply/reply/commands-models.ts index 0df73d85509..80fa7c00bab 100644 --- a/src/auto-reply/reply/commands-models.ts +++ b/src/auto-reply/reply/commands-models.ts @@ -1,3 +1,8 @@ +import { parseStrictPositiveInteger } from "@openclaw/normalization-core/number-coercion"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveAgentDir, resolveAgentWorkspaceDir, @@ -28,11 +33,6 @@ import { resolveDefaultAgentWorkspaceDir } from "../../agents/workspace.js"; import { getChannelPlugin } from "../../channels/plugins/index.js"; import type { SessionEntry } from "../../config/sessions.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { parseStrictPositiveInteger } from "../../shared/number-coercion.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { resolveAgentRuntimeLabel } from "../../status/agent-runtime-label.js"; import type { ReplyPayload } from "../types.js"; import { rejectUnauthorizedCommand } from "./command-gates.js"; diff --git a/src/auto-reply/reply/commands-plugin.ts b/src/auto-reply/reply/commands-plugin.ts index 91124d39256..88cbb2807e3 100644 --- a/src/auto-reply/reply/commands-plugin.ts +++ b/src/auto-reply/reply/commands-plugin.ts @@ -5,8 +5,8 @@ * This handler is called before built-in command handlers. */ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { matchPluginCommand, executePluginCommand } from "../../plugins/commands.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { CommandHandler, CommandHandlerResult } from "./commands-types.js"; /** diff --git a/src/auto-reply/reply/commands-plugins.ts b/src/auto-reply/reply/commands-plugins.ts index 33b02fe49c1..49cba31fe41 100644 --- a/src/auto-reply/reply/commands-plugins.ts +++ b/src/auto-reply/reply/commands-plugins.ts @@ -1,4 +1,5 @@ import fs from "node:fs"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { buildNpmInstallRecordFields } from "../../cli/npm-resolution.js"; import { resolveOfficialExternalNpmPackageTrust } from "../../cli/plugin-install-plan.js"; import { @@ -33,7 +34,6 @@ import { formatPluginCompatibilityNotice, type PluginStatusReport, } from "../../plugins/status.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { resolveUserPath } from "../../utils.js"; import { rejectUnauthorizedCommand, diff --git a/src/auto-reply/reply/commands-private-route.test.ts b/src/auto-reply/reply/commands-private-route.test.ts index 894f4001fa2..0d94c648f1f 100644 --- a/src/auto-reply/reply/commands-private-route.test.ts +++ b/src/auto-reply/reply/commands-private-route.test.ts @@ -1,9 +1,9 @@ +import { MAX_DATE_TIMESTAMP_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, describe, expect, it, vi } from "vitest"; import type { ChannelPlugin } from "../../channels/plugins/types.public.js"; import type { OpenClawConfig } from "../../config/config.js"; import type { ExecApprovalRequest } from "../../infra/exec-approvals.js"; import { resetPluginRuntimeStateForTest, setActivePluginRegistry } from "../../plugins/runtime.js"; -import { MAX_DATE_TIMESTAMP_MS } from "../../shared/number-coercion.js"; import { createChannelTestPluginBase, createTestRegistry, diff --git a/src/auto-reply/reply/commands-private-route.ts b/src/auto-reply/reply/commands-private-route.ts index 718eab74cc3..f8ef2fc7bbe 100644 --- a/src/auto-reply/reply/commands-private-route.ts +++ b/src/auto-reply/reply/commands-private-route.ts @@ -1,14 +1,14 @@ +import { resolveExpiresAtMsFromDurationMs } from "@openclaw/normalization-core/number-coercion"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { getLoadedChannelPlugin, listChannelPlugins, resolveChannelApprovalAdapter, } from "../../channels/plugins/index.js"; import type { ExecApprovalRequest } from "../../infra/exec-approvals.js"; -import { resolveExpiresAtMsFromDurationMs } from "../../shared/number-coercion.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import type { OriginatingChannelType } from "../templating.js"; import type { ReplyPayload } from "../types.js"; import type { HandleCommandsParams } from "./commands-types.js"; diff --git a/src/auto-reply/reply/commands-reset-mode.ts b/src/auto-reply/reply/commands-reset-mode.ts index b9241292805..87125eb748b 100644 --- a/src/auto-reply/reply/commands-reset-mode.ts +++ b/src/auto-reply/reply/commands-reset-mode.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export type SoftResetParseResult = { matched: false } | { matched: true; tail: string }; diff --git a/src/auto-reply/reply/commands-session-abort.ts b/src/auto-reply/reply/commands-session-abort.ts index c2c7a5504b5..da2c38c2bb1 100644 --- a/src/auto-reply/reply/commands-session-abort.ts +++ b/src/auto-reply/reply/commands-session-abort.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { SessionEntry } from "../../config/sessions.js"; import { logVerbose } from "../../globals.js"; import { createInternalHookEvent, triggerInternalHook } from "../../hooks/internal-hooks.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { resolveAbortCutoffFromContext, shouldPersistAbortCutoff, diff --git a/src/auto-reply/reply/commands-session.ts b/src/auto-reply/reply/commands-session.ts index 592d64f7372..302de434e01 100644 --- a/src/auto-reply/reply/commands-session.ts +++ b/src/auto-reply/reply/commands-session.ts @@ -1,3 +1,9 @@ +import { timestampMsToIsoString } from "@openclaw/normalization-core/number-coercion"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveSessionAgentId } from "../../agents/agent-scope.js"; import { resolveFastModeState } from "../../agents/fast-mode.js"; import { @@ -21,12 +27,6 @@ import { } from "../../infra/restart-sentinel.js"; import { scheduleGatewaySigusr1Restart, triggerOpenClawRestart } from "../../infra/restart.js"; import { loadCostUsageSummary, loadSessionCostSummary } from "../../infra/session-cost-usage.js"; -import { timestampMsToIsoString } from "../../shared/number-coercion.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { formatTokenCount, formatUsd } from "../../utils/usage-format.js"; import { parseActivationCommand } from "../group-activation.js"; import { parseSendPolicyCommand } from "../send-policy.js"; diff --git a/src/auto-reply/reply/commands-slash-parse.ts b/src/auto-reply/reply/commands-slash-parse.ts index 92e3f2a2513..28e226cff4d 100644 --- a/src/auto-reply/reply/commands-slash-parse.ts +++ b/src/auto-reply/reply/commands-slash-parse.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export type SlashCommandParseResult = | { kind: "no-match" } diff --git a/src/auto-reply/reply/commands-steer.ts b/src/auto-reply/reply/commands-steer.ts index 2de05b42048..9437ee38965 100644 --- a/src/auto-reply/reply/commands-steer.ts +++ b/src/auto-reply/reply/commands-steer.ts @@ -1,10 +1,10 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveInternalSessionKey, resolveMainSessionAlias, } from "../../agents/tools/sessions-helpers.js"; import type { SessionEntry } from "../../config/sessions.js"; import { logVerbose } from "../../globals.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { isNativeCommandTurn, resolveCommandTurnContext } from "../command-turn-context.js"; import { rejectUnauthorizedCommand } from "./command-gates.js"; import { diff --git a/src/auto-reply/reply/commands-subagents/action-agents.ts b/src/auto-reply/reply/commands-subagents/action-agents.ts index 4d130932878..359b2041baf 100644 --- a/src/auto-reply/reply/commands-subagents/action-agents.ts +++ b/src/auto-reply/reply/commands-subagents/action-agents.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { subagentRuns } from "../../../agents/subagent-registry-memory.js"; import { countPendingDescendantRunsFromRuns } from "../../../agents/subagent-registry-queries.js"; import { getSubagentRunsSnapshotForRead } from "../../../agents/subagent-registry-state.js"; import { getChannelPlugin, normalizeChannelId } from "../../../channels/plugins/index.js"; import { getSessionBindingService } from "../../../infra/outbound/session-binding-service.js"; -import { normalizeOptionalString } from "../../../shared/string-coerce.js"; import type { CommandHandlerResult } from "../commands-types.js"; import { formatRunLabel, sortSubagentRuns } from "../subagents-utils.js"; import { diff --git a/src/auto-reply/reply/commands-subagents/action-focus.ts b/src/auto-reply/reply/commands-subagents/action-focus.ts index 528d27d0d21..8f9658fcb8a 100644 --- a/src/auto-reply/reply/commands-subagents/action-focus.ts +++ b/src/auto-reply/reply/commands-subagents/action-focus.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveAcpSessionCwd, resolveAcpThreadSessionDetailLines, @@ -18,7 +19,6 @@ import { } from "../../../channels/thread-bindings-policy.js"; import { normalizeConversationRef } from "../../../infra/outbound/session-binding-normalization.js"; import { getSessionBindingService } from "../../../infra/outbound/session-binding-service.js"; -import { normalizeOptionalString } from "../../../shared/string-coerce.js"; import type { CommandHandlerResult } from "../commands-types.js"; import { resolveConversationBindingContextFromAcpCommand } from "../conversation-binding-input.js"; import { diff --git a/src/auto-reply/reply/commands-subagents/action-info.ts b/src/auto-reply/reply/commands-subagents/action-info.ts index 55dfc6bfab7..8ed63fea238 100644 --- a/src/auto-reply/reply/commands-subagents/action-info.ts +++ b/src/auto-reply/reply/commands-subagents/action-info.ts @@ -1,3 +1,4 @@ +import { timestampMsToIsoString } from "@openclaw/normalization-core/number-coercion"; import { subagentRuns } from "../../../agents/subagent-registry-memory.js"; import { countPendingDescendantRunsFromRuns } from "../../../agents/subagent-registry-queries.js"; import { getSubagentRunsSnapshotForRead } from "../../../agents/subagent-registry-state.js"; @@ -5,7 +6,6 @@ import { resolveStorePath } from "../../../config/sessions/paths.js"; import { loadSessionStore } from "../../../config/sessions/store-load.js"; import { formatTimeAgo } from "../../../infra/format-time/format-relative.ts"; import { parseAgentSessionKey } from "../../../routing/session-key.js"; -import { timestampMsToIsoString } from "../../../shared/number-coercion.js"; import { formatDurationCompact } from "../../../shared/subagents-format.js"; import { findTaskByRunIdForOwner } from "../../../tasks/task-owner-access.js"; import { sanitizeTaskStatusText } from "../../../tasks/task-status.js"; diff --git a/src/auto-reply/reply/commands-subagents/action-log.ts b/src/auto-reply/reply/commands-subagents/action-log.ts index 70a1254e574..e3385f354c5 100644 --- a/src/auto-reply/reply/commands-subagents/action-log.ts +++ b/src/auto-reply/reply/commands-subagents/action-log.ts @@ -1,6 +1,6 @@ +import { parseStrictNonNegativeInteger } from "@openclaw/normalization-core/number-coercion"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { callGateway } from "../../../gateway/call.js"; -import { parseStrictNonNegativeInteger } from "../../../shared/number-coercion.js"; -import { normalizeLowercaseStringOrEmpty } from "../../../shared/string-coerce.js"; import type { CommandHandlerResult } from "../commands-types.js"; import { formatRunLabel } from "../subagents-utils.js"; import { diff --git a/src/auto-reply/reply/commands-subagents/action-unfocus.ts b/src/auto-reply/reply/commands-subagents/action-unfocus.ts index 4e1207f9897..dcf352e171d 100644 --- a/src/auto-reply/reply/commands-subagents/action-unfocus.ts +++ b/src/auto-reply/reply/commands-subagents/action-unfocus.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { normalizeConversationRef } from "../../../infra/outbound/session-binding-normalization.js"; import { getSessionBindingService } from "../../../infra/outbound/session-binding-service.js"; -import { normalizeOptionalString } from "../../../shared/string-coerce.js"; import type { CommandHandlerResult } from "../commands-types.js"; import { resolveConversationBindingContextFromAcpCommand } from "../conversation-binding-input.js"; import { type SubagentsCommandContext, stopWithText } from "./shared.js"; diff --git a/src/auto-reply/reply/commands-subagents/shared.ts b/src/auto-reply/reply/commands-subagents/shared.ts index edaf6537581..a289c0b2e4c 100644 --- a/src/auto-reply/reply/commands-subagents/shared.ts +++ b/src/auto-reply/reply/commands-subagents/shared.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveStoredSubagentCapabilities } from "../../../agents/subagent-capabilities.js"; import type { ResolvedSubagentController } from "../../../agents/subagent-control.js"; import { subagentRuns } from "../../../agents/subagent-registry-memory.js"; @@ -13,10 +17,6 @@ import { callGateway } from "../../../gateway/call.js"; import { parseAgentSessionKey } from "../../../routing/session-key.js"; import { isSubagentSessionKey } from "../../../routing/session-key.js"; import { looksLikeSessionId } from "../../../sessions/session-id.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../../shared/string-coerce.js"; import { isNativeCommandTurn, resolveCommandTurnContext } from "../../command-turn-context.js"; import { resolveCommandSurfaceChannel, resolveChannelAccountId } from "../channel-context.js"; import { extractMessageText, type ChatMessage } from "../commands-subagents-text.js"; diff --git a/src/auto-reply/reply/commands-tts.ts b/src/auto-reply/reply/commands-tts.ts index 0183240bc10..813d5591f7f 100644 --- a/src/auto-reply/reply/commands-tts.ts +++ b/src/auto-reply/reply/commands-tts.ts @@ -1,10 +1,10 @@ import crypto from "node:crypto"; -import { readLatestAssistantTextFromSessionTranscript } from "../../config/sessions.js"; -import { logVerbose } from "../../globals.js"; import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { readLatestAssistantTextFromSessionTranscript } from "../../config/sessions.js"; +import { logVerbose } from "../../globals.js"; import { canonicalizeSpeechProviderId, getSpeechProvider, diff --git a/src/auto-reply/reply/conversation-binding-input.ts b/src/auto-reply/reply/conversation-binding-input.ts index 5f99c42da7c..dc4b25cf799 100644 --- a/src/auto-reply/reply/conversation-binding-input.ts +++ b/src/auto-reply/reply/conversation-binding-input.ts @@ -1,8 +1,8 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { normalizeConversationText } from "../../acp/conversation-id.js"; import { resolveConversationBindingContext } from "../../channels/conversation-binding-context.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { getActivePluginChannelRegistry } from "../../plugins/runtime.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import type { MsgContext } from "../templating.js"; import type { HandleCommandsParams } from "./commands-types.js"; diff --git a/src/auto-reply/reply/current-turn-images.ts b/src/auto-reply/reply/current-turn-images.ts index d511885e5c2..323185eba74 100644 --- a/src/auto-reply/reply/current-turn-images.ts +++ b/src/auto-reply/reply/current-turn-images.ts @@ -1,10 +1,10 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { logVerbose } from "../../globals.js"; import { formatErrorMessage } from "../../infra/errors.js"; import type { ImageContent } from "../../llm/types.js"; import { mimeTypeFromFilePath } from "../../media/mime.js"; import type { PromptImageOrderEntry } from "../../media/prompt-image-order.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { MsgContext } from "../templating.js"; import { resolveAgentTurnAttachments } from "./agent-turn-attachments.js"; diff --git a/src/auto-reply/reply/directive-handling.auth-profile.ts b/src/auto-reply/reply/directive-handling.auth-profile.ts index 73e348af097..977a3731561 100644 --- a/src/auto-reply/reply/directive-handling.auth-profile.ts +++ b/src/auto-reply/reply/directive-handling.auth-profile.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { ensureAuthProfileStore, findPersistedAuthProfileCredential, } from "../../agents/auth-profiles/store.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; export function resolveProfileOverride(params: { rawProfile?: string; diff --git a/src/auto-reply/reply/directive-handling.auth.ts b/src/auto-reply/reply/directive-handling.auth.ts index 23def01cc0a..15b1a6c611c 100644 --- a/src/auto-reply/reply/directive-handling.auth.ts +++ b/src/auto-reply/reply/directive-handling.auth.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { formatRemainingShort } from "../../agents/auth-health.js"; import { isConfiguredAwsSdkAuthProfileForProvider, @@ -15,7 +16,6 @@ import { import { findNormalizedProviderValue, normalizeProviderId } from "../../agents/model-selection.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { coerceSecretRef } from "../../config/types.secrets.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { shortenHomePath } from "../../utils.js"; import { maskApiKey } from "../../utils/mask-api-key.js"; diff --git a/src/auto-reply/reply/directive-handling.impl.ts b/src/auto-reply/reply/directive-handling.impl.ts index 7c5f989d1a7..8bc2a61b5e6 100644 --- a/src/auto-reply/reply/directive-handling.impl.ts +++ b/src/auto-reply/reply/directive-handling.impl.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { resolveAgentDir, resolveSessionAgentId } from "../../agents/agent-scope.js"; import { renderExecTargetLabel } from "../../agents/bash-tools.exec-runtime.js"; import { resolveExecDefaults } from "../../agents/exec-defaults.js"; @@ -8,7 +9,6 @@ import { triggerSessionPatchHook } from "../../gateway/session-patch-hooks.js"; import { enqueueSystemEvent } from "../../infra/system-events.js"; import { applyTraceOverride, applyVerboseOverride } from "../../sessions/level-overrides.js"; import { applyModelOverrideToSessionEntry } from "../../sessions/model-overrides.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { formatThinkingLevels, isThinkingLevelSupported, diff --git a/src/auto-reply/reply/directive-handling.model-picker.ts b/src/auto-reply/reply/directive-handling.model-picker.ts index 65d67684e94..2f77a84666b 100644 --- a/src/auto-reply/reply/directive-handling.model-picker.ts +++ b/src/auto-reply/reply/directive-handling.model-picker.ts @@ -1,13 +1,13 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { findNormalizedProviderValue, type ModelRef, normalizeProviderId, } from "../../agents/model-selection.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; export type ModelPickerCatalogEntry = { provider: string; diff --git a/src/auto-reply/reply/directive-handling.model.ts b/src/auto-reply/reply/directive-handling.model.ts index 88a39729d27..1c5458ab452 100644 --- a/src/auto-reply/reply/directive-handling.model.ts +++ b/src/auto-reply/reply/directive-handling.model.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { normalizeOptionalAgentRuntimeId } from "../../agents/agent-runtime-id.js"; import { resolveAuthStorePathForDisplay } from "../../agents/auth-profiles.js"; import type { AuthProfileCredential } from "../../agents/auth-profiles/types.js"; @@ -14,10 +18,6 @@ import { buildAgentRuntimeAuthPlan } from "../../agents/runtime-plan/auth.js"; import { getChannelPlugin } from "../../channels/plugins/index.js"; import type { SessionEntry } from "../../config/sessions.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { shortenHomePath } from "../../utils.js"; import { resolveSelectedAndActiveModel } from "../model-runtime.js"; import type { ReplyPayload } from "../types.js"; diff --git a/src/auto-reply/reply/directive-handling.shared.ts b/src/auto-reply/reply/directive-handling.shared.ts index 1d7143a5537..9c623ff8c7c 100644 --- a/src/auto-reply/reply/directive-handling.shared.ts +++ b/src/auto-reply/reply/directive-handling.shared.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { formatCliCommand } from "../../cli/command-format.js"; import { SYSTEM_MARK, prefixSystemMessage } from "../../infra/system-message.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { isInternalMessageChannel } from "../../utils/message-channel.js"; import type { ElevatedLevel, ReasoningLevel } from "./directives.js"; diff --git a/src/auto-reply/reply/dispatch-acp-delivery.ts b/src/auto-reply/reply/dispatch-acp-delivery.ts index 13e09b2ba00..d59f85414ad 100644 --- a/src/auto-reply/reply/dispatch-acp-delivery.ts +++ b/src/auto-reply/reply/dispatch-acp-delivery.ts @@ -1,13 +1,13 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { hasOutboundReplyContent } from "openclaw/plugin-sdk/reply-payload"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { TtsAutoMode } from "../../config/types.tts.js"; import { logVerbose } from "../../globals.js"; import { formatErrorMessage } from "../../infra/errors.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { createTtsDirectiveTextStreamCleaner } from "../../tts/directives.js"; import { resolveStatusTtsSnapshot } from "../../tts/status-config.js"; import { resolveConfiguredTtsMode, shouldCleanTtsDirectiveText } from "../../tts/tts-config.js"; diff --git a/src/auto-reply/reply/dispatch-acp.ts b/src/auto-reply/reply/dispatch-acp.ts index 2794e6d9ad0..6f7a094b26d 100644 --- a/src/auto-reply/reply/dispatch-acp.ts +++ b/src/auto-reply/reply/dispatch-acp.ts @@ -1,3 +1,8 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveAcpAgentPolicyError, resolveAcpDispatchPolicyError } from "../../acp/policy.js"; import { formatAcpRuntimeErrorText } from "../../acp/runtime/error-text.js"; import { type AcpRuntimeError, toAcpRuntimeError } from "../../acp/runtime/errors.js"; @@ -18,11 +23,6 @@ import { prefixSystemMessage } from "../../infra/system-message.js"; import { markDiagnosticSessionProgress } from "../../logging/diagnostic.js"; import { resolveAgentIdFromSessionKey } from "../../routing/session-key.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { resolveStatusTtsSnapshot } from "../../tts/status-config.js"; import { resolveConfiguredTtsMode } from "../../tts/tts-config.js"; import type { SourceReplyDeliveryMode } from "../get-reply-options.types.js"; diff --git a/src/auto-reply/reply/dispatch-from-config.ts b/src/auto-reply/reply/dispatch-from-config.ts index 1c9eb524d0c..057f2543c86 100644 --- a/src/auto-reply/reply/dispatch-from-config.ts +++ b/src/auto-reply/reply/dispatch-from-config.ts @@ -1,4 +1,9 @@ import crypto from "node:crypto"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { hasOutboundReplyContent, resolveSendableOutboundReplyParts, @@ -77,11 +82,6 @@ import type { PluginHookReplyDispatchEvent } from "../../plugins/hook-types.js"; import { isAcpSessionKey } from "../../routing/session-key.js"; import { resolveSendPolicy } from "../../sessions/send-policy.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { createTtsDirectiveTextStreamCleaner } from "../../tts/directives.js"; import { normalizeTtsAutoMode, diff --git a/src/auto-reply/reply/elevated-allowlist-matcher.ts b/src/auto-reply/reply/elevated-allowlist-matcher.ts index bd4bac85f2d..1f6d1cdf349 100644 --- a/src/auto-reply/reply/elevated-allowlist-matcher.ts +++ b/src/auto-reply/reply/elevated-allowlist-matcher.ts @@ -1,9 +1,9 @@ -import { CHAT_CHANNEL_ORDER } from "../../channels/registry.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../../shared/string-coerce.js"; -import { normalizeAtHashSlug } from "../../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeAtHashSlug } from "@openclaw/normalization-core/string-normalization"; +import { CHAT_CHANNEL_ORDER } from "../../channels/registry.js"; export type ExplicitElevatedAllowField = "id" | "from" | "e164" | "name" | "username" | "tag"; const INTERNAL_ALLOWLIST_CHANNEL = "webchat"; diff --git a/src/auto-reply/reply/exec/directive.ts b/src/auto-reply/reply/exec/directive.ts index de7d3bffae3..86b52df9353 100644 --- a/src/auto-reply/reply/exec/directive.ts +++ b/src/auto-reply/reply/exec/directive.ts @@ -1,10 +1,10 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { type ExecAsk, type ExecSecurity, type ExecTarget, normalizeExecTarget, } from "../../../infra/exec-approvals.js"; -import { normalizeOptionalLowercaseString } from "../../../shared/string-coerce.js"; import { skipDirectiveArgPrefix, takeDirectiveToken } from "../directive-parsing.js"; type ExecDirectiveParse = { diff --git a/src/auto-reply/reply/followup-runner.ts b/src/auto-reply/reply/followup-runner.ts index c6211754c4c..8777bdd1bba 100644 --- a/src/auto-reply/reply/followup-runner.ts +++ b/src/auto-reply/reply/followup-runner.ts @@ -1,4 +1,5 @@ import crypto from "node:crypto"; +import { readStringValue } from "@openclaw/normalization-core/string-coerce"; import { hasOutboundReplyContent } from "openclaw/plugin-sdk/reply-payload"; import { clearAutoFallbackPrimaryProbeSelection, @@ -26,7 +27,6 @@ import { emitAgentEvent, registerAgentRunContext } from "../../infra/agent-event import { formatErrorMessage } from "../../infra/errors.js"; import { defaultRuntime } from "../../runtime.js"; import { shouldPreserveUserFacingSessionStateForInputProvenance } from "../../sessions/input-provenance.js"; -import { readStringValue } from "../../shared/string-coerce.js"; import { isInternalMessageChannel } from "../../utils/message-channel.js"; import type { GetReplyOptions, ReplyPayload } from "../types.js"; import { diff --git a/src/auto-reply/reply/get-reply-directive-aliases.ts b/src/auto-reply/reply/get-reply-directive-aliases.ts index 9a6ce5e4265..8d8750aa933 100644 --- a/src/auto-reply/reply/get-reply-directive-aliases.ts +++ b/src/auto-reply/reply/get-reply-directive-aliases.ts @@ -1,8 +1,8 @@ -import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { SkillCommandSpec } from "../../skills/types.js"; export function reserveSkillCommandNames(params: { diff --git a/src/auto-reply/reply/get-reply-directives.ts b/src/auto-reply/reply/get-reply-directives.ts index 29f04ada853..3ae623417d1 100644 --- a/src/auto-reply/reply/get-reply-directives.ts +++ b/src/auto-reply/reply/get-reply-directives.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { listAgentEntries } from "../../agents/agent-scope.js"; import { DEFAULT_CONTEXT_TOKENS } from "../../agents/defaults.js"; import { resolveFastModeState } from "../../agents/fast-mode.js"; @@ -7,10 +11,6 @@ import type { SessionEntry } from "../../config/sessions.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { normalizeAgentId } from "../../routing/session-key.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import type { SkillCommandSpec } from "../../skills/types.js"; import { shouldHandleTextCommands } from "../commands-text-routing.js"; import type { MsgContext, TemplateContext } from "../templating.js"; diff --git a/src/auto-reply/reply/get-reply-fast-path.ts b/src/auto-reply/reply/get-reply-fast-path.ts index 8d8931ca0dc..3553d5aa1dd 100644 --- a/src/auto-reply/reply/get-reply-fast-path.ts +++ b/src/auto-reply/reply/get-reply-fast-path.ts @@ -1,4 +1,8 @@ import crypto from "node:crypto"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { normalizeChatType } from "../../channels/chat-type.js"; import { normalizeAnyChannelId } from "../../channels/registry.js"; import { applyMergePatch } from "../../config/merge-patch.js"; @@ -7,15 +11,11 @@ import { resolveSessionKey } from "../../config/sessions/session-key.js"; import { loadSessionStore } from "../../config/sessions/store.js"; import type { SessionEntry, SessionScope } from "../../config/sessions/types.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { resolveCommandTurnTargetSessionKey } from "../command-turn-context.js"; import { normalizeCommandBody } from "../commands-registry.js"; import type { MsgContext, TemplateContext } from "../templating.js"; -import { parseSoftResetCommand } from "./commands-reset-mode.js"; import { isFormattedGoalContinuationPrompt } from "./commands-goal.js"; +import { parseSoftResetCommand } from "./commands-reset-mode.js"; import type { CommandContext } from "./commands-types.js"; import { stripMentions, stripStructuralPrefixes } from "./mentions.js"; import type { SessionInitResult } from "./session.js"; diff --git a/src/auto-reply/reply/get-reply-inline-actions.ts b/src/auto-reply/reply/get-reply-inline-actions.ts index 1fc469341bc..fddf8709326 100644 --- a/src/auto-reply/reply/get-reply-inline-actions.ts +++ b/src/auto-reply/reply/get-reply-inline-actions.ts @@ -1,3 +1,7 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { collectTextContentBlocks } from "../../agents/content-blocks.js"; import type { BlockReplyChunking } from "../../agents/embedded-agent-block-chunker.js"; import { getChannelPlugin } from "../../channels/plugins/index.js"; @@ -7,10 +11,6 @@ import { logVerbose } from "../../globals.js"; import { formatErrorMessage } from "../../infra/errors.js"; import { generateSecureToken } from "../../infra/secure-random.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { listReservedChatSlashCommandNames, resolveSkillCommandInvocation, diff --git a/src/auto-reply/reply/get-reply-native-slash-fast-path.ts b/src/auto-reply/reply/get-reply-native-slash-fast-path.ts index c7921985727..c30f32d59b7 100644 --- a/src/auto-reply/reply/get-reply-native-slash-fast-path.ts +++ b/src/auto-reply/reply/get-reply-native-slash-fast-path.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { loadModelCatalog } from "../../agents/model-catalog.js"; import { resolveThinkingDefaultWithRuntimeCatalog, @@ -5,7 +6,6 @@ import { } from "../../agents/model-selection.js"; import type { OpenClawConfig } from "../../config/config.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { SkillCommandSpec } from "../../skills/types.js"; import { isNativeCommandTurn, resolveCommandTurnContext } from "../command-turn-context.js"; import type { GetReplyOptions } from "../get-reply-options.types.js"; diff --git a/src/auto-reply/reply/get-reply-run.ts b/src/auto-reply/reply/get-reply-run.ts index e184d68c0f1..a60f2c62403 100644 --- a/src/auto-reply/reply/get-reply-run.ts +++ b/src/auto-reply/reply/get-reply-run.ts @@ -1,5 +1,6 @@ import crypto from "node:crypto"; import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { clearAutoFallbackPrimaryProbeSelection, hasSessionAutoModelFallbackProvenance, @@ -40,7 +41,6 @@ import { } from "../../sessions/user-turn-transcript.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; import type { SilentReplyConversationType } from "../../shared/silent-reply-policy.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { isReasoningTagProvider } from "../../utils/provider-utils.js"; import { hasControlCommand } from "../command-detection.js"; import { resolveCommandTurnTargetSessionKey } from "../command-turn-context.js"; diff --git a/src/auto-reply/reply/get-reply.ts b/src/auto-reply/reply/get-reply.ts index 055884d6064..89adb25abfe 100644 --- a/src/auto-reply/reply/get-reply.ts +++ b/src/auto-reply/reply/get-reply.ts @@ -1,4 +1,6 @@ import fs from "node:fs/promises"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { resolveAutoFallbackPrimaryProbe, resolveAgentConfig, @@ -19,8 +21,6 @@ import { createSubsystemLogger } from "../../logging/subsystem.js"; import { buildAgentHookContextChannelFields } from "../../plugins/hook-agent-context.js"; import { defaultRuntime } from "../../runtime.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; -import { normalizeStringEntries } from "../../shared/string-normalization.js"; import { resolveCommandTurnTargetSessionKey } from "../command-turn-context.js"; import type { GetReplyOptions } from "../get-reply-options.types.js"; import { DEFAULT_HEARTBEAT_ACK_MAX_CHARS, stripHeartbeatToken } from "../heartbeat.js"; diff --git a/src/auto-reply/reply/group-id-simple.ts b/src/auto-reply/reply/group-id-simple.ts index 66dcc5ab57e..65c99e0a31c 100644 --- a/src/auto-reply/reply/group-id-simple.ts +++ b/src/auto-reply/reply/group-id-simple.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export function extractSimpleExplicitGroupId(raw: string | undefined | null): string | undefined { const trimmed = normalizeOptionalString(raw) ?? ""; diff --git a/src/auto-reply/reply/group-id.ts b/src/auto-reply/reply/group-id.ts index 605be7a52f6..7b72037b782 100644 --- a/src/auto-reply/reply/group-id.ts +++ b/src/auto-reply/reply/group-id.ts @@ -1,3 +1,8 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { getLoadedChannelPluginForRead } from "../../channels/plugins/registry-loaded-read.js"; import type { ChannelMessagingAdapter } from "../../channels/plugins/types.public.js"; import { normalizeAnyChannelId } from "../../channels/registry.js"; @@ -6,11 +11,6 @@ import { stripTargetProviderPrefix, stripTargetTopicSuffix, } from "../../infra/outbound/channel-target-prefix.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; import { extractSimpleExplicitGroupId } from "./group-id-simple.js"; function extractInferredGroupTargetId(params: { diff --git a/src/auto-reply/reply/groups.ts b/src/auto-reply/reply/groups.ts index 91d5f45854f..d12220a3ff1 100644 --- a/src/auto-reply/reply/groups.ts +++ b/src/auto-reply/reply/groups.ts @@ -1,12 +1,12 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveChannelGroupRequireMention } from "../../config/group-policy.js"; import type { GroupKeyResolution, SessionEntry } from "../../config/sessions.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; import type { SilentReplyPolicy } from "../../shared/silent-reply-policy.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { isInternalMessageChannel } from "../../utils/message-channel.js"; import type { SourceReplyDeliveryMode } from "../get-reply-options.types.js"; import { normalizeGroupActivation } from "../group-activation.js"; diff --git a/src/auto-reply/reply/history-media.ts b/src/auto-reply/reply/history-media.ts index a595f2c1f35..f38ea5db5c6 100644 --- a/src/auto-reply/reply/history-media.ts +++ b/src/auto-reply/reply/history-media.ts @@ -1,6 +1,6 @@ +import { asFiniteNumber } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { mimeTypeFromFilePath } from "../../media/mime.js"; -import { asFiniteNumber } from "../../shared/number-coercion.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { MsgContext } from "../templating.js"; import type { HistoryEntry, HistoryMediaEntry } from "./history.types.js"; diff --git a/src/auto-reply/reply/inbound-context.ts b/src/auto-reply/reply/inbound-context.ts index be8a6c47ef7..fe5d2a6fc14 100644 --- a/src/auto-reply/reply/inbound-context.ts +++ b/src/auto-reply/reply/inbound-context.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { normalizeChatType } from "../../channels/chat-type.js"; import { resolveConversationLabel } from "../../channels/conversation-label.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { resolveCommandTurnContext } from "../command-turn-context.js"; import type { FinalizedMsgContext, MsgContext } from "../templating.js"; import { normalizeInboundTextNewlines, sanitizeInboundSystemTags } from "./inbound-text.js"; diff --git a/src/auto-reply/reply/inbound-dedupe.ts b/src/auto-reply/reply/inbound-dedupe.ts index f5ecfe0e8fb..1b32827d26e 100644 --- a/src/auto-reply/reply/inbound-dedupe.ts +++ b/src/auto-reply/reply/inbound-dedupe.ts @@ -1,12 +1,12 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { logVerbose, shouldLogVerbose } from "../../globals.js"; import { resolveGlobalDedupeCache, type DedupeCache } from "../../infra/dedupe.js"; import { channelRouteDedupeKey } from "../../plugin-sdk/channel-route.js"; import { parseAgentSessionKey } from "../../sessions/session-key-utils.js"; import { resolveGlobalSingleton } from "../../shared/global-singleton.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { resolveCommandTurnTargetSessionKey } from "../command-turn-context.js"; import type { MsgContext } from "../templating.js"; diff --git a/src/auto-reply/reply/inbound-media.ts b/src/auto-reply/reply/inbound-media.ts index 23383bda6a4..64ae17be012 100644 --- a/src/auto-reply/reply/inbound-media.ts +++ b/src/auto-reply/reply/inbound-media.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export type InboundMediaContext = { StickerMediaIncluded?: unknown; diff --git a/src/auto-reply/reply/inbound-meta.ts b/src/auto-reply/reply/inbound-meta.ts index f5626c136a8..e9ba588adc7 100644 --- a/src/auto-reply/reply/inbound-meta.ts +++ b/src/auto-reply/reply/inbound-meta.ts @@ -1,10 +1,10 @@ +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { normalizeChatType } from "../../channels/chat-type.js"; import { getLoadedChannelPluginById } from "../../channels/plugins/registry-loaded.js"; import type { ChannelPlugin } from "../../channels/plugins/types.plugin.js"; import { normalizeAnyChannelId } from "../../channels/registry.js"; import { resolveSenderLabel } from "../../channels/sender-label.js"; -import { isRecord } from "../../shared/record-coerce.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { truncateUtf16Safe } from "../../utils.js"; import type { EnvelopeFormatOptions } from "../envelope.js"; import { formatEnvelopeTimestamp } from "../envelope.js"; diff --git a/src/auto-reply/reply/mentions.ts b/src/auto-reply/reply/mentions.ts index 3eab85f7f2c..6421811e614 100644 --- a/src/auto-reply/reply/mentions.ts +++ b/src/auto-reply/reply/mentions.ts @@ -1,3 +1,8 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveAgentConfig } from "../../agents/agent-scope.js"; import type { ChannelId } from "../../channels/plugins/channel-id.types.js"; import { getLoadedChannelPluginById } from "../../channels/plugins/registry-loaded.js"; @@ -6,11 +11,6 @@ import { normalizeAnyChannelId } from "../../channels/registry.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { createSubsystemLogger } from "../../logging/subsystem.js"; import { compileConfigRegexes, type ConfigRegexRejectReason } from "../../security/config-regex.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { escapeRegExp } from "../../utils.js"; import type { MsgContext } from "../templating.js"; import type { ExplicitMentionSignal } from "./mentions.types.js"; diff --git a/src/auto-reply/reply/message-preprocess-hooks.ts b/src/auto-reply/reply/message-preprocess-hooks.ts index 34a84ddea53..35687145f26 100644 --- a/src/auto-reply/reply/message-preprocess-hooks.ts +++ b/src/auto-reply/reply/message-preprocess-hooks.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { fireAndForgetHook } from "../../hooks/fire-and-forget.js"; import { createInternalHookEvent, triggerInternalHook } from "../../hooks/internal-hooks.js"; @@ -6,7 +7,6 @@ import { toInternalMessagePreprocessedContext, toInternalMessageTranscribedContext, } from "../../hooks/message-hook-mappers.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { FinalizedMsgContext } from "../templating.js"; export function emitPreAgentMessageHooks(params: { diff --git a/src/auto-reply/reply/model-selection-directive.ts b/src/auto-reply/reply/model-selection-directive.ts index 880c9aad8a9..9269cd6c9e6 100644 --- a/src/auto-reply/reply/model-selection-directive.ts +++ b/src/auto-reply/reply/model-selection-directive.ts @@ -1,7 +1,7 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { splitTrailingAuthProfile } from "../../agents/model-ref-profile.js"; import { isModelKeyAllowedBySet } from "../../agents/model-selection-shared.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; export type ModelAliasIndex = { byAlias: Map< diff --git a/src/auto-reply/reply/normalize-reply.ts b/src/auto-reply/reply/normalize-reply.ts index ed5405dd1b1..cd5ab304b53 100644 --- a/src/auto-reply/reply/normalize-reply.ts +++ b/src/auto-reply/reply/normalize-reply.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { sanitizeUserFacingText } from "../../agents/embedded-agent-helpers/sanitize-user-facing-text.js"; import { hasReplyPayloadContent } from "../../interactive/payload.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { stripHeartbeatToken } from "../heartbeat.js"; import { copyReplyPayloadMetadata } from "../reply-payload.js"; import { diff --git a/src/auto-reply/reply/origin-routing.ts b/src/auto-reply/reply/origin-routing.ts index e05ba9b0021..bf8876d0e66 100644 --- a/src/auto-reply/reply/origin-routing.ts +++ b/src/auto-reply/reply/origin-routing.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { OriginatingChannelType } from "../templating.js"; export function resolveOriginMessageProvider(params: { diff --git a/src/auto-reply/reply/plugins-commands.ts b/src/auto-reply/reply/plugins-commands.ts index da3d5a2cea6..db6778ed04c 100644 --- a/src/auto-reply/reply/plugins-commands.ts +++ b/src/auto-reply/reply/plugins-commands.ts @@ -1,7 +1,7 @@ import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; export type PluginsCommand = | { action: "list" } diff --git a/src/auto-reply/reply/post-compaction-context.ts b/src/auto-reply/reply/post-compaction-context.ts index 2ea2a0be72d..536f1f91249 100644 --- a/src/auto-reply/reply/post-compaction-context.ts +++ b/src/auto-reply/reply/post-compaction-context.ts @@ -1,11 +1,11 @@ import fs from "node:fs"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { resolveAgentContextLimits } from "../../agents/agent-scope.js"; import { resolveCronStyleNow } from "../../agents/current-time.js"; import { formatDateStamp, resolveUserTimezone } from "../../agents/date-time.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { openRootFile } from "../../infra/boundary-file-read.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; const MAX_CONTEXT_CHARS = 1800; const DEFAULT_POST_COMPACTION_SECTIONS = ["Session Startup", "Red Lines"]; diff --git a/src/auto-reply/reply/prompt-prelude.ts b/src/auto-reply/reply/prompt-prelude.ts index 42ff64bb37d..e9caf411c81 100644 --- a/src/auto-reply/reply/prompt-prelude.ts +++ b/src/auto-reply/reply/prompt-prelude.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { CurrentInboundPromptContext } from "../../agents/embedded-agent-runner/run/params.js"; import type { InboundEventKind } from "../../channels/inbound-event/kind.js"; import { annotateInterSessionPromptText } from "../../sessions/input-provenance.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { SourceReplyDeliveryMode } from "../get-reply-options.types.js"; import { HEARTBEAT_TRANSCRIPT_PROMPT } from "../heartbeat.js"; import { buildInboundMediaNote } from "../media-note.js"; diff --git a/src/auto-reply/reply/provider-request-error-classifier.ts b/src/auto-reply/reply/provider-request-error-classifier.ts index b7e1cd83603..bfc0f60c977 100644 --- a/src/auto-reply/reply/provider-request-error-classifier.ts +++ b/src/auto-reply/reply/provider-request-error-classifier.ts @@ -1,5 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { formatErrorMessage } from "../../infra/errors.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; export type ProviderRequestErrorCode = "provider_conversation_state_error"; diff --git a/src/auto-reply/reply/queue/cleanup.ts b/src/auto-reply/reply/queue/cleanup.ts index 5363a6b04ba..11b90492e7f 100644 --- a/src/auto-reply/reply/queue/cleanup.ts +++ b/src/auto-reply/reply/queue/cleanup.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveEmbeddedSessionLane } from "../../../agents/embedded-agent-runner/lanes.js"; import { clearCommandLane } from "../../../process/command-queue.js"; -import { normalizeOptionalString } from "../../../shared/string-coerce.js"; import { clearFollowupDrainCallback } from "./drain.js"; import { clearFollowupQueue } from "./state.js"; diff --git a/src/auto-reply/reply/queue/directive.ts b/src/auto-reply/reply/queue/directive.ts index 31b381b3dca..90e6fe64553 100644 --- a/src/auto-reply/reply/queue/directive.ts +++ b/src/auto-reply/reply/queue/directive.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { parseDurationMs } from "../../../cli/parse-duration.js"; import { parseStrictPositiveInteger } from "../../../infra/parse-finite-number.js"; -import { normalizeOptionalLowercaseString } from "../../../shared/string-coerce.js"; import { skipDirectiveArgPrefix, takeDirectiveToken } from "../directive-parsing.js"; import { normalizeQueueDropPolicy, normalizeQueueMode } from "./normalize.js"; import type { QueueDropPolicy, QueueMode } from "./types.js"; diff --git a/src/auto-reply/reply/queue/enqueue.ts b/src/auto-reply/reply/queue/enqueue.ts index 6604ff970c4..b4cbd68633a 100644 --- a/src/auto-reply/reply/queue/enqueue.ts +++ b/src/auto-reply/reply/queue/enqueue.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveGlobalDedupeCache } from "../../../infra/dedupe.js"; import { channelRouteDedupeKey } from "../../../plugin-sdk/channel-route.js"; -import { normalizeOptionalString } from "../../../shared/string-coerce.js"; import { applyQueueDropPolicy, shouldSkipQueueItem } from "../../../utils/queue-helpers.js"; import { kickFollowupDrainIfIdle, rememberFollowupDrainCallback } from "./drain.js"; import { getExistingFollowupQueue, getFollowupQueue } from "./state.js"; diff --git a/src/auto-reply/reply/queue/normalize.ts b/src/auto-reply/reply/queue/normalize.ts index 07c1be592e7..22c1b57c6db 100644 --- a/src/auto-reply/reply/queue/normalize.ts +++ b/src/auto-reply/reply/queue/normalize.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../../../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { QueueDropPolicy, QueueMode } from "./types.js"; export function normalizeQueueMode(raw?: string): QueueMode | undefined { diff --git a/src/auto-reply/reply/queue/settings-runtime.ts b/src/auto-reply/reply/queue/settings-runtime.ts index 5e40e13bba6..dba5635f534 100644 --- a/src/auto-reply/reply/queue/settings-runtime.ts +++ b/src/auto-reply/reply/queue/settings-runtime.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { getLoadedChannelPlugin } from "../../../channels/plugins/index.js"; -import { normalizeOptionalLowercaseString } from "../../../shared/string-coerce.js"; import { resolveQueueSettings as resolveQueueSettingsCore } from "./settings.js"; import type { QueueSettings, ResolveQueueSettingsParams } from "./types.js"; diff --git a/src/auto-reply/reply/queue/settings.ts b/src/auto-reply/reply/queue/settings.ts index 15c61a02296..aa57ee1ee46 100644 --- a/src/auto-reply/reply/queue/settings.ts +++ b/src/auto-reply/reply/queue/settings.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { InboundDebounceByProvider } from "../../../config/types.messages.js"; -import { normalizeOptionalLowercaseString } from "../../../shared/string-coerce.js"; import { normalizePersistedQueueMode, normalizeQueueDropPolicy, diff --git a/src/auto-reply/reply/queue/state.ts b/src/auto-reply/reply/queue/state.ts index 3dcdaa1fef2..a82bdaded15 100644 --- a/src/auto-reply/reply/queue/state.ts +++ b/src/auto-reply/reply/queue/state.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveGlobalMap } from "../../../shared/global-singleton.js"; -import { normalizeOptionalString } from "../../../shared/string-coerce.js"; import { applyQueueRuntimeSettings } from "../../../utils/queue-helpers.js"; import { completeFollowupRunLifecycle, diff --git a/src/auto-reply/reply/reply-elevated.ts b/src/auto-reply/reply/reply-elevated.ts index 360372f3baf..2ed9ba9476f 100644 --- a/src/auto-reply/reply/reply-elevated.ts +++ b/src/auto-reply/reply/reply-elevated.ts @@ -1,8 +1,8 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { resolveAgentConfig } from "../../agents/agent-scope.js"; import { getChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js"; import type { AgentElevatedAllowFromConfig, OpenClawConfig } from "../../config/config.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; -import { normalizeStringEntries } from "../../shared/string-normalization.js"; import type { MsgContext } from "../templating.js"; import { type AllowFromFormatter, diff --git a/src/auto-reply/reply/reply-inline.ts b/src/auto-reply/reply/reply-inline.ts index 59fe87888e0..c2d48e1ca2a 100644 --- a/src/auto-reply/reply/reply-inline.ts +++ b/src/auto-reply/reply/reply-inline.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { collapseInlineHorizontalWhitespace } from "./reply-inline-whitespace.js"; const INLINE_SIMPLE_COMMAND_ALIASES = new Map([ diff --git a/src/auto-reply/reply/reply-payloads-base.ts b/src/auto-reply/reply/reply-payloads-base.ts index 86e601695ef..81a009283bd 100644 --- a/src/auto-reply/reply/reply-payloads-base.ts +++ b/src/auto-reply/reply/reply-payloads-base.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { ReplyToMode } from "../../config/types.js"; import { hasReplyPayloadContent } from "../../interactive/payload.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { copyReplyPayloadMetadata } from "../reply-payload.js"; import type { OriginatingChannelType } from "../templating.js"; import type { ReplyPayload, ReplyThreadingPolicy } from "../types.js"; diff --git a/src/auto-reply/reply/reply-payloads-dedupe.ts b/src/auto-reply/reply/reply-payloads-dedupe.ts index 06be608958a..2edcb99717a 100644 --- a/src/auto-reply/reply/reply-payloads-dedupe.ts +++ b/src/auto-reply/reply/reply-payloads-dedupe.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { isMessagingToolDuplicate } from "../../agents/embedded-agent-helpers.js"; import type { MessagingToolSend } from "../../agents/embedded-agent-messaging.types.js"; import { getChannelPlugin } from "../../channels/plugins/index.js"; @@ -9,10 +13,6 @@ import { type ChannelRouteTargetInput, } from "../../plugin-sdk/channel-route.js"; import { normalizeOptionalAccountId } from "../../routing/account-id.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import type { ReplyPayload } from "../types.js"; export function filterMessagingToolDuplicates(params: { diff --git a/src/auto-reply/reply/reply-reference.ts b/src/auto-reply/reply/reply-reference.ts index 87e8669a3b1..488fb4651b6 100644 --- a/src/auto-reply/reply/reply-reference.ts +++ b/src/auto-reply/reply/reply-reference.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { ReplyToMode } from "../../config/types.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; export type ReplyReferencePlanner = { /** Returns the effective reply/thread id for the next send without updating state. */ diff --git a/src/auto-reply/reply/reply-run-registry.ts b/src/auto-reply/reply/reply-run-registry.ts index 6898d3b5533..48670d02c9e 100644 --- a/src/auto-reply/reply/reply-run-registry.ts +++ b/src/auto-reply/reply/reply-run-registry.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { markDiagnosticEmbeddedRunEnded, markDiagnosticEmbeddedRunStarted, } from "../../logging/diagnostic-run-activity.js"; import { resolveGlobalSingleton } from "../../shared/global-singleton.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; export type ReplyRunKey = string; diff --git a/src/auto-reply/reply/reply-threading.ts b/src/auto-reply/reply/reply-threading.ts index d07c0ad3b56..eb1d462eca7 100644 --- a/src/auto-reply/reply/reply-threading.ts +++ b/src/auto-reply/reply/reply-threading.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { getChannelPlugin } from "../../channels/plugins/index.js"; import type { ChannelThreadingAdapter } from "../../channels/plugins/types.core.js"; import { normalizeAnyChannelId } from "../../channels/registry.js"; import type { ReplyToMode } from "../../config/types.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { copyReplyPayloadMetadata, isReplyPayloadStatusNotice } from "../reply-payload.js"; import type { OriginatingChannelType } from "../templating.js"; import type { ReplyPayload, ReplyThreadingPolicy } from "../types.js"; diff --git a/src/auto-reply/reply/response-prefix-template.ts b/src/auto-reply/reply/response-prefix-template.ts index e8098757d89..f3a1fb06aeb 100644 --- a/src/auto-reply/reply/response-prefix-template.ts +++ b/src/auto-reply/reply/response-prefix-template.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; /** * Template interpolation for response prefix. diff --git a/src/auto-reply/reply/route-reply.ts b/src/auto-reply/reply/route-reply.ts index b135fc44c78..7345b6d5023 100644 --- a/src/auto-reply/reply/route-reply.ts +++ b/src/auto-reply/reply/route-reply.ts @@ -7,6 +7,7 @@ * across multiple providers. */ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { resolveSessionAgentId } from "../../agents/agent-scope.js"; import { resolveEffectiveMessagesConfig } from "../../agents/identity.js"; import { getBundledChannelPlugin } from "../../channels/plugins/bundled.js"; @@ -18,7 +19,6 @@ import { buildOutboundSessionContext } from "../../infra/outbound/session-contex import { hasReplyPayloadContent } from "../../interactive/payload.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; import type { SilentReplyConversationType } from "../../shared/silent-reply-policy.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { INTERNAL_MESSAGE_CHANNEL, normalizeMessageChannel } from "../../utils/message-channel.js"; import type { OriginatingChannelType } from "../templating.js"; import type { ReplyPayload } from "../types.js"; diff --git a/src/auto-reply/reply/runtime-policy-session-key.ts b/src/auto-reply/reply/runtime-policy-session-key.ts index 0bcd4c05b9b..27edc73b105 100644 --- a/src/auto-reply/reply/runtime-policy-session-key.ts +++ b/src/auto-reply/reply/runtime-policy-session-key.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { normalizeChatType } from "../../channels/chat-type.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { @@ -7,10 +11,6 @@ import { normalizeMainKey, resolveAgentIdFromSessionKey, } from "../../routing/session-key.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import type { MsgContext } from "../templating.js"; type RuntimePolicyContext = Pick< diff --git a/src/auto-reply/reply/session-delivery.ts b/src/auto-reply/reply/session-delivery.ts index e6e858b6829..2a8471b3077 100644 --- a/src/auto-reply/reply/session-delivery.ts +++ b/src/auto-reply/reply/session-delivery.ts @@ -1,11 +1,11 @@ -import type { SessionEntry } from "../../config/sessions.js"; -import { buildAgentMainSessionKey } from "../../routing/session-key.js"; -import { parseAgentSessionKey } from "../../sessions/session-key-utils.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { SessionEntry } from "../../config/sessions.js"; +import { buildAgentMainSessionKey } from "../../routing/session-key.js"; +import { parseAgentSessionKey } from "../../sessions/session-key-utils.js"; import { deliveryContextFromSession, deliveryContextKey, diff --git a/src/auto-reply/reply/session-reset-model.ts b/src/auto-reply/reply/session-reset-model.ts index d6b21413271..972811d5b66 100644 --- a/src/auto-reply/reply/session-reset-model.ts +++ b/src/auto-reply/reply/session-reset-model.ts @@ -1,4 +1,5 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { ModelCatalogEntry } from "../../agents/model-catalog.types.js"; import { buildAllowedModelSetWithFallbacks, @@ -8,7 +9,6 @@ import { resolveAgentModelFallbackValues } from "../../config/model-input.js"; import type { SessionEntry } from "../../config/sessions.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { applyModelOverrideToSessionEntry } from "../../sessions/model-overrides.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { MsgContext, TemplateContext } from "../templating.js"; import { modelKey, diff --git a/src/auto-reply/reply/session-system-events.ts b/src/auto-reply/reply/session-system-events.ts index cafa3a72777..92f9d2ab9f7 100644 --- a/src/auto-reply/reply/session-system-events.ts +++ b/src/auto-reply/reply/session-system-events.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveUserTimezone } from "../../agents/date-time.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { buildChannelSummary } from "../../infra/channel-summary.js"; @@ -12,10 +16,6 @@ import { peekSystemEventEntries, type SystemEvent, } from "../../infra/system-events.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; function selectGenericSystemEvents(events: readonly SystemEvent[]): SystemEvent[] { return events.filter((event) => !isExecCompletionEvent(event.text)); diff --git a/src/auto-reply/reply/session-updates.ts b/src/auto-reply/reply/session-updates.ts index cb230ac9734..900a8e28cad 100644 --- a/src/auto-reply/reply/session-updates.ts +++ b/src/auto-reply/reply/session-updates.ts @@ -1,5 +1,6 @@ import crypto from "node:crypto"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveSessionAgentId } from "../../agents/agent-scope.js"; import { canExecRequestNode } from "../../agents/exec-defaults.js"; import { @@ -19,7 +20,6 @@ import { resolveStableSessionEndTranscript } from "../../gateway/session-transcr import { logVerbose } from "../../globals.js"; import { getGlobalHookRunner } from "../../plugins/hook-runner-global.js"; import { resolveAgentIdFromSessionKey } from "../../routing/session-key.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { getRemoteSkillEligibility } from "../../skills/runtime/remote.js"; import { resolveReusableWorkspaceSkillSnapshot } from "../../skills/runtime/session-snapshot.js"; import { buildSessionEndHookPayload, buildSessionStartHookPayload } from "./session-hooks.js"; diff --git a/src/auto-reply/reply/session.ts b/src/auto-reply/reply/session.ts index fcd20bb5b3b..e4636ffb72a 100644 --- a/src/auto-reply/reply/session.ts +++ b/src/auto-reply/reply/session.ts @@ -1,5 +1,10 @@ import crypto from "node:crypto"; import path from "node:path"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { retireSessionMcpRuntime } from "../../agents/agent-bundle-mcp-tools.js"; import { resolveSessionAgentId } from "../../agents/agent-scope.js"; import { clearBootstrapSnapshotOnSessionRollover } from "../../agents/bootstrap-cache.js"; @@ -46,11 +51,6 @@ import type { PluginHookSessionEndReason } from "../../plugins/hook-types.js"; import { isAcpSessionKey, normalizeMainKey } from "../../routing/session-key.js"; import { isInterSessionInputProvenance } from "../../sessions/input-provenance.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { normalizeDeliveryChannelRoute, normalizeSessionDeliveryFields, diff --git a/src/auto-reply/reply/stage-sandbox-media.ts b/src/auto-reply/reply/stage-sandbox-media.ts index 1096cc7f9fb..cb9f3ffc4c0 100644 --- a/src/auto-reply/reply/stage-sandbox-media.ts +++ b/src/auto-reply/reply/stage-sandbox-media.ts @@ -2,6 +2,7 @@ import { spawn } from "node:child_process"; import fs from "node:fs/promises"; import path from "node:path"; import { fileURLToPath } from "node:url"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { assertSandboxPath } from "../../agents/sandbox-paths.js"; import { ensureSandboxWorkspaceForSession } from "../../agents/sandbox.js"; import { slugifySessionKey } from "../../agents/sandbox/shared.js"; @@ -14,7 +15,6 @@ import { resolveChannelRemoteInboundAttachmentRoots } from "../../media/channel- import { isInboundPathAllowed } from "../../media/inbound-path-policy.js"; import { resolveInboundMediaReference } from "../../media/media-reference.js"; import { getMediaDir, MEDIA_MAX_BYTES } from "../../media/store.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { CONFIG_DIR } from "../../utils.js"; import type { MsgContext, TemplateContext } from "../templating.js"; diff --git a/src/auto-reply/reply/startup-context.ts b/src/auto-reply/reply/startup-context.ts index 9d0cb673300..df5092b51e1 100644 --- a/src/auto-reply/reply/startup-context.ts +++ b/src/auto-reply/reply/startup-context.ts @@ -1,9 +1,9 @@ import fs from "node:fs"; import path from "node:path"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { formatDateStamp, resolveUserTimezone } from "../../agents/date-time.js"; import type { OpenClawConfig } from "../../config/config.js"; import { openRootFile } from "../../infra/boundary-file-read.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; const STARTUP_MEMORY_FILE_MAX_BYTES = 16_384; const STARTUP_MEMORY_FILE_MAX_CHARS = 1_200; diff --git a/src/auto-reply/reply/stored-model-override.ts b/src/auto-reply/reply/stored-model-override.ts index d73d9473a24..3d52fc6b5cd 100644 --- a/src/auto-reply/reply/stored-model-override.ts +++ b/src/auto-reply/reply/stored-model-override.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { hasSessionAutoModelFallbackProvenance } from "../../agents/agent-scope.js"; import { modelKey, @@ -6,7 +7,6 @@ import { } from "../../agents/model-selection.js"; import { resolveSessionParentSessionKey } from "../../channels/plugins/session-conversation.js"; import type { SessionEntry } from "../../config/sessions/types.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; export type StoredModelOverride = { provider?: string; diff --git a/src/auto-reply/reply/subagents-utils.ts b/src/auto-reply/reply/subagents-utils.ts index dc1f6fe34ae..fba565ffa7a 100644 --- a/src/auto-reply/reply/subagents-utils.ts +++ b/src/auto-reply/reply/subagents-utils.ts @@ -1,8 +1,8 @@ -import type { SubagentRunRecord } from "../../agents/subagent-registry.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { SubagentRunRecord } from "../../agents/subagent-registry.js"; import { sanitizeTaskStatusText } from "../../tasks/task-status.js"; import { truncateUtf16Safe } from "../../utils.js"; diff --git a/src/auto-reply/reply/typing-mode.ts b/src/auto-reply/reply/typing-mode.ts index 8b90552f131..ce3afd91fd3 100644 --- a/src/auto-reply/reply/typing-mode.ts +++ b/src/auto-reply/reply/typing-mode.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { TypingMode } from "../../config/types.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { SourceReplyDeliveryMode } from "../get-reply-options.types.js"; import { isSilentReplyText, SILENT_REPLY_TOKEN } from "../tokens.js"; import type { TypingPolicy } from "../types.js"; diff --git a/src/auto-reply/reply/typing.ts b/src/auto-reply/reply/typing.ts index 8b135a0ed3e..b7cf54205a6 100644 --- a/src/auto-reply/reply/typing.ts +++ b/src/auto-reply/reply/typing.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { createTypingKeepaliveLoop } from "../../channels/typing-lifecycle.js"; import { createTypingStartGuard } from "../../channels/typing-start-guard.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { isSilentReplyPrefixText, isSilentReplyText, SILENT_REPLY_TOKEN } from "../tokens.js"; export type TypingController = { diff --git a/src/auto-reply/send-policy.ts b/src/auto-reply/send-policy.ts index bcccfa98745..b727249e5ff 100644 --- a/src/auto-reply/send-policy.ts +++ b/src/auto-reply/send-policy.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { normalizeCommandBody } from "./commands-registry.js"; import { stripInboundMetadata } from "./reply/strip-inbound-meta.js"; diff --git a/src/auto-reply/test-helpers/command-auth-registry-fixture.ts b/src/auto-reply/test-helpers/command-auth-registry-fixture.ts index f5845ea93c0..53221ed2431 100644 --- a/src/auto-reply/test-helpers/command-auth-registry-fixture.ts +++ b/src/auto-reply/test-helpers/command-auth-registry-fixture.ts @@ -1,8 +1,8 @@ +import { lowercasePreservingWhitespace } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { afterEach, beforeEach } from "vitest"; import { normalizeE164 } from "../../plugin-sdk/account-resolution.js"; import { setActivePluginRegistry } from "../../plugins/runtime.js"; -import { lowercasePreservingWhitespace } from "../../shared/string-coerce.js"; -import { normalizeStringEntries } from "../../shared/string-normalization.js"; import { createOutboundTestPlugin, createTestRegistry } from "../../test-utils/channel-plugins.js"; function formatDiscordAllowFromEntries(allowFrom: Array): string[] { diff --git a/src/auto-reply/thinking.shared.ts b/src/auto-reply/thinking.shared.ts index 5629d7aa526..4a48fe8a003 100644 --- a/src/auto-reply/thinking.shared.ts +++ b/src/auto-reply/thinking.shared.ts @@ -2,7 +2,7 @@ import { normalizeFastMode, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; +} from "../../packages/normalization-core/src/string-coerce.js"; export { normalizeFastMode }; diff --git a/src/auto-reply/thinking.ts b/src/auto-reply/thinking.ts index 264e38b59af..5c63c3f84f1 100644 --- a/src/auto-reply/thinking.ts +++ b/src/auto-reply/thinking.ts @@ -31,6 +31,10 @@ export type { UsageDisplayLevel, VerboseLevel, } from "./thinking.shared.js"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveProviderBinaryThinking, resolveProviderDefaultThinkingLevel, @@ -38,10 +42,6 @@ import { resolveProviderXHighThinking, } from "../plugins/provider-thinking.js"; import type { ProviderThinkingProfile } from "../plugins/provider-thinking.types.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; export type ThinkingLevelOption = { id: ThinkLevel; diff --git a/src/auto-reply/tool-meta.ts b/src/auto-reply/tool-meta.ts index 136875ea59c..9b261633067 100644 --- a/src/auto-reply/tool-meta.ts +++ b/src/auto-reply/tool-meta.ts @@ -1,5 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { formatToolSummary, resolveToolDisplay } from "../agents/tool-display.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { shortenHomeInString, shortenHomePath } from "../utils.js"; type ToolAggregateOptions = { diff --git a/src/channels/account-snapshot-fields.ts b/src/channels/account-snapshot-fields.ts index e89ca531e9f..fc2cf2a54c8 100644 --- a/src/channels/account-snapshot-fields.ts +++ b/src/channels/account-snapshot-fields.ts @@ -1,7 +1,7 @@ import { stripUrlUserInfo } from "@openclaw/net-policy/url-userinfo"; -import { asFiniteNumber } from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; +import { asFiniteNumber } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { isRecord } from "../utils.js"; import { asBoolean } from "../utils/boolean.js"; import type { ChannelAccountSnapshot } from "./plugins/types.core.js"; diff --git a/src/channels/account-summary.ts b/src/channels/account-summary.ts index c2b4a271670..324026e694a 100644 --- a/src/channels/account-summary.ts +++ b/src/channels/account-summary.ts @@ -1,5 +1,5 @@ +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { isRecord } from "../utils.js"; import { projectSafeChannelAccountSnapshotFields } from "./account-snapshot-fields.js"; import type { ChannelAccountSnapshot } from "./plugins/types.core.js"; diff --git a/src/channels/allow-from.ts b/src/channels/allow-from.ts index 83d7836b0ec..f30ed702aa9 100644 --- a/src/channels/allow-from.ts +++ b/src/channels/allow-from.ts @@ -1,4 +1,4 @@ -import { normalizeStringEntries } from "../shared/string-normalization.js"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; export const ACCESS_GROUP_ALLOW_FROM_PREFIX = "accessGroup:"; diff --git a/src/channels/allowlist-match.ts b/src/channels/allowlist-match.ts index e65f58e3c6b..7ffa000913d 100644 --- a/src/channels/allowlist-match.ts +++ b/src/channels/allowlist-match.ts @@ -1,7 +1,7 @@ import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; export type AllowlistMatchSource = | "wildcard" diff --git a/src/channels/allowlists/resolve-utils.ts b/src/channels/allowlists/resolve-utils.ts index 9b16596b434..b9e24d61eaf 100644 --- a/src/channels/allowlists/resolve-utils.ts +++ b/src/channels/allowlists/resolve-utils.ts @@ -1,9 +1,9 @@ -import { mapAllowFromEntries } from "openclaw/plugin-sdk/channel-config-helpers"; -import type { RuntimeEnv } from "../../runtime.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { mapAllowFromEntries } from "openclaw/plugin-sdk/channel-config-helpers"; +import type { RuntimeEnv } from "../../runtime.js"; import { summarizeStringEntries } from "../../shared/string-sample.js"; export type AllowlistUserResolutionLike = { diff --git a/src/channels/bundled-channel-catalog-read.ts b/src/channels/bundled-channel-catalog-read.ts index 7c77b9102e9..97743ff6591 100644 --- a/src/channels/bundled-channel-catalog-read.ts +++ b/src/channels/bundled-channel-catalog-read.ts @@ -1,11 +1,11 @@ import fs from "node:fs"; import path from "node:path"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { tryReadJsonSync } from "../infra/json-files.js"; import { resolveOpenClawPackageRootSync } from "../infra/openclaw-root.js"; import { resolveBundledPluginsDir } from "../plugins/bundled-dir.js"; import type { PluginPackageChannel } from "../plugins/manifest.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; type ChannelCatalogEntryLike = { openclaw?: { diff --git a/src/channels/channel-config.ts b/src/channels/channel-config.ts index fbca00dcf55..48c6c4c4ef4 100644 --- a/src/channels/channel-config.ts +++ b/src/channels/channel-config.ts @@ -1,5 +1,5 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { normalizeUniqueSingleOrTrimmedStringList } from "../shared/string-normalization.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { normalizeUniqueSingleOrTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; export type ChannelMatchSource = "direct" | "parent" | "wildcard"; diff --git a/src/channels/chat-meta-shared.ts b/src/channels/chat-meta-shared.ts index d65d7702ccc..50610fa6419 100644 --- a/src/channels/chat-meta-shared.ts +++ b/src/channels/chat-meta-shared.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { PluginPackageChannel } from "../plugins/manifest.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { listBundledChannelCatalogEntries } from "./bundled-channel-catalog-read.js"; import { CHAT_CHANNEL_ORDER, type ChatChannelId } from "./ids.js"; import { buildManifestChannelMeta } from "./plugins/channel-meta.js"; diff --git a/src/channels/chat-type.ts b/src/channels/chat-type.ts index 2f2914df8cf..4fce0080123 100644 --- a/src/channels/chat-type.ts +++ b/src/channels/chat-type.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; export type ChatType = "direct" | "group" | "channel"; diff --git a/src/channels/config-presence.ts b/src/channels/config-presence.ts index 99df31ba432..02576f6f8e8 100644 --- a/src/channels/config-presence.ts +++ b/src/channels/config-presence.ts @@ -1,5 +1,7 @@ import fs from "node:fs"; import os from "node:os"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { hasBundledChannelPersistedAuthState, listBundledChannelIdsWithPersistedAuthState, @@ -8,8 +10,6 @@ import { resolveStateDir } from "../config/paths.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { hasNonEmptyString } from "../infra/outbound/channel-target.js"; import type { PluginDiscoveryResult } from "../plugins/discovery.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { isRecord } from "../utils.js"; import { listBundledChannelIds } from "./plugins/bundled-ids.js"; diff --git a/src/channels/conversation-label.ts b/src/channels/conversation-label.ts index 0c329e0d8ec..2d87ea03184 100644 --- a/src/channels/conversation-label.ts +++ b/src/channels/conversation-label.ts @@ -1,8 +1,8 @@ -import type { MsgContext } from "../auto-reply/templating.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { MsgContext } from "../auto-reply/templating.js"; import { normalizeChatType } from "./chat-type.js"; function extractConversationId(from?: string): string | undefined { diff --git a/src/channels/conversation-resolution.ts b/src/channels/conversation-resolution.ts index 3f466a04af3..405e59d19ed 100644 --- a/src/channels/conversation-resolution.ts +++ b/src/channels/conversation-resolution.ts @@ -1,3 +1,8 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { resolveTargetPrefixedChannel, @@ -9,11 +14,6 @@ import { resolveConversationIdFromTargets } from "../infra/outbound/conversation import { normalizeConversationTargetRef } from "../infra/outbound/session-binding-normalization.js"; import { stringifyRouteThreadId } from "../plugin-sdk/channel-route.js"; import { getActivePluginChannelRegistry } from "../plugins/runtime.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { getLoadedChannelPlugin, normalizeChannelId } from "./plugins/index.js"; import { resolveExplicitDeliveryTargetCompat } from "./plugins/target-parsing-loaded.js"; import { diff --git a/src/channels/direct-dm-guard-policy.ts b/src/channels/direct-dm-guard-policy.ts index af0c649d467..44c3cfcfc04 100644 --- a/src/channels/direct-dm-guard-policy.ts +++ b/src/channels/direct-dm-guard-policy.ts @@ -1,4 +1,4 @@ -import { resolveIntegerOption } from "../shared/number-coercion.js"; +import { resolveIntegerOption } from "@openclaw/normalization-core/number-coercion"; export type DirectDmPreCryptoGuardPolicy = { allowedKinds: readonly number[]; diff --git a/src/channels/ids.ts b/src/channels/ids.ts index d38f2fe52bf..a1e75213660 100644 --- a/src/channels/ids.ts +++ b/src/channels/ids.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { GENERATED_BUNDLED_CHANNEL_CONFIG_METADATA } from "../config/bundled-channel-config-metadata.generated.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import { listBundledChannelCatalogEntries } from "./bundled-channel-catalog-read.js"; export type ChatChannelId = string; diff --git a/src/channels/inbound-debounce-policy.ts b/src/channels/inbound-debounce-policy.ts index 457bd392259..790fed8b8d4 100644 --- a/src/channels/inbound-debounce-policy.ts +++ b/src/channels/inbound-debounce-policy.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { isControlCommandMessage } from "../auto-reply/command-detection.js"; import type { CommandNormalizeOptions } from "../auto-reply/commands-registry.js"; import { @@ -6,7 +7,6 @@ import { type InboundDebounceCreateParams, } from "../auto-reply/inbound-debounce.js"; import type { OpenClawConfig } from "../config/types.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; export function shouldDebounceTextInbound(params: { text: string | null | undefined; diff --git a/src/channels/inbound-event/media.ts b/src/channels/inbound-event/media.ts index f0da19e75be..73e497c5581 100644 --- a/src/channels/inbound-event/media.ts +++ b/src/channels/inbound-event/media.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString as normalizeString } from "@openclaw/normalization-core/string-coerce"; import type { HistoryMediaEntry } from "../../auto-reply/reply/history.types.js"; -import { normalizeOptionalString as normalizeString } from "../../shared/string-coerce.js"; import type { InboundMediaFacts } from "../turn/types.js"; export type ChannelInboundMediaInput = { diff --git a/src/channels/message-access/allowlist.ts b/src/channels/message-access/allowlist.ts index 587848f5cd1..24a554f2abd 100644 --- a/src/channels/message-access/allowlist.ts +++ b/src/channels/message-access/allowlist.ts @@ -1,4 +1,4 @@ -import { uniqueStrings } from "../../shared/string-normalization.js"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { ChannelIngressPolicyInput, ChannelIngressState, diff --git a/src/channels/message-access/decision.ts b/src/channels/message-access/decision.ts index 9f642e680d7..75c6807012b 100644 --- a/src/channels/message-access/decision.ts +++ b/src/channels/message-access/decision.ts @@ -1,4 +1,4 @@ -import { uniqueStrings } from "../../shared/string-normalization.js"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { resolveCommandAuthorizedFromAuthorizers } from "../command-gating.js"; import { resolveInboundMentionDecision } from "../mention-gating.js"; import { applyMutableIdentifierPolicy, redactedAllowlistDiagnostics } from "./allowlist.js"; diff --git a/src/channels/message-access/dm-allow-state.ts b/src/channels/message-access/dm-allow-state.ts index 40bcba333a4..18f67a1c110 100644 --- a/src/channels/message-access/dm-allow-state.ts +++ b/src/channels/message-access/dm-allow-state.ts @@ -1,4 +1,4 @@ -import { normalizeStringEntries } from "../../shared/string-normalization.js"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { ChannelId } from "../plugins/types.public.js"; import { readChannelIngressStoreAllowFromForDmPolicy } from "./runtime.js"; diff --git a/src/channels/message-access/runtime-access-groups.ts b/src/channels/message-access/runtime-access-groups.ts index f6e5b26f5fd..0e0acdb9742 100644 --- a/src/channels/message-access/runtime-access-groups.ts +++ b/src/channels/message-access/runtime-access-groups.ts @@ -1,4 +1,7 @@ -import { normalizeStringEntries, uniqueStrings } from "../../shared/string-normalization.js"; +import { + normalizeStringEntries, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { parseAccessGroupAllowFromEntry } from "../allow-from.js"; import type { ChannelIngressAdapter, ResolveChannelMessageIngressParams } from "./runtime-types.js"; import type { AccessGroupMembershipFact, ChannelIngressChannelId } from "./types.js"; diff --git a/src/channels/message-access/runtime.ts b/src/channels/message-access/runtime.ts index be629d8b125..84d79991e41 100644 --- a/src/channels/message-access/runtime.ts +++ b/src/channels/message-access/runtime.ts @@ -1,6 +1,9 @@ +import { + normalizeStringEntries, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { readChannelAllowFromStore } from "../../pairing/pairing-store.js"; import type { PairingChannel } from "../../pairing/pairing-store.types.js"; -import { normalizeStringEntries, uniqueStrings } from "../../shared/string-normalization.js"; import { mergeDmAllowFromSources, resolveGroupAllowFromSources } from "../allow-from.js"; import { decideChannelIngress } from "./decision.js"; import { diff --git a/src/channels/message-access/state.ts b/src/channels/message-access/state.ts index bd4e0fb0a0b..9f67e626620 100644 --- a/src/channels/message-access/state.ts +++ b/src/channels/message-access/state.ts @@ -1,4 +1,7 @@ -import { normalizeStringEntries, uniqueStrings } from "../../shared/string-normalization.js"; +import { + normalizeStringEntries, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { parseAccessGroupAllowFromEntry } from "../allow-from.js"; import type { AccessGroupMembershipFact, diff --git a/src/channels/message/receipt.ts b/src/channels/message/receipt.ts index d5dab3a83d2..657bbe9269f 100644 --- a/src/channels/message/receipt.ts +++ b/src/channels/message/receipt.ts @@ -1,4 +1,4 @@ -import { normalizeUniqueStringEntries } from "../../shared/string-normalization.js"; +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { MessageReceipt, MessageReceiptPartKind, diff --git a/src/channels/model-overrides.ts b/src/channels/model-overrides.ts index edcceb8bb4e..89e97259214 100644 --- a/src/channels/model-overrides.ts +++ b/src/channels/model-overrides.ts @@ -1,12 +1,12 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { parseRawSessionConversationRef, parseThreadSessionSuffix, } from "../sessions/session-key-utils.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { normalizeMessageChannel } from "../utils/message-channel.js"; import { buildChannelKeyCandidates, diff --git a/src/channels/native-command-session-targets.ts b/src/channels/native-command-session-targets.ts index 5850f769e42..d7e05733070 100644 --- a/src/channels/native-command-session-targets.ts +++ b/src/channels/native-command-session-targets.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export type ResolveNativeCommandSessionTargetsParams = { agentId: string; diff --git a/src/channels/plugins/account-helpers.ts b/src/channels/plugins/account-helpers.ts index 7d649662ab7..bb13e593d69 100644 --- a/src/channels/plugins/account-helpers.ts +++ b/src/channels/plugins/account-helpers.ts @@ -1,3 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { resolveAccountEntry, @@ -8,8 +10,6 @@ import { normalizeAccountId, normalizeOptionalAccountId, } from "../../routing/session-key.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; -import { normalizeUniqueStringEntries } from "../../shared/string-normalization.js"; import type { ChannelAccountSnapshot } from "./types.core.js"; export function createAccountListHelpers( diff --git a/src/channels/plugins/acp-configured-binding-consumer.ts b/src/channels/plugins/acp-configured-binding-consumer.ts index d1b45ce7b75..7d903dbb41f 100644 --- a/src/channels/plugins/acp-configured-binding-consumer.ts +++ b/src/channels/plugins/acp-configured-binding-consumer.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, +} from "@openclaw/normalization-core/string-coerce"; import { buildConfiguredAcpSessionKey, normalizeBindingConfig, @@ -13,10 +17,6 @@ import { resolveDefaultAgentId, } from "../../agents/agent-scope.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, -} from "../../shared/string-coerce.js"; import type { ConfiguredBindingRuleConfig, ConfiguredBindingTargetFactory, diff --git a/src/channels/plugins/bootstrap-registry.ts b/src/channels/plugins/bootstrap-registry.ts index 9d7b4523a7f..fb4a1c742a6 100644 --- a/src/channels/plugins/bootstrap-registry.ts +++ b/src/channels/plugins/bootstrap-registry.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { listBundledChannelPluginIdsForRoot } from "./bundled-ids.js"; import { resolveBundledChannelRootScope } from "./bundled-root.js"; import { diff --git a/src/channels/plugins/bundled.ts b/src/channels/plugins/bundled.ts index bc4abc20844..850487f2903 100644 --- a/src/channels/plugins/bundled.ts +++ b/src/channels/plugins/bundled.ts @@ -1,4 +1,5 @@ import path from "node:path"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { extractErrorCode, formatErrorMessage } from "../../infra/errors.js"; import { isPathInside } from "../../infra/path-guards.js"; @@ -21,7 +22,6 @@ import { type PluginModuleLoaderCache, } from "../../plugins/plugin-module-loader-cache.js"; import type { PluginRuntime } from "../../plugins/runtime/types.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { resolveBundledChannelRootScope, type BundledChannelRootScope } from "./bundled-root.js"; import { normalizeChannelMeta } from "./meta-normalization.js"; import { loadChannelPluginModule } from "./module-loader.js"; diff --git a/src/channels/plugins/catalog.ts b/src/channels/plugins/catalog.ts index 49790ca9711..7592830859b 100644 --- a/src/channels/plugins/catalog.ts +++ b/src/channels/plugins/catalog.ts @@ -1,4 +1,9 @@ import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { + normalizeStringEntries, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { MANIFEST_KEY } from "../../compat/legacy-names.js"; import type { PluginInstallRecord } from "../../config/types.plugins.js"; import { tryReadJsonSync } from "../../infra/json-files.js"; @@ -14,8 +19,6 @@ import type { OpenClawPackageManifest } from "../../plugins/manifest.js"; import type { PluginPackageChannel, PluginPackageInstall } from "../../plugins/manifest.js"; import { listOfficialExternalChannelCatalogEntries } from "../../plugins/official-external-plugin-catalog.js"; import type { PluginOrigin } from "../../plugins/plugin-origin.types.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; -import { normalizeStringEntries, uniqueStrings } from "../../shared/string-normalization.js"; import { isRecord, resolveConfigDir, resolveUserPath } from "../../utils.js"; import { buildManifestChannelMeta } from "./channel-meta.js"; import type { ChannelMeta } from "./types.public.js"; diff --git a/src/channels/plugins/chat-target-prefixes.ts b/src/channels/plugins/chat-target-prefixes.ts index 6bea6a6d9b4..50332d71625 100644 --- a/src/channels/plugins/chat-target-prefixes.ts +++ b/src/channels/plugins/chat-target-prefixes.ts @@ -1,9 +1,9 @@ -import { parseStrictInteger } from "../../infra/parse-finite-number.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../../shared/string-coerce.js"; -import { normalizeStringEntries } from "../../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; +import { parseStrictInteger } from "../../infra/parse-finite-number.js"; export type ServicePrefix = { prefix: string; service: TService }; diff --git a/src/channels/plugins/config-writes.ts b/src/channels/plugins/config-writes.ts index 43e0fa9e0b0..c32c75e7bc0 100644 --- a/src/channels/plugins/config-writes.ts +++ b/src/channels/plugins/config-writes.ts @@ -1,5 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { authorizeConfigWriteShared, canBypassConfigWritePolicyShared, diff --git a/src/channels/plugins/configured-binding-compiler.ts b/src/channels/plugins/configured-binding-compiler.ts index 5e3a65ed522..c68a7544b70 100644 --- a/src/channels/plugins/configured-binding-compiler.ts +++ b/src/channels/plugins/configured-binding-compiler.ts @@ -1,10 +1,10 @@ -import { listConfiguredBindings } from "../../config/bindings.js"; -import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { pickFirstExistingAgentId } from "../../routing/resolve-route.js"; import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { listConfiguredBindings } from "../../config/bindings.js"; +import type { OpenClawConfig } from "../../config/types.openclaw.js"; +import { pickFirstExistingAgentId } from "../../routing/resolve-route.js"; import { resolveChannelConfiguredBindingProvider } from "./binding-provider.js"; import type { CompiledConfiguredBinding, ConfiguredBindingChannel } from "./binding-types.js"; import { resolveConfiguredBindingConsumer } from "./configured-binding-consumers.js"; diff --git a/src/channels/plugins/configured-binding-match.ts b/src/channels/plugins/configured-binding-match.ts index 0e62a3d3e81..1f0f6df5270 100644 --- a/src/channels/plugins/configured-binding-match.ts +++ b/src/channels/plugins/configured-binding-match.ts @@ -1,9 +1,9 @@ -import type { ConversationRef } from "../../infra/outbound/session-binding-service.js"; -import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js"; import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { ConversationRef } from "../../infra/outbound/session-binding-service.js"; +import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js"; import type { CompiledConfiguredBinding, ConfiguredBindingChannel, diff --git a/src/channels/plugins/directory-config-helpers.ts b/src/channels/plugins/directory-config-helpers.ts index bb0e7ffc9bc..37e129b3df2 100644 --- a/src/channels/plugins/directory-config-helpers.ts +++ b/src/channels/plugins/directory-config-helpers.ts @@ -1,9 +1,9 @@ -import type { OpenClawConfig } from "../../config/types.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../../shared/string-coerce.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; +import type { OpenClawConfig } from "../../config/types.js"; import type { DirectoryConfigParams } from "./directory-types.js"; import type { ChannelDirectoryEntry } from "./types.public.js"; diff --git a/src/channels/plugins/dm-access.ts b/src/channels/plugins/dm-access.ts index df3105a0a4e..53c2c869dff 100644 --- a/src/channels/plugins/dm-access.ts +++ b/src/channels/plugins/dm-access.ts @@ -1,4 +1,4 @@ -import { normalizeStringEntries } from "../../shared/string-normalization.js"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; export type ChannelDmAllowFromMode = "topOnly" | "topOrNested" | "nestedOnly"; export type ChannelDmPolicy = "pairing" | "allowlist" | "open" | "disabled"; diff --git a/src/channels/plugins/helpers.ts b/src/channels/plugins/helpers.ts index 820420ee307..dd2291df367 100644 --- a/src/channels/plugins/helpers.ts +++ b/src/channels/plugins/helpers.ts @@ -1,7 +1,7 @@ +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { formatCliCommand } from "../../cli/command-format.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { DEFAULT_ACCOUNT_ID } from "../../routing/session-key.js"; -import { normalizeStringEntries } from "../../shared/string-normalization.js"; import type { ChannelSecurityDmPolicy } from "./types.core.js"; import type { ChannelPlugin } from "./types.plugin.js"; diff --git a/src/channels/plugins/message-action-discovery.ts b/src/channels/plugins/message-action-discovery.ts index e111d91eb53..343f6b3d489 100644 --- a/src/channels/plugins/message-action-discovery.ts +++ b/src/channels/plugins/message-action-discovery.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { TSchema } from "typebox"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { formatErrorMessage } from "../../infra/errors.js"; import { defaultRuntime } from "../../runtime.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; import { normalizeAnyChannelId } from "../registry.js"; import { getChannelPlugin, getLoadedChannelPlugin, listChannelPlugins } from "./index.js"; import type { ChannelMessageCapability } from "./message-capabilities.js"; diff --git a/src/channels/plugins/meta-normalization.ts b/src/channels/plugins/meta-normalization.ts index 91c71eac931..07cabf75c79 100644 --- a/src/channels/plugins/meta-normalization.ts +++ b/src/channels/plugins/meta-normalization.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { ChannelMeta } from "./types.public.js"; function stripRequiredChannelMeta(meta?: Partial | null) { diff --git a/src/channels/plugins/native-approval-prompt.ts b/src/channels/plugins/native-approval-prompt.ts index 1208a8f2ac7..8ec70801ebe 100644 --- a/src/channels/plugins/native-approval-prompt.ts +++ b/src/channels/plugins/native-approval-prompt.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { resolveChannelApprovalCapability } from "./approvals.js"; import type { ChannelPlugin } from "./types.plugin.js"; diff --git a/src/channels/plugins/outbound/presentation-limits.ts b/src/channels/plugins/outbound/presentation-limits.ts index 7edbced269b..2002749351e 100644 --- a/src/channels/plugins/outbound/presentation-limits.ts +++ b/src/channels/plugins/outbound/presentation-limits.ts @@ -1,10 +1,10 @@ +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { MessagePresentation, MessagePresentationBlock, MessagePresentationButton, MessagePresentationOption, } from "../../../interactive/payload.js"; -import { normalizeStringEntries } from "../../../shared/string-normalization.js"; import type { ChannelPresentationCapabilities } from "../outbound.types.js"; type ActionLimits = NonNullable["actions"]>; diff --git a/src/channels/plugins/package-state-probes.ts b/src/channels/plugins/package-state-probes.ts index 9591f88d053..3e0e51a9fee 100644 --- a/src/channels/plugins/package-state-probes.ts +++ b/src/channels/plugins/package-state-probes.ts @@ -1,5 +1,7 @@ import fs from "node:fs"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { formatErrorMessage } from "../../infra/errors.js"; import { createSubsystemLogger } from "../../logging/subsystem.js"; @@ -13,8 +15,6 @@ import { getCachedPluginModuleLoader, type PluginModuleLoaderCache, } from "../../plugins/plugin-module-loader-cache.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; -import { normalizeTrimmedStringList } from "../../shared/string-normalization.js"; import { loadChannelPluginModule, resolveExistingPluginModulePath } from "./module-loader.js"; type ChannelPackageStateChecker = (params: { diff --git a/src/channels/plugins/read-only-command-defaults.ts b/src/channels/plugins/read-only-command-defaults.ts index 6b0094ebb26..6ba1d994e69 100644 --- a/src/channels/plugins/read-only-command-defaults.ts +++ b/src/channels/plugins/read-only-command-defaults.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { isBlockedObjectKey } from "../../infra/prototype-keys.js"; import { isInstalledPluginEnabled } from "../../plugins/installed-plugin-index.js"; import type { PluginManifestRecord } from "../../plugins/manifest-registry.js"; import { resolvePluginMetadataSnapshot } from "../../plugins/plugin-metadata-snapshot.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { ChannelPlugin } from "./types.plugin.js"; const SAFE_MANIFEST_CHANNEL_ID_PATTERN = /^[a-z0-9][a-z0-9_-]{0,63}$/i; diff --git a/src/channels/plugins/read-only.ts b/src/channels/plugins/read-only.ts index 01ceaa200d0..fe15aa62f58 100644 --- a/src/channels/plugins/read-only.ts +++ b/src/channels/plugins/read-only.ts @@ -1,6 +1,10 @@ import { createHash } from "node:crypto"; import path from "node:path"; import { fileURLToPath, pathToFileURL } from "node:url"; +import { + sortUniqueStrings, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { sanitizeForLog } from "../../../packages/terminal-core/src/ansi.js"; import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/agent-scope.js"; import { resolveRuntimeConfigCacheKey } from "../../config/runtime-snapshot.js"; @@ -27,7 +31,6 @@ import { } from "../../plugins/plugin-module-loader-cache.js"; import { getActivePluginChannelRegistryVersion } from "../../plugins/runtime.js"; import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js"; -import { sortUniqueStrings, uniqueStrings } from "../../shared/string-normalization.js"; import { getBundledChannelSetupPlugin } from "./bundled.js"; import { isSafeManifestChannelId, diff --git a/src/channels/plugins/registry-loaded-read.ts b/src/channels/plugins/registry-loaded-read.ts index 47cfe3f1435..c03970f98b8 100644 --- a/src/channels/plugins/registry-loaded-read.ts +++ b/src/channels/plugins/registry-loaded-read.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { ActiveChannelPluginRuntimeShape } from "../../plugins/channel-registry-state.types.js"; import { getActivePluginChannelRegistryFromState } from "../../plugins/runtime-channel-state.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { ChannelPlugin } from "./types.plugin.js"; import type { ChannelId } from "./types.public.js"; diff --git a/src/channels/plugins/registry-loaded.ts b/src/channels/plugins/registry-loaded.ts index ea8d65d0603..b4fc3f6217c 100644 --- a/src/channels/plugins/registry-loaded.ts +++ b/src/channels/plugins/registry-loaded.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { ActiveChannelPluginRuntimeShape, ActivePluginChannelRegistration, } from "../../plugins/channel-registry-state.types.js"; import { getActivePluginChannelRegistryFromState } from "../../plugins/runtime-channel-state.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { CHAT_CHANNEL_ORDER } from "../registry.js"; export type LoadedChannelPlugin = ActiveChannelPluginRuntimeShape & { diff --git a/src/channels/plugins/registry.ts b/src/channels/plugins/registry.ts index 2ceeec069ea..7cbfb816997 100644 --- a/src/channels/plugins/registry.ts +++ b/src/channels/plugins/registry.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { normalizeAnyChannelId } from "../registry.js"; import { getBundledChannelPlugin } from "./bundled.js"; import { diff --git a/src/channels/plugins/session-conversation.ts b/src/channels/plugins/session-conversation.ts index 62ecae8f6b4..ac6fb521b28 100644 --- a/src/channels/plugins/session-conversation.ts +++ b/src/channels/plugins/session-conversation.ts @@ -1,3 +1,8 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeUniqueSingleOrTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import { getRuntimeConfigSnapshot } from "../../config/runtime-snapshot.js"; import { tryLoadActivatedBundledPluginPublicSurfaceModuleSync } from "../../plugin-sdk/facade-runtime.js"; import { @@ -6,11 +11,6 @@ import { type ParsedThreadSessionSuffix, type RawSessionConversationRef, } from "../../sessions/session-key-utils.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; -import { normalizeUniqueSingleOrTrimmedStringList } from "../../shared/string-normalization.js"; import { normalizeChannelId as normalizeChatChannelId } from "../registry.js"; import { getLoadedChannelPlugin, normalizeChannelId as normalizeAnyChannelId } from "./registry.js"; diff --git a/src/channels/plugins/session-thread-info-loaded.ts b/src/channels/plugins/session-thread-info-loaded.ts index 9462f65d6de..2ec8e1a44f2 100644 --- a/src/channels/plugins/session-thread-info-loaded.ts +++ b/src/channels/plugins/session-thread-info-loaded.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { parseRawSessionConversationRef, parseThreadSessionSuffix, type ParsedThreadSessionSuffix, } from "../../sessions/session-key-utils.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { getLoadedChannelPluginForRead } from "./registry-loaded-read.js"; type SessionConversationHookResult = { diff --git a/src/channels/plugins/setup-group-access.ts b/src/channels/plugins/setup-group-access.ts index 08ddc4f69f3..6982087abc6 100644 --- a/src/channels/plugins/setup-group-access.ts +++ b/src/channels/plugins/setup-group-access.ts @@ -1,4 +1,4 @@ -import { normalizeStringEntries } from "../../shared/string-normalization.js"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { WizardPrompter } from "../../wizard/prompts.js"; export type ChannelAccessPolicy = "allowlist" | "open" | "disabled"; diff --git a/src/channels/plugins/setup-promotion-helpers.ts b/src/channels/plugins/setup-promotion-helpers.ts index 180a94dc8c0..d87772a5f08 100644 --- a/src/channels/plugins/setup-promotion-helpers.ts +++ b/src/channels/plugins/setup-promotion-helpers.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { getBundledChannelPlugin, hasBundledChannelPackageSetupFeature } from "./bundled.js"; import { getLoadedChannelPlugin } from "./registry.js"; import { diff --git a/src/channels/plugins/setup-registry.ts b/src/channels/plugins/setup-registry.ts index db19cf77fc3..3be3ce4c974 100644 --- a/src/channels/plugins/setup-registry.ts +++ b/src/channels/plugins/setup-registry.ts @@ -1,8 +1,8 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { getActivePluginChannelRegistry, requireActivePluginRegistry, } from "../../plugins/runtime.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { CHAT_CHANNEL_ORDER, type ChatChannelId } from "../registry.js"; import { listBundledChannelSetupPlugins } from "./bundled.js"; import type { ChannelPlugin } from "./types.plugin.js"; diff --git a/src/channels/plugins/setup-wizard-helpers.ts b/src/channels/plugins/setup-wizard-helpers.ts index 6db4e474307..4ce5de6be53 100644 --- a/src/channels/plugins/setup-wizard-helpers.ts +++ b/src/channels/plugins/setup-wizard-helpers.ts @@ -1,10 +1,13 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { + normalizeStringEntries, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import type { DmPolicy, GroupPolicy } from "../../config/types.base.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { SecretInput } from "../../config/types.secrets.js"; import { resolveSecretInputModeForEnvSelection } from "../../plugins/provider-auth-mode.js"; import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; -import { normalizeStringEntries, uniqueStrings } from "../../shared/string-normalization.js"; import type { WizardPrompter } from "../../wizard/prompts.js"; import { resolveChannelDmAllowFrom, resolveChannelDmPolicy } from "./dm-access.js"; import { diff --git a/src/channels/plugins/setup-wizard.ts b/src/channels/plugins/setup-wizard.ts index a93f8be4287..7e3bdf19886 100644 --- a/src/channels/plugins/setup-wizard.ts +++ b/src/channels/plugins/setup-wizard.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { DEFAULT_ACCOUNT_ID } from "../../routing/session-key.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { configureChannelAccessWithAllowlist } from "./setup-group-access-configure.js"; import { promptResolvedAllowFrom, diff --git a/src/channels/plugins/status-issues/shared.ts b/src/channels/plugins/status-issues/shared.ts index 460eb83699c..c4cfdd43fdd 100644 --- a/src/channels/plugins/status-issues/shared.ts +++ b/src/channels/plugins/status-issues/shared.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../../../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { isRecord } from "../../../utils.js"; import type { ChannelAccountSnapshot, ChannelStatusIssue } from "../types.public.js"; export { isRecord }; diff --git a/src/channels/plugins/status.ts b/src/channels/plugins/status.ts index e6125035075..fb9da9aeddf 100644 --- a/src/channels/plugins/status.ts +++ b/src/channels/plugins/status.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { inspectChannelAccount } from "../account-inspection.js"; import { projectSafeChannelAccountSnapshotFields } from "../account-snapshot-fields.js"; import type { ChannelPlugin } from "./types.plugin.js"; diff --git a/src/channels/plugins/target-parsing-loaded.ts b/src/channels/plugins/target-parsing-loaded.ts index 2d7b5ef6fb1..3072f5a6428 100644 --- a/src/channels/plugins/target-parsing-loaded.ts +++ b/src/channels/plugins/target-parsing-loaded.ts @@ -1,13 +1,13 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, + normalizeOptionalThreadValue, +} from "@openclaw/normalization-core/string-coerce"; import { channelRouteTargetsMatchExact, channelRouteTargetsShareConversation, type ChannelRouteParsedTarget, } from "../../plugin-sdk/channel-route.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, - normalizeOptionalThreadValue, -} from "../../shared/string-coerce.js"; import { getChannelPlugin, normalizeChannelId } from "./index.js"; import { getLoadedChannelPluginForRead } from "./registry-loaded-read.js"; diff --git a/src/channels/plugins/thread-binding-api.ts b/src/channels/plugins/thread-binding-api.ts index 7d3a4628f26..3845310ca73 100644 --- a/src/channels/plugins/thread-binding-api.ts +++ b/src/channels/plugins/thread-binding-api.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { loadBundledPluginPublicArtifactModuleSync } from "../../plugins/public-surface-loader.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; type ThreadBindingPlacement = "current" | "child"; diff --git a/src/channels/registry-lookup.ts b/src/channels/registry-lookup.ts index 82130194ceb..743352ac092 100644 --- a/src/channels/registry-lookup.ts +++ b/src/channels/registry-lookup.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { ActivePluginChannelRegistration, ActivePluginChannelRegistry, } from "../plugins/channel-registry-state.types.js"; import { getActivePluginChannelRegistrySnapshotFromState } from "../plugins/runtime-channel-state.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; export type RegisteredChannelPluginEntry = ActivePluginChannelRegistration & { plugin: ActivePluginChannelRegistration["plugin"] & { diff --git a/src/channels/registry-normalize.ts b/src/channels/registry-normalize.ts index ed293cb6bf5..b7e63585f56 100644 --- a/src/channels/registry-normalize.ts +++ b/src/channels/registry-normalize.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { ChannelId } from "./plugins/channel-id.types.js"; import { findRegisteredChannelPluginEntry } from "./registry-lookup.js"; diff --git a/src/channels/registry.ts b/src/channels/registry.ts index bb020b52600..c77199d752e 100644 --- a/src/channels/registry.ts +++ b/src/channels/registry.ts @@ -1,7 +1,7 @@ import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; import { normalizeChatChannelId, type ChatChannelId } from "./ids.js"; import type { ChannelId } from "./plugins/channel-id.types.js"; import type { ChannelMeta } from "./plugins/types.core.js"; diff --git a/src/channels/reply-prefix.ts b/src/channels/reply-prefix.ts index 3a1b785e651..17108782618 100644 --- a/src/channels/reply-prefix.ts +++ b/src/channels/reply-prefix.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveAgentIdentity, resolveEffectiveMessagesConfig } from "../agents/identity.js"; import type { GetReplyOptions } from "../auto-reply/get-reply-options.types.js"; import { @@ -5,7 +6,6 @@ import { type ResponsePrefixContext, } from "../auto-reply/reply/response-prefix-template.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; type ModelSelectionContext = Parameters>[0]; diff --git a/src/channels/sender-identity.ts b/src/channels/sender-identity.ts index 5652d578df1..f313d6f4b98 100644 --- a/src/channels/sender-identity.ts +++ b/src/channels/sender-identity.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { MsgContext } from "../auto-reply/templating.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { normalizeChatType } from "./chat-type.js"; export function validateSenderIdentity(ctx: MsgContext): string[] { diff --git a/src/channels/sender-label.ts b/src/channels/sender-label.ts index 2ef44f593eb..33d46cb9f1f 100644 --- a/src/channels/sender-label.ts +++ b/src/channels/sender-label.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export type SenderLabelParams = { name?: string; diff --git a/src/channels/session.ts b/src/channels/session.ts index e1810a0babd..ae219f2a94a 100644 --- a/src/channels/session.ts +++ b/src/channels/session.ts @@ -1,7 +1,7 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { MsgContext } from "../auto-reply/templating.js"; import type { GroupKeyResolution } from "../config/sessions/types.js"; import { normalizeSessionKeyPreservingOpaquePeerIds } from "../sessions/session-key-utils.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import type { InboundLastRouteUpdate } from "./session.types.js"; export type { InboundLastRouteUpdate, RecordInboundSession } from "./session.types.js"; diff --git a/src/channels/status-reactions.ts b/src/channels/status-reactions.ts index 89fe0dc1e35..9b641916a3a 100644 --- a/src/channels/status-reactions.ts +++ b/src/channels/status-reactions.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { TOOL_DISPLAY_CONFIG } from "../agents/tool-display-config.js"; import { resolveToolDisplay } from "../agents/tool-display.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; /** * Channel-agnostic status reaction controller. diff --git a/src/channels/status/read-model.ts b/src/channels/status/read-model.ts index 8a26f757288..6215cd5cbd1 100644 --- a/src/channels/status/read-model.ts +++ b/src/channels/status/read-model.ts @@ -1,7 +1,7 @@ +import { asRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { DEFAULT_ACCOUNT_ID } from "../../routing/session-key.js"; -import { asRecord } from "../../shared/record-coerce.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; import { hasConfiguredUnavailableCredentialStatus } from "../account-snapshot-fields.js"; import type { ChannelAccountSnapshot } from "../plugins/types.public.js"; diff --git a/src/channels/streaming.ts b/src/channels/streaming.ts index a0599bc34b3..72baeddbbff 100644 --- a/src/channels/streaming.ts +++ b/src/channels/streaming.ts @@ -1,3 +1,5 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import { formatToolDetail, resolveToolDisplay } from "../agents/tool-display.js"; import { formatToolAggregate } from "../auto-reply/tool-meta.js"; import type { @@ -9,8 +11,6 @@ import type { StreamingMode, TextChunkMode, } from "../config/types.base.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { normalizeTrimmedStringList } from "../shared/string-normalization.js"; import { asBoolean } from "../utils/boolean.js"; export type { diff --git a/src/channels/targets.ts b/src/channels/targets.ts index d47b82c6e02..cd7d7c7f1aa 100644 --- a/src/channels/targets.ts +++ b/src/channels/targets.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export type { DirectoryConfigParams } from "./plugins/directory-types.js"; export type { ChannelDirectoryEntry } from "./plugins/types.public.js"; diff --git a/src/channels/thread-binding-id.ts b/src/channels/thread-binding-id.ts index 071bf67a82b..d5983ee3f8a 100644 --- a/src/channels/thread-binding-id.ts +++ b/src/channels/thread-binding-id.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export function resolveThreadBindingConversationIdFromBindingId(params: { accountId: string; diff --git a/src/channels/thread-bindings-messages.ts b/src/channels/thread-bindings-messages.ts index a00b5bc5cdc..fb3321108a6 100644 --- a/src/channels/thread-bindings-messages.ts +++ b/src/channels/thread-bindings-messages.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { prefixSystemMessage } from "../infra/system-message.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; const DEFAULT_THREAD_BINDING_FAREWELL_TEXT = "Session ended. Messages here will no longer be routed."; diff --git a/src/channels/thread-bindings-policy.ts b/src/channels/thread-bindings-policy.ts index 62d2e873fae..8a8ab598b3c 100644 --- a/src/channels/thread-bindings-policy.ts +++ b/src/channels/thread-bindings-policy.ts @@ -1,6 +1,6 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeAccountId } from "../routing/session-key.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { resolveThreadBindingLifecycle as resolveSharedThreadBindingLifecycle, type ThreadBindingLifecycleRecord, diff --git a/src/channels/transport/stall-watchdog.test.ts b/src/channels/transport/stall-watchdog.test.ts index fe9e55eb94c..e8551186fef 100644 --- a/src/channels/transport/stall-watchdog.test.ts +++ b/src/channels/transport/stall-watchdog.test.ts @@ -1,5 +1,5 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../../shared/number-coercion.js"; import { createArmableStallWatchdog } from "./stall-watchdog.js"; function createTestWatchdog( diff --git a/src/channels/transport/stall-watchdog.ts b/src/channels/transport/stall-watchdog.ts index ee18f098722..9977255e42a 100644 --- a/src/channels/transport/stall-watchdog.ts +++ b/src/channels/transport/stall-watchdog.ts @@ -1,5 +1,5 @@ +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; import type { RuntimeEnv } from "../../runtime.js"; -import { resolveTimerTimeoutMs } from "../../shared/number-coercion.js"; export type StallWatchdogTimeoutMeta = { idleMs: number; diff --git a/src/channels/turn/durable-delivery.ts b/src/channels/turn/durable-delivery.ts index 5deb3c4bc43..1096f9f7e22 100644 --- a/src/channels/turn/durable-delivery.ts +++ b/src/channels/turn/durable-delivery.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { ReplyPayload } from "../../auto-reply/reply-payload.js"; import type { FinalizedMsgContext } from "../../auto-reply/templating.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; @@ -10,7 +11,6 @@ import { resolveOutboundDurableFinalDeliverySupport, } from "../../infra/outbound/deliver.js"; import { buildOutboundSessionContext } from "../../infra/outbound/session-context.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { deriveDurableFinalDeliveryRequirements } from "../message/capabilities.js"; import { sendDurableMessageBatch } from "../message/send.js"; import { createChannelDeliveryResultFromReceipt } from "./delivery-result.js"; diff --git a/src/channels/typing.ts b/src/channels/typing.ts index b7455db78e5..b2649caab2b 100644 --- a/src/channels/typing.ts +++ b/src/channels/typing.ts @@ -1,4 +1,4 @@ -import { parseFiniteNumber } from "../shared/number-coercion.js"; +import { parseFiniteNumber } from "@openclaw/normalization-core/number-coercion"; import { createTypingKeepaliveLoop } from "./typing-lifecycle.js"; import { createTypingStartGuard } from "./typing-start-guard.js"; diff --git a/src/chat/canvas-render.ts b/src/chat/canvas-render.ts index 939475d3a3b..cea1659fec3 100644 --- a/src/chat/canvas-render.ts +++ b/src/chat/canvas-render.ts @@ -1,6 +1,6 @@ +import { asFiniteNumber } from "@openclaw/normalization-core/number-coercion"; +import { asOptionalRecord } from "@openclaw/normalization-core/record-coerce"; import { parseFenceSpans } from "../../packages/markdown-core/src/fences.js"; -import { asFiniteNumber } from "../shared/number-coercion.js"; -import { asOptionalRecord } from "../shared/record-coerce.js"; type CanvasSurface = "assistant_message"; diff --git a/src/cli/capability-cli.ts b/src/cli/capability-cli.ts index b5eccfb3e0b..e5f3b41d2e3 100644 --- a/src/cli/capability-cli.ts +++ b/src/cli/capability-cli.ts @@ -4,6 +4,11 @@ import fs from "node:fs/promises"; import path from "node:path"; import { Readable } from "node:stream"; import { pipeline } from "node:stream/promises"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, + normalizeStringifiedOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import { GATEWAY_CLIENT_MODES, @@ -69,11 +74,6 @@ import { } from "../plugins/memory-embedding-providers.js"; import { writeRuntimeJson, defaultRuntime, type RuntimeEnv } from "../runtime.js"; import { getProviderEnvVars } from "../secrets/provider-env-vars.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, - normalizeStringifiedOptionalString, -} from "../shared/string-coerce.js"; import { canonicalizeSpeechProviderId, listSpeechProviders } from "../tts/provider-registry.js"; import { getTtsProvider, diff --git a/src/cli/channel-auth.ts b/src/cli/channel-auth.ts index b32c97a2904..e5bfdd56ace 100644 --- a/src/cli/channel-auth.ts +++ b/src/cli/channel-auth.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { sanitizeForLog } from "../../packages/terminal-core/src/ansi.js"; import { resolveChannelDefaultAccountId } from "../channels/plugins/helpers.js"; import { @@ -13,7 +14,6 @@ import { setVerbose } from "../globals.js"; import { formatErrorMessage } from "../infra/errors.js"; import { isBlockedObjectKey } from "../infra/prototype-keys.js"; import { defaultRuntime, type RuntimeEnv } from "../runtime.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js"; import { formatCliCommand } from "./command-format.js"; import { formatUnsupportedChannelActionMessage } from "./error-format.js"; diff --git a/src/cli/channel-options.ts b/src/cli/channel-options.ts index 49778ebb9e0..c6fdc232cce 100644 --- a/src/cli/channel-options.ts +++ b/src/cli/channel-options.ts @@ -1,4 +1,4 @@ -import { uniqueStrings } from "../shared/string-normalization.js"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { readCliStartupMetadata } from "./startup-metadata.js"; function dedupe(values: string[]): string[] { diff --git a/src/cli/command-secret-gateway.ts b/src/cli/command-secret-gateway.ts index 88044959de0..4e1fcb31879 100644 --- a/src/cli/command-secret-gateway.ts +++ b/src/cli/command-secret-gateway.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES, @@ -22,7 +23,6 @@ import { discoverConfigSecretTargetsByIds, type DiscoveredConfigSecretTarget, } from "../secrets/target-registry.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; type ResolveCommandSecretsResult = { resolvedConfig: OpenClawConfig; diff --git a/src/cli/command-secret-targets.ts b/src/cli/command-secret-targets.ts index b51f04fed73..91d1174f601 100644 --- a/src/cli/command-secret-targets.ts +++ b/src/cli/command-secret-targets.ts @@ -1,3 +1,6 @@ +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { listReadOnlyChannelPluginsForConfig } from "../channels/plugins/read-only.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { @@ -14,9 +17,6 @@ import { discoverConfigSecretTargetsByIds, listSecretTargetRegistryEntries, } from "../secrets/target-registry.js"; -import { isRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; const STATIC_QR_REMOTE_TARGET_IDS = ["gateway.remote.token", "gateway.remote.password"] as const; const STATIC_MODEL_TARGET_IDS = [ diff --git a/src/cli/completion-runtime.ts b/src/cli/completion-runtime.ts index a64042a7dc8..05ecf31f845 100644 --- a/src/cli/completion-runtime.ts +++ b/src/cli/completion-runtime.ts @@ -1,11 +1,11 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; -import { resolveStateDir } from "../config/paths.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { resolveStateDir } from "../config/paths.js"; import { pathExists } from "../utils.js"; export const COMPLETION_SHELLS = ["zsh", "bash", "powershell", "fish"] as const; diff --git a/src/cli/config-cli.ts b/src/cli/config-cli.ts index 5db5c0cf5e1..5562a7f7f36 100644 --- a/src/cli/config-cli.ts +++ b/src/cli/config-cli.ts @@ -1,4 +1,10 @@ import fs from "node:fs"; +import { isRecord as isPlainRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { + normalizeStringEntries, + uniqueValues, +} from "@openclaw/normalization-core/string-normalization"; import type { Command } from "commander"; import JSON5 from "json5"; import { formatDocsLink } from "../../packages/terminal-core/src/links.js"; @@ -58,9 +64,6 @@ import { resolveConfigSecretTargetByPath, } from "../secrets/target-registry.js"; import { parseConfigPathArrayIndex } from "../shared/path-array-index.js"; -import { isRecord as isPlainRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { normalizeStringEntries, uniqueValues } from "../shared/string-normalization.js"; import { shortenHomePath } from "../utils.js"; import { formatCliCommand } from "./command-format.js"; import { formatPluginPackagingRuntimeOutputRecoveryHint } from "./config-recovery-hints.js"; diff --git a/src/cli/config-set-input.ts b/src/cli/config-set-input.ts index 679923311a7..b954fa636bd 100644 --- a/src/cli/config-set-input.ts +++ b/src/cli/config-set-input.ts @@ -1,9 +1,9 @@ import fs from "node:fs"; -import JSON5 from "json5"; import { normalizeOptionalString, normalizeStringifiedOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import JSON5 from "json5"; export type ConfigSetOptions = { strictJson?: boolean; diff --git a/src/cli/container-target.ts b/src/cli/container-target.ts index dfde9efae8a..f17419fb914 100644 --- a/src/cli/container-target.ts +++ b/src/cli/container-target.ts @@ -1,7 +1,7 @@ import { spawnSync } from "node:child_process"; import { isIP } from "node:net"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { consumeRootOptionToken, FLAG_TERMINATOR } from "../infra/cli-root-options.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resolveCliArgvInvocation } from "./argv-invocation.js"; import { scanCliRootOptions } from "./root-option-scan.js"; import { takeCliRootOptionValue } from "./root-option-value.js"; diff --git a/src/cli/cron-cli/register.cron-add.ts b/src/cli/cron-cli/register.cron-add.ts index 5b4fa4b7b33..ce606135c59 100644 --- a/src/cli/cron-cli/register.cron-add.ts +++ b/src/cli/cron-cli/register.cron-add.ts @@ -1,12 +1,12 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import { theme } from "../../../packages/terminal-core/src/theme.js"; import type { CronJob } from "../../cron/types.js"; import { sanitizeAgentId } from "../../routing/session-key.js"; import { defaultRuntime } from "../../runtime.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import type { GatewayRpcOpts } from "../gateway-rpc.js"; import { addGatewayClientOptions, callGatewayFromCli } from "../gateway-rpc.js"; import { parsePositiveIntOrUndefined } from "../program/helpers.js"; diff --git a/src/cli/cron-cli/register.cron-edit.ts b/src/cli/cron-cli/register.cron-edit.ts index 365d42e48e2..f3808d10afc 100644 --- a/src/cli/cron-cli/register.cron-edit.ts +++ b/src/cli/cron-cli/register.cron-edit.ts @@ -1,13 +1,13 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import type { CronJob } from "../../cron/types.js"; import { danger } from "../../globals.js"; import { parseStrictPositiveInteger } from "../../infra/parse-finite-number.js"; import { sanitizeAgentId } from "../../routing/session-key.js"; import { defaultRuntime } from "../../runtime.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { addGatewayClientOptions, callGatewayFromCli } from "../gateway-rpc.js"; import { applyExistingCronSchedulePatch, diff --git a/src/cli/cron-cli/register.cron-simple.ts b/src/cli/cron-cli/register.cron-simple.ts index a223f318424..979f36a84d8 100644 --- a/src/cli/cron-cli/register.cron-simple.ts +++ b/src/cli/cron-cli/register.cron-simple.ts @@ -1,8 +1,8 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import type { CronDeliveryPreview, CronJob } from "../../cron/types.js"; import { parseStrictPositiveInteger } from "../../infra/parse-finite-number.js"; import { defaultRuntime } from "../../runtime.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import type { GatewayRpcOpts } from "../gateway-rpc.js"; import { addGatewayClientOptions, callGatewayFromCli } from "../gateway-rpc.js"; import { parseDurationMs } from "../parse-duration.js"; diff --git a/src/cli/cron-cli/schedule-options.ts b/src/cli/cron-cli/schedule-options.ts index bf8cd1e407f..13ef4499a02 100644 --- a/src/cli/cron-cli/schedule-options.ts +++ b/src/cli/cron-cli/schedule-options.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { CronSchedule } from "../../cron/types.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { parseAt, parseCronStaggerMs, parseDurationMs } from "./shared.js"; type ScheduleOptionInput = { diff --git a/src/cli/cron-cli/shared.ts b/src/cli/cron-cli/shared.ts index a94fbf8c7e3..87636d1af50 100644 --- a/src/cli/cron-cli/shared.ts +++ b/src/cli/cron-cli/shared.ts @@ -1,3 +1,11 @@ +import { + resolveExpiresAtMsFromDurationMs, + timestampMsToIsoString, +} from "@openclaw/normalization-core/number-coercion"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { colorize, isRich, theme } from "../../../packages/terminal-core/src/theme.js"; import { listChannelPlugins } from "../../channels/plugins/index.js"; import { parseAbsoluteTimeMs } from "../../cron/parse.js"; @@ -10,14 +18,6 @@ import { parseOffsetlessIsoDateTimeInTimeZone, } from "../../infra/format-time/parse-offsetless-zoned-datetime.js"; import { defaultRuntime, type RuntimeEnv } from "../../runtime.js"; -import { - resolveExpiresAtMsFromDurationMs, - timestampMsToIsoString, -} from "../../shared/number-coercion.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import type { GatewayRpcOpts } from "../gateway-rpc.js"; import { callGatewayFromCli } from "../gateway-rpc.js"; diff --git a/src/cli/cron-cli/thread-id-shared.ts b/src/cli/cron-cli/thread-id-shared.ts index c94b77469ad..a4d7917cf45 100644 --- a/src/cli/cron-cli/thread-id-shared.ts +++ b/src/cli/cron-cli/thread-id-shared.ts @@ -1,7 +1,7 @@ import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; export function parseCronThreadIdOption(value: unknown): number | undefined { const raw = normalizeOptionalString(value); diff --git a/src/cli/daemon-cli/install.ts b/src/cli/daemon-cli/install.ts index f571a9ff021..1d67fddf3cc 100644 --- a/src/cli/daemon-cli/install.ts +++ b/src/cli/daemon-cli/install.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveNodeStartupTlsEnvironment } from "../../bootstrap/node-startup-env.js"; import { buildGatewayInstallPlan } from "../../commands/daemon-install-helpers.js"; import { @@ -22,7 +23,6 @@ import { normalizeEnvVarKey, } from "../../infra/host-env-security.js"; import { defaultRuntime } from "../../runtime.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { formatCliCommand } from "../command-format.js"; import { formatInvalidConfigPort, formatInvalidPortOption } from "../error-format.js"; import { buildDaemonServiceSnapshot, installDaemonServiceAndEmit } from "./response.js"; diff --git a/src/cli/daemon-cli/lifecycle.ts b/src/cli/daemon-cli/lifecycle.ts index 4535eaa4873..c493727cb9e 100644 --- a/src/cli/daemon-cli/lifecycle.ts +++ b/src/cli/daemon-cli/lifecycle.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { theme } from "../../../packages/terminal-core/src/theme.js"; import { isRestartEnabled } from "../../config/commands.flags.js"; import { readBestEffortConfig, resolveGatewayPort } from "../../config/config.js"; @@ -12,7 +13,6 @@ import { import type { SafeGatewayRestartRequestResult } from "../../infra/restart-coordinator.js"; import { type GatewayRestartIntent, writeGatewayRestartIntentSync } from "../../infra/restart.js"; import { defaultRuntime } from "../../runtime.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { formatCliCommand } from "../command-format.js"; import { parseDurationMs } from "../parse-duration.js"; import { recoverInstalledLaunchAgent } from "./launchd-recovery.js"; diff --git a/src/cli/daemon-cli/restart-health.ts b/src/cli/daemon-cli/restart-health.ts index acb572f5c74..7fcb91d3814 100644 --- a/src/cli/daemon-cli/restart-health.ts +++ b/src/cli/daemon-cli/restart-health.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { PluginHealthErrorSummary } from "../../commands/health.types.js"; import { createConfigIO } from "../../config/io.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; @@ -12,10 +16,6 @@ import { type PortUsage, } from "../../infra/ports.js"; import { killProcessTree } from "../../process/kill-tree.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { sleep } from "../../utils.js"; export const DEFAULT_RESTART_HEALTH_TIMEOUT_MS = 60_000; diff --git a/src/cli/daemon-cli/status.gather.ts b/src/cli/daemon-cli/status.gather.ts index 75844942b33..2c668933783 100644 --- a/src/cli/daemon-cli/status.gather.ts +++ b/src/cli/daemon-cli/status.gather.ts @@ -1,4 +1,5 @@ import fs from "node:fs/promises"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import JSON5 from "json5"; import { createConfigIO, @@ -38,7 +39,6 @@ import { } from "../../infra/restart-handoff.js"; import { resolveConfiguredLogFilePath } from "../../logging/log-file-path.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; import { VERSION } from "../../version.js"; import { normalizeListenerAddress, parsePortFromArgs, pickProbeHostForBind } from "./shared.js"; import type { GatewayRpcOpts } from "./types.js"; diff --git a/src/cli/devices-cli.runtime.ts b/src/cli/devices-cli.runtime.ts index 079fc24b588..9a2354d4b32 100644 --- a/src/cli/devices-cli.runtime.ts +++ b/src/cli/devices-cli.runtime.ts @@ -1,3 +1,9 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, + normalizeStringifiedOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES, @@ -31,12 +37,6 @@ import { type DevicePairingAccessSummary, type PendingDeviceApprovalKind, } from "../shared/device-pairing-access.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, - normalizeStringifiedOptionalString, -} from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { formatCliCommand } from "./command-format.js"; import { parseTimeoutMsWithFallback } from "./parse-timeout.js"; import { withProgress } from "./progress.js"; diff --git a/src/cli/directory-cli.ts b/src/cli/directory-cli.ts index 4fff9ef24c8..a92aba042a9 100644 --- a/src/cli/directory-cli.ts +++ b/src/cli/directory-cli.ts @@ -1,3 +1,7 @@ +import { + normalizeOptionalString, + normalizeStringifiedOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import { formatDocsLink } from "../../packages/terminal-core/src/links.js"; import { getTerminalTableWidth, renderTable } from "../../packages/terminal-core/src/table.js"; @@ -11,10 +15,6 @@ import { danger } from "../globals.js"; import { resolveMessageChannelSelection } from "../infra/outbound/channel-selection.js"; import { parseStrictPositiveInteger } from "../infra/parse-finite-number.js"; import { defaultRuntime } from "../runtime.js"; -import { - normalizeOptionalString, - normalizeStringifiedOptionalString, -} from "../shared/string-coerce.js"; import { formatHelpExamples } from "./help-format.js"; import { commitConfigWithPendingPluginInstalls } from "./plugins-install-record-commit.js"; diff --git a/src/cli/exec-approvals-cli.ts b/src/cli/exec-approvals-cli.ts index dfca861a1a2..4df3a607ddb 100644 --- a/src/cli/exec-approvals-cli.ts +++ b/src/cli/exec-approvals-cli.ts @@ -1,4 +1,5 @@ import fs from "node:fs/promises"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import JSON5 from "json5"; import { sanitizeForLog } from "../../packages/terminal-core/src/ansi.js"; @@ -19,7 +20,6 @@ import { } from "../infra/exec-approvals.js"; import { formatTimeAgo } from "../infra/format-time/format-relative.ts"; import { defaultRuntime } from "../runtime.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { callGatewayFromCli } from "./gateway-rpc.js"; import { nodesCallOpts, resolveNodeId } from "./nodes-cli/rpc.js"; import type { NodesRpcOpts } from "./nodes-cli/types.js"; diff --git a/src/cli/gateway-cli/dev.ts b/src/cli/gateway-cli/dev.ts index 4113c1d2e50..b7273fc14bb 100644 --- a/src/cli/gateway-cli/dev.ts +++ b/src/cli/gateway-cli/dev.ts @@ -1,12 +1,12 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { resolveWorkspaceTemplateSearchDirs } from "../../agents/workspace-templates.js"; import { resolveDefaultAgentWorkspaceDir } from "../../agents/workspace.js"; import { handleReset } from "../../commands/onboard-helpers.js"; import { createConfigIO, replaceConfigFile } from "../../config/config.js"; import { defaultRuntime } from "../../runtime.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { resolveUserPath, shortenHomePath } from "../../utils.js"; const DEV_IDENTITY_NAME = "C3-PO"; diff --git a/src/cli/gateway-cli/qa-parent-watchdog.ts b/src/cli/gateway-cli/qa-parent-watchdog.ts index ca85454e84a..24bc277a962 100644 --- a/src/cli/gateway-cli/qa-parent-watchdog.ts +++ b/src/cli/gateway-cli/qa-parent-watchdog.ts @@ -1,7 +1,7 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { createSubsystemLogger } from "../../logging/subsystem.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; export const QA_PARENT_PID_ENV = "OPENCLAW_QA_PARENT_PID"; export const QA_TEMP_ROOT_ENV = "OPENCLAW_QA_TEMP_ROOT"; diff --git a/src/cli/gateway-cli/run.ts b/src/cli/gateway-cli/run.ts index 255764e19bc..9ff82ea78d2 100644 --- a/src/cli/gateway-cli/run.ts +++ b/src/cli/gateway-cli/run.ts @@ -1,6 +1,10 @@ import fs from "node:fs"; import { request } from "node:http"; import path from "node:path"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import type { ConfigFileSnapshot, @@ -35,10 +39,6 @@ import { setConsoleSubsystemFilter, setConsoleTimestampPrefix } from "../../logg import { withDiagnosticPhase } from "../../logging/diagnostic-phase.js"; import { createSubsystemLogger } from "../../logging/subsystem.js"; import { defaultRuntime } from "../../runtime.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { formatCliCommand } from "../command-format.js"; import { inheritOptionFromParent } from "../command-options.js"; import { formatInvalidConfigPort, formatInvalidPortOption } from "../error-format.js"; diff --git a/src/cli/gateway-secret-options.ts b/src/cli/gateway-secret-options.ts index 38ae2abd774..4be7b394f25 100644 --- a/src/cli/gateway-secret-options.ts +++ b/src/cli/gateway-secret-options.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { readSecretFromFile } from "../acp/secret-file.js"; import { defaultRuntime } from "../runtime.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; function resolveGatewaySecretOption(params: { direct?: unknown; diff --git a/src/cli/logs-cli.ts b/src/cli/logs-cli.ts index 0c142425175..2a3e9f82552 100644 --- a/src/cli/logs-cli.ts +++ b/src/cli/logs-cli.ts @@ -1,4 +1,5 @@ import { setTimeout as delay } from "node:timers/promises"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import { GATEWAY_CLIENT_MODES, @@ -22,7 +23,6 @@ import { readConfiguredLogTail } from "../logging/log-tail.js"; import { parseLogLine } from "../logging/parse-log-line.js"; import { redactSensitiveLines, resolveRedactOptions } from "../logging/redact.js"; import { formatTimestamp } from "../logging/timestamps.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { formatCliCommand } from "./command-format.js"; import { addGatewayClientOptions, callGatewayFromCli } from "./gateway-rpc.js"; diff --git a/src/cli/mcp-cli.ts b/src/cli/mcp-cli.ts index 46b1bbc430a..b0e79476db9 100644 --- a/src/cli/mcp-cli.ts +++ b/src/cli/mcp-cli.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeStringifiedOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { Command } from "commander"; import { buildBundleMcpToolsFromCatalog } from "../agents/agent-bundle-mcp-materialize.js"; import { createSessionMcpRuntime } from "../agents/agent-bundle-mcp-runtime.js"; @@ -20,10 +24,6 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; import { formatErrorMessage } from "../infra/errors.js"; import { serveOpenClawChannelMcp } from "../mcp/channel-server.js"; import { defaultRuntime } from "../runtime.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeStringifiedOptionalString, -} from "../shared/string-coerce.js"; import { formatCliCommand } from "./command-format.js"; import { resolveGatewayAuthOptions } from "./gateway-secret-options.js"; import { applyParentDefaultHelpAction } from "./program/parent-default-help.js"; diff --git a/src/cli/message-secret-scope.ts b/src/cli/message-secret-scope.ts index a60afb550ef..938abb2f294 100644 --- a/src/cli/message-secret-scope.ts +++ b/src/cli/message-secret-scope.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { normalizeAccountId } from "../routing/session-key.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { isDeliverableMessageChannel, normalizeMessageChannel } from "../utils/message-channel.js"; function resolveScopedChannelCandidate(value: unknown): string | undefined { diff --git a/src/cli/node-cli/daemon.ts b/src/cli/node-cli/daemon.ts index 436760cbc36..7a0f52f857b 100644 --- a/src/cli/node-cli/daemon.ts +++ b/src/cli/node-cli/daemon.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { colorize } from "../../../packages/terminal-core/src/theme.js"; import { buildNodeInstallPlan } from "../../commands/node-daemon-install-helpers.js"; import { @@ -17,7 +18,6 @@ import { import type { GatewayServiceRuntime } from "../../daemon/service-runtime.js"; import { loadNodeHostConfig } from "../../node-host/config.js"; import { defaultRuntime } from "../../runtime.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { formatCliCommand } from "../command-format.js"; import { runServiceRestart, diff --git a/src/cli/node-cli/register.ts b/src/cli/node-cli/register.ts index 63716d1a85a..b024402c155 100644 --- a/src/cli/node-cli/register.ts +++ b/src/cli/node-cli/register.ts @@ -1,10 +1,10 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import { formatDocsLink } from "../../../packages/terminal-core/src/links.js"; import { theme } from "../../../packages/terminal-core/src/theme.js"; import { loadNodeHostConfig } from "../../node-host/config.js"; import { runNodeHost } from "../../node-host/runner.js"; import { defaultRuntime } from "../../runtime.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { parsePort } from "../daemon-cli/shared.js"; import { formatInvalidPortOption } from "../error-format.js"; import { formatHelpExamples } from "../help-format.js"; diff --git a/src/cli/nodes-cli/format.ts b/src/cli/nodes-cli/format.ts index 5f03edab6c8..530de28ca29 100644 --- a/src/cli/nodes-cli/format.ts +++ b/src/cli/nodes-cli/format.ts @@ -1,4 +1,4 @@ -import { normalizeStringifiedOptionalString } from "../../shared/string-coerce.js"; +import { normalizeStringifiedOptionalString } from "@openclaw/normalization-core/string-coerce"; export { parseNodeList, parsePairingList } from "../../shared/node-list-parse.js"; diff --git a/src/cli/nodes-cli/register.camera.ts b/src/cli/nodes-cli/register.camera.ts index c2f1b4af52b..d6da65e5858 100644 --- a/src/cli/nodes-cli/register.camera.ts +++ b/src/cli/nodes-cli/register.camera.ts @@ -1,10 +1,10 @@ -import type { Command } from "commander"; -import { getTerminalTableWidth, renderTable } from "../../../packages/terminal-core/src/table.js"; -import { defaultRuntime } from "../../runtime.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { Command } from "commander"; +import { getTerminalTableWidth, renderTable } from "../../../packages/terminal-core/src/table.js"; +import { defaultRuntime } from "../../runtime.js"; import { shortenHomePath } from "../../utils.js"; import { type CameraFacing, diff --git a/src/cli/nodes-cli/register.invoke.ts b/src/cli/nodes-cli/register.invoke.ts index bbc1d9eb1de..115ed47226c 100644 --- a/src/cli/nodes-cli/register.invoke.ts +++ b/src/cli/nodes-cli/register.invoke.ts @@ -1,10 +1,10 @@ -import type { Command } from "commander"; -import { randomIdempotencyKey } from "../../gateway/call.js"; -import { defaultRuntime } from "../../runtime.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { Command } from "commander"; +import { randomIdempotencyKey } from "../../gateway/call.js"; +import { defaultRuntime } from "../../runtime.js"; import { getNodesTheme, runNodesCommand } from "./cli-utils.js"; import { callGatewayCli, diff --git a/src/cli/nodes-cli/register.location.ts b/src/cli/nodes-cli/register.location.ts index 278be407409..3107cd1f852 100644 --- a/src/cli/nodes-cli/register.location.ts +++ b/src/cli/nodes-cli/register.location.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import { randomIdempotencyKey } from "../../gateway/call.js"; import { defaultRuntime } from "../../runtime.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { runNodesCommand } from "./cli-utils.js"; import { callGatewayCli, diff --git a/src/cli/nodes-cli/register.notify.ts b/src/cli/nodes-cli/register.notify.ts index 1bf0c702e85..e1486355f5b 100644 --- a/src/cli/nodes-cli/register.notify.ts +++ b/src/cli/nodes-cli/register.notify.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import { randomIdempotencyKey } from "../../gateway/call.js"; import { defaultRuntime } from "../../runtime.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { getNodesTheme, runNodesCommand } from "./cli-utils.js"; import { callGatewayCli, diff --git a/src/cli/nodes-cli/register.pairing.ts b/src/cli/nodes-cli/register.pairing.ts index 232efd744cc..3ca0d9ef35c 100644 --- a/src/cli/nodes-cli/register.pairing.ts +++ b/src/cli/nodes-cli/register.pairing.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import { getTerminalTableWidth } from "../../../packages/terminal-core/src/table.js"; import type { OperatorScope } from "../../gateway/method-scopes.js"; import { resolveNodePairApprovalScopes } from "../../infra/node-pairing-authz.js"; import { defaultRuntime } from "../../runtime.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { formatCliCommand } from "../command-format.js"; import { getNodesTheme, runNodesCommand } from "./cli-utils.js"; import { parsePairingList } from "./format.js"; diff --git a/src/cli/nodes-cli/register.push.ts b/src/cli/nodes-cli/register.push.ts index 30b581bf2b6..db0fcfa7cc7 100644 --- a/src/cli/nodes-cli/register.push.ts +++ b/src/cli/nodes-cli/register.push.ts @@ -1,9 +1,9 @@ -import type { Command } from "commander"; -import { defaultRuntime } from "../../runtime.js"; import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { Command } from "commander"; +import { defaultRuntime } from "../../runtime.js"; import { getNodesTheme, runNodesCommand } from "./cli-utils.js"; import { callGatewayCli, nodesCallOpts, resolveNodeId } from "./rpc.js"; import type { NodesRpcOpts } from "./types.js"; diff --git a/src/cli/nodes-cli/register.status.ts b/src/cli/nodes-cli/register.status.ts index f2fbd6bb59f..979a818c654 100644 --- a/src/cli/nodes-cli/register.status.ts +++ b/src/cli/nodes-cli/register.status.ts @@ -1,14 +1,14 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import { sanitizeTerminalText } from "../../../packages/terminal-core/src/safe-text.js"; import { getTerminalTableWidth, renderTable } from "../../../packages/terminal-core/src/table.js"; import { formatErrorMessage } from "../../infra/errors.js"; import { formatTimeAgo } from "../../infra/format-time/format-relative.ts"; import { defaultRuntime } from "../../runtime.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { shortenHomeInString } from "../../utils.js"; import { parseDurationMs } from "../parse-duration.js"; import { getNodesTheme, runNodesCommand } from "./cli-utils.js"; diff --git a/src/cli/nodes-cli/rpc.ts b/src/cli/nodes-cli/rpc.ts index 7146daa986e..b9d00cea5a6 100644 --- a/src/cli/nodes-cli/rpc.ts +++ b/src/cli/nodes-cli/rpc.ts @@ -1,4 +1,5 @@ import { randomUUID } from "node:crypto"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import type { OperatorScope } from "../../gateway/method-scopes.js"; import { @@ -8,7 +9,6 @@ import { } from "../../infra/parse-finite-number.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; import { resolveNodeFromNodeList } from "../../shared/node-resolve.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { parseNodeList, parsePairingList } from "./format.js"; import type { NodeListNode, NodesRpcOpts } from "./types.js"; diff --git a/src/cli/nodes-media-utils.ts b/src/cli/nodes-media-utils.ts index 82526f86e0d..5da6eac173c 100644 --- a/src/cli/nodes-media-utils.ts +++ b/src/cli/nodes-media-utils.ts @@ -1,9 +1,9 @@ import { randomUUID } from "node:crypto"; import fs from "node:fs"; import { resolvePreferredOpenClawTmpDir } from "../infra/tmp-openclaw-dir.js"; -export { asFiniteNumber as asNumber } from "../shared/number-coercion.js"; -import { readStringValue } from "../shared/string-coerce.js"; -export { asRecord } from "../shared/record-coerce.js"; +export { asFiniteNumber as asNumber } from "../../packages/normalization-core/src/number-coercion.js"; +import { readStringValue } from "../../packages/normalization-core/src/string-coerce.js"; +export { asRecord } from "../../packages/normalization-core/src/record-coerce.js"; export { asBoolean } from "../utils/boolean.js"; export const asString = readStringValue; diff --git a/src/cli/outbound-send-mapping.ts b/src/cli/outbound-send-mapping.ts index 900f5bf8a5e..4752bf8c537 100644 --- a/src/cli/outbound-send-mapping.ts +++ b/src/cli/outbound-send-mapping.ts @@ -1,9 +1,9 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { normalizeChannelId } from "../channels/registry.js"; import { resolveLegacyOutboundSendDepKeys, type OutboundSendDeps, } from "../infra/outbound/send-deps.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; /** * CLI-internal send function sources, keyed by channel ID. diff --git a/src/cli/pairing-cli.ts b/src/cli/pairing-cli.ts index efaccf91b1b..4b220d2806d 100644 --- a/src/cli/pairing-cli.ts +++ b/src/cli/pairing-cli.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeStringifiedOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import { formatDocsLink } from "../../packages/terminal-core/src/links.js"; import { getTerminalTableWidth, renderTable } from "../../packages/terminal-core/src/table.js"; @@ -17,10 +21,6 @@ import { resolvePairingIdLabel } from "../pairing/pairing-labels.js"; import { approveChannelPairingCode, listChannelPairingRequests } from "../pairing/pairing-store.js"; import type { PairingChannel } from "../pairing/pairing-store.types.js"; import { defaultRuntime } from "../runtime.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeStringifiedOptionalString, -} from "../shared/string-coerce.js"; import { formatCliCommand } from "./command-format.js"; /** Parse channel, allowing extension channels not in core registry. */ diff --git a/src/cli/parse-bytes.ts b/src/cli/parse-bytes.ts index 62cf6e0485c..27858a112e7 100644 --- a/src/cli/parse-bytes.ts +++ b/src/cli/parse-bytes.ts @@ -1,7 +1,7 @@ import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; type BytesParseOptions = { defaultUnit?: "b" | "kb" | "mb" | "gb" | "tb"; diff --git a/src/cli/parse-duration.ts b/src/cli/parse-duration.ts index 111183c573d..eb3c38aed5d 100644 --- a/src/cli/parse-duration.ts +++ b/src/cli/parse-duration.ts @@ -1,7 +1,7 @@ import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; export type DurationMsParseOptions = { defaultUnit?: "ms" | "s" | "m" | "h" | "d"; diff --git a/src/cli/plugin-install-config-policy.ts b/src/cli/plugin-install-config-policy.ts index 3b44c7edaec..31b49e66e73 100644 --- a/src/cli/plugin-install-config-policy.ts +++ b/src/cli/plugin-install-config-policy.ts @@ -1,5 +1,6 @@ import fs from "node:fs"; import path from "node:path"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { Command } from "commander"; import { tryReadJsonSync } from "../infra/json-files.js"; import { findBundledPluginSource } from "../plugins/bundled-sources.js"; @@ -9,7 +10,6 @@ import { resolveOfficialExternalPluginId, resolveOfficialExternalPluginInstall, } from "../plugins/official-external-plugin-catalog.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { resolveUserPath } from "../utils.js"; import { parseNpmPrefixSpec, resolveFileNpmSpecToLocalPath } from "./plugins-command-helpers.js"; diff --git a/src/cli/plugins-authoring-command.ts b/src/cli/plugins-authoring-command.ts index b641a2a0fe0..01108625b1f 100644 --- a/src/cli/plugins-authoring-command.ts +++ b/src/cli/plugins-authoring-command.ts @@ -1,5 +1,6 @@ import fs from "node:fs"; import path from "node:path"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { getToolPluginMetadata, type ToolPluginMetadata } from "../plugin-sdk/tool-plugin.js"; import { loadPluginManifest, @@ -14,7 +15,6 @@ import { import { buildPluginLoaderAliasMap } from "../plugins/sdk-alias.js"; import { defaultRuntime } from "../runtime.js"; import { toSafeImportPath } from "../shared/import-specifier.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { isRecord } from "../utils.js"; type JsonObject = Record; diff --git a/src/cli/plugins-command-helpers.ts b/src/cli/plugins-command-helpers.ts index f24c3d88063..ea7fe8e56c3 100644 --- a/src/cli/plugins-command-helpers.ts +++ b/src/cli/plugins-command-helpers.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { theme } from "../../packages/terminal-core/src/theme.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { PluginKind } from "../plugins/plugin-kind.types.js"; @@ -6,7 +7,6 @@ import { applyExclusiveSlotSelection } from "../plugins/slots.js"; import { buildPluginDiagnosticsReport } from "../plugins/status.js"; import type { PluginLogger } from "../plugins/types.js"; import { defaultRuntime, type RuntimeEnv } from "../runtime.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; type HookInternalEntryLike = Record & { enabled?: boolean }; diff --git a/src/cli/plugins-install-command.ts b/src/cli/plugins-install-command.ts index 27e9c77bcf3..f1fd925e4f9 100644 --- a/src/cli/plugins-install-command.ts +++ b/src/cli/plugins-install-command.ts @@ -1,4 +1,6 @@ import fs from "node:fs"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { theme } from "../../packages/terminal-core/src/theme.js"; import { collectChannelDoctorStaleConfigMutations } from "../commands/doctor/shared/channel-doctor.js"; import { assertConfigWriteAllowedInCurrentMode, readConfigFileSnapshot } from "../config/config.js"; @@ -32,8 +34,6 @@ import { import { tracePluginLifecyclePhaseAsync } from "../plugins/plugin-lifecycle-trace.js"; import { validateJsonSchemaValue } from "../plugins/schema-validator.js"; import { defaultRuntime, type RuntimeEnv } from "../runtime.js"; -import { isRecord } from "../shared/record-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { shortenHomePath } from "../utils.js"; import { formatCliCommand } from "./command-format.js"; import { looksLikeLocalInstallSpec } from "./install-spec.js"; diff --git a/src/cli/plugins-search-command.ts b/src/cli/plugins-search-command.ts index c48aa971911..9b6ce53cd6b 100644 --- a/src/cli/plugins-search-command.ts +++ b/src/cli/plugins-search-command.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { theme } from "../../packages/terminal-core/src/theme.js"; import { searchClawHubPackages, @@ -6,7 +7,6 @@ import { } from "../infra/clawhub.js"; import { formatErrorMessage } from "../infra/errors.js"; import { defaultRuntime, writeRuntimeJson, type RuntimeEnv } from "../runtime.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; export type PluginsSearchOptions = { json?: boolean; diff --git a/src/cli/profile-utils.ts b/src/cli/profile-utils.ts index 2ad1ee9910e..578f73aabfb 100644 --- a/src/cli/profile-utils.ts +++ b/src/cli/profile-utils.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; const PROFILE_NAME_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/i; diff --git a/src/cli/profile.ts b/src/cli/profile.ts index 0532325bebc..38e7cd5a41a 100644 --- a/src/cli/profile.ts +++ b/src/cli/profile.ts @@ -1,11 +1,11 @@ import os from "node:os"; import path from "node:path"; -import { isValueToken } from "../infra/cli-root-options.js"; -import { resolveRequiredHomeDir } from "../infra/home-dir.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { isValueToken } from "../infra/cli-root-options.js"; +import { resolveRequiredHomeDir } from "../infra/home-dir.js"; import { resolveCliArgvInvocation } from "./argv-invocation.js"; import { isValidProfileName } from "./profile-utils.js"; import { scanCliRootOptions } from "./root-option-scan.js"; diff --git a/src/cli/program/message/register.thread.ts b/src/cli/program/message/register.thread.ts index 755bce95374..33e403b24dc 100644 --- a/src/cli/program/message/register.thread.ts +++ b/src/cli/program/message/register.thread.ts @@ -1,7 +1,7 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import { getChannelPlugin } from "../../../channels/plugins/index.js"; import type { ChannelMessageActionName } from "../../../channels/plugins/types.public.js"; -import { normalizeLowercaseStringOrEmpty } from "../../../shared/string-coerce.js"; import type { MessageCliHelpers } from "./helpers.js"; function resolveThreadCreateRequest(opts: Record) { diff --git a/src/cli/program/register-command-groups.ts b/src/cli/program/register-command-groups.ts index 6443fee0937..ac84ce43728 100644 --- a/src/cli/program/register-command-groups.ts +++ b/src/cli/program/register-command-groups.ts @@ -1,5 +1,5 @@ +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { Command } from "commander"; -import { uniqueStrings } from "../../shared/string-normalization.js"; import { removeCommandByName } from "./command-tree.js"; import { registerLazyCommand } from "./register-lazy-command.js"; diff --git a/src/cli/program/register.agent.ts b/src/cli/program/register.agent.ts index 48bb5995c15..7e23bcbf28d 100644 --- a/src/cli/program/register.agent.ts +++ b/src/cli/program/register.agent.ts @@ -1,8 +1,8 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import { formatDocsLink } from "../../../packages/terminal-core/src/links.js"; import { theme } from "../../../packages/terminal-core/src/theme.js"; import { defaultRuntime } from "../../runtime.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { runCommandWithRuntime } from "../cli-utils.js"; import { hasExplicitOptions } from "../command-options.js"; import { formatHelpExamples } from "../help-format.js"; diff --git a/src/cli/prompt.ts b/src/cli/prompt.ts index 506a7531982..b314265df42 100644 --- a/src/cli/prompt.ts +++ b/src/cli/prompt.ts @@ -1,7 +1,7 @@ import { stdin as input, stdout as output } from "node:process"; import readline from "node:readline/promises"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { isVerbose, isYes } from "../globals.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; export class PromptInputClosedError extends Error { constructor() { diff --git a/src/cli/run-main-policy.ts b/src/cli/run-main-policy.ts index 7b4665f0ece..7434791f5e9 100644 --- a/src/cli/run-main-policy.ts +++ b/src/cli/run-main-policy.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, +} from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { consumeRootOptionToken } from "../infra/cli-root-options.js"; import { @@ -7,10 +11,6 @@ import { type PluginManifestCommandAliasRegistry, type PluginManifestToolOwnerRecord, } from "../plugins/manifest-command-aliases.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; import { resolveCliArgvInvocation } from "./argv-invocation.js"; import { hasFlag } from "./argv.js"; import { diff --git a/src/cli/run-main.ts b/src/cli/run-main.ts index 574ab35f7f0..247a557d32e 100644 --- a/src/cli/run-main.ts +++ b/src/cli/run-main.ts @@ -2,6 +2,7 @@ import { existsSync } from "node:fs"; import path from "node:path"; import process from "node:process"; import { fileURLToPath } from "node:url"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveStateDir } from "../config/paths.js"; import type { ConfigFileSnapshot, OpenClawConfig } from "../config/types.openclaw.js"; import { isTruthyEnvValue, normalizeEnv } from "../infra/env.js"; @@ -10,7 +11,6 @@ import type { ProxyHandle } from "../infra/net/proxy/proxy-lifecycle.js"; import { ensureOpenClawCliOnPath } from "../infra/path-env.js"; import { assertSupportedRuntime } from "../infra/runtime-guard.js"; import type { PluginManifestCommandAliasRegistry } from "../plugins/manifest-command-aliases.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resolveCliArgvInvocation } from "./argv-invocation.js"; import { normalizeGeneratedHelpCommandArgv, normalizeRootHelpTargetArgv } from "./argv.js"; import { diff --git a/src/cli/security-cli.ts b/src/cli/security-cli.ts index c4f36f1076f..e3f4fd0eeb9 100644 --- a/src/cli/security-cli.ts +++ b/src/cli/security-cli.ts @@ -1,3 +1,7 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import { formatDocsLink } from "../../packages/terminal-core/src/links.js"; import { isRich, theme } from "../../packages/terminal-core/src/theme.js"; @@ -6,10 +10,6 @@ import type { GatewayAuthMode } from "../config/types.gateway.js"; import { defaultRuntime } from "../runtime.js"; import { runSecurityAudit } from "../security/audit.js"; import { fixSecurityFootguns } from "../security/fix.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { shortenHomeInString, shortenHomePath } from "../utils.js"; import { formatCliCommand } from "./command-format.js"; import { resolveCommandSecretRefsViaGateway } from "./command-secret-gateway.js"; diff --git a/src/cli/send-runtime/channel-outbound-send.ts b/src/cli/send-runtime/channel-outbound-send.ts index 00b3a752edb..7f0bc3620ad 100644 --- a/src/cli/send-runtime/channel-outbound-send.ts +++ b/src/cli/send-runtime/channel-outbound-send.ts @@ -1,10 +1,10 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { loadChannelOutboundAdapter } from "../../channels/plugins/outbound/load.js"; import type { ChannelId } from "../../channels/plugins/types.public.js"; import { getRuntimeConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { OutboundDeliveryFormattingOptions } from "../../infra/outbound/formatting.js"; import type { OutboundMediaAccess } from "../../media/load-options.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; type RuntimeSendOpts = { cfg?: OpenClawConfig; diff --git a/src/cli/skills-cli.ts b/src/cli/skills-cli.ts index d3aa485f739..398b7aa08a5 100644 --- a/src/cli/skills-cli.ts +++ b/src/cli/skills-cli.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import { formatDocsLink } from "../../packages/terminal-core/src/links.js"; import { theme } from "../../packages/terminal-core/src/theme.js"; @@ -13,7 +14,6 @@ import { type ClawHubSkillVerificationResponse, } from "../infra/clawhub.js"; import { defaultRuntime } from "../runtime.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { installSkillFromClawHub, readTrackedClawHubSkillSlugs, diff --git a/src/cli/system-cli.ts b/src/cli/system-cli.ts index 49dda5148bc..23d8f946bc2 100644 --- a/src/cli/system-cli.ts +++ b/src/cli/system-cli.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import { formatDocsLink } from "../../packages/terminal-core/src/links.js"; import { theme } from "../../packages/terminal-core/src/theme.js"; import { danger } from "../globals.js"; import { defaultRuntime } from "../runtime.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { formatCliCommand } from "./command-format.js"; import type { GatewayRpcOpts } from "./gateway-rpc.js"; import { addGatewayClientOptions, callGatewayFromCli } from "./gateway-rpc.js"; diff --git a/src/cli/update-cli/progress.ts b/src/cli/update-cli/progress.ts index 00a6964ed53..4a0a12ff109 100644 --- a/src/cli/update-cli/progress.ts +++ b/src/cli/update-cli/progress.ts @@ -1,4 +1,5 @@ import { spinner } from "@clack/prompts"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { theme } from "../../../packages/terminal-core/src/theme.js"; import { formatDurationPrecise } from "../../infra/format-time/format-duration.ts"; import type { @@ -7,7 +8,6 @@ import type { UpdateStepProgress, } from "../../infra/update-runner.js"; import { defaultRuntime } from "../../runtime.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import type { UpdateCommandOptions } from "./shared.js"; const STEP_LABELS: Record = { diff --git a/src/cli/update-cli/restart-helper.ts b/src/cli/update-cli/restart-helper.ts index 0dd7b2217de..50c2fd18c9d 100644 --- a/src/cli/update-cli/restart-helper.ts +++ b/src/cli/update-cli/restart-helper.ts @@ -2,6 +2,7 @@ import { spawn } from "node:child_process"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { DEFAULT_GATEWAY_PORT } from "../../config/paths.js"; import { quoteCmdScriptArg } from "../../daemon/cmd-argv.js"; import { @@ -14,7 +15,6 @@ import { resolveGatewayRestartLogPath, shellEscapeRestartLogValue, } from "../../daemon/restart-logs.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; /** * Shell-escape a string for embedding in single-quoted shell arguments. diff --git a/src/cli/update-cli/shared.ts b/src/cli/update-cli/shared.ts index 60a5605ec0a..aad9153ea77 100644 --- a/src/cli/update-cli/shared.ts +++ b/src/cli/update-cli/shared.ts @@ -2,6 +2,7 @@ import { spawnSync } from "node:child_process"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { theme } from "../../../packages/terminal-core/src/theme.js"; import { resolveRequiredHomeDir } from "../../infra/home-dir.js"; import { resolveOpenClawPackageRoot } from "../../infra/openclaw-root.js"; @@ -22,7 +23,6 @@ import { import type { UpdateStepProgress, UpdateStepResult } from "../../infra/update-runner.js"; import { runCommandWithTimeout } from "../../process/exec.js"; import { defaultRuntime } from "../../runtime.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { pathExists } from "../../utils.js"; import { COMPLETION_SKIP_PLUGIN_COMMANDS_ENV } from "../completion-runtime.js"; diff --git a/src/cli/update-cli/update-command.ts b/src/cli/update-cli/update-command.ts index 1cc0405162e..a8da8e33d83 100644 --- a/src/cli/update-cli/update-command.ts +++ b/src/cli/update-cli/update-command.ts @@ -5,6 +5,8 @@ import os from "node:os"; import path from "node:path"; import { Writable } from "node:stream"; import { confirm, isCancel } from "@clack/prompts"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { stylePromptMessage } from "../../../packages/terminal-core/src/prompt-style.js"; import { theme } from "../../../packages/terminal-core/src/theme.js"; import { @@ -99,8 +101,6 @@ import { } from "../../plugins/update.js"; import { runCommandWithTimeout } from "../../process/exec.js"; import { defaultRuntime } from "../../runtime.js"; -import { isRecord } from "../../shared/record-coerce.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { resolveUserPath } from "../../utils.js"; import { VERSION } from "../../version.js"; import { replaceCliName, resolveCliName } from "../cli-name.js"; diff --git a/src/cli/webhooks-cli.ts b/src/cli/webhooks-cli.ts index 01cad5d0a08..8ae54c93b81 100644 --- a/src/cli/webhooks-cli.ts +++ b/src/cli/webhooks-cli.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import { formatDocsLink } from "../../packages/terminal-core/src/links.js"; import { theme } from "../../packages/terminal-core/src/theme.js"; @@ -20,7 +21,6 @@ import { } from "../hooks/gmail.js"; import { parseStrictPositiveInteger } from "../infra/parse-finite-number.js"; import { defaultRuntime } from "../runtime.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { formatCliCommand } from "./command-format.js"; export function registerWebhooksCli(program: Command) { diff --git a/src/cli/windows-argv.ts b/src/cli/windows-argv.ts index 8d7a29b07a1..5f11c9e54c1 100644 --- a/src/cli/windows-argv.ts +++ b/src/cli/windows-argv.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export function normalizeWindowsArgv( argv: string[], diff --git a/src/commands/agent-via-gateway.ts b/src/commands/agent-via-gateway.ts index 2529123d370..ac22d2a4b4d 100644 --- a/src/commands/agent-via-gateway.ts +++ b/src/commands/agent-via-gateway.ts @@ -1,4 +1,5 @@ import { randomUUID } from "node:crypto"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload"; import { GATEWAY_CLIENT_MODES, @@ -27,7 +28,6 @@ import { scopeLegacySessionKeyToAgent, } from "../routing/session-key.js"; import { type RuntimeEnv, writeRuntimeJson } from "../runtime.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { normalizeMessageChannel } from "../utils/message-channel.js"; type AgentGatewayResult = { diff --git a/src/commands/agents.bindings.ts b/src/commands/agents.bindings.ts index ab02ed9e240..ffe975782b1 100644 --- a/src/commands/agents.bindings.ts +++ b/src/commands/agents.bindings.ts @@ -1,3 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeSortedUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import { getBundledChannelSetupPlugin } from "../channels/plugins/bundled.js"; import { resolveChannelDefaultAccountId } from "../channels/plugins/helpers.js"; import { getLoadedChannelPlugin } from "../channels/plugins/index.js"; @@ -9,8 +11,6 @@ import type { AgentRouteBinding } from "../config/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { listManifestChannelContributionIds } from "../plugins/manifest-contribution-ids.js"; import { DEFAULT_ACCOUNT_ID, normalizeAgentId } from "../routing/session-key.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { normalizeSortedUniqueStringEntries } from "../shared/string-normalization.js"; import type { ChannelChoice } from "./onboard-types.js"; export { describeBinding } from "./agents.binding-format.js"; diff --git a/src/commands/agents.commands.add.ts b/src/commands/agents.commands.add.ts index b54352e0688..f3a99164996 100644 --- a/src/commands/agents.commands.add.ts +++ b/src/commands/agents.commands.add.ts @@ -1,5 +1,9 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveAgentDir, resolveAgentWorkspaceDir, @@ -25,10 +29,6 @@ import { saveJsonFile } from "../infra/json-file.js"; import { DEFAULT_AGENT_ID, normalizeAgentId } from "../routing/session-key.js"; import { type RuntimeEnv, writeRuntimeJson } from "../runtime.js"; import { defaultRuntime } from "../runtime.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { resolveUserPath, shortenHomePath } from "../utils.js"; import { createClackPrompter } from "../wizard/clack-prompter.js"; import { WizardCancelledError } from "../wizard/prompts.js"; diff --git a/src/commands/agents.commands.bind.ts b/src/commands/agents.commands.bind.ts index fe63e58909c..83f944919ff 100644 --- a/src/commands/agents.commands.bind.ts +++ b/src/commands/agents.commands.bind.ts @@ -1,3 +1,4 @@ +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { listAgentEntries, resolveDefaultAgentId } from "../agents/agent-scope.js"; import { formatCliCommand } from "../cli/command-format.js"; import { isRouteBinding, listRouteBindings } from "../config/bindings.js"; @@ -8,7 +9,6 @@ import { normalizeAgentId } from "../routing/session-key.js"; import { type RuntimeEnv, writeRuntimeJson } from "../runtime.js"; import { defaultRuntime } from "../runtime.js"; import { createLazyImportLoader } from "../shared/lazy-promise.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { describeBinding } from "./agents.binding-format.js"; import { requireValidConfig, requireValidConfigFileSnapshot } from "./agents.command-shared.js"; diff --git a/src/commands/agents.commands.identity.ts b/src/commands/agents.commands.identity.ts index 7b0a35d2f6c..276163eef90 100644 --- a/src/commands/agents.commands.identity.ts +++ b/src/commands/agents.commands.identity.ts @@ -1,5 +1,6 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js"; import { identityHasValues, parseIdentityMarkdown } from "../agents/identity-file.js"; import { DEFAULT_IDENTITY_FILENAME } from "../agents/workspace.js"; @@ -9,7 +10,6 @@ import type { IdentityConfig } from "../config/types.js"; import { normalizeAgentId } from "../routing/session-key.js"; import { type RuntimeEnv, writeRuntimeJson } from "../runtime.js"; import { defaultRuntime } from "../runtime.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resolveUserPath, shortenHomePath } from "../utils.js"; import { requireValidConfigFileSnapshot } from "./agents.command-shared.js"; import { diff --git a/src/commands/agents.config.ts b/src/commands/agents.config.ts index f5f96c5e814..ffd3282cefb 100644 --- a/src/commands/agents.config.ts +++ b/src/commands/agents.config.ts @@ -1,3 +1,8 @@ +import { + normalizeOptionalString, + resolvePrimaryStringValue, +} from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { listAgentEntries, resolveAgentDir, @@ -10,8 +15,6 @@ import { listRouteBindings } from "../config/bindings.js"; import type { IdentityConfig } from "../config/types.base.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeAgentId } from "../routing/session-key.js"; -import { normalizeOptionalString, resolvePrimaryStringValue } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; export type AgentSummary = { id: string; diff --git a/src/commands/auth-choice-options.ts b/src/commands/auth-choice-options.ts index 470fe565918..6ebf3628a4c 100644 --- a/src/commands/auth-choice-options.ts +++ b/src/commands/auth-choice-options.ts @@ -1,7 +1,7 @@ +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { AuthProfileStore } from "../agents/auth-profiles/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { resolveProviderSetupFlowContributions } from "../flows/provider-flow.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { CORE_AUTH_CHOICE_OPTIONS, type AuthChoiceGroup, diff --git a/src/commands/backup-verify.ts b/src/commands/backup-verify.ts index 57d6ae5e6d9..c443cfd8a42 100644 --- a/src/commands/backup-verify.ts +++ b/src/commands/backup-verify.ts @@ -1,7 +1,7 @@ import path from "node:path"; +import { readStringValue } from "@openclaw/normalization-core/string-coerce"; import * as tar from "tar"; import { type RuntimeEnv, writeRuntimeJson } from "../runtime.js"; -import { readStringValue } from "../shared/string-coerce.js"; import { isRecord, resolveUserPath } from "../utils.js"; const WINDOWS_ABSOLUTE_ARCHIVE_PATH_RE = /^[A-Za-z]:[\\/]/; diff --git a/src/commands/channel-setup/channel-plugin-resolution.ts b/src/commands/channel-setup/channel-plugin-resolution.ts index 997ef16c775..83e1622ace9 100644 --- a/src/commands/channel-setup/channel-plugin-resolution.ts +++ b/src/commands/channel-setup/channel-plugin-resolution.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/agent-scope.js"; import { listChannelPluginCatalogEntries, @@ -8,7 +9,6 @@ import type { ChannelPlugin } from "../../channels/plugins/types.plugin.js"; import type { ChannelId } from "../../channels/plugins/types.public.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { RuntimeEnv } from "../../runtime.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { createClackPrompter } from "../../wizard/clack-prompter.js"; import type { WizardPrompter } from "../../wizard/prompts.js"; import { diff --git a/src/commands/channels/add.ts b/src/commands/channels/add.ts index d857ee9b5d7..d93d264a57d 100644 --- a/src/commands/channels/add.ts +++ b/src/commands/channels/add.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/agent-scope.js"; import { getBundledChannelSetupPlugin } from "../../channels/plugins/bundled.js"; import { parseOptionalDelimitedEntries } from "../../channels/plugins/helpers.js"; @@ -18,7 +19,6 @@ import { parseStrictNonNegativeInteger } from "../../infra/parse-finite-number.j import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js"; import { defaultRuntime, type RuntimeEnv } from "../../runtime.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { createClackPrompter } from "../../wizard/clack-prompter.js"; import { WizardCancelledError } from "../../wizard/prompts.js"; import { applyAgentBindings, describeBinding } from "../agents.bindings.js"; diff --git a/src/commands/channels/capabilities.ts b/src/commands/channels/capabilities.ts index c787bc06c15..09559ac6ace 100644 --- a/src/commands/channels/capabilities.ts +++ b/src/commands/channels/capabilities.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { theme } from "../../../packages/terminal-core/src/theme.js"; import { resolveChannelDefaultAccountId } from "../../channels/plugins/helpers.js"; import { @@ -24,10 +28,6 @@ import { import { danger } from "../../globals.js"; import { formatErrorMessage } from "../../infra/errors.js"; import { defaultRuntime, type RuntimeEnv, writeRuntimeJson } from "../../runtime.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { resolveInstallableChannelPlugin } from "../channel-setup/channel-plugin-resolution.js"; import { formatChannelAccountLabel, requireValidConfig } from "./shared.js"; diff --git a/src/commands/channels/logs.ts b/src/commands/channels/logs.ts index 6aedb8b6abf..044d7a51f3d 100644 --- a/src/commands/channels/logs.ts +++ b/src/commands/channels/logs.ts @@ -1,4 +1,5 @@ import fs from "node:fs/promises"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { theme } from "../../../packages/terminal-core/src/theme.js"; import { normalizeChannelId as normalizeBundledChannelId } from "../../channels/registry.js"; import { parseStrictPositiveInteger } from "../../infra/parse-finite-number.js"; @@ -7,7 +8,6 @@ import { resolveLogFile } from "../../logging/log-tail.js"; import { parseLogLine } from "../../logging/parse-log-line.js"; import { listManifestChannelContributionIds } from "../../plugins/manifest-contribution-ids.js"; import { defaultRuntime, type RuntimeEnv, writeRuntimeJson } from "../../runtime.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; export type ChannelsLogsOptions = { channel?: string; diff --git a/src/commands/channels/remove.ts b/src/commands/channels/remove.ts index bd43ad25d40..244a43c87a7 100644 --- a/src/commands/channels/remove.ts +++ b/src/commands/channels/remove.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveChannelDefaultAccountId } from "../../channels/plugins/helpers.js"; import { getChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js"; import { listReadOnlyChannelPluginsForConfig } from "../../channels/plugins/read-only.js"; @@ -14,7 +15,6 @@ import { callGateway } from "../../gateway/call.js"; import { formatErrorMessage } from "../../infra/errors.js"; import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js"; import { defaultRuntime, type RuntimeEnv } from "../../runtime.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../../utils/message-channel.js"; import { createClackPrompter } from "../../wizard/clack-prompter.js"; import { channelLabel } from "./runtime-label.js"; diff --git a/src/commands/channels/resolve.ts b/src/commands/channels/resolve.ts index b20c432035d..da97e728f74 100644 --- a/src/commands/channels/resolve.ts +++ b/src/commands/channels/resolve.ts @@ -1,3 +1,8 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { getChannelPlugin } from "../../channels/plugins/index.js"; import type { ChannelResolveKind, @@ -17,11 +22,6 @@ import { import { danger } from "../../globals.js"; import { resolveMessageChannelSelection } from "../../infra/outbound/channel-selection.js"; import { type RuntimeEnv, writeRuntimeJson } from "../../runtime.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, -} from "../../shared/string-coerce.js"; -import { normalizeStringEntries } from "../../shared/string-normalization.js"; import { resolveInstallableChannelPlugin } from "../channel-setup/channel-plugin-resolution.js"; export type ChannelsResolveOptions = { diff --git a/src/commands/chutes-oauth.ts b/src/commands/chutes-oauth.ts index 022b693363c..d7b86d1806b 100644 --- a/src/commands/chutes-oauth.ts +++ b/src/commands/chutes-oauth.ts @@ -1,5 +1,6 @@ import { randomBytes } from "node:crypto"; import { createServer } from "node:http"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { ChutesOAuthAppConfig } from "../agents/chutes-oauth.js"; import { CHUTES_AUTHORIZE_ENDPOINT, @@ -9,7 +10,6 @@ import { } from "../agents/chutes-oauth.js"; import { isLoopbackHost } from "../gateway/net.js"; import type { OAuthCredentials } from "../llm/oauth.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; type OAuthPrompt = { message: string; diff --git a/src/commands/commitments.ts b/src/commands/commitments.ts index d5c17834fd1..7635a45261c 100644 --- a/src/commands/commitments.ts +++ b/src/commands/commitments.ts @@ -1,3 +1,6 @@ +import { timestampMsToIsoString } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { sanitizeTerminalText } from "../../packages/terminal-core/src/safe-text.js"; import { isRich, theme } from "../../packages/terminal-core/src/theme.js"; import { formatCliCommand } from "../cli/command-format.js"; @@ -10,9 +13,6 @@ import type { CommitmentRecord, CommitmentStatus } from "../commitments/types.js import { getRuntimeConfig } from "../config/config.js"; import { info } from "../globals.js"; import { type RuntimeEnv, writeRuntimeJson } from "../runtime.js"; -import { timestampMsToIsoString } from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; const STATUS_VALUES = new Set([ "pending", diff --git a/src/commands/configure.gateway.ts b/src/commands/configure.gateway.ts index cc9f8445895..4d69be924a9 100644 --- a/src/commands/configure.gateway.ts +++ b/src/commands/configure.gateway.ts @@ -1,4 +1,9 @@ import { validateIPv4AddressInput } from "@openclaw/net-policy/ipv4"; +import { + normalizeOptionalString, + readStringValue, +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { note } from "../../packages/terminal-core/src/note.js"; import { formatPortRangeHint } from "../cli/error-format.js"; import { parsePort } from "../cli/shared/parse-port.js"; @@ -14,8 +19,6 @@ import { import { findTailscaleBinary } from "../infra/tailscale.js"; import type { RuntimeEnv } from "../runtime.js"; import { resolveDefaultSecretProviderAlias } from "../secrets/ref-contract.js"; -import { normalizeOptionalString, readStringValue } from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { buildGatewayAuthConfig } from "./configure.gateway-auth.js"; import { confirm, select, text } from "./configure.shared.js"; import { diff --git a/src/commands/configure.shared.ts b/src/commands/configure.shared.ts index 59c91cfbe6b..907083d4249 100644 --- a/src/commands/configure.shared.ts +++ b/src/commands/configure.shared.ts @@ -5,12 +5,12 @@ import { select as clackSelect, text as clackText, } from "@clack/prompts"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { stylePromptHint, stylePromptMessage, stylePromptTitle, } from "../../packages/terminal-core/src/prompt-style.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; export const CONFIGURE_WIZARD_SECTIONS = [ "workspace", diff --git a/src/commands/configure.wizard.ts b/src/commands/configure.wizard.ts index 63f0436047a..22b692d2aef 100644 --- a/src/commands/configure.wizard.ts +++ b/src/commands/configure.wizard.ts @@ -1,6 +1,7 @@ import fsPromises from "node:fs/promises"; import nodePath from "node:path"; import { isDeepStrictEqual } from "node:util"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { note } from "../../packages/terminal-core/src/note.js"; import { describeCodexNativeWebSearch } from "../agents/codex-native-web-search.shared.js"; import { formatCliCommand } from "../cli/command-format.js"; @@ -16,7 +17,6 @@ import { resolvePluginContributionOwners } from "../plugins/plugin-registry.js"; import type { RuntimeEnv } from "../runtime.js"; import { defaultRuntime } from "../runtime.js"; import { createLazyImportLoader } from "../shared/lazy-promise.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { isPlainObject, resolveUserPath } from "../utils.js"; import { createClackPrompter } from "../wizard/clack-prompter.js"; import { WizardCancelledError } from "../wizard/prompts.js"; diff --git a/src/commands/doctor-auth-flat-profiles.ts b/src/commands/doctor-auth-flat-profiles.ts index ca4b6ff6537..f009f277762 100644 --- a/src/commands/doctor-auth-flat-profiles.ts +++ b/src/commands/doctor-auth-flat-profiles.ts @@ -1,5 +1,6 @@ import fs from "node:fs"; import path from "node:path"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { note } from "../../packages/terminal-core/src/note.js"; import { resolveAgentDir, resolveDefaultAgentDir, listAgentIds } from "../agents/agent-scope.js"; import { AUTH_STORE_VERSION } from "../agents/auth-profiles/constants.js"; @@ -15,7 +16,6 @@ import type { AuthProfileConfig } from "../config/types.auth.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { coerceSecretRef } from "../config/types.secrets.js"; import { loadJsonFile } from "../infra/json-file.js"; -import { isRecord } from "../shared/record-coerce.js"; import { shortenHomePath } from "../utils.js"; import type { DoctorPrompter } from "./doctor-prompter.js"; diff --git a/src/commands/doctor-auth-oauth-sidecar.ts b/src/commands/doctor-auth-oauth-sidecar.ts index b7d929337f0..c606766caed 100644 --- a/src/commands/doctor-auth-oauth-sidecar.ts +++ b/src/commands/doctor-auth-oauth-sidecar.ts @@ -1,5 +1,6 @@ import fs from "node:fs"; import path from "node:path"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { note } from "../../packages/terminal-core/src/note.js"; import { listAgentIds, resolveAgentDir, resolveDefaultAgentDir } from "../agents/agent-scope.js"; import { AUTH_STORE_VERSION } from "../agents/auth-profiles/constants.js"; @@ -9,7 +10,6 @@ import { formatCliCommand } from "../cli/command-format.js"; import { resolveOAuthDir, resolveStateDir } from "../config/paths.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { loadJsonFile, saveJsonFile } from "../infra/json-file.js"; -import { isRecord } from "../shared/record-coerce.js"; import { shortenHomePath } from "../utils.js"; import type { DoctorPrompter } from "./doctor-prompter.js"; import { diff --git a/src/commands/doctor-auth-profile-config.ts b/src/commands/doctor-auth-profile-config.ts index 0929ec92a1c..ccd1ca2924f 100644 --- a/src/commands/doctor-auth-profile-config.ts +++ b/src/commands/doctor-auth-profile-config.ts @@ -1,11 +1,11 @@ import { collectConfiguredModelRefs } from "@openclaw/model-catalog-core/configured-model-refs"; -import { splitTrailingAuthProfile } from "../agents/model-ref-profile.js"; -import type { AuthProfileConfig } from "../config/types.auth.js"; -import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { splitTrailingAuthProfile } from "../agents/model-ref-profile.js"; +import type { AuthProfileConfig } from "../config/types.auth.js"; +import type { OpenClawConfig } from "../config/types.openclaw.js"; import { isRecord } from "../utils.js"; const AUTH_PROFILE_MODES = new Set([ diff --git a/src/commands/doctor-claude-cli.ts b/src/commands/doctor-claude-cli.ts index 2d04edb5786..b2d5e40be3d 100644 --- a/src/commands/doctor-claude-cli.ts +++ b/src/commands/doctor-claude-cli.ts @@ -1,4 +1,9 @@ import fs from "node:fs"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, + resolvePrimaryStringValue, +} from "@openclaw/normalization-core/string-coerce"; import { note } from "../../packages/terminal-core/src/note.js"; import { resolveModelAgentRuntimeMetadata } from "../agents/agent-runtime-metadata.js"; import { @@ -19,11 +24,6 @@ import { resolveClaudeCliProjectDirForWorkspace } from "../agents/command/claude import { formatCliCommand } from "../cli/command-format.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { resolveExecutablePath } from "../infra/executable-path.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, - resolvePrimaryStringValue, -} from "../shared/string-coerce.js"; import { shortenHomePath } from "../utils.js"; const CLAUDE_CLI_PROVIDER = "claude-cli"; diff --git a/src/commands/doctor-command-owner.ts b/src/commands/doctor-command-owner.ts index b1202971f44..9151a274721 100644 --- a/src/commands/doctor-command-owner.ts +++ b/src/commands/doctor-command-owner.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { note } from "../../packages/terminal-core/src/note.js"; import { formatCliCommand } from "../cli/command-format.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { PairingChannel } from "../pairing/pairing-store.types.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; function resolveConfiguredCommandOwners(cfg: OpenClawConfig): string[] { const owners = cfg.commands?.ownerAllowFrom; diff --git a/src/commands/doctor-config-analysis.ts b/src/commands/doctor-config-analysis.ts index d7f218139e9..51092d34f78 100644 --- a/src/commands/doctor-config-analysis.ts +++ b/src/commands/doctor-config-analysis.ts @@ -1,11 +1,11 @@ import path from "node:path"; +import { resolvePrimaryStringValue } from "@openclaw/normalization-core/string-coerce"; import type { ZodIssue } from "zod"; import { note } from "../../packages/terminal-core/src/note.js"; import { CONFIG_PATH } from "../config/config.js"; import { resolveAgentModelFallbackValues } from "../config/model-input.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { OpenClawSchema } from "../config/zod-schema.js"; -import { resolvePrimaryStringValue } from "../shared/string-coerce.js"; import { isRecord } from "../utils.js"; type UnrecognizedKeysIssue = ZodIssue & { diff --git a/src/commands/doctor-device-pairing.ts b/src/commands/doctor-device-pairing.ts index b1aa2359c89..ccc00d03f66 100644 --- a/src/commands/doctor-device-pairing.ts +++ b/src/commands/doctor-device-pairing.ts @@ -1,4 +1,5 @@ import path from "node:path"; +import { normalizeUniqueSingleOrTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import { note } from "../../packages/terminal-core/src/note.js"; import { sanitizeTerminalText } from "../../packages/terminal-core/src/safe-text.js"; import { formatCliCommand } from "../cli/command-format.js"; @@ -17,7 +18,6 @@ import { JsonFileReadError, tryReadJsonSync } from "../infra/json-files.js"; import type { DeviceAuthStore } from "../shared/device-auth.js"; import { normalizeDeviceAuthScopes } from "../shared/device-auth.js"; import { roleScopesAllow } from "../shared/operator-scope-compat.js"; -import { normalizeUniqueSingleOrTrimmedStringList } from "../shared/string-normalization.js"; type GatewayListedPairedDevice = Omit & { tokens?: DeviceAuthTokenSummary[]; diff --git a/src/commands/doctor-gateway-services.ts b/src/commands/doctor-gateway-services.ts index 79b19fbe5b3..60229471596 100644 --- a/src/commands/doctor-gateway-services.ts +++ b/src/commands/doctor-gateway-services.ts @@ -3,6 +3,10 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { promisify } from "node:util"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { note } from "../../packages/terminal-core/src/note.js"; import { replaceConfigFile, type OpenClawConfig } from "../config/config.js"; import { resolveGatewayPort, resolveIsNixMode } from "../config/paths.js"; @@ -29,10 +33,6 @@ import { type SystemdUnitScope, } from "../daemon/systemd.js"; import type { RuntimeEnv } from "../runtime.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { buildGatewayInstallPlan } from "./daemon-install-helpers.js"; import { DEFAULT_GATEWAY_DAEMON_RUNTIME, type GatewayDaemonRuntime } from "./daemon-runtime.js"; import { resolveGatewayAuthTokenForService } from "./doctor-gateway-auth-token.js"; diff --git a/src/commands/doctor-heartbeat-main-session-repair.ts b/src/commands/doctor-heartbeat-main-session-repair.ts index 2b39c660a8c..27297e5d13e 100644 --- a/src/commands/doctor-heartbeat-main-session-repair.ts +++ b/src/commands/doctor-heartbeat-main-session-repair.ts @@ -1,5 +1,6 @@ import fs from "node:fs"; import path from "node:path"; +import { asNullableObjectRecord } from "@openclaw/normalization-core/record-coerce"; import type { note } from "../../packages/terminal-core/src/note.js"; import { isHeartbeatOkResponse, isHeartbeatUserMessage } from "../auto-reply/heartbeat-filter.js"; import { formatSessionArchiveTimestamp } from "../config/sessions/artifacts.js"; @@ -12,7 +13,6 @@ import { updateSessionStore } from "../config/sessions/store.js"; import type { SessionEntry } from "../config/sessions/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { parseAgentSessionKey } from "../sessions/session-key-utils.js"; -import { asNullableObjectRecord } from "../shared/record-coerce.js"; type DoctorPrompterLike = { confirmRuntimeRepair: (params: { diff --git a/src/commands/doctor-heartbeat-session-target.ts b/src/commands/doctor-heartbeat-session-target.ts index 04281ee388f..284b22aff40 100644 --- a/src/commands/doctor-heartbeat-session-target.ts +++ b/src/commands/doctor-heartbeat-session-target.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { listAgentEntries, listAgentIds, resolveAgentConfig } from "../agents/agent-scope.js"; import { canonicalizeMainSessionAlias } from "../config/sessions/main-session.js"; import { resolveStorePath } from "../config/sessions/paths.js"; @@ -12,7 +13,6 @@ import { toAgentStoreSessionKey, } from "../routing/session-key.js"; import { isSubagentSessionKey } from "../sessions/session-key-utils.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; type HeartbeatConfig = AgentDefaultsConfig["heartbeat"]; diff --git a/src/commands/doctor-memory-search.ts b/src/commands/doctor-memory-search.ts index abad6a2c43a..e3a4495835d 100644 --- a/src/commands/doctor-memory-search.ts +++ b/src/commands/doctor-memory-search.ts @@ -3,6 +3,7 @@ import { findNormalizedProviderValue, normalizeProviderId, } from "@openclaw/model-catalog-core/provider-id"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { note } from "../../packages/terminal-core/src/note.js"; import { resolveAgentDir, @@ -40,7 +41,6 @@ import { } from "../plugins/memory-runtime.js"; import { defaultSlotIdForKey } from "../plugins/slots.js"; import { getProviderEnvVars } from "../secrets/provider-env-vars.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resolveUserPath } from "../utils.js"; import type { DoctorPrompter } from "./doctor-prompter.js"; import { maybeRepairWorkspaceMemoryHealth, noteWorkspaceMemoryHealth } from "./doctor-workspace.js"; diff --git a/src/commands/doctor-platform-notes.ts b/src/commands/doctor-platform-notes.ts index ead7a057eda..13ab19c89a0 100644 --- a/src/commands/doctor-platform-notes.ts +++ b/src/commands/doctor-platform-notes.ts @@ -3,12 +3,12 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import { promisify } from "node:util"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { note } from "../../packages/terminal-core/src/note.js"; import { formatCliCommand } from "../cli/command-format.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { hasConfiguredSecretInput } from "../config/types.secrets.js"; import { findStaleOpenClawUpdateLaunchdJobs } from "../daemon/launchd.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { shortenHomePath } from "../utils.js"; const execFileAsync = promisify(execFile); diff --git a/src/commands/doctor-plugin-manifests.ts b/src/commands/doctor-plugin-manifests.ts index 857b7e6489c..e4a0093e805 100644 --- a/src/commands/doctor-plugin-manifests.ts +++ b/src/commands/doctor-plugin-manifests.ts @@ -1,12 +1,12 @@ import fs from "node:fs"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import { z } from "zod"; import { note } from "../../packages/terminal-core/src/note.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { loadPluginManifestRegistry } from "../plugins/manifest-registry.js"; import type { RuntimeEnv } from "../runtime.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { normalizeTrimmedStringList } from "../shared/string-normalization.js"; import { shortenHomePath } from "../utils.js"; import { safeParseJsonWithSchema, safeParseWithSchema } from "../utils/zod-parse.js"; import type { DoctorPrompter } from "./doctor-prompter.js"; diff --git a/src/commands/doctor-plugin-registry.ts b/src/commands/doctor-plugin-registry.ts index 500b486322a..a5c1c5a0f8e 100644 --- a/src/commands/doctor-plugin-registry.ts +++ b/src/commands/doctor-plugin-registry.ts @@ -1,5 +1,6 @@ import fs from "node:fs"; import path from "node:path"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { note } from "../../packages/terminal-core/src/note.js"; import { formatCliCommand } from "../cli/command-format.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; @@ -22,7 +23,6 @@ import { listStaleLocalBundledPluginInstallRecords, type StaleLocalBundledPluginInstallRecord, } from "../plugins/stale-local-bundled-plugin-install-records.js"; -import { isRecord } from "../shared/record-coerce.js"; import { shortenHomePath } from "../utils.js"; import type { DoctorPrompter } from "./doctor-prompter.js"; import { diff --git a/src/commands/doctor-security.ts b/src/commands/doctor-security.ts index 302e3a24101..42140bddd00 100644 --- a/src/commands/doctor-security.ts +++ b/src/commands/doctor-security.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { note } from "../../packages/terminal-core/src/note.js"; import { resolveDmAllowAuditState } from "../channels/message-access/dm-allow-state.js"; import { listReadOnlyChannelPluginsForConfig } from "../channels/plugins/read-only.js"; @@ -20,7 +21,6 @@ import { isLikelySensitiveModelProviderHeaderName } from "../secrets/model-provi import { hasConfiguredPlaintextSecretValue } from "../secrets/secret-value.js"; import { discoverConfigSecretTargets } from "../secrets/target-registry.js"; import { collectExecFilesystemPolicyDriftHits } from "../security/exec-filesystem-policy.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resolveDefaultChannelAccountContext } from "./channel-account-context.js"; function collectImplicitHeartbeatDirectPolicyWarnings(cfg: OpenClawConfig): string[] { diff --git a/src/commands/doctor-service-audit.test-helpers.ts b/src/commands/doctor-service-audit.test-helpers.ts index af697037ca8..c323993061f 100644 --- a/src/commands/doctor-service-audit.test-helpers.ts +++ b/src/commands/doctor-service-audit.test-helpers.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { isEnvironmentFileOnlySource } from "../daemon/service-managed-env.js"; import type { GatewayServiceEnvironmentValueSource } from "../daemon/service-types.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; export const testServiceAuditCodes = { gatewayCommandMissing: "gateway-command-missing", diff --git a/src/commands/doctor-session-snapshots.ts b/src/commands/doctor-session-snapshots.ts index 6b73d0f92f5..06145625d6f 100644 --- a/src/commands/doctor-session-snapshots.ts +++ b/src/commands/doctor-session-snapshots.ts @@ -1,5 +1,6 @@ import fs from "node:fs"; import path from "node:path"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { note } from "../../packages/terminal-core/src/note.js"; import { resolveStateDir } from "../config/paths.js"; import { hydrateSessionStoreSkillPromptRefs } from "../config/sessions/skill-prompt-blobs.js"; @@ -7,7 +8,6 @@ import { resolveAllAgentSessionStoreTargetsSync } from "../config/sessions/targe import type { SessionEntry } from "../config/sessions/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { expandHomePrefix } from "../infra/home-dir.js"; -import { isRecord } from "../shared/record-coerce.js"; import { resolveBundledSkillsDir } from "../skills/loading/bundled-dir.js"; import { shortenHomePath } from "../utils.js"; diff --git a/src/commands/doctor-session-state-providers.ts b/src/commands/doctor-session-state-providers.ts index 11dc70cda2f..3689b011546 100644 --- a/src/commands/doctor-session-state-providers.ts +++ b/src/commands/doctor-session-state-providers.ts @@ -1,3 +1,5 @@ +import { normalizeOptionalString as normalizeString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntriesLower } from "@openclaw/normalization-core/string-normalization"; import { note } from "../../packages/terminal-core/src/note.js"; import { resolveAgentModelFallbacksOverride, @@ -17,8 +19,6 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; import { listPluginDoctorSessionRouteStateOwners } from "../plugins/doctor-contract-registry.js"; import type { DoctorSessionRouteStateOwner } from "../plugins/doctor-session-route-state-owner-types.js"; import { parseAgentSessionKey } from "../sessions/session-key-utils.js"; -import { normalizeOptionalString as normalizeString } from "../shared/string-coerce.js"; -import { normalizeStringEntriesLower } from "../shared/string-normalization.js"; type DoctorPrompterLike = { confirmRuntimeRepair: (params: { diff --git a/src/commands/doctor-state-integrity.ts b/src/commands/doctor-state-integrity.ts index dfddb908d12..e9fdef5358f 100644 --- a/src/commands/doctor-state-integrity.ts +++ b/src/commands/doctor-state-integrity.ts @@ -1,6 +1,9 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; +import { asNullableObjectRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { note } from "../../packages/terminal-core/src/note.js"; import { listAgentEntries, resolveDefaultAgentId } from "../agents/agent-scope.js"; import { @@ -30,9 +33,6 @@ import { resolveOpenClawAgentDir } from "../plugin-sdk/agent-dir-compat.js"; import { listConfiguredChannelIdsForReadOnlyScope } from "../plugins/channel-plugin-ids.js"; import { normalizeAgentId } from "../routing/session-key.js"; import { parseAgentSessionKey } from "../sessions/session-key-utils.js"; -import { asNullableObjectRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { shortenHomePath } from "../utils.js"; import { repairHeartbeatPoisonedMainSession } from "./doctor-heartbeat-main-session-repair.js"; import { describeHeartbeatSessionTargetIssues } from "./doctor-heartbeat-session-target.js"; diff --git a/src/commands/doctor-update.ts b/src/commands/doctor-update.ts index 3e9f0969dd3..e39b4680494 100644 --- a/src/commands/doctor-update.ts +++ b/src/commands/doctor-update.ts @@ -1,12 +1,12 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { note } from "../../packages/terminal-core/src/note.js"; import { formatCliCommand } from "../cli/command-format.js"; import { isTruthyEnvValue } from "../infra/env.js"; import { runGatewayUpdate } from "../infra/update-runner.js"; import { runCommandWithTimeout } from "../process/exec.js"; import type { RuntimeEnv } from "../runtime.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import type { DoctorOptions } from "./doctor-prompter.js"; async function resolveComparablePath(target: string): Promise { diff --git a/src/commands/doctor.e2e-harness.ts b/src/commands/doctor.e2e-harness.ts index cd25c0782f2..ec3cc64c4e6 100644 --- a/src/commands/doctor.e2e-harness.ts +++ b/src/commands/doctor.e2e-harness.ts @@ -1,9 +1,9 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { afterEach, beforeEach, vi } from "vitest"; import { createEmptyPluginRegistry } from "../plugins/registry-empty.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import type { MockFn } from "../test-utils/vitest-mock-fn.js"; import { readEmbeddedGatewayTokenForTest, diff --git a/src/commands/doctor/cron/dreaming-payload-migration.ts b/src/commands/doctor/cron/dreaming-payload-migration.ts index 92302e7242c..1fd4c643361 100644 --- a/src/commands/doctor/cron/dreaming-payload-migration.ts +++ b/src/commands/doctor/cron/dreaming-payload-migration.ts @@ -6,7 +6,7 @@ import { import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../../../shared/string-coerce.js"; +} from "../../../../packages/normalization-core/src/string-coerce.js"; type UnknownRecord = Record; diff --git a/src/commands/doctor/cron/index.ts b/src/commands/doctor/cron/index.ts index a1020a198ba..a8c5ea18cd2 100644 --- a/src/commands/doctor/cron/index.ts +++ b/src/commands/doctor/cron/index.ts @@ -15,7 +15,7 @@ import type { CronJob } from "../../../cron/types.js"; import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../../../shared/string-coerce.js"; +} from "../../../../packages/normalization-core/src/string-coerce.js"; import { shortenHomePath } from "../../../utils.js"; import type { DoctorPrompter, DoctorOptions } from "../../doctor-prompter.js"; import { diff --git a/src/commands/doctor/cron/legacy-store-migration.ts b/src/commands/doctor/cron/legacy-store-migration.ts index df0f1abd43f..49eb7663739 100644 --- a/src/commands/doctor/cron/legacy-store-migration.ts +++ b/src/commands/doctor/cron/legacy-store-migration.ts @@ -7,8 +7,8 @@ import type { QuarantinedCronConfigJob, } from "../../../cron/store.js"; import type { CronStoreFile } from "../../../cron/types.js"; -import { isRecord } from "../../../shared/record-coerce.js"; -import { normalizeOptionalString } from "../../../shared/string-coerce.js"; +import { isRecord } from "../../../../packages/normalization-core/src/record-coerce.js"; +import { normalizeOptionalString } from "../../../../packages/normalization-core/src/string-coerce.js"; import { parseJsonWithJson5Fallback } from "../../../utils/parse-json-compat.js"; const LEGACY_CRON_ARCHIVE_SUFFIX = ".migrated"; diff --git a/src/commands/doctor/cron/payload-migration.ts b/src/commands/doctor/cron/payload-migration.ts index f38242895f9..80f3729dcfd 100644 --- a/src/commands/doctor/cron/payload-migration.ts +++ b/src/commands/doctor/cron/payload-migration.ts @@ -1,7 +1,7 @@ import { normalizeOptionalLowercaseString, readStringValue as readString, -} from "../../../shared/string-coerce.js"; +} from "../../../../packages/normalization-core/src/string-coerce.js"; type UnknownRecord = Record; diff --git a/src/commands/doctor/cron/store-migration.ts b/src/commands/doctor/cron/store-migration.ts index 224982ed09a..acd7b086b54 100644 --- a/src/commands/doctor/cron/store-migration.ts +++ b/src/commands/doctor/cron/store-migration.ts @@ -4,13 +4,13 @@ import { getInvalidPersistedCronJobReason } from "../../../cron/persisted-shape. import { coerceFiniteScheduleNumber } from "../../../cron/schedule.js"; import { inferLegacyName } from "../../../cron/service/normalize.js"; import { normalizeCronStaggerMs, resolveDefaultCronStaggerMs } from "../../../cron/stagger.js"; -import { timestampMsToIsoString } from "../../../shared/number-coercion.js"; +import { timestampMsToIsoString } from "../../../../packages/normalization-core/src/number-coercion.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeOptionalStringifiedId, -} from "../../../shared/string-coerce.js"; +} from "../../../../packages/normalization-core/src/string-coerce.js"; import { normalizeLegacyDeliveryInput } from "./legacy-delivery.js"; import { hasLegacyOpenAICodexCronModelRef, migrateLegacyCronPayload } from "./payload-migration.js"; diff --git a/src/commands/doctor/shared/allowfrom-fallback-migration.ts b/src/commands/doctor/shared/allowfrom-fallback-migration.ts index 11aaf2d61a5..12bc515465c 100644 --- a/src/commands/doctor/shared/allowfrom-fallback-migration.ts +++ b/src/commands/doctor/shared/allowfrom-fallback-migration.ts @@ -1,8 +1,8 @@ +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import { resolveChannelDmAllowFrom } from "../../../channels/plugins/dm-access.js"; import { normalizeAnyChannelId } from "../../../channels/registry.js"; import { GENERATED_BUNDLED_CHANNEL_CONFIG_METADATA } from "../../../config/bundled-channel-config-metadata.generated.js"; import type { OpenClawConfig } from "../../../config/types.openclaw.js"; -import { normalizeUniqueStringEntries } from "../../../shared/string-normalization.js"; import { getDoctorChannelCapabilities } from "../channel-capabilities.js"; import { asObjectRecord } from "./object.js"; diff --git a/src/commands/doctor/shared/allowlist-policy-repair.ts b/src/commands/doctor/shared/allowlist-policy-repair.ts index df0863679b5..ccee506ddd5 100644 --- a/src/commands/doctor/shared/allowlist-policy-repair.ts +++ b/src/commands/doctor/shared/allowlist-policy-repair.ts @@ -1,10 +1,10 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import { normalizeChatChannelId } from "../../../channels/ids.js"; import { setCanonicalDmAllowFrom } from "../../../channels/plugins/dm-access.js"; import type { OpenClawConfig } from "../../../config/types.openclaw.js"; import { readChannelAllowFromStore } from "../../../pairing/pairing-store.js"; import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../routing/session-key.js"; -import { normalizeOptionalLowercaseString } from "../../../shared/string-coerce.js"; -import { normalizeUniqueStringEntries } from "../../../shared/string-normalization.js"; import { resolveAllowFromMode, type AllowFromMode } from "./allow-from-mode.js"; import { hasAllowFromEntries } from "./allowlist.js"; import { asObjectRecord } from "./object.js"; diff --git a/src/commands/doctor/shared/allowlist.ts b/src/commands/doctor/shared/allowlist.ts index f362421c125..61926dc6c29 100644 --- a/src/commands/doctor/shared/allowlist.ts +++ b/src/commands/doctor/shared/allowlist.ts @@ -1,4 +1,4 @@ -import { normalizeStringEntries } from "../../../shared/string-normalization.js"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { DoctorAllowFromList } from "../types.js"; export function hasAllowFromEntries(list?: DoctorAllowFromList) { diff --git a/src/commands/doctor/shared/channel-doctor.ts b/src/commands/doctor/shared/channel-doctor.ts index 2e7e82cf201..ab1d3642c4f 100644 --- a/src/commands/doctor/shared/channel-doctor.ts +++ b/src/commands/doctor/shared/channel-doctor.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { getBundledChannelPlugin, getBundledChannelSetupPlugin, @@ -11,7 +12,6 @@ import type { ChannelDoctorSequenceResult, } from "../../../channels/plugins/types.adapters.js"; import type { OpenClawConfig } from "../../../config/types.openclaw.js"; -import { normalizeOptionalLowercaseString } from "../../../shared/string-coerce.js"; type ChannelDoctorEntry = { doctor: ChannelDoctorAdapter; diff --git a/src/commands/doctor/shared/channel-plugin-blockers.ts b/src/commands/doctor/shared/channel-plugin-blockers.ts index 1b3ee4e2956..62a6c3af461 100644 --- a/src/commands/doctor/shared/channel-plugin-blockers.ts +++ b/src/commands/doctor/shared/channel-plugin-blockers.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { sanitizeForLog } from "../../../../packages/terminal-core/src/ansi.js"; import type { OpenClawConfig } from "../../../config/types.openclaw.js"; import { @@ -9,7 +10,6 @@ import { resolveEffectivePluginActivationState, } from "../../../plugins/config-state.js"; import { loadPluginManifestRegistryForPluginRegistry } from "../../../plugins/plugin-registry.js"; -import { normalizeOptionalLowercaseString } from "../../../shared/string-coerce.js"; export type ChannelPluginBlockerHit = { channelId: string; diff --git a/src/commands/doctor/shared/codex-native-assets.ts b/src/commands/doctor/shared/codex-native-assets.ts index f3a028d0022..c50998e4185 100644 --- a/src/commands/doctor/shared/codex-native-assets.ts +++ b/src/commands/doctor/shared/codex-native-assets.ts @@ -2,10 +2,10 @@ import type { Dirent } from "node:fs"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; +import { isRecord as hasRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalLowercaseString as normalizeString } from "@openclaw/normalization-core/string-coerce"; import { collectConfiguredAgentHarnessRuntimes } from "../../../agents/harness-runtimes.js"; import type { OpenClawConfig } from "../../../config/types.openclaw.js"; -import { isRecord as hasRecord } from "../../../shared/record-coerce.js"; -import { normalizeOptionalLowercaseString as normalizeString } from "../../../shared/string-coerce.js"; export type CodexNativeAssetHit = { kind: "skill" | "plugin" | "config" | "hooks"; diff --git a/src/commands/doctor/shared/codex-route-warnings.ts b/src/commands/doctor/shared/codex-route-warnings.ts index 0e4f496ad69..b0e0c1c89b7 100644 --- a/src/commands/doctor/shared/codex-route-warnings.ts +++ b/src/commands/doctor/shared/codex-route-warnings.ts @@ -1,6 +1,8 @@ import fs from "node:fs"; import { AGENT_MODEL_CONFIG_KEYS } from "@openclaw/model-catalog-core/configured-model-refs"; import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { asOptionalRecord as asMutableRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalLowercaseString as normalizeString } from "@openclaw/normalization-core/string-coerce"; import { normalizeOptionalAgentRuntimeId } from "../../../agents/agent-runtime-id.js"; import { resolveConfiguredProviderFallback } from "../../../agents/configured-provider-fallback.js"; import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../../../agents/defaults.js"; @@ -15,8 +17,6 @@ import type { AgentRuntimePolicyConfig } from "../../../config/types.agents-shar import type { OpenClawConfig } from "../../../config/types.openclaw.js"; import { detectWindowsSpawnCommandInlineArgs } from "../../../plugin-sdk/windows-spawn.js"; import { normalizeAgentId } from "../../../routing/session-key.js"; -import { asOptionalRecord as asMutableRecord } from "../../../shared/record-coerce.js"; -import { normalizeOptionalLowercaseString as normalizeString } from "../../../shared/string-coerce.js"; type CodexRouteHit = { path: string; diff --git a/src/commands/doctor/shared/configured-runtime-plugin-installs.ts b/src/commands/doctor/shared/configured-runtime-plugin-installs.ts index 32ff2d28c95..7e5832eb23b 100644 --- a/src/commands/doctor/shared/configured-runtime-plugin-installs.ts +++ b/src/commands/doctor/shared/configured-runtime-plugin-installs.ts @@ -1,10 +1,10 @@ +import { asOptionalRecord } from "@openclaw/normalization-core/record-coerce"; import { collectConfiguredAgentHarnessRuntimes, type ConfiguredAgentHarnessRuntimeOptions, } from "../../../agents/harness-runtimes.js"; import type { OpenClawConfig } from "../../../config/types.openclaw.js"; import type { PluginPackageInstall } from "../../../plugins/manifest.js"; -import { asOptionalRecord } from "../../../shared/record-coerce.js"; export type ConfiguredRuntimePluginInstallCandidate = { pluginId: string; diff --git a/src/commands/doctor/shared/context-engine-host-compat.ts b/src/commands/doctor/shared/context-engine-host-compat.ts index 7ce269b5adb..26497ee0e33 100644 --- a/src/commands/doctor/shared/context-engine-host-compat.ts +++ b/src/commands/doctor/shared/context-engine-host-compat.ts @@ -1,4 +1,5 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { normalizeEmbeddedAgentRuntime } from "../../../agents/agent-runtime-id.js"; import { resolveDefaultAgentDir } from "../../../agents/agent-scope-config.js"; import { resolveCliBackendConfig } from "../../../agents/cli-backends.js"; @@ -18,7 +19,6 @@ import { getContextEngineFactory, resolveContextEngine } from "../../../context- import type { ContextEngineInfo } from "../../../context-engine/types.js"; import { ensurePluginRegistryLoaded } from "../../../plugins/runtime/runtime-registry-loader.js"; import { defaultSlotIdForKey } from "../../../plugins/slots.js"; -import { uniqueStrings } from "../../../shared/string-normalization.js"; import { isRecord, resolveUserPath } from "../../../utils.js"; export type HostCandidate = { diff --git a/src/commands/doctor/shared/default-account-warnings.ts b/src/commands/doctor/shared/default-account-warnings.ts index 809a39ceee7..5c15fa2bf55 100644 --- a/src/commands/doctor/shared/default-account-warnings.ts +++ b/src/commands/doctor/shared/default-account-warnings.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { normalizeChatChannelId } from "../../../channels/ids.js"; import { listRouteBindings } from "../../../config/bindings.js"; import type { OpenClawConfig } from "../../../config/types.openclaw.js"; @@ -11,10 +15,6 @@ import { normalizeAccountId, normalizeOptionalAccountId, } from "../../../routing/session-key.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../../shared/string-coerce.js"; import { asObjectRecord } from "./object.js"; type ChannelMissingDefaultAccountContext = { diff --git a/src/commands/doctor/shared/exec-safe-bins.ts b/src/commands/doctor/shared/exec-safe-bins.ts index 24d70b053e0..1d9f8a447f8 100644 --- a/src/commands/doctor/shared/exec-safe-bins.ts +++ b/src/commands/doctor/shared/exec-safe-bins.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { sanitizeForLog } from "../../../../packages/terminal-core/src/ansi.js"; import type { OpenClawConfig } from "../../../config/types.openclaw.js"; import { resolveCommandResolutionFromArgv } from "../../../infra/exec-command-resolution.js"; @@ -11,7 +12,6 @@ import { isTrustedSafeBinPath, normalizeTrustedSafeBinDirs, } from "../../../infra/exec-safe-bin-trust.js"; -import { normalizeOptionalLowercaseString } from "../../../shared/string-coerce.js"; import { asObjectRecord } from "./object.js"; export type ExecSafeBinCoverageHit = { diff --git a/src/commands/doctor/shared/legacy-config-core-normalizers.ts b/src/commands/doctor/shared/legacy-config-core-normalizers.ts index efe88ad1a68..307f8a5ec4e 100644 --- a/src/commands/doctor/shared/legacy-config-core-normalizers.ts +++ b/src/commands/doctor/shared/legacy-config-core-normalizers.ts @@ -1,14 +1,14 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { sanitizeForLog } from "../../../../packages/terminal-core/src/ansi.js"; import { resolveSingleAccountKeysToMove } from "../../../channels/plugins/setup-promotion-helpers.js"; import { resolveNormalizedProviderModelMaxTokens } from "../../../config/defaults.js"; import type { OpenClawConfig } from "../../../config/types.openclaw.js"; import { DEFAULT_GOOGLE_API_BASE_URL } from "../../../infra/google-api-base-url.js"; import { DEFAULT_ACCOUNT_ID } from "../../../routing/session-key.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../../shared/string-coerce.js"; import { hasOwnKey, isRecord } from "./legacy-config-record-shared.js"; import { isLegacyModelsAddCodexMetadataModel } from "./legacy-models-add-metadata.js"; import { diff --git a/src/commands/doctor/shared/legacy-config-migrations.runtime.agents.ts b/src/commands/doctor/shared/legacy-config-migrations.runtime.agents.ts index 616b671095e..fb340f5dee8 100644 --- a/src/commands/doctor/shared/legacy-config-migrations.runtime.agents.ts +++ b/src/commands/doctor/shared/legacy-config-migrations.runtime.agents.ts @@ -1,4 +1,5 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { isKnownCoreToolId } from "../../../agents/tool-catalog.js"; import { isToolAllowedByPolicyName } from "../../../agents/tool-policy-match.js"; import { resolveToolProfilePolicy } from "../../../agents/tool-policy-shared.js"; @@ -12,7 +13,6 @@ import { type LegacyConfigRule, } from "../../../config/legacy.shared.js"; import { isBlockedObjectKey } from "../../../config/prototype-keys.js"; -import { uniqueStrings } from "../../../shared/string-normalization.js"; import { listLegacyRuntimeModelProviderAliases } from "./legacy-runtime-model-providers.js"; const AGENT_HEARTBEAT_KEYS = new Set([ diff --git a/src/commands/doctor/shared/legacy-config-migrations.runtime.gateway.ts b/src/commands/doctor/shared/legacy-config-migrations.runtime.gateway.ts index 2be1cf92b4a..2a70ea16822 100644 --- a/src/commands/doctor/shared/legacy-config-migrations.runtime.gateway.ts +++ b/src/commands/doctor/shared/legacy-config-migrations.runtime.gateway.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { buildDefaultControlUiAllowedOrigins, hasConfiguredControlUiAllowedOrigins, @@ -11,7 +12,6 @@ import { type LegacyConfigRule, } from "../../../config/legacy.shared.js"; import { DEFAULT_GATEWAY_PORT } from "../../../config/paths.js"; -import { normalizeOptionalLowercaseString } from "../../../shared/string-coerce.js"; const GATEWAY_BIND_RULE: LegacyConfigRule = { path: ["gateway", "bind"], diff --git a/src/commands/doctor/shared/legacy-oauth-sidecar.ts b/src/commands/doctor/shared/legacy-oauth-sidecar.ts index f9e848439c1..2c396b162e4 100644 --- a/src/commands/doctor/shared/legacy-oauth-sidecar.ts +++ b/src/commands/doctor/shared/legacy-oauth-sidecar.ts @@ -3,11 +3,11 @@ import { createCipheriv, createDecipheriv, hash } from "node:crypto"; import fs from "node:fs"; import os from "node:os"; import path from "node:path"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { log } from "../../../agents/auth-profiles/constants.js"; import { resolveOAuthDir, resolveStateDir } from "../../../config/paths.js"; import { loadJsonFile } from "../../../infra/json-file.js"; -import { isRecord } from "../../../shared/record-coerce.js"; -import { uniqueStrings } from "../../../shared/string-normalization.js"; const LEGACY_OAUTH_REF_SOURCE = "openclaw-credentials"; const LEGACY_OAUTH_REF_PROVIDER = "openai-codex"; diff --git a/src/commands/doctor/shared/legacy-talk-config-normalizer.ts b/src/commands/doctor/shared/legacy-talk-config-normalizer.ts index 02d4fd4b81b..8334fa54d15 100644 --- a/src/commands/doctor/shared/legacy-talk-config-normalizer.ts +++ b/src/commands/doctor/shared/legacy-talk-config-normalizer.ts @@ -1,7 +1,7 @@ import { isDeepStrictEqual } from "node:util"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { normalizeTalkSection } from "../../../config/talk.js"; import type { OpenClawConfig } from "../../../config/types.js"; -import { isRecord } from "../../../shared/record-coerce.js"; function buildLegacyTalkProviderCompat( talk: Record, diff --git a/src/commands/doctor/shared/missing-configured-plugin-install.ts b/src/commands/doctor/shared/missing-configured-plugin-install.ts index 9e0a444b133..aac104722c9 100644 --- a/src/commands/doctor/shared/missing-configured-plugin-install.ts +++ b/src/commands/doctor/shared/missing-configured-plugin-install.ts @@ -1,6 +1,7 @@ import { existsSync } from "node:fs"; import { readFile, rm } from "node:fs/promises"; import path from "node:path"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { listExplicitlyDisabledChannelIdsForConfig, listPotentialConfiguredChannelIds, @@ -50,7 +51,6 @@ import type { PluginMetadataSnapshot } from "../../../plugins/plugin-metadata-sn import { resolveProviderInstallCatalogEntries } from "../../../plugins/provider-install-catalog.js"; import { updateNpmInstalledPlugins } from "../../../plugins/update.js"; import { resolveWebSearchInstallCatalogEntry } from "../../../plugins/web-search-install-catalog.js"; -import { normalizeOptionalLowercaseString } from "../../../shared/string-coerce.js"; import { resolveUserPath } from "../../../utils.js"; import { VERSION } from "../../../version.js"; import { diff --git a/src/commands/doctor/shared/plugin-runtime-symlinks.ts b/src/commands/doctor/shared/plugin-runtime-symlinks.ts index a9925c69a47..36a14862a6f 100644 --- a/src/commands/doctor/shared/plugin-runtime-symlinks.ts +++ b/src/commands/doctor/shared/plugin-runtime-symlinks.ts @@ -1,7 +1,7 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { note } from "../../../../packages/terminal-core/src/note.js"; -import { sortUniqueStrings } from "../../../shared/string-normalization.js"; import { shortenHomePath } from "../../../utils.js"; const PLUGIN_RUNTIME_DEPS_MARKER = "plugin-runtime-deps"; diff --git a/src/commands/doctor/shared/plugin-tool-allowlist-warnings.ts b/src/commands/doctor/shared/plugin-tool-allowlist-warnings.ts index d17b13346db..c444c7215d7 100644 --- a/src/commands/doctor/shared/plugin-tool-allowlist-warnings.ts +++ b/src/commands/doctor/shared/plugin-tool-allowlist-warnings.ts @@ -1,4 +1,10 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { isRecord as hasRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { + sortUniqueStrings, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { sanitizeServerName, TOOL_NAME_SEPARATOR } from "../../../agents/agent-bundle-mcp-names.js"; import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../../../agents/defaults.js"; import { compileGlobPatterns, matchesAnyGlobPattern } from "../../../agents/glob-pattern.js"; @@ -14,9 +20,6 @@ import type { OpenClawConfig } from "../../../config/types.openclaw.js"; import { normalizePluginId } from "../../../plugins/config-state.js"; import { loadManifestMetadataSnapshot } from "../../../plugins/manifest-contract-eligibility.js"; import type { PluginManifestRegistry } from "../../../plugins/manifest-registry.js"; -import { isRecord as hasRecord } from "../../../shared/record-coerce.js"; -import { normalizeLowercaseStringOrEmpty } from "../../../shared/string-coerce.js"; -import { sortUniqueStrings, uniqueStrings } from "../../../shared/string-normalization.js"; type ToolAllowlistSource = { label: string; diff --git a/src/commands/doctor/shared/preview-warnings.ts b/src/commands/doctor/shared/preview-warnings.ts index dc84a021130..bd81e837889 100644 --- a/src/commands/doctor/shared/preview-warnings.ts +++ b/src/commands/doctor/shared/preview-warnings.ts @@ -1,4 +1,6 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { isRecord as hasRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { resolveAgentConfig } from "../../../agents/agent-scope-config.js"; import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../../../agents/defaults.js"; import { parseModelRef } from "../../../agents/model-selection-normalize.js"; @@ -13,8 +15,6 @@ import type { OpenClawConfig } from "../../../config/types.openclaw.js"; import type { AgentToolsConfig, ToolsConfig } from "../../../config/types.tools.js"; import { collectChannelRouteTargets } from "../../../routing/channel-route-targets.js"; import { createLazyImportLoader } from "../../../shared/lazy-promise.js"; -import { isRecord as hasRecord } from "../../../shared/record-coerce.js"; -import { normalizeLowercaseStringOrEmpty } from "../../../shared/string-coerce.js"; type ChannelDoctorModule = typeof import("./channel-doctor.js"); diff --git a/src/commands/doctor/shared/release-configured-plugin-installs.ts b/src/commands/doctor/shared/release-configured-plugin-installs.ts index 7a13cb2f505..1c06f1c39ad 100644 --- a/src/commands/doctor/shared/release-configured-plugin-installs.ts +++ b/src/commands/doctor/shared/release-configured-plugin-installs.ts @@ -1,4 +1,5 @@ import { collectConfiguredModelRefs } from "@openclaw/model-catalog-core/configured-model-refs"; +import { normalizeNullableString as normalizeId } from "@openclaw/normalization-core/string-coerce"; import { collectConfiguredAgentHarnessRuntimes } from "../../../agents/harness-runtimes.js"; import { listPotentialConfiguredChannelPresenceSignals } from "../../../channels/config-presence.js"; import { normalizeChatChannelId } from "../../../channels/registry.js"; @@ -9,7 +10,6 @@ import { compareOpenClawVersions } from "../../../config/version.js"; import { getOfficialExternalPluginCatalogEntry } from "../../../plugins/official-external-plugin-catalog.js"; import { resolveProviderInstallCatalogEntries } from "../../../plugins/provider-install-catalog.js"; import { resolveWebSearchInstallCatalogEntry } from "../../../plugins/web-search-install-catalog.js"; -import { normalizeNullableString as normalizeId } from "../../../shared/string-coerce.js"; import { VERSION } from "../../../version.js"; import { repairMissingPluginInstallsForIds } from "./missing-configured-plugin-install.js"; import { asObjectRecord } from "./object.js"; diff --git a/src/commands/doctor/shared/stale-oauth-profile-shadows.ts b/src/commands/doctor/shared/stale-oauth-profile-shadows.ts index 176cc4bd679..aeca20b4d0d 100644 --- a/src/commands/doctor/shared/stale-oauth-profile-shadows.ts +++ b/src/commands/doctor/shared/stale-oauth-profile-shadows.ts @@ -1,5 +1,6 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { resolveAgentDir, resolveDefaultAgentDir, @@ -18,7 +19,6 @@ import type { AuthProfileStore, OAuthCredential } from "../../../agents/auth-pro import { resolveStateDir } from "../../../config/paths.js"; import type { OpenClawConfig } from "../../../config/types.openclaw.js"; import { withFileLock } from "../../../infra/file-lock.js"; -import { isRecord } from "../../../shared/record-coerce.js"; import { shortenHomePath } from "../../../utils.js"; type StaleOAuthProfileShadow = { diff --git a/src/commands/doctor/shared/stale-subagent-allowlist.ts b/src/commands/doctor/shared/stale-subagent-allowlist.ts index 3acc4d641cd..526784867a0 100644 --- a/src/commands/doctor/shared/stale-subagent-allowlist.ts +++ b/src/commands/doctor/shared/stale-subagent-allowlist.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { listAgentIds } from "../../../agents/agent-scope-config.js"; import type { OpenClawConfig } from "../../../config/types.openclaw.js"; import { normalizeAgentId } from "../../../routing/session-key.js"; -import { normalizeOptionalString } from "../../../shared/string-coerce.js"; export type StaleSubagentAllowlistHit = { pathLabel: string; diff --git a/src/commands/flows.ts b/src/commands/flows.ts index 90cc4a93b78..8913b294982 100644 --- a/src/commands/flows.ts +++ b/src/commands/flows.ts @@ -1,11 +1,11 @@ +import { timestampMsToIsoString } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { sanitizeTerminalText } from "../../packages/terminal-core/src/safe-text.js"; import { isRich, theme } from "../../packages/terminal-core/src/theme.js"; import { formatCliCommand } from "../cli/command-format.js"; import { getRuntimeConfig } from "../config/config.js"; import { info } from "../globals.js"; import type { RuntimeEnv } from "../runtime.js"; -import { timestampMsToIsoString } from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { listTasksForFlowId } from "../tasks/runtime-internal.js"; import { cancelFlowById, getFlowTaskSummary } from "../tasks/task-executor.js"; import type { TaskFlowRecord, TaskFlowStatus } from "../tasks/task-flow-registry.types.js"; diff --git a/src/commands/gateway-install-token.ts b/src/commands/gateway-install-token.ts index 81b4251e325..fc276ecc05c 100644 --- a/src/commands/gateway-install-token.ts +++ b/src/commands/gateway-install-token.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { formatCliCommand } from "../cli/command-format.js"; import type { ConfigWriteOptions } from "../config/io.js"; import type { OpenClawConfig } from "../config/types.js"; @@ -11,7 +12,6 @@ import { formatUnsafeGatewayTailscaleNoAuthMessage, isUnsafeGatewayTailscaleNoAuth, } from "../shared/gateway-tailscale-auth-policy.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { readConfigFileSnapshotForWrite, replaceConfigFile, diff --git a/src/commands/gateway-presence.ts b/src/commands/gateway-presence.ts index 48d674febeb..cddf5979c2d 100644 --- a/src/commands/gateway-presence.ts +++ b/src/commands/gateway-presence.ts @@ -1,4 +1,4 @@ -import { readStringValue } from "../shared/string-coerce.js"; +import { readStringValue } from "@openclaw/normalization-core/string-coerce"; type GatewaySelfPresence = { host?: string; diff --git a/src/commands/gateway-status/discovery.ts b/src/commands/gateway-status/discovery.ts index 7c8a9520a2e..a4ebeae50d1 100644 --- a/src/commands/gateway-status/discovery.ts +++ b/src/commands/gateway-status/discovery.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { GatewayBonjourBeacon } from "../../infra/bonjour-discovery.js"; import { buildGatewayDiscoveryTarget, serializeGatewayDiscoveryBeacon, } from "../../infra/gateway-discovery-targets.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; export function inferSshTargetFromRemoteUrl(rawUrl?: string | null): string | null { if (typeof rawUrl !== "string") { diff --git a/src/commands/gateway-status/helpers.ts b/src/commands/gateway-status/helpers.ts index d90bc751da9..72698327d37 100644 --- a/src/commands/gateway-status/helpers.ts +++ b/src/commands/gateway-status/helpers.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { colorize, theme } from "../../../packages/terminal-core/src/theme.js"; import { parseTimeoutMsWithFallback } from "../../cli/parse-timeout.js"; import { resolveGatewayPort } from "../../config/config.js"; @@ -8,7 +9,6 @@ import { isLoopbackHost } from "../../gateway/net.js"; import { type GatewayProbeCapability, type GatewayProbeResult } from "../../gateway/probe.js"; import { inspectBestEffortPrimaryTailnetIPv4 } from "../../infra/network-discovery-display.js"; import { parseStrictInteger } from "../../infra/parse-finite-number.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { pickGatewaySelfPresence } from "../gateway-presence.js"; const MISSING_SCOPE_PATTERN = /\bmissing scope:\s*[a-z0-9._-]+/i; diff --git a/src/commands/gateway-status/probe-run.ts b/src/commands/gateway-status/probe-run.ts index f3d9100d68f..7c6828b8e73 100644 --- a/src/commands/gateway-status/probe-run.ts +++ b/src/commands/gateway-status/probe-run.ts @@ -1,3 +1,7 @@ +import { + normalizeOptionalString, + readStringValue, +} from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.js"; import { probeGateway } from "../../gateway/probe.js"; import { @@ -5,7 +9,6 @@ import { type GatewayBonjourBeacon, } from "../../infra/bonjour-discovery.js"; import { formatErrorMessage } from "../../infra/errors.js"; -import { normalizeOptionalString, readStringValue } from "../../shared/string-coerce.js"; import { pickAutoSshTargetFromDiscovery } from "./discovery.js"; import { extractConfigSummary, diff --git a/src/commands/health-format.ts b/src/commands/health-format.ts index c511f4afbab..2b6c025de0b 100644 --- a/src/commands/health-format.ts +++ b/src/commands/health-format.ts @@ -1,6 +1,6 @@ +import { asNullableRecord } from "@openclaw/normalization-core/record-coerce"; import { colorize, isRich, theme } from "../../packages/terminal-core/src/theme.js"; import { formatChannelStatusState } from "../channels/plugins/status-state.js"; -import { asNullableRecord } from "../shared/record-coerce.js"; import type { ChannelAccountHealthSummary, HealthSummary } from "./health.types.js"; const formatKv = (line: string, rich: boolean) => { diff --git a/src/commands/health.ts b/src/commands/health.ts index 1dcc61fb69e..fc125c5cc90 100644 --- a/src/commands/health.ts +++ b/src/commands/health.ts @@ -1,3 +1,4 @@ +import { asNullableRecord } from "@openclaw/normalization-core/record-coerce"; import { styleHealthChannelLine } from "../../packages/terminal-core/src/health-style.js"; import { isRich } from "../../packages/terminal-core/src/theme.js"; import { resolveDefaultAgentId } from "../agents/agent-scope.js"; @@ -36,7 +37,6 @@ import { getActivePluginRegistry } from "../plugins/runtime.js"; import { buildChannelAccountBindings, resolvePreferredAccountId } from "../routing/bindings.js"; import { normalizeAgentId } from "../routing/session-key.js"; import { type RuntimeEnv, writeRuntimeJson } from "../runtime.js"; -import { asNullableRecord } from "../shared/record-coerce.js"; import { formatHealthChannelLines } from "./health-format.js"; import type { AgentHealthSummary, diff --git a/src/commands/message-format.ts b/src/commands/message-format.ts index 06a54582f1c..da0c85a0093 100644 --- a/src/commands/message-format.ts +++ b/src/commands/message-format.ts @@ -1,3 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { getTerminalTableWidth, renderTable } from "../../packages/terminal-core/src/table.js"; import { isRich, theme } from "../../packages/terminal-core/src/theme.js"; import { getLoadedChannelPlugin } from "../channels/plugins/index.js"; @@ -6,8 +8,6 @@ import type { OutboundDeliveryResult } from "../infra/outbound/deliver.js"; import { formatGatewaySummary, formatOutboundDeliverySummary } from "../infra/outbound/format.js"; import type { MessageActionRunResult } from "../infra/outbound/message-action-runner.js"; import { formatTargetDisplay } from "../infra/outbound/target-resolver.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { shortenText } from "./text-format.js"; const resolveChannelLabel = (channel: ChannelId) => diff --git a/src/commands/message.ts b/src/commands/message.ts index dd8e5ee3f33..0d46fb0926a 100644 --- a/src/commands/message.ts +++ b/src/commands/message.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES, @@ -15,10 +19,6 @@ import { getRuntimeConfig } from "../config/config.js"; import type { OutboundSendDeps } from "../infra/outbound/deliver.js"; import { runMessageAction } from "../infra/outbound/message-action-runner.js"; import { type RuntimeEnv, writeRuntimeJson } from "../runtime.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; function extractMessageId(payload: unknown): string | undefined { if (!payload || typeof payload !== "object") { diff --git a/src/commands/migrate/context.ts b/src/commands/migrate/context.ts index 1ea17293b99..a4b45f3bcca 100644 --- a/src/commands/migrate/context.ts +++ b/src/commands/migrate/context.ts @@ -1,10 +1,10 @@ import path from "node:path"; +import { timestampMsToIsoFileStamp } from "@openclaw/normalization-core/number-coercion"; import { getRuntimeConfig } from "../../config/config.js"; import { resolveStateDir } from "../../config/paths.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { MigrationProviderContext } from "../../plugins/types.js"; import type { RuntimeEnv } from "../../runtime.js"; -import { timestampMsToIsoFileStamp } from "../../shared/number-coercion.js"; export function createMigrationLogger(runtime: RuntimeEnv, opts: { json?: boolean } = {}) { const info = opts.json ? runtime.error : runtime.log; diff --git a/src/commands/migrate/selection.ts b/src/commands/migrate/selection.ts index ad2892abc0b..ed5ea7ebdbe 100644 --- a/src/commands/migrate/selection.ts +++ b/src/commands/migrate/selection.ts @@ -1,9 +1,9 @@ import path from "node:path"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { markMigrationItemSkipped, summarizeMigrationItems } from "../../plugin-sdk/migration.js"; import type { MigrationItem, MigrationPlan } from "../../plugins/types.js"; -import { isRecord } from "../../shared/record-coerce.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; import { MIGRATION_CONFLICT_REASON_PHRASES } from "./output.js"; export const MIGRATION_SKILL_NOT_SELECTED_REASON = "not selected for migration"; diff --git a/src/commands/models/auth-list.ts b/src/commands/models/auth-list.ts index e65cd65420d..d1cb64a63c4 100644 --- a/src/commands/models/auth-list.ts +++ b/src/commands/models/auth-list.ts @@ -1,3 +1,4 @@ +import { timestampMsToIsoString } from "@openclaw/normalization-core/number-coercion"; import { resolveAgentDir, resolveDefaultAgentId } from "../../agents/agent-scope.js"; import { ensureAuthProfileStore, @@ -10,7 +11,6 @@ import { } from "../../agents/auth-profiles.js"; import { resolveProviderIdForAuth } from "../../agents/provider-auth-aliases.js"; import { type RuntimeEnv, writeRuntimeJson } from "../../runtime.js"; -import { timestampMsToIsoString } from "../../shared/number-coercion.js"; import { shortenHomePath } from "../../utils.js"; import { loadModelsConfig } from "./load-config.js"; import { resolveKnownAgentId } from "./shared.js"; diff --git a/src/commands/models/auth-order.ts b/src/commands/models/auth-order.ts index 25374bb8e98..823603804ac 100644 --- a/src/commands/models/auth-order.ts +++ b/src/commands/models/auth-order.ts @@ -1,3 +1,4 @@ +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { resolveAgentDir, resolveDefaultAgentId } from "../../agents/agent-scope.js"; import { type AuthProfileStore, @@ -9,7 +10,6 @@ import { import { normalizeProviderId } from "../../agents/model-selection.js"; import { formatCliCommand } from "../../cli/command-format.js"; import { type RuntimeEnv, writeRuntimeJson } from "../../runtime.js"; -import { normalizeStringEntries } from "../../shared/string-normalization.js"; import { shortenHomePath } from "../../utils.js"; import { loadModelsConfig } from "./load-config.js"; import { resolveKnownAgentId } from "./shared.js"; diff --git a/src/commands/models/auth.test.ts b/src/commands/models/auth.test.ts index ef94064057d..798959eb0be 100644 --- a/src/commands/models/auth.test.ts +++ b/src/commands/models/auth.test.ts @@ -1,8 +1,8 @@ +import { MAX_DATE_TIMESTAMP_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../../config/config.js"; import type { ProviderPlugin } from "../../plugins/types.js"; import type { RuntimeEnv } from "../../runtime.js"; -import { MAX_DATE_TIMESTAMP_MS } from "../../shared/number-coercion.js"; type AuthRunCall = { agentDir?: string; diff --git a/src/commands/models/auth.ts b/src/commands/models/auth.ts index 8dae3a21e0f..7f6005b6590 100644 --- a/src/commands/models/auth.ts +++ b/src/commands/models/auth.ts @@ -6,6 +6,11 @@ import { select as clackSelect, text as clackText, } from "@clack/prompts"; +import { resolveExpiresAtMsFromDurationMs } from "@openclaw/normalization-core/number-coercion"; +import { + normalizeOptionalString, + normalizeStringifiedOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { stylePromptHint, stylePromptMessage, @@ -51,11 +56,6 @@ import type { ProviderPlugin, } from "../../plugins/types.js"; import type { RuntimeEnv } from "../../runtime.js"; -import { resolveExpiresAtMsFromDurationMs } from "../../shared/number-coercion.js"; -import { - normalizeOptionalString, - normalizeStringifiedOptionalString, -} from "../../shared/string-coerce.js"; import { normalizeSecretInput } from "../../utils/normalize-secret-input.js"; import { createClackPrompter } from "../../wizard/clack-prompter.js"; import { validateAnthropicSetupToken } from "../auth-token.js"; diff --git a/src/commands/models/list.auth-overview.ts b/src/commands/models/list.auth-overview.ts index c2f2c58d92c..56c2cc67389 100644 --- a/src/commands/models/list.auth-overview.ts +++ b/src/commands/models/list.auth-overview.ts @@ -1,4 +1,8 @@ import { normalizeProviderIdForAuth } from "@openclaw/model-catalog-core/provider-id"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { formatRemainingShort } from "../../agents/auth-health.js"; import { resolveAuthProfileDisplayLabel } from "../../agents/auth-profiles/display.js"; import { resolveAuthStorePathForDisplay } from "../../agents/auth-profiles/paths.js"; @@ -14,10 +18,6 @@ import { } from "../../agents/model-auth.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { ProviderAuthEvidence } from "../../secrets/provider-env-vars.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { shortenHomePath } from "../../utils.js"; import { maskApiKey } from "./list.format.js"; import type { ProviderAuthOverview } from "./list.types.js"; diff --git a/src/commands/models/list.list-command.ts b/src/commands/models/list.list-command.ts index 01cd3389954..e5b5a895212 100644 --- a/src/commands/models/list.list-command.ts +++ b/src/commands/models/list.list-command.ts @@ -1,10 +1,10 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { parseModelRef } from "../../agents/model-selection.js"; import type { ModelRegistry } from "../../llm/model-registry.js"; import type { Model } from "../../llm/types.js"; import { loadManifestMetadataSnapshot } from "../../plugins/manifest-contract-eligibility.js"; import type { RuntimeEnv } from "../../runtime.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { createModelListAuthIndex } from "./list.auth-index.js"; import { resolveConfiguredEntries } from "./list.configured.js"; import { formatErrorWithStack } from "./list.errors.js"; diff --git a/src/commands/models/list.local-url.ts b/src/commands/models/list.local-url.ts index d66bc06d1fc..808dbe028e1 100644 --- a/src/commands/models/list.local-url.ts +++ b/src/commands/models/list.local-url.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export const isLocalBaseUrl = (baseUrl: string) => { try { diff --git a/src/commands/models/list.probe.ts b/src/commands/models/list.probe.ts index 748f8927223..38f928b7407 100644 --- a/src/commands/models/list.probe.ts +++ b/src/commands/models/list.probe.ts @@ -1,5 +1,6 @@ import crypto from "node:crypto"; import fs from "node:fs/promises"; +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import { resolveAgentDir, resolveAgentWorkspaceDir, @@ -32,7 +33,6 @@ import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { coerceSecretRef, normalizeSecretInputString } from "../../config/types.secrets.js"; import { type SecretRefResolveCache, resolveSecretRefString } from "../../secrets/resolve.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { normalizeUniqueStringEntries } from "../../shared/string-normalization.js"; import { redactSecrets } from "../status-all/format.js"; import { DEFAULT_PROVIDER, formatMs } from "./shared.js"; diff --git a/src/commands/models/list.provider-catalog.ts b/src/commands/models/list.provider-catalog.ts index 915a5bd1522..84f65d9f77b 100644 --- a/src/commands/models/list.provider-catalog.ts +++ b/src/commands/models/list.provider-catalog.ts @@ -1,4 +1,5 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { loadAuthProfileStoreWithoutExternalProfiles } from "../../agents/auth-profiles/store.js"; import { createProviderApiKeyResolver, @@ -28,7 +29,6 @@ import { resolveOwningPluginIdsForProviderRef, } from "../../plugins/providers.js"; import type { ProviderPlugin } from "../../plugins/types.js"; -import { sortUniqueStrings } from "../../shared/string-normalization.js"; const DISCOVERY_ORDERS = ["simple", "profile", "paired", "late"] as const; const SELF_HOSTED_DISCOVERY_PROVIDER_IDS = new Set(["lmstudio", "ollama", "sglang", "vllm"]); diff --git a/src/commands/models/list.status-command.ts b/src/commands/models/list.status-command.ts index 2de11ebb696..b2aa8b40bea 100644 --- a/src/commands/models/list.status-command.ts +++ b/src/commands/models/list.status-command.ts @@ -1,4 +1,5 @@ import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { colorize, theme } from "../../../packages/terminal-core/src/theme.js"; import { resolveAgentDir, @@ -60,7 +61,6 @@ import { resolveProviderSyntheticAuthWithPlugin } from "../../plugins/provider-r import { resolveRuntimeSyntheticAuthProviderRefs } from "../../plugins/synthetic-auth.runtime.js"; import { type RuntimeEnv, writeRuntimeJson } from "../../runtime.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { resolveUserPath, shortenHomePath } from "../../utils.js"; import { resolveProviderAuthOverview } from "./list.auth-overview.js"; import { isRich } from "./list.format.js"; diff --git a/src/commands/oauth-tls-preflight.test.ts b/src/commands/oauth-tls-preflight.test.ts index 01977f06c9e..bf8230df264 100644 --- a/src/commands/oauth-tls-preflight.test.ts +++ b/src/commands/oauth-tls-preflight.test.ts @@ -1,5 +1,5 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { beforeEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { formatOpenAIOAuthTlsPreflightFix, runOpenAIOAuthTlsPreflight, diff --git a/src/commands/onboard-custom-config.ts b/src/commands/onboard-custom-config.ts index 939f7b07961..2c85b1f482f 100644 --- a/src/commands/onboard-custom-config.ts +++ b/src/commands/onboard-custom-config.ts @@ -1,3 +1,8 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { CONTEXT_WINDOW_HARD_MIN_TOKENS } from "../agents/context-window-guard.js"; import { DEFAULT_PROVIDER } from "../agents/defaults.js"; import { buildModelAliasIndex, modelKey } from "../agents/model-selection.js"; @@ -5,11 +10,6 @@ import type { ModelProviderConfig } from "../config/types.models.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { isSecretRef, type SecretInput } from "../config/types.secrets.js"; import { applyPrimaryModel } from "../plugins/provider-model-primary.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { normalizeOptionalSecretInput } from "../utils/normalize-secret-input.js"; import { normalizeAlias } from "./models/alias-name.js"; diff --git a/src/commands/onboard-helpers.ts b/src/commands/onboard-helpers.ts index 48ce7461a72..9592344bd5c 100644 --- a/src/commands/onboard-helpers.ts +++ b/src/commands/onboard-helpers.ts @@ -2,6 +2,8 @@ import fs from "node:fs/promises"; import path from "node:path"; import { inspect } from "node:util"; import { cancel, isCancel } from "@clack/prompts"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { visibleWidth } from "../../packages/terminal-core/src/ansi.js"; import { decorativeEmoji, @@ -25,8 +27,6 @@ import { import { detectBinary } from "../infra/detect-binary.js"; import { movePathToTrash } from "../infra/fs-safe.js"; import type { RuntimeEnv } from "../runtime.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { resolveConfigDir, shortenHomeInString, shortenHomePath, sleep } from "../utils.js"; import { VERSION } from "../version.js"; import type { NodeManagerChoice, OnboardMode, ResetScope } from "./onboard-types.js"; diff --git a/src/commands/onboard-non-interactive/local/auth-choice-inference.ts b/src/commands/onboard-non-interactive/local/auth-choice-inference.ts index d8a08af04c6..d944aa74d52 100644 --- a/src/commands/onboard-non-interactive/local/auth-choice-inference.ts +++ b/src/commands/onboard-non-interactive/local/auth-choice-inference.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../../config/types.openclaw.js"; import { resolveManifestProviderOnboardAuthFlags } from "../../../plugins/provider-auth-choices.js"; -import { normalizeOptionalString } from "../../../shared/string-coerce.js"; import { CORE_ONBOARD_AUTH_FLAGS } from "../../onboard-core-auth-flags.js"; import type { AuthChoice, OnboardOptions } from "../../onboard-types.js"; diff --git a/src/commands/onboard-non-interactive/local/gateway-config.ts b/src/commands/onboard-non-interactive/local/gateway-config.ts index 6d4f9d2fbdb..94fc9aa5166 100644 --- a/src/commands/onboard-non-interactive/local/gateway-config.ts +++ b/src/commands/onboard-non-interactive/local/gateway-config.ts @@ -1,10 +1,10 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { formatCliCommand } from "../../../cli/command-format.js"; import { formatInvalidPortOption } from "../../../cli/error-format.js"; import type { OpenClawConfig } from "../../../config/types.openclaw.js"; import { isValidEnvSecretRefId, resolveSecretInputRef } from "../../../config/types.secrets.js"; import type { RuntimeEnv } from "../../../runtime.js"; import { resolveDefaultSecretProviderAlias } from "../../../secrets/ref-contract.js"; -import { normalizeOptionalString } from "../../../shared/string-coerce.js"; import { normalizeGatewayTokenInput, randomToken } from "../../onboard-helpers.js"; import type { OnboardOptions } from "../../onboard-types.js"; diff --git a/src/commands/onboard-non-interactive/remote.ts b/src/commands/onboard-non-interactive/remote.ts index 51f32c03d8f..bc93c2fecdf 100644 --- a/src/commands/onboard-non-interactive/remote.ts +++ b/src/commands/onboard-non-interactive/remote.ts @@ -1,8 +1,8 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { formatCliCommand } from "../../cli/command-format.js"; import { logConfigUpdated } from "../../config/logging.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { type RuntimeEnv, writeRuntimeJson } from "../../runtime.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { applySkipBootstrapConfig } from "../onboard-config.js"; import { applyWizardMetadata } from "../onboard-helpers.js"; import type { OnboardOptions } from "../onboard-types.js"; diff --git a/src/commands/onboarding-plugin-install.ts b/src/commands/onboarding-plugin-install.ts index d6b9b3b07f9..4fc816f3d05 100644 --- a/src/commands/onboarding-plugin-install.ts +++ b/src/commands/onboarding-plugin-install.ts @@ -1,5 +1,6 @@ import fs from "node:fs"; import path from "node:path"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { sanitizeTerminalText } from "../../packages/terminal-core/src/safe-text.js"; import { resolveBundledInstallPlanForCatalogEntry } from "../cli/plugin-install-plan.js"; import { assertConfigWriteAllowedInCurrentMode } from "../config/nix-mode-write-guard.js"; @@ -33,7 +34,6 @@ import { import { buildNpmResolutionInstallFields, recordPluginInstall } from "../plugins/installs.js"; import type { PluginPackageInstall } from "../plugins/manifest.js"; import type { RuntimeEnv } from "../runtime.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { withTimeout } from "../utils/with-timeout.js"; import { VERSION } from "../version.js"; import { t } from "../wizard/i18n/index.js"; diff --git a/src/commands/sandbox-explain.ts b/src/commands/sandbox-explain.ts index cc6b20d3ac9..7cb64422c9d 100644 --- a/src/commands/sandbox-explain.ts +++ b/src/commands/sandbox-explain.ts @@ -1,3 +1,7 @@ +import { + normalizeOptionalLowercaseString, + normalizeStringifiedEntries, +} from "@openclaw/normalization-core/string-coerce"; import { formatDocsLink } from "../../packages/terminal-core/src/links.js"; import { colorize, isRich, theme } from "../../packages/terminal-core/src/theme.js"; import { resolveAgentConfig } from "../agents/agent-scope.js"; @@ -20,10 +24,6 @@ import { resolveAgentIdFromSessionKey, } from "../routing/session-key.js"; import { type RuntimeEnv, writeRuntimeJson } from "../runtime.js"; -import { - normalizeOptionalLowercaseString, - normalizeStringifiedEntries, -} from "../shared/string-coerce.js"; import { INTERNAL_MESSAGE_CHANNEL } from "../utils/message-channel.js"; type SandboxExplainOptions = { diff --git a/src/commands/sessions.ts b/src/commands/sessions.ts index 3599f38776c..afd6adc132f 100644 --- a/src/commands/sessions.ts +++ b/src/commands/sessions.ts @@ -1,3 +1,7 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { isRich, theme } from "../../packages/terminal-core/src/theme.js"; import { resolveModelAgentRuntimeMetadata } from "../agents/agent-runtime-metadata.js"; import { DEFAULT_CONTEXT_TOKENS } from "../agents/defaults.js"; @@ -14,10 +18,6 @@ import { type RuntimeEnv, writeRuntimeJson } from "../runtime.js"; import { classifySessionKind, type SessionKind } from "../sessions/classify-session-kind.js"; import { isAcpSessionKey } from "../sessions/session-key-utils.js"; import { createLazyImportLoader } from "../shared/lazy-promise.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { resolveAgentRuntimeLabel } from "../status/agent-runtime-label.js"; import { resolveSessionStoreTargetsOrExit } from "./session-store-targets.js"; import { diff --git a/src/commands/status-all/channels-token-summary.ts b/src/commands/status-all/channels-token-summary.ts index 7f430a784c8..919e6f121d4 100644 --- a/src/commands/status-all/channels-token-summary.ts +++ b/src/commands/status-all/channels-token-summary.ts @@ -1,8 +1,8 @@ +import { asRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { hasConfiguredUnavailableCredentialStatus } from "../../channels/account-snapshot-fields.js"; import type { ChannelAccountSnapshot } from "../../channels/plugins/types.public.js"; import { sha256HexPrefix } from "../../logging/redact-identifier.js"; -import { asRecord } from "../../shared/record-coerce.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; export type ChannelAccountTokenSummaryRow = { account: unknown; diff --git a/src/commands/status-all/channels.ts b/src/commands/status-all/channels.ts index 59e8ecf5e0b..79d6a56dfb1 100644 --- a/src/commands/status-all/channels.ts +++ b/src/commands/status-all/channels.ts @@ -1,4 +1,6 @@ import fs from "node:fs"; +import { asRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { sanitizeForLog } from "../../../packages/terminal-core/src/ansi.js"; import { resolveInspectedChannelAccount } from "../../channels/account-inspection.js"; import { hasConfiguredUnavailableCredentialStatus } from "../../channels/account-snapshot-fields.js"; @@ -22,8 +24,6 @@ import { import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { listExplicitConfiguredChannelIdsForConfig } from "../../plugins/channel-plugin-ids.js"; import { resolveMissingOfficialExternalChannelPluginRepairHint } from "../../plugins/official-external-plugin-repair-hints.js"; -import { asRecord } from "../../shared/record-coerce.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { summarizeTokenConfig, type ChannelAccountTokenSummaryRow, diff --git a/src/commands/status-all/diagnosis.ts b/src/commands/status-all/diagnosis.ts index 34ccdbbdbac..e39d2821510 100644 --- a/src/commands/status-all/diagnosis.ts +++ b/src/commands/status-all/diagnosis.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { ProgressReporter } from "../../cli/progress.js"; import { formatConfigIssueLine } from "../../config/issue-format.js"; import { @@ -20,7 +21,6 @@ import { formatPluginCompatibilityNotice, type PluginCompatibilityNotice, } from "../../plugins/status.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { formatUpdateRestartActionLines, formatUpdateRestartStatusValue, diff --git a/src/commands/status-all/format.ts b/src/commands/status-all/format.ts index 7188aa9de6c..57a4d7776a5 100644 --- a/src/commands/status-all/format.ts +++ b/src/commands/status-all/format.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveGatewayPort } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/types.js"; import { resolveControlUiLinks } from "../../gateway/control-ui-links.js"; @@ -7,7 +8,6 @@ import { resolveUpdateChannelDisplay, } from "../../infra/update-channels.js"; import { formatGitInstallLabel, type UpdateCheckResult } from "../../infra/update-check.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { VERSION } from "../../version.js"; import { formatUpdateOneLiner, resolveUpdateAvailability } from "../status.update.js"; diff --git a/src/commands/status-all/gateway.ts b/src/commands/status-all/gateway.ts index 7df4ad3ddd2..a4e56a64625 100644 --- a/src/commands/status-all/gateway.ts +++ b/src/commands/status-all/gateway.ts @@ -1,6 +1,6 @@ import fs from "node:fs/promises"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { classifyOAuthRefreshFailureReason } from "../../agents/auth-profiles/oauth-refresh-failure.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; export async function readFileTailLines(filePath: string, maxLines: number): Promise { const raw = await fs.readFile(filePath, "utf8").catch(() => ""); diff --git a/src/commands/status.command-report-data.ts b/src/commands/status.command-report-data.ts index d0aa6d69cbd..437847ac7f8 100644 --- a/src/commands/status.command-report-data.ts +++ b/src/commands/status.command-report-data.ts @@ -1,10 +1,10 @@ +import { timestampMsToIsoString } from "@openclaw/normalization-core/number-coercion"; import type { ConnectPairingRequiredReason } from "../../packages/gateway-protocol/src/connect-error-details.js"; import type { RenderTableOptions, TableColumn } from "../../packages/terminal-core/src/table.js"; import type { HeartbeatEventPayload } from "../infra/heartbeat-events.js"; import type { resolveOsSummary } from "../infra/os-summary.js"; import type { PluginCompatibilityNotice } from "../plugins/status.js"; import type { SecurityAuditReport } from "../security/audit.js"; -import { timestampMsToIsoString } from "../shared/number-coercion.js"; import type { HealthSummary } from "./health.js"; import { buildStatusChannelsTableRows, diff --git a/src/commands/status.command-sections.ts b/src/commands/status.command-sections.ts index d417811d22e..868e627a1a6 100644 --- a/src/commands/status.command-sections.ts +++ b/src/commands/status.command-sections.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { buildPairingConnectRecoveryTitle, describePairingConnectRequirement, @@ -7,7 +8,6 @@ import type { TableColumn } from "../../packages/terminal-core/src/table.js"; import { areRuntimeModelRefsEquivalent } from "../agents/model-runtime-aliases.js"; import type { HeartbeatEventPayload } from "../infra/heartbeat-events.js"; import type { Tone } from "../memory-host-sdk/status.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import type { HealthSummary } from "./health.js"; import type { AgentLocalStatus } from "./status.agent-local.js"; import type { MemoryStatusSnapshot, MemoryPluginStatus } from "./status.scan.shared.js"; diff --git a/src/commands/status.format.ts b/src/commands/status.format.ts index 28f7015b4a3..e5b1a0ec972 100644 --- a/src/commands/status.format.ts +++ b/src/commands/status.format.ts @@ -1,7 +1,7 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { getSystemdCgroupHygieneSummary } from "../daemon/service-runtime.js"; import { formatDurationPrecise } from "../infra/format-time/format-duration.ts"; import { formatRuntimeStatusWithDetails } from "../infra/runtime-status.ts"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import type { SessionStatus } from "./status.types.js"; export { shortenText } from "./text-format.js"; diff --git a/src/commands/status.scan.shared.ts b/src/commands/status.scan.shared.ts index 381cea23a32..609b94f3b64 100644 --- a/src/commands/status.scan.shared.ts +++ b/src/commands/status.scan.shared.ts @@ -1,5 +1,9 @@ import { existsSync } from "node:fs"; import { isLoopbackIpAddress } from "@openclaw/net-policy/ip"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES, @@ -12,10 +16,6 @@ import type { GatewayProbeResult, probeGateway as probeGatewayFn } from "../gate import type { MemoryProviderStatus } from "../memory-host-sdk/engine-storage.js"; import { defaultSlotIdForKey } from "../plugins/slots.js"; import { createLazyImportLoader } from "../shared/lazy-promise.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { pickGatewaySelfPresence } from "./gateway-presence.js"; import { isProbeReachable } from "./gateway-status/helpers.js"; export { pickGatewaySelfPresence } from "./gateway-presence.js"; diff --git a/src/commands/status.summary.runtime.ts b/src/commands/status.summary.runtime.ts index 97e01c39668..228be334a5b 100644 --- a/src/commands/status.summary.runtime.ts +++ b/src/commands/status.summary.runtime.ts @@ -1,4 +1,9 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, + normalizeOptionalLowercaseString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveModelAgentRuntimeMetadata } from "../agents/agent-runtime-metadata.js"; import { resolveConfiguredProviderFallback } from "../agents/configured-provider-fallback.js"; import { DEFAULT_CONTEXT_TOKENS, DEFAULT_MODEL, DEFAULT_PROVIDER } from "../agents/defaults.js"; @@ -7,11 +12,6 @@ import { resolveAgentModelPrimaryValue } from "../config/model-input.js"; import type { SessionEntry } from "../config/sessions/types.js"; import type { OpenClawConfig } from "../config/types.js"; import { classifySessionKind } from "../sessions/classify-session-kind.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, - normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; import { resolveAgentRuntimeLabel } from "../status/agent-runtime-label.js"; function resolveStatusModelRefFromRaw(params: { diff --git a/src/commands/tasks.ts b/src/commands/tasks.ts index 28b07163e5b..44e45163e58 100644 --- a/src/commands/tasks.ts +++ b/src/commands/tasks.ts @@ -1,4 +1,6 @@ import fs from "node:fs"; +import { timestampMsToIsoString } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { isRich, theme } from "../../packages/terminal-core/src/theme.js"; import { formatCliCommand } from "../cli/command-format.js"; import { formatLookupMiss } from "../cli/error-format.js"; @@ -13,8 +15,6 @@ import { import { loadCronStoreSync, resolveCronStorePath } from "../cron/store.js"; import type { RuntimeEnv } from "../runtime.js"; import { parseAgentSessionKey } from "../sessions/session-key-utils.js"; -import { timestampMsToIsoString } from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { getTaskById, updateTaskNotifyPolicyById } from "../tasks/runtime-internal.js"; import { cancelDetachedTaskRunById } from "../tasks/task-executor.js"; import { listTaskFlowAuditFindings } from "../tasks/task-flow-registry.audit.js"; diff --git a/src/commitments/extraction.ts b/src/commitments/extraction.ts index 946789e4341..2b58a66fa24 100644 --- a/src/commitments/extraction.ts +++ b/src/commitments/extraction.ts @@ -1,8 +1,11 @@ +import { + asFiniteNumber, + timestampMsToIsoString, +} from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString as asString } from "@openclaw/normalization-core/string-coerce"; import { resolveAgentConfig } from "../agents/agent-scope.js"; import type { OpenClawConfig } from "../config/config.js"; import { resolveHeartbeatIntervalMs } from "../infra/heartbeat-summary.js"; -import { asFiniteNumber, timestampMsToIsoString } from "../shared/number-coercion.js"; -import { normalizeOptionalString as asString } from "../shared/string-coerce.js"; import { isRecord } from "../utils.js"; import { resolveCommitmentsConfig } from "./config.js"; import { listPendingCommitmentsForScope, upsertInferredCommitments } from "./store.js"; diff --git a/src/commitments/runtime.ts b/src/commitments/runtime.ts index f75c93885f5..05c5918d867 100644 --- a/src/commitments/runtime.ts +++ b/src/commitments/runtime.ts @@ -1,11 +1,11 @@ import { randomUUID } from "node:crypto"; import path from "node:path"; +import { resolveExpiresAtMsFromDurationMs } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveAgentWorkspaceDir } from "../agents/agent-scope.js"; import type { OpenClawConfig } from "../config/config.js"; import { resolveStateDir } from "../config/paths.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; -import { resolveExpiresAtMsFromDurationMs } from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resolveCommitmentTimezone, resolveCommitmentsConfig } from "./config.js"; import { buildCommitmentExtractionPrompt, diff --git a/src/commitments/store.ts b/src/commitments/store.ts index d4efa5dcbfa..8832b38e030 100644 --- a/src/commitments/store.ts +++ b/src/commitments/store.ts @@ -1,11 +1,11 @@ import { randomBytes } from "node:crypto"; import path from "node:path"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/config.js"; import { resolveStateDir } from "../config/paths.js"; import { expandHomePrefix } from "../infra/home-dir.js"; import { privateFileStore } from "../infra/private-file-store.js"; -import { isRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { DEFAULT_COMMITMENT_EXPIRE_AFTER_HOURS, DEFAULT_COMMITMENT_MAX_PER_HEARTBEAT, diff --git a/src/config/agent-dirs.ts b/src/config/agent-dirs.ts index 481b77ac13d..e1f08d0e4ed 100644 --- a/src/config/agent-dirs.ts +++ b/src/config/agent-dirs.ts @@ -1,8 +1,8 @@ import os from "node:os"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { resolveRequiredHomeDir } from "../infra/home-dir.js"; import { DEFAULT_AGENT_ID, normalizeAgentId } from "../routing/session-key.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { resolveUserPath } from "../utils.js"; import { resolveStateDir } from "./paths.js"; import type { OpenClawConfig } from "./types.js"; diff --git a/src/config/allowed-values.ts b/src/config/allowed-values.ts index 37c900a41fd..4030d60caaf 100644 --- a/src/config/allowed-values.ts +++ b/src/config/allowed-values.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; const MAX_ALLOWED_VALUES_HINT = 12; const MAX_ALLOWED_VALUE_CHARS = 160; diff --git a/src/config/channel-capabilities.ts b/src/config/channel-capabilities.ts index 0815d6fc4a2..b2d4338b6f1 100644 --- a/src/config/channel-capabilities.ts +++ b/src/config/channel-capabilities.ts @@ -1,7 +1,7 @@ +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { normalizeAnyChannelId } from "../channels/registry.js"; import { resolveAccountEntry } from "../routing/account-lookup.js"; import { normalizeAccountId } from "../routing/session-key.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import type { OpenClawConfig } from "./config.js"; import type { SlackCapabilitiesConfig } from "./types.slack.js"; import type { TelegramCapabilitiesConfig } from "./types.telegram.js"; diff --git a/src/config/commands.ts b/src/config/commands.ts index b2926c8da2d..42837c87136 100644 --- a/src/config/commands.ts +++ b/src/config/commands.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { getLoadedChannelPlugin, normalizeChannelId } from "../channels/plugins/index.js"; import { resolveReadOnlyChannelCommandDefaults } from "../channels/plugins/read-only-command-defaults.js"; import type { ChannelId } from "../channels/plugins/types.public.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import type { NativeCommandsSetting } from "./types.js"; import type { OpenClawConfig } from "./types.openclaw.js"; export { isCommandFlagEnabled, isRestartEnabled } from "./commands.flags.js"; diff --git a/src/config/defaults.ts b/src/config/defaults.ts index d199340868a..7e8fb4ff492 100644 --- a/src/config/defaults.ts +++ b/src/config/defaults.ts @@ -3,9 +3,9 @@ import { collectManifestModelIdNormalizationPolicies, normalizeConfiguredProviderCatalogModelId, } from "@openclaw/model-catalog-core/provider-model-id-normalization"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { DEFAULT_CONTEXT_TOKENS } from "../agents/defaults.js"; import type { PluginManifestRegistry } from "../plugins/manifest-registry.js"; -import { isRecord } from "../shared/record-coerce.js"; import { DEFAULT_AGENT_MAX_CONCURRENT, DEFAULT_SUBAGENT_ARCHIVE_AFTER_MINUTES, diff --git a/src/config/doc-baseline.ts b/src/config/doc-baseline.ts index a61d5a8300b..93311462d84 100644 --- a/src/config/doc-baseline.ts +++ b/src/config/doc-baseline.ts @@ -3,9 +3,9 @@ import fsSync from "node:fs"; import os from "node:os"; import path from "node:path"; import { fileURLToPath } from "node:url"; +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { resolveOpenClawPackageRootSync } from "../infra/openclaw-root.js"; import { replaceFileAtomicSync } from "../infra/replace-file.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; import type { ConfigSchemaResponse } from "./schema.js"; import { schemaHasChildren } from "./schema.shared.js"; diff --git a/src/config/group-policy.ts b/src/config/group-policy.ts index b032f54d36b..262123f2704 100644 --- a/src/config/group-policy.ts +++ b/src/config/group-policy.ts @@ -1,10 +1,10 @@ -import type { ChannelId } from "../channels/plugins/channel-id.types.js"; -import { resolveAccountEntry } from "../routing/account-lookup.js"; -import { normalizeAccountId } from "../routing/session-key.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { ChannelId } from "../channels/plugins/channel-id.types.js"; +import { resolveAccountEntry } from "../routing/account-lookup.js"; +import { normalizeAccountId } from "../routing/session-key.js"; import { normalizeMessageChannel } from "../utils/message-channel-core.js"; import type { OpenClawConfig } from "./types.openclaw.js"; import { diff --git a/src/config/model-input.ts b/src/config/model-input.ts index 3b014ab0b4b..9acdf513158 100644 --- a/src/config/model-input.ts +++ b/src/config/model-input.ts @@ -3,12 +3,12 @@ import { normalizeGooglePreviewModelId, normalizeTogetherModelId, } from "@openclaw/model-catalog-core/provider-model-id-normalize"; -import { isRecord as isPlainRecord } from "../shared/record-coerce.js"; +import { isRecord as isPlainRecord } from "@openclaw/normalization-core/record-coerce"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, resolvePrimaryStringValue, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; import type { AgentModelConfig, AgentToolModelConfig } from "./types.agents-shared.js"; type AgentModelListLike = { diff --git a/src/config/plugin-auto-enable.prefer-over.ts b/src/config/plugin-auto-enable.prefer-over.ts index 0466db63461..d580f0e3882 100644 --- a/src/config/plugin-auto-enable.prefer-over.ts +++ b/src/config/plugin-auto-enable.prefer-over.ts @@ -1,9 +1,9 @@ import fs from "node:fs"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { getChatChannelMeta, normalizeChatChannelId } from "../channels/registry.js"; import type { PluginManifestRegistry } from "../plugins/manifest-registry.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { isRecord, resolveConfigDir, resolveUserPath } from "../utils.js"; import type { PluginAutoEnableCandidate } from "./plugin-auto-enable.types.js"; import type { OpenClawConfig } from "./types.openclaw.js"; diff --git a/src/config/plugin-auto-enable.shared.ts b/src/config/plugin-auto-enable.shared.ts index 232a6edc91a..4e42766dbe9 100644 --- a/src/config/plugin-auto-enable.shared.ts +++ b/src/config/plugin-auto-enable.shared.ts @@ -1,5 +1,6 @@ import { collectConfiguredModelRefs } from "@openclaw/model-catalog-core/configured-model-refs"; import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { collectConfiguredAgentHarnessRuntimes } from "../agents/harness-runtimes.js"; import { listPotentialConfiguredChannelPresenceSignals, @@ -21,7 +22,6 @@ import { import { loadPluginMetadataSnapshot } from "../plugins/plugin-metadata-snapshot.js"; import { resolveOwningPluginIdsForModelRef } from "../plugins/providers.js"; import { resolvePluginSetupAutoEnableReasons } from "../plugins/setup-registry.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import { isRecord } from "../utils.js"; import { isChannelConfigured } from "./channel-configured.js"; import { shouldSkipPreferredPluginAutoEnable } from "./plugin-auto-enable.prefer-over.js"; diff --git a/src/config/plugin-install-config-migration.ts b/src/config/plugin-install-config-migration.ts index 562a730c780..fb2a713f85e 100644 --- a/src/config/plugin-install-config-migration.ts +++ b/src/config/plugin-install-config-migration.ts @@ -1,5 +1,5 @@ +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { z } from "zod"; -import { isRecord } from "../shared/record-coerce.js"; import type { PluginInstallRecord } from "./types.plugins.js"; import { PluginInstallRecordShape } from "./zod-schema.installs.js"; diff --git a/src/config/plugin-web-search-config.ts b/src/config/plugin-web-search-config.ts index 9793616df08..e8d30b8c02f 100644 --- a/src/config/plugin-web-search-config.ts +++ b/src/config/plugin-web-search-config.ts @@ -1,4 +1,4 @@ -import { isRecord } from "../shared/record-coerce.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; type PluginWebSearchConfigCarrier = { plugins?: { diff --git a/src/config/redact-snapshot.raw.ts b/src/config/redact-snapshot.raw.ts index 7b10d249cc2..ec7723fdf95 100644 --- a/src/config/redact-snapshot.raw.ts +++ b/src/config/redact-snapshot.raw.ts @@ -1,6 +1,6 @@ import { isDeepStrictEqual } from "node:util"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import JSON5 from "json5"; -import { uniqueStrings } from "../shared/string-normalization.js"; export function replaceSensitiveValuesInRaw(params: { raw: string; diff --git a/src/config/redact-snapshot.ts b/src/config/redact-snapshot.ts index 522e4515065..8088469c41c 100644 --- a/src/config/redact-snapshot.ts +++ b/src/config/redact-snapshot.ts @@ -3,10 +3,10 @@ import { isSensitiveUrlConfigPath, redactSensitiveUrlLikeString, } from "@openclaw/net-policy/redact-sensitive-url"; +import { isRecord as isObjectRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { type ConfigUiHints } from "../shared/config-ui-hints-types.js"; -import { isRecord as isObjectRecord } from "../shared/record-coerce.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { replaceSensitiveValuesInRaw, shouldFallbackToStructuredRawRedaction, diff --git a/src/config/runtime-group-policy.ts b/src/config/runtime-group-policy.ts index e92a9ee5560..8303cb23fcd 100644 --- a/src/config/runtime-group-policy.ts +++ b/src/config/runtime-group-policy.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { GroupPolicy } from "./types.base.js"; type RuntimeGroupPolicyResolution = { diff --git a/src/config/schema.tags.ts b/src/config/schema.tags.ts index 62ab7fdc457..7f9b786323c 100644 --- a/src/config/schema.tags.ts +++ b/src/config/schema.tags.ts @@ -1,5 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { ConfigUiHint, ConfigUiHints } from "../shared/config-ui-hints-types.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; export const CONFIG_TAGS = [ "security", diff --git a/src/config/schema.ts b/src/config/schema.ts index 886d10c394d..d7507383557 100644 --- a/src/config/schema.ts +++ b/src/config/schema.ts @@ -1,7 +1,7 @@ import crypto from "node:crypto"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { CHANNEL_IDS } from "../channels/ids.js"; import { parseConfigPathArrayIndex } from "../shared/path-array-index.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { GENERATED_BUNDLED_CHANNEL_CONFIG_METADATA } from "./bundled-channel-config-metadata.generated.js"; import { computeBaseConfigSchemaResponse } from "./schema-base.js"; import type { ConfigUiHint, ConfigUiHints } from "./schema.hints.js"; diff --git a/src/config/sensitive-paths.ts b/src/config/sensitive-paths.ts index a834cf03bc0..d4a7e572add 100644 --- a/src/config/sensitive-paths.ts +++ b/src/config/sensitive-paths.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; /** * Non-sensitive field names that happen to match sensitive patterns. diff --git a/src/config/sessions/artifacts.ts b/src/config/sessions/artifacts.ts index 114141a37d0..c124546f6d3 100644 --- a/src/config/sessions/artifacts.ts +++ b/src/config/sessions/artifacts.ts @@ -1,4 +1,4 @@ -import { timestampMsToIsoFileStamp } from "../../shared/number-coercion.js"; +import { timestampMsToIsoFileStamp } from "@openclaw/normalization-core/number-coercion"; import { escapeRegExp } from "../../shared/regexp.js"; export type SessionArchiveReason = "bak" | "reset" | "deleted"; diff --git a/src/config/sessions/delivery-info.ts b/src/config/sessions/delivery-info.ts index 82767673abd..e7f3a413b53 100644 --- a/src/config/sessions/delivery-info.ts +++ b/src/config/sessions/delivery-info.ts @@ -1,9 +1,9 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { resolveSessionStoreAgentId, resolveSessionStoreKey, } from "../../gateway/session-store-key.js"; import { requiresFoldedSessionKeyAliasProof } from "../../sessions/session-key-utils.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { deliveryContextFromSession } from "../../utils/delivery-context.shared.js"; import { getRuntimeConfig } from "../io.js"; import type { OpenClawConfig } from "../types.openclaw.js"; diff --git a/src/config/sessions/disk-budget.ts b/src/config/sessions/disk-budget.ts index 86e0244b9cc..186ef690155 100644 --- a/src/config/sessions/disk-budget.ts +++ b/src/config/sessions/disk-budget.ts @@ -3,7 +3,7 @@ import path from "node:path"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; import { resolveTrajectoryFilePath, resolveTrajectoryPointerFilePath, diff --git a/src/config/sessions/explicit-session-key-normalization.ts b/src/config/sessions/explicit-session-key-normalization.ts index f78b825b802..afcec3ee59d 100644 --- a/src/config/sessions/explicit-session-key-normalization.ts +++ b/src/config/sessions/explicit-session-key-normalization.ts @@ -1,10 +1,10 @@ -import type { MsgContext } from "../../auto-reply/templating.js"; -import { getLoadedChannelPlugin, listChannelPlugins } from "../../channels/plugins/index.js"; -import { normalizeSessionKeyPreservingOpaquePeerIds } from "../../sessions/session-key-utils.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { MsgContext } from "../../auto-reply/templating.js"; +import { getLoadedChannelPlugin, listChannelPlugins } from "../../channels/plugins/index.js"; +import { normalizeSessionKeyPreservingOpaquePeerIds } from "../../sessions/session-key-utils.js"; import { normalizeMessageChannel } from "../../utils/message-channel.js"; function resolveExplicitSessionKeyNormalizerCandidates( diff --git a/src/config/sessions/group.ts b/src/config/sessions/group.ts index d4b7bb86e81..aef34d00220 100644 --- a/src/config/sessions/group.ts +++ b/src/config/sessions/group.ts @@ -1,12 +1,12 @@ -import type { MsgContext } from "../../auto-reply/templating.js"; -import { listChannelPlugins } from "../../channels/plugins/registry.js"; -import { normalizeSessionPeerId } from "../../sessions/session-key-utils.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../../shared/string-coerce.js"; -import { normalizeHyphenSlug } from "../../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeHyphenSlug } from "@openclaw/normalization-core/string-normalization"; +import type { MsgContext } from "../../auto-reply/templating.js"; +import { listChannelPlugins } from "../../channels/plugins/registry.js"; +import { normalizeSessionPeerId } from "../../sessions/session-key-utils.js"; import { listDeliverableMessageChannels } from "../../utils/message-channel.js"; import type { GroupKeyResolution } from "./types.js"; diff --git a/src/config/sessions/metadata.ts b/src/config/sessions/metadata.ts index be740b2f62a..50397dabae2 100644 --- a/src/config/sessions/metadata.ts +++ b/src/config/sessions/metadata.ts @@ -1,11 +1,11 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { MsgContext } from "../../auto-reply/templating.js"; import { normalizeChatType } from "../../channels/chat-type.js"; import { resolveConversationLabel } from "../../channels/conversation-label.js"; import { getLoadedChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { normalizeMessageChannel } from "../../utils/message-channel.js"; import { buildGroupDisplayName, resolveGroupSessionKey } from "./group.js"; import type { GroupKeyResolution, SessionEntry, SessionOrigin } from "./types.js"; diff --git a/src/config/sessions/model-override-provenance.ts b/src/config/sessions/model-override-provenance.ts index 010f15860f0..c00fbb7ac3f 100644 --- a/src/config/sessions/model-override-provenance.ts +++ b/src/config/sessions/model-override-provenance.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { SessionEntry } from "./types.js"; export function hasSessionAutoModelFallbackProvenance( diff --git a/src/config/sessions/paths.ts b/src/config/sessions/paths.ts index 6141d368255..38c8ae022e0 100644 --- a/src/config/sessions/paths.ts +++ b/src/config/sessions/paths.ts @@ -1,9 +1,9 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { expandHomePrefix, resolveRequiredHomeDir } from "../../infra/home-dir.js"; import { DEFAULT_AGENT_ID, normalizeAgentId } from "../../routing/session-key.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { resolveStateDir } from "../paths.js"; import { isCompactionCheckpointTranscriptFileName } from "./artifacts.js"; diff --git a/src/config/sessions/reset.ts b/src/config/sessions/reset.ts index 31c96664a20..ac578e6cc31 100644 --- a/src/config/sessions/reset.ts +++ b/src/config/sessions/reset.ts @@ -1,8 +1,8 @@ -import { resolveLoadedSessionThreadInfo } from "../../channels/plugins/session-thread-info-loaded.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { resolveLoadedSessionThreadInfo } from "../../channels/plugins/session-thread-info-loaded.js"; import { normalizeMessageChannel } from "../../utils/message-channel.js"; import type { SessionConfig, SessionResetConfig } from "../types.base.js"; export { diff --git a/src/config/sessions/session-file-rotation.ts b/src/config/sessions/session-file-rotation.ts index 3ae9c3906ff..789117de04d 100644 --- a/src/config/sessions/session-file-rotation.ts +++ b/src/config/sessions/session-file-rotation.ts @@ -1,6 +1,6 @@ import fs from "node:fs"; import path from "node:path"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export function rewriteSessionFileForNewSessionId(params: { sessionFile?: string; diff --git a/src/config/sessions/store-entry-shape.ts b/src/config/sessions/store-entry-shape.ts index 987bbc77462..6f57148bb2e 100644 --- a/src/config/sessions/store-entry-shape.ts +++ b/src/config/sessions/store-entry-shape.ts @@ -1,4 +1,4 @@ -import { isRecord } from "../../shared/record-coerce.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { validateSessionId } from "./paths.js"; import type { SessionEntry } from "./types.js"; diff --git a/src/config/sessions/store-entry.ts b/src/config/sessions/store-entry.ts index 5704f57eaa7..1fc99291a1d 100644 --- a/src/config/sessions/store-entry.ts +++ b/src/config/sessions/store-entry.ts @@ -1,9 +1,9 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { normalizeSessionKeyPreservingOpaquePeerIds, parseThreadSessionSuffix, requiresFoldedSessionKeyAliasProof, } from "../../sessions/session-key-utils.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import type { SessionEntry } from "./types.js"; export function normalizeStoreSessionKey(sessionKey: string): string { diff --git a/src/config/sessions/store-load.ts b/src/config/sessions/store-load.ts index 9aa3af9cecf..c9ed4a031b0 100644 --- a/src/config/sessions/store-load.ts +++ b/src/config/sessions/store-load.ts @@ -1,9 +1,9 @@ import fs from "node:fs"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { createSubsystemLogger } from "../../logging/subsystem.js"; import type { ChannelRouteRef } from "../../plugin-sdk/channel-route.js"; import { isPluginJsonValue, type PluginJsonValue } from "../../plugins/host-hook-json.js"; import { normalizeSessionEntrySlotKey } from "../../plugins/session-entry-slot-keys.js"; -import { isRecord } from "../../shared/record-coerce.js"; import { normalizeDeliveryChannelRoute, normalizeDeliveryContext, diff --git a/src/config/sessions/store-maintenance.ts b/src/config/sessions/store-maintenance.ts index e3afa073005..4e2f1967d04 100644 --- a/src/config/sessions/store-maintenance.ts +++ b/src/config/sessions/store-maintenance.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeStringifiedOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { parseByteSize } from "../../cli/parse-bytes.js"; import { parseDurationMs } from "../../cli/parse-duration.js"; import { createSubsystemLogger } from "../../logging/subsystem.js"; @@ -7,10 +11,6 @@ import { isSubagentSessionKey, parseAgentSessionKey, } from "../../sessions/session-key-utils.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeStringifiedOptionalString, -} from "../../shared/string-coerce.js"; import type { SessionMaintenanceConfig, SessionMaintenanceMode } from "../types.base.js"; import { parseSessionThreadInfoFast } from "./thread-info.js"; import type { SessionEntry } from "./types.js"; diff --git a/src/config/sessions/targets.ts b/src/config/sessions/targets.ts index 371836bd1ba..500f43b4cb9 100644 --- a/src/config/sessions/targets.ts +++ b/src/config/sessions/targets.ts @@ -1,13 +1,13 @@ import fsSync from "node:fs"; import fs from "node:fs/promises"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { listAgentIds, resolveDefaultAgentId } from "../../agents/agent-scope.js"; import { resolveAgentSessionDirsFromAgentsDir, resolveAgentSessionDirsFromAgentsDirSync, } from "../../agents/session-dirs.js"; import { DEFAULT_AGENT_ID, normalizeAgentId } from "../../routing/session-key.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { resolveStateDir } from "../paths.js"; import type { OpenClawConfig } from "../types.openclaw.js"; import { resolveAgentsDirFromSessionStorePath, resolveStorePath } from "./paths.js"; diff --git a/src/config/sessions/transcript-append.ts b/src/config/sessions/transcript-append.ts index 068fd816fdc..d31e7099eee 100644 --- a/src/config/sessions/transcript-append.ts +++ b/src/config/sessions/transcript-append.ts @@ -2,6 +2,7 @@ import { randomUUID } from "node:crypto"; import fs from "node:fs/promises"; import path from "node:path"; import { StringDecoder } from "node:string_decoder"; +import { resolveTimestampMsToIsoString } from "@openclaw/normalization-core/number-coercion"; import type { AgentMessage } from "../../agents/runtime/index.js"; import { acquireSessionWriteLock, @@ -10,7 +11,6 @@ import { import { redactTranscriptMessage } from "../../agents/transcript-redact.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { redactSecrets } from "../../logging/redact.js"; -import { resolveTimestampMsToIsoString } from "../../shared/number-coercion.js"; import { createSessionTranscriptHeader } from "./transcript-header.js"; import { appendJsonlEntry, diff --git a/src/config/sessions/types.ts b/src/config/sessions/types.ts index eb3008af5f7..e56c4462533 100644 --- a/src/config/sessions/types.ts +++ b/src/config/sessions/types.ts @@ -1,8 +1,8 @@ import crypto from "node:crypto"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { ChatType } from "../../channels/chat-type.js"; import type { ChannelId } from "../../channels/plugins/channel-id.types.js"; import type { ChannelRouteRef } from "../../plugin-sdk/channel-route.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { Skill } from "../../skills/loading/skill-contract.js"; import type { DeliveryContext } from "../../utils/delivery-context.types.js"; import type { TtsAutoMode } from "../types.tts.js"; diff --git a/src/config/shell-env-expected-keys.ts b/src/config/shell-env-expected-keys.ts index 2bc4620c0b1..945e067b517 100644 --- a/src/config/shell-env-expected-keys.ts +++ b/src/config/shell-env-expected-keys.ts @@ -1,6 +1,6 @@ +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { listKnownChannelEnvVarNames } from "../secrets/channel-env-vars.js"; import { listKnownProviderAuthEnvVarNames } from "../secrets/provider-env-vars.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; const CORE_SHELL_ENV_EXPECTED_KEYS = ["OPENCLAW_GATEWAY_TOKEN", "OPENCLAW_GATEWAY_PASSWORD"]; diff --git a/src/config/silent-reply.ts b/src/config/silent-reply.ts index 4555009a394..ebf1b5e7bd0 100644 --- a/src/config/silent-reply.ts +++ b/src/config/silent-reply.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { classifySilentReplyConversationType, resolveSilentReplyPolicyFromPolicies, @@ -5,7 +6,6 @@ import { type SilentReplyPolicy, type SilentReplyPolicyShape, } from "../shared/silent-reply-policy.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import type { OpenClawConfig } from "./types.openclaw.js"; type ResolveSilentReplyParams = { diff --git a/src/config/talk.ts b/src/config/talk.ts index c4634bdc931..c81685f9428 100644 --- a/src/config/talk.ts +++ b/src/config/talk.ts @@ -1,5 +1,8 @@ +import { + normalizeFastMode, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { normalizeThinkLevel } from "../auto-reply/thinking.js"; -import { normalizeFastMode, normalizeOptionalString } from "../shared/string-coerce.js"; import { isRecord } from "../utils.js"; import type { ResolvedTalkConfig, diff --git a/src/config/types.tools.ts b/src/config/types.tools.ts index b11c3876582..fe96a51c71d 100644 --- a/src/config/types.tools.ts +++ b/src/config/types.tools.ts @@ -1,6 +1,6 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { ChatType } from "../channels/chat-type.js"; import type { SafeBinProfileFixture } from "../infra/exec-safe-bin-policy.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import type { AgentModelConfig } from "./types.agents-shared.js"; import type { AgentElevatedAllowFromConfig, SessionSendPolicyAction } from "./types.base.js"; import type { MemoryQmdIndexPath } from "./types.memory.js"; diff --git a/src/config/validation.ts b/src/config/validation.ts index cdd3012702d..d5df2621afe 100644 --- a/src/config/validation.ts +++ b/src/config/validation.ts @@ -1,6 +1,7 @@ import path from "node:path"; import { collectConfiguredModelRefs } from "@openclaw/model-catalog-core/configured-model-refs"; import { isCanonicalDottedDecimalIPv4, isLoopbackIpAddress } from "@openclaw/net-policy/ip"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js"; import { isPathInside } from "../infra/path-guards.js"; import { planManifestModelCatalogSuppressions } from "../model-catalog/index.js"; @@ -36,7 +37,6 @@ import { formatUnsafeGatewayTailscaleNoAuthMessage, isUnsafeGatewayTailscaleNoAuth, } from "../shared/gateway-tailscale-auth-policy.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { isRecord, resolveUserPath } from "../utils.js"; import { findDuplicateAgentDirs, formatDuplicateAgentDirError } from "./agent-dirs.js"; import { appendAllowedValuesHint, summarizeAllowedValues } from "./allowed-values.js"; diff --git a/src/config/zod-schema.agent-runtime.ts b/src/config/zod-schema.agent-runtime.ts index 1b5ce783312..df9ddb4e841 100644 --- a/src/config/zod-schema.agent-runtime.ts +++ b/src/config/zod-schema.agent-runtime.ts @@ -1,14 +1,14 @@ +import { isRecord as isPlainRecord } from "@openclaw/normalization-core/record-coerce"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { z } from "zod"; import { splitSandboxBindSpec } from "../agents/sandbox/bind-spec.js"; import { isSandboxHostPathAbsolute } from "../agents/sandbox/host-paths.js"; import { getBlockedNetworkModeReason } from "../agents/sandbox/network-mode.js"; import { parseDurationMs } from "../cli/parse-duration.js"; -import { isRecord as isPlainRecord } from "../shared/record-coerce.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { isBlockedObjectKey } from "./prototype-keys.js"; import { LEGACY_WEB_SEARCH_PROVIDER_CONFIG_KEYS } from "./web-search-legacy-provider-keys.js"; import { AgentModelSchema, AgentToolModelSchema } from "./zod-schema.agent-model.js"; diff --git a/src/config/zod-schema.agents.ts b/src/config/zod-schema.agents.ts index 2abf5d70a5b..8572457be08 100644 --- a/src/config/zod-schema.agents.ts +++ b/src/config/zod-schema.agents.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { z } from "zod"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { AgentDefaultsSchema } from "./zod-schema.agent-defaults.js"; import { AgentEntrySchema } from "./zod-schema.agent-runtime.js"; import { TranscribeAudioSchema } from "./zod-schema.core.js"; diff --git a/src/config/zod-schema.core.ts b/src/config/zod-schema.core.ts index 3b618cd91f2..17d9cd08109 100644 --- a/src/config/zod-schema.core.ts +++ b/src/config/zod-schema.core.ts @@ -1,5 +1,6 @@ import path from "node:path"; import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { z } from "zod"; import { isSafeExecutableValue } from "../infra/exec-safety.js"; import { @@ -7,7 +8,6 @@ import { isValidExecSecretRefId, isValidFileSecretRefId, } from "../secrets/ref-contract.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import type { ModelCompatConfig } from "./types.models.js"; import { MODEL_APIS, MODEL_THINKING_FORMATS } from "./types.models.js"; import type { MediaToolsConfig } from "./types.tools.js"; diff --git a/src/config/zod-schema.providers-core.ts b/src/config/zod-schema.providers-core.ts index 94025af78db..96417b46ee5 100644 --- a/src/config/zod-schema.providers-core.ts +++ b/src/config/zod-schema.providers-core.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { z } from "zod"; import { isSafeScpRemoteHost } from "../infra/scp-host.js"; import { isValidInboundPathRootPattern } from "../media/inbound-path-policy.js"; @@ -6,7 +7,6 @@ import { normalizeSlashCommandName, resolveCustomCommands, } from "../shared/custom-command-config.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { ToolPolicySchema } from "./zod-schema.agent-runtime.js"; import { NativeExecApprovalEnableModeSchema } from "./zod-schema.approvals.js"; import { diff --git a/src/config/zod-schema.providers-whatsapp.ts b/src/config/zod-schema.providers-whatsapp.ts index b150d5b119a..0e126fed150 100644 --- a/src/config/zod-schema.providers-whatsapp.ts +++ b/src/config/zod-schema.providers-whatsapp.ts @@ -1,6 +1,6 @@ +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { z } from "zod"; import { resolveAccountEntry } from "../routing/account-lookup.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { ToolPolicySchema } from "./zod-schema.agent-runtime.js"; import { ChannelHealthMonitorSchema, diff --git a/src/config/zod-schema.secret-input-validation.ts b/src/config/zod-schema.secret-input-validation.ts index 7dc5ff61f42..5f5798ea65d 100644 --- a/src/config/zod-schema.secret-input-validation.ts +++ b/src/config/zod-schema.secret-input-validation.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { z } from "zod"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { hasConfiguredSecretInput } from "./types.secrets.js"; type TelegramAccountLike = { diff --git a/src/config/zod-schema.session.ts b/src/config/zod-schema.session.ts index d627778003f..534f5731558 100644 --- a/src/config/zod-schema.session.ts +++ b/src/config/zod-schema.session.ts @@ -1,7 +1,7 @@ +import { normalizeStringifiedOptionalString } from "@openclaw/normalization-core/string-coerce"; import { z } from "zod"; import { parseByteSize } from "../cli/parse-bytes.js"; import { parseDurationMs } from "../cli/parse-duration.js"; -import { normalizeStringifiedOptionalString } from "../shared/string-coerce.js"; import { ElevatedAllowFromSchema } from "./zod-schema.agent-runtime.js"; import { createAllowDenyChannelRulesSchema } from "./zod-schema.allowdeny.js"; import { diff --git a/src/config/zod-schema.ts b/src/config/zod-schema.ts index f43f91bfd48..75ac4c17de3 100644 --- a/src/config/zod-schema.ts +++ b/src/config/zod-schema.ts @@ -1,11 +1,11 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeStringifiedOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { z } from "zod"; import { parseByteSize } from "../cli/parse-bytes.js"; import { parseDurationMs } from "../cli/parse-duration.js"; import { normalizeAgentId } from "../routing/session-key.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeStringifiedOptionalString, -} from "../shared/string-coerce.js"; import { isValidControlUiChatMessageMaxWidth, normalizeControlUiChatMessageMaxWidth, diff --git a/src/crestodian/probes.test.ts b/src/crestodian/probes.test.ts index cdeaea9270b..272fd8d4d69 100644 --- a/src/crestodian/probes.test.ts +++ b/src/crestodian/probes.test.ts @@ -1,5 +1,5 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { probeGatewayUrl, probeLocalCommand } from "./probes.js"; describe("crestodian probes", () => { diff --git a/src/crestodian/probes.ts b/src/crestodian/probes.ts index 1d9ef6fb877..d432377fb25 100644 --- a/src/crestodian/probes.ts +++ b/src/crestodian/probes.ts @@ -1,5 +1,5 @@ import { spawn } from "node:child_process"; -import { resolveTimerTimeoutMs } from "../shared/number-coercion.js"; +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; export type LocalCommandProbe = { command: string; diff --git a/src/crestodian/rescue-message.ts b/src/crestodian/rescue-message.ts index 0caa04e2f32..e9a93a58e2d 100644 --- a/src/crestodian/rescue-message.ts +++ b/src/crestodian/rescue-message.ts @@ -1,12 +1,15 @@ import { createHash, randomUUID } from "node:crypto"; import fs from "node:fs/promises"; import path from "node:path"; +import { + asDateTimestampMs, + resolveExpiresAtMsFromDurationMs, +} from "@openclaw/normalization-core/number-coercion"; import type { CommandContext } from "../auto-reply/reply/commands-types.js"; import { resolveStateDir } from "../config/paths.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { tryReadJson, writeJson } from "../infra/json-files.js"; import type { RuntimeEnv } from "../runtime.js"; -import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "../shared/number-coercion.js"; import { executeCrestodianOperation, formatCrestodianPersistentPlan, diff --git a/src/cron/delivery-field-schemas.ts b/src/cron/delivery-field-schemas.ts index 0a253c1e1d0..ee7bb8906fa 100644 --- a/src/cron/delivery-field-schemas.ts +++ b/src/cron/delivery-field-schemas.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { z, type ZodType } from "zod"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; const trimStringPreprocess = (value: unknown) => (typeof value === "string" ? value.trim() : value); diff --git a/src/cron/delivery-plan.ts b/src/cron/delivery-plan.ts index f2129c2fa88..035eab6156e 100644 --- a/src/cron/delivery-plan.ts +++ b/src/cron/delivery-plan.ts @@ -1,11 +1,11 @@ -import type { CronFailureDestinationConfig } from "../config/types.cron.js"; -import { resolveTargetPrefixedChannel } from "../infra/outbound/channel-target-prefix.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeOptionalThreadValue, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { CronFailureDestinationConfig } from "../config/types.cron.js"; +import { resolveTargetPrefixedChannel } from "../infra/outbound/channel-target-prefix.js"; import type { CronDelivery, CronDeliveryMode, CronJob, CronMessageChannel } from "./types.js"; export type CronDeliveryPlan = { diff --git a/src/cron/isolated-agent.run-timeout-override.test.ts b/src/cron/isolated-agent.run-timeout-override.test.ts index 19dd24421f1..4c6598794db 100644 --- a/src/cron/isolated-agent.run-timeout-override.test.ts +++ b/src/cron/isolated-agent.run-timeout-override.test.ts @@ -1,5 +1,5 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { describe, expect, it } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { resolveCronRunTimeoutOverrideMs } from "./isolated-agent/run-timeout.js"; describe("resolveCronRunTimeoutOverrideMs", () => { diff --git a/src/cron/isolated-agent/channel-output-policy.ts b/src/cron/isolated-agent/channel-output-policy.ts index f5e2bb4817b..3cd3372642a 100644 --- a/src/cron/isolated-agent/channel-output-policy.ts +++ b/src/cron/isolated-agent/channel-output-policy.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; type ChannelPluginRuntime = typeof import("../../channels/plugins/index.js"); diff --git a/src/cron/isolated-agent/delivery-dispatch.ts b/src/cron/isolated-agent/delivery-dispatch.ts index 2fda49d8c96..f94dbe662a3 100644 --- a/src/cron/isolated-agent/delivery-dispatch.ts +++ b/src/cron/isolated-agent/delivery-dispatch.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { retireSessionMcpRuntime } from "../../agents/agent-bundle-mcp-tools.js"; import type { ReplyPayload } from "../../auto-reply/reply-payload.js"; import { @@ -38,7 +39,6 @@ import { resolveAgentIdFromSessionKey, } from "../../routing/session-key.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { shouldAttemptTtsPayload } from "../../tts/tts-config.js"; import { createCronExecutionId } from "../run-id.js"; import { hasScheduledNextRunAtMs } from "../service/jobs.js"; diff --git a/src/cron/isolated-agent/delivery-target.ts b/src/cron/isolated-agent/delivery-target.ts index 0ff9d3beb13..f1a9ce6903c 100644 --- a/src/cron/isolated-agent/delivery-target.ts +++ b/src/cron/isolated-agent/delivery-target.ts @@ -1,3 +1,5 @@ +import { normalizeOptionalThreadValue } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { resolveExplicitDeliveryTargetCompat } from "../../channels/plugins/target-parsing-loaded.js"; import type { ChannelId } from "../../channels/plugins/types.public.js"; import { resolveAgentMainSessionKey } from "../../config/sessions/main-session.js"; @@ -14,8 +16,6 @@ import { resolveSessionDeliveryTarget } from "../../infra/outbound/targets-sessi import type { OutboundChannel } from "../../infra/outbound/targets.js"; import { normalizeAccountId } from "../../routing/session-key.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { normalizeOptionalThreadValue } from "../../shared/string-coerce.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; import { resolveCronStoredDeliveryContext } from "../delivery-context.js"; import { resolveCronAgentSessionKey } from "./session-key.js"; diff --git a/src/cron/isolated-agent/helpers.ts b/src/cron/isolated-agent/helpers.ts index e70a80e8355..bfec369f33d 100644 --- a/src/cron/isolated-agent/helpers.ts +++ b/src/cron/isolated-agent/helpers.ts @@ -1,8 +1,8 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { hasOutboundReplyContent } from "openclaw/plugin-sdk/reply-payload"; import { DEFAULT_HEARTBEAT_ACK_MAX_CHARS } from "../../auto-reply/heartbeat.js"; import { getReplyPayloadMetadata } from "../../auto-reply/reply-payload.js"; import type { ReplyPayload } from "../../auto-reply/reply-payload.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { truncateUtf16Safe } from "../../utils.js"; import { shouldSkipHeartbeatOnlyDelivery } from "../heartbeat-policy.js"; diff --git a/src/cron/isolated-agent/model-preflight.runtime.ts b/src/cron/isolated-agent/model-preflight.runtime.ts index 57b1d592624..2df986bcdab 100644 --- a/src/cron/isolated-agent/model-preflight.runtime.ts +++ b/src/cron/isolated-agent/model-preflight.runtime.ts @@ -1,9 +1,9 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { ModelProviderConfig } from "../../config/types.models.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { fetchWithSsrFGuard } from "../../infra/net/fetch-guard.js"; import type { SsrFPolicy } from "../../infra/net/ssrf.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; const PREFLIGHT_CACHE_TTL_MS = 5 * 60_000; const PREFLIGHT_TIMEOUT_MS = 2_500; diff --git a/src/cron/isolated-agent/run-timeout.ts b/src/cron/isolated-agent/run-timeout.ts index a49863cdccb..37233882d4e 100644 --- a/src/cron/isolated-agent/run-timeout.ts +++ b/src/cron/isolated-agent/run-timeout.ts @@ -1,4 +1,4 @@ -import { finiteSecondsToTimerSafeMilliseconds } from "../../shared/number-coercion.js"; +import { finiteSecondsToTimerSafeMilliseconds } from "@openclaw/normalization-core/number-coercion"; export function resolveCronRunTimeoutOverrideMs(timeoutSeconds: unknown): number | undefined { return finiteSecondsToTimerSafeMilliseconds(timeoutSeconds); diff --git a/src/cron/isolated-agent/run.test-harness.ts b/src/cron/isolated-agent/run.test-harness.ts index a8155bdbe7a..00d0f040c43 100644 --- a/src/cron/isolated-agent/run.test-harness.ts +++ b/src/cron/isolated-agent/run.test-harness.ts @@ -1,8 +1,8 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { vi, type Mock } from "vitest"; import { resolveFastModeState as resolveFastModeStateImpl } from "../../agents/fast-mode.js"; import { LiveSessionModelSwitchError } from "../../agents/live-model-switch-error.js"; import { resolveAgentModelFallbackValues } from "../../config/model-input.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; type CronSessionEntry = { sessionId: string; diff --git a/src/cron/isolated-agent/run.ts b/src/cron/isolated-agent/run.ts index 3e525c7467c..1d4eff3ae7d 100644 --- a/src/cron/isolated-agent/run.ts +++ b/src/cron/isolated-agent/run.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { retireSessionMcpRuntime } from "../../agents/agent-bundle-mcp-tools.js"; import { hasAnyAuthProfileStoreSource } from "../../agents/auth-profiles/source-check.js"; import { resolveAgentHarnessPolicy } from "../../agents/harness/selection.js"; @@ -25,7 +26,6 @@ import { createDiagnosticMessageLifecycle } from "../../logging/message-lifecycl import { isCommandLaneTaskTimeoutError } from "../../process/command-queue.js"; import { CommandLane } from "../../process/lanes.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { resolveCronSkillsSnapshot } from "../../skills/runtime/cron-snapshot.js"; import type { SkillSnapshot } from "../../skills/types.js"; import { diff --git a/src/cron/isolated-agent/subagent-followup-hints.ts b/src/cron/isolated-agent/subagent-followup-hints.ts index 9becd4e40b3..7db1e3c2494 100644 --- a/src/cron/isolated-agent/subagent-followup-hints.ts +++ b/src/cron/isolated-agent/subagent-followup-hints.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; const SUBAGENT_FOLLOWUP_HINTS = [ "subagent spawned", diff --git a/src/cron/normalize-job-identity.ts b/src/cron/normalize-job-identity.ts index 783e46b2c99..689892c228d 100644 --- a/src/cron/normalize-job-identity.ts +++ b/src/cron/normalize-job-identity.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export function normalizeCronJobIdentityFields(raw: Record): { mutated: boolean; diff --git a/src/cron/normalize.ts b/src/cron/normalize.ts index a7975082652..676df714275 100644 --- a/src/cron/normalize.ts +++ b/src/cron/normalize.ts @@ -1,11 +1,11 @@ -import { sanitizeAgentId } from "../routing/session-key.js"; -import { timestampMsToIsoString } from "../shared/number-coercion.js"; +import { timestampMsToIsoString } from "@openclaw/normalization-core/number-coercion"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; -import { normalizeTrimmedStringList } from "../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; +import { sanitizeAgentId } from "../routing/session-key.js"; import { isRecord } from "../utils.js"; import { TimeoutSecondsFieldSchema, diff --git a/src/cron/run-diagnostics.ts b/src/cron/run-diagnostics.ts index 84ce35ce2c1..cf7882758ee 100644 --- a/src/cron/run-diagnostics.ts +++ b/src/cron/run-diagnostics.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { getReplyPayloadMetadata } from "../auto-reply/reply-payload.js"; import { redactSensitiveText } from "../logging/redact.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { CronRunDiagnostic, CronRunDiagnostics, diff --git a/src/cron/run-log-jsonl.ts b/src/cron/run-log-jsonl.ts index 69f75807080..126c85927c3 100644 --- a/src/cron/run-log-jsonl.ts +++ b/src/cron/run-log-jsonl.ts @@ -1,6 +1,6 @@ import type { FailoverReason } from "../agents/embedded-agent-helpers/types.js"; import { resolveFailoverReasonFromError } from "../agents/failover-error.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "../../packages/normalization-core/src/string-coerce.js"; import { normalizeCronRunDiagnostics } from "./run-diagnostics.js"; import type { CronRunLogEntry } from "./run-log-types.js"; import type { CronDeliveryStatus } from "./types.js"; diff --git a/src/cron/run-log.ts b/src/cron/run-log.ts index 187f386250f..1193b30e85f 100644 --- a/src/cron/run-log.ts +++ b/src/cron/run-log.ts @@ -1,15 +1,15 @@ import path from "node:path"; import type { DatabaseSync } from "node:sqlite"; -import type { Insertable, Selectable } from "kysely"; -import { parseByteSize } from "../cli/parse-bytes.js"; -import type { CronConfig } from "../config/types.cron.js"; -import { executeSqliteQuerySync, getNodeSqliteKysely } from "../infra/kysely-sync.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeStringifiedOptionalString, -} from "../shared/string-coerce.js"; -import { uniqueValues } from "../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { uniqueValues } from "@openclaw/normalization-core/string-normalization"; +import type { Insertable, Selectable } from "kysely"; +import { parseByteSize } from "../cli/parse-bytes.js"; +import type { CronConfig } from "../config/types.cron.js"; +import { executeSqliteQuerySync, getNodeSqliteKysely } from "../infra/kysely-sync.js"; import type { DB as OpenClawStateKyselyDatabase } from "../state/openclaw-state-db.generated.js"; import { openOpenClawStateDatabase, diff --git a/src/cron/schedule-identity.ts b/src/cron/schedule-identity.ts index 59795ec1907..8fcd8ae39e0 100644 --- a/src/cron/schedule-identity.ts +++ b/src/cron/schedule-identity.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { coerceFiniteScheduleNumber } from "./schedule-number.js"; import { normalizeCronStaggerMs } from "./stagger.js"; diff --git a/src/cron/schedule-number.ts b/src/cron/schedule-number.ts index 29bcadff3e0..3a71162a6f6 100644 --- a/src/cron/schedule-number.ts +++ b/src/cron/schedule-number.ts @@ -1,4 +1,4 @@ -import { parseStrictFiniteNumber } from "../shared/number-coercion.js"; +import { parseStrictFiniteNumber } from "@openclaw/normalization-core/number-coercion"; export function coerceFiniteScheduleNumber(value: unknown): number | undefined { return parseStrictFiniteNumber(value); diff --git a/src/cron/schedule.ts b/src/cron/schedule.ts index 4519df78b13..303b0307365 100644 --- a/src/cron/schedule.ts +++ b/src/cron/schedule.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { Cron } from "croner"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { parseAbsoluteTimeMs } from "./parse.js"; import { coerceFiniteScheduleNumber } from "./schedule-number.js"; import type { CronSchedule } from "./types.js"; diff --git a/src/cron/service/jobs.ts b/src/cron/service/jobs.ts index beb74606b3f..f3d6ee5e464 100644 --- a/src/cron/service/jobs.ts +++ b/src/cron/service/jobs.ts @@ -1,9 +1,9 @@ import crypto from "node:crypto"; -import { normalizeAgentId } from "../../routing/session-key.js"; import { normalizeOptionalString, normalizeOptionalThreadValue, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeAgentId } from "../../routing/session-key.js"; import { parseAbsoluteTimeMs } from "../parse.js"; import { coerceFiniteScheduleNumber, diff --git a/src/cron/service/normalize.ts b/src/cron/service/normalize.ts index ecde866ad47..1dfb1da20a4 100644 --- a/src/cron/service/normalize.ts +++ b/src/cron/service/normalize.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { normalizeAgentId } from "../../routing/session-key.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { truncateUtf16Safe } from "../../utils.js"; import type { CronPayload } from "../types.js"; diff --git a/src/cron/service/ops.ts b/src/cron/service/ops.ts index a4294188329..17093f37d1e 100644 --- a/src/cron/service/ops.ts +++ b/src/cron/service/ops.ts @@ -1,7 +1,7 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { enqueueCommandInLane } from "../../process/command-queue.js"; import { CommandLane } from "../../process/lanes.js"; import { DEFAULT_AGENT_ID } from "../../routing/session-key.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { completeTaskRunByRunId, createRunningTaskRun, diff --git a/src/cron/service/timeout-policy.test.ts b/src/cron/service/timeout-policy.test.ts index 5fe3f36946d..5827e5657e5 100644 --- a/src/cron/service/timeout-policy.test.ts +++ b/src/cron/service/timeout-policy.test.ts @@ -1,5 +1,5 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { describe, expect, it } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../../shared/number-coercion.js"; import type { CronJob } from "../types.js"; import { AGENT_TURN_SAFETY_TIMEOUT_MS, diff --git a/src/cron/service/timeout-policy.ts b/src/cron/service/timeout-policy.ts index 0e49cd1c4d9..b7a155ea0b9 100644 --- a/src/cron/service/timeout-policy.ts +++ b/src/cron/service/timeout-policy.ts @@ -1,4 +1,4 @@ -import { finiteSecondsToTimerSafeMilliseconds } from "../../shared/number-coercion.js"; +import { finiteSecondsToTimerSafeMilliseconds } from "@openclaw/normalization-core/number-coercion"; import type { CronJob } from "../types.js"; /** diff --git a/src/cron/service/timer.ts b/src/cron/service/timer.ts index d43b2c2bbb6..6e29bba6882 100644 --- a/src/cron/service/timer.ts +++ b/src/cron/service/timer.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { formatEmbeddedAgentExecutionPhase } from "../../agents/embedded-agent-runner/execution-phase.js"; import { resolveFailoverReasonFromError } from "../../agents/failover-error.js"; import { readSessionEntry } from "../../config/sessions/store-load.js"; @@ -14,7 +15,6 @@ import { normalizeAgentId, resolveAgentIdFromSessionKey, } from "../../routing/session-key.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { completeTaskRunByRunId, createRunningTaskRun, diff --git a/src/cron/store.ts b/src/cron/store.ts index 11ba9fb8c22..b97d1f06795 100644 --- a/src/cron/store.ts +++ b/src/cron/store.ts @@ -1,12 +1,12 @@ import fs from "node:fs"; import path from "node:path"; import type { DatabaseSync } from "node:sqlite"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { Insertable, Selectable } from "kysely"; import { expandHomePrefix } from "../infra/home-dir.js"; import { executeSqliteQuerySync, getNodeSqliteKysely } from "../infra/kysely-sync.js"; import { replaceFileAtomic } from "../infra/replace-file.js"; -import { isRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { DB as OpenClawStateKyselyDatabase } from "../state/openclaw-state-db.generated.js"; import { openOpenClawStateDatabase, diff --git a/src/cron/validate-timestamp.ts b/src/cron/validate-timestamp.ts index f3a622d39b9..838fbfb44b0 100644 --- a/src/cron/validate-timestamp.ts +++ b/src/cron/validate-timestamp.ts @@ -1,5 +1,8 @@ -import { asDateTimestampMs, resolveTimestampMsToIsoString } from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { + asDateTimestampMs, + resolveTimestampMsToIsoString, +} from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { parseAbsoluteTimeMs } from "./parse.js"; import type { CronSchedule } from "./types.js"; diff --git a/src/daemon/constants.ts b/src/daemon/constants.ts index b954c18e814..9607fb27541 100644 --- a/src/daemon/constants.ts +++ b/src/daemon/constants.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; // Default service labels (canonical + legacy compatibility) export const GATEWAY_LAUNCH_AGENT_LABEL = "ai.openclaw.gateway"; diff --git a/src/daemon/container-context.ts b/src/daemon/container-context.ts index c8c4781405b..7e80683479f 100644 --- a/src/daemon/container-context.ts +++ b/src/daemon/container-context.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export function resolveDaemonContainerContext( env: Record = process.env, diff --git a/src/daemon/inspect.ts b/src/daemon/inspect.ts index 56806429469..38c717554cf 100644 --- a/src/daemon/inspect.ts +++ b/src/daemon/inspect.ts @@ -1,6 +1,6 @@ import fs from "node:fs/promises"; import path from "node:path"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { GATEWAY_SERVICE_KIND, GATEWAY_SERVICE_MARKER, diff --git a/src/daemon/launchd-restart-handoff.ts b/src/daemon/launchd-restart-handoff.ts index 31ac2bc2eed..57a19d0648c 100644 --- a/src/daemon/launchd-restart-handoff.ts +++ b/src/daemon/launchd-restart-handoff.ts @@ -1,10 +1,10 @@ import { spawn } from "node:child_process"; import os from "node:os"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { sanitizeForLog } from "../../packages/terminal-core/src/ansi.js"; import { formatErrorMessage } from "../infra/errors.js"; import { sanitizeHostExecEnv } from "../infra/host-env-security.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resolveGatewayLaunchAgentLabel } from "./constants.js"; import { renderPosixRestartLogSetup } from "./restart-logs.js"; diff --git a/src/daemon/launchd.ts b/src/daemon/launchd.ts index 239709ed0a1..9b6fae521d1 100644 --- a/src/daemon/launchd.ts +++ b/src/daemon/launchd.ts @@ -1,12 +1,12 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { sanitizeForLog } from "../../packages/terminal-core/src/ansi.js"; import { normalizeEnvVarKey } from "../infra/host-env-security.js"; import { parseStrictInteger, parseStrictPositiveInteger } from "../infra/parse-finite-number.js"; import { formatPortDiagnostics, inspectPortUsage } from "../infra/ports.js"; import { cleanStaleGatewayProcessesSync } from "../infra/restart-stale-pids.js"; import { parseTcpPort } from "../infra/tcp-port.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { GATEWAY_LAUNCH_AGENT_LABEL, GATEWAY_SERVICE_KIND, diff --git a/src/daemon/paths.ts b/src/daemon/paths.ts index 464d7ca3dfe..29abe76bbf9 100644 --- a/src/daemon/paths.ts +++ b/src/daemon/paths.ts @@ -1,5 +1,5 @@ import path from "node:path"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveGatewayProfileSuffix } from "./constants.js"; const windowsAbsolutePath = /^[a-zA-Z]:[\\/]/; diff --git a/src/daemon/runtime-binary.ts b/src/daemon/runtime-binary.ts index b5ade2570ae..4e127d51e1f 100644 --- a/src/daemon/runtime-binary.ts +++ b/src/daemon/runtime-binary.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; const NODE_VERSIONED_PATTERN = /^node(?:-\d+|\d+)(?:\.\d+)*(?:\.exe)?$/; diff --git a/src/daemon/runtime-parse.ts b/src/daemon/runtime-parse.ts index 1555d9d1371..21cee5094a6 100644 --- a/src/daemon/runtime-parse.ts +++ b/src/daemon/runtime-parse.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export function parseKeyValueOutput(output: string, separator: string): Record { const entries: Record = {}; diff --git a/src/daemon/runtime-paths.ts b/src/daemon/runtime-paths.ts index f7ca9138968..af3bf441bd2 100644 --- a/src/daemon/runtime-paths.ts +++ b/src/daemon/runtime-paths.ts @@ -2,10 +2,10 @@ import { execFile } from "node:child_process"; import fs from "node:fs/promises"; import path from "node:path"; import { promisify } from "node:util"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { isSupportedNodeVersion } from "../infra/runtime-guard.js"; import { resolveStableNodePath } from "../infra/stable-node-path.js"; import { getWindowsProgramFilesRoots } from "../infra/windows-install-roots.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; const VERSION_MANAGER_MARKERS = [ "/.nvm/", diff --git a/src/daemon/schtasks.ts b/src/daemon/schtasks.ts index 6f1fa8d3e2f..a7aa4063ad2 100644 --- a/src/daemon/schtasks.ts +++ b/src/daemon/schtasks.ts @@ -2,14 +2,14 @@ import { spawn, spawnSync } from "node:child_process"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { isGatewayArgv } from "../infra/gateway-process-argv.js"; import { findVerifiedGatewayListenerPidsOnPortSync } from "../infra/gateway-processes.js"; import { inspectPortUsage } from "../infra/ports.js"; import { parseTcpPort } from "../infra/tcp-port.js"; import { getWindowsInstallRoots } from "../infra/windows-install-roots.js"; import { killProcessTree } from "../process/kill-tree.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { sleep } from "../utils.js"; import { parseCmdScriptCommandLine, quoteCmdScriptArg } from "./cmd-argv.js"; import { assertNoCmdLineBreak, parseCmdSetAssignment, renderCmdSetAssignment } from "./cmd-set.js"; diff --git a/src/daemon/service-audit.ts b/src/daemon/service-audit.ts index 28a208b2d07..3c664a1e69c 100644 --- a/src/daemon/service-audit.ts +++ b/src/daemon/service-audit.ts @@ -1,12 +1,15 @@ import fs from "node:fs/promises"; import path from "node:path"; -import { normalizeEnvVarKey } from "../infra/host-env-security.js"; -import { parseTcpPort } from "../infra/tcp-port.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; -import { normalizeStringEntries, sortUniqueStrings } from "../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { + normalizeStringEntries, + sortUniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; +import { normalizeEnvVarKey } from "../infra/host-env-security.js"; +import { parseTcpPort } from "../infra/tcp-port.js"; import { resolveLaunchAgentPlistPath } from "./launchd.js"; import { isBunRuntime, isNodeRuntime } from "./runtime-binary.js"; import { diff --git a/src/daemon/service-env.ts b/src/daemon/service-env.ts index cee3f1325eb..a5fe83875a9 100644 --- a/src/daemon/service-env.ts +++ b/src/daemon/service-env.ts @@ -1,12 +1,12 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { isNodeVersionManagerRuntime, resolveLinuxSystemCaBundle, } from "../bootstrap/node-extra-ca-certs.js"; import { resolveNodeStartupTlsEnvironment } from "../bootstrap/node-startup-env.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { VERSION } from "../version.js"; import { GATEWAY_SERVICE_KIND, diff --git a/src/daemon/service-managed-env.ts b/src/daemon/service-managed-env.ts index 8d572a3fd15..4810bee3955 100644 --- a/src/daemon/service-managed-env.ts +++ b/src/daemon/service-managed-env.ts @@ -1,5 +1,5 @@ +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { normalizeEnvVarKey } from "../infra/host-env-security.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; import type { GatewayServiceEnvironmentValueSource } from "./service-types.js"; const MANAGED_SERVICE_ENV_KEYS_VAR = "OPENCLAW_SERVICE_MANAGED_ENV_KEYS"; diff --git a/src/daemon/service-path-policy.ts b/src/daemon/service-path-policy.ts index ffe5b6b24c6..81428ed933e 100644 --- a/src/daemon/service-path-policy.ts +++ b/src/daemon/service-path-policy.ts @@ -1,5 +1,5 @@ import path from "node:path"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; function getPathModule(platform: NodeJS.Platform) { return platform === "win32" ? path.win32 : path.posix; diff --git a/src/daemon/service-runtime.ts b/src/daemon/service-runtime.ts index cadc43240a7..5d70f9f651a 100644 --- a/src/daemon/service-runtime.ts +++ b/src/daemon/service-runtime.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export type GatewayServiceSystemdRuntime = { unit?: string; diff --git a/src/daemon/service.ts b/src/daemon/service.ts index db69d185f21..8030a030ea6 100644 --- a/src/daemon/service.ts +++ b/src/daemon/service.ts @@ -1,7 +1,7 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { VERSION } from "../version.js"; import { assertFutureConfigActionAllowed } from "./future-config-guard.js"; import { diff --git a/src/daemon/systemd-linger.ts b/src/daemon/systemd-linger.ts index d4459ff09e5..f1c34e03e44 100644 --- a/src/daemon/systemd-linger.ts +++ b/src/daemon/systemd-linger.ts @@ -1,10 +1,10 @@ import os from "node:os"; -import { formatErrorMessage } from "../infra/errors.js"; -import { runCommandWithTimeout, runExec } from "../process/exec.js"; import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { formatErrorMessage } from "../infra/errors.js"; +import { runCommandWithTimeout, runExec } from "../process/exec.js"; function resolveLoginctlUser(env: Record): string | null { const fromEnv = normalizeOptionalString(env.USER) || normalizeOptionalString(env.LOGNAME); diff --git a/src/daemon/systemd-unavailable.ts b/src/daemon/systemd-unavailable.ts index 196e980cc46..c8ac6d387d4 100644 --- a/src/daemon/systemd-unavailable.ts +++ b/src/daemon/systemd-unavailable.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export type SystemdUnavailableKind = | "missing_systemctl" diff --git a/src/daemon/systemd-unit.ts b/src/daemon/systemd-unit.ts index 51d9f150572..e1d241682f3 100644 --- a/src/daemon/systemd-unit.ts +++ b/src/daemon/systemd-unit.ts @@ -1,4 +1,4 @@ -import { normalizeStringEntries } from "../shared/string-normalization.js"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { splitArgsPreservingQuotes } from "./arg-split.js"; import type { GatewayServiceRenderArgs } from "./service-types.js"; diff --git a/src/daemon/systemd.ts b/src/daemon/systemd.ts index 221ad67fc8d..d72f55f6ee8 100644 --- a/src/daemon/systemd.ts +++ b/src/daemon/systemd.ts @@ -2,6 +2,8 @@ import * as fsSync from "node:fs"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { resolveStateDir } from "../config/paths.js"; import { readStateDirDotEnvVarsFromStateDir } from "../config/state-dir-dotenv.js"; import { formatErrorMessage } from "../infra/errors.js"; @@ -11,8 +13,6 @@ import { parseStrictNonNegativeInteger, parseStrictPositiveInteger, } from "../infra/parse-finite-number.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { splitArgsPreservingQuotes } from "./arg-split.js"; import { LEGACY_GATEWAY_SYSTEMD_SERVICE_NAMES, diff --git a/src/flows/bundled-health-checks.ts b/src/flows/bundled-health-checks.ts index c5adb4ee011..669c30713fe 100644 --- a/src/flows/bundled-health-checks.ts +++ b/src/flows/bundled-health-checks.ts @@ -1,8 +1,8 @@ +import { asOptionalObjectRecord as readRecord } from "@openclaw/normalization-core/record-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizePluginsConfig } from "../plugins/config-state.js"; import { passesManifestOwnerBasePolicy } from "../plugins/manifest-owner-policy.js"; import { loadBundledPluginPublicArtifactModuleSync } from "../plugins/public-surface-loader.js"; -import { asOptionalObjectRecord as readRecord } from "../shared/record-coerce.js"; import { registerHealthCheck } from "./health-check-registry.js"; type BundledHealthApi = { diff --git a/src/flows/doctor-repair-flow.ts b/src/flows/doctor-repair-flow.ts index e48cee60af9..3e379afc298 100644 --- a/src/flows/doctor-repair-flow.ts +++ b/src/flows/doctor-repair-flow.ts @@ -1,5 +1,5 @@ +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { scrubDoctorErrorMessage } from "./doctor-error-message.js"; import { normalizeHealthCheck } from "./health-check-adapter.js"; import { listHealthChecks } from "./health-check-registry.js"; diff --git a/src/flows/model-picker.ts b/src/flows/model-picker.ts index 8a49bdfb14f..80016df7622 100644 --- a/src/flows/model-picker.ts +++ b/src/flows/model-picker.ts @@ -1,3 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { resolveDefaultAgentDir } from "../agents/agent-scope.js"; import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../agents/defaults.js"; import { resolveVisibleModelCatalog } from "../agents/model-catalog-visibility.js"; @@ -29,8 +31,6 @@ import { resolveOwningPluginIdsForProviderRef } from "../plugins/providers.js"; import type { ProviderPlugin } from "../plugins/types.js"; import type { RuntimeEnv } from "../runtime.js"; import { createLazyRuntimeSurface } from "../shared/lazy-runtime.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; import { t } from "../wizard/i18n/index.js"; import type { WizardPrompter, WizardSelectOption } from "../wizard/prompts.js"; import { loadPreferredProviderPickerCatalog } from "./model-picker.provider-catalog.js"; diff --git a/src/flows/provider-flow.runtime.ts b/src/flows/provider-flow.runtime.ts index 9c755e51324..e24e533aa74 100644 --- a/src/flows/provider-flow.runtime.ts +++ b/src/flows/provider-flow.runtime.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import * as providerWizard from "../plugins/provider-wizard.js"; import type { ProviderModelPickerEntry } from "../plugins/provider-wizard.js"; import * as providersRuntime from "../plugins/providers.runtime.js"; import type { ProviderPlugin } from "../plugins/types.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { FlowContribution } from "./types.js"; import { sortFlowContributionsByLabel } from "./types.js"; diff --git a/src/flows/search-setup.ts b/src/flows/search-setup.ts index 9445a126656..882b0e31edc 100644 --- a/src/flows/search-setup.ts +++ b/src/flows/search-setup.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveDefaultAgentDir } from "../agents/agent-scope-config.js"; import { hasAuthProfileForProvider } from "../agents/tools/model-config.helpers.js"; import type { SecretInputMode } from "../commands/onboard-types.js"; @@ -19,7 +20,6 @@ import { import { resolvePluginWebSearchProviders } from "../plugins/web-search-providers.runtime.js"; import { sortWebSearchProviders } from "../plugins/web-search-providers.shared.js"; import type { RuntimeEnv } from "../runtime.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { t } from "../wizard/i18n/index.js"; import type { WizardPrompter } from "../wizard/prompts.js"; import type { FlowContribution, FlowOption } from "./types.js"; diff --git a/src/gateway/agent-list.ts b/src/gateway/agent-list.ts index 8c6b858b229..16438bddddb 100644 --- a/src/gateway/agent-list.ts +++ b/src/gateway/agent-list.ts @@ -1,11 +1,11 @@ import fs from "node:fs"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveDefaultAgentId } from "../agents/agent-scope.js"; import { resolveStateDir } from "../config/paths.js"; import type { SessionScope } from "../config/sessions.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeAgentId, normalizeMainKey } from "../routing/session-key.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; type GatewayAgentListRow = { id: string; diff --git a/src/gateway/auth-install-policy.ts b/src/gateway/auth-install-policy.ts index d4be65c1f2e..f576e94f386 100644 --- a/src/gateway/auth-install-policy.ts +++ b/src/gateway/auth-install-policy.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { collectDurableServiceEnvVars } from "../config/state-dir-dotenv.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { hasConfiguredSecretInput } from "../config/types.secrets.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; type GatewayInstallAuthMode = NonNullable["auth"]>["mode"]; diff --git a/src/gateway/auth-token-source-conflict.ts b/src/gateway/auth-token-source-conflict.ts index 98e6f9b348f..5bc5f66856d 100644 --- a/src/gateway/auth-token-source-conflict.ts +++ b/src/gateway/auth-token-source-conflict.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeSecretInputString, resolveSecretInputRef } from "../config/types.secrets.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; const GATEWAY_ENV_TOKEN = "OPENCLAW_GATEWAY_TOKEN"; const GATEWAY_SERVICE_KIND = "gateway"; diff --git a/src/gateway/auth.ts b/src/gateway/auth.ts index 561928574fa..94a8244c7de 100644 --- a/src/gateway/auth.ts +++ b/src/gateway/auth.ts @@ -1,11 +1,11 @@ import type { IncomingMessage } from "node:http"; -import type { GatewayAuthConfig, GatewayTrustedProxyConfig } from "../config/types.gateway.js"; -import { readTailscaleWhoisIdentity, type TailscaleWhoisIdentity } from "../infra/tailscale.js"; -import { safeEqualSecret } from "../security/secret-equal.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { GatewayAuthConfig, GatewayTrustedProxyConfig } from "../config/types.gateway.js"; +import { readTailscaleWhoisIdentity, type TailscaleWhoisIdentity } from "../infra/tailscale.js"; +import { safeEqualSecret } from "../security/secret-equal.js"; import { AUTH_RATE_LIMIT_SCOPE_SHARED_SECRET, type AuthRateLimiter, diff --git a/src/gateway/call.ts b/src/gateway/call.ts index 13a15d9caf8..756e18419bc 100644 --- a/src/gateway/call.ts +++ b/src/gateway/call.ts @@ -1,6 +1,7 @@ import { randomUUID } from "node:crypto"; import { isLoopbackIpAddress } from "@openclaw/net-policy/ip"; import { redactSensitiveUrlLikeString } from "@openclaw/net-policy/redact-sensitive-url"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { MIN_CLIENT_PROTOCOL_VERSION, PROTOCOL_VERSION, @@ -15,7 +16,6 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; import { loadDeviceAuthToken } from "../infra/device-auth-store.js"; import { loadOrCreateDeviceIdentity, type DeviceIdentity } from "../infra/device-identity.js"; import { loadGatewayTlsRuntime } from "../infra/tls/gateway.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES, diff --git a/src/gateway/chat-abort.ts b/src/gateway/chat-abort.ts index e6d334945d0..fb9732e3186 100644 --- a/src/gateway/chat-abort.ts +++ b/src/gateway/chat-abort.ts @@ -1,12 +1,12 @@ -import { resolveDefaultAgentId } from "../agents/agent-scope-config.js"; -import { isAbortRequestText } from "../auto-reply/reply/abort-primitives.js"; -import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { emitAgentEvent } from "../infra/agent-events.js"; import { asDateTimestampMs, resolveDateTimestampMs, resolveExpiresAtMsFromDurationMs, -} from "../shared/number-coercion.js"; +} from "@openclaw/normalization-core/number-coercion"; +import { resolveDefaultAgentId } from "../agents/agent-scope-config.js"; +import { isAbortRequestText } from "../auto-reply/reply/abort-primitives.js"; +import type { OpenClawConfig } from "../config/types.openclaw.js"; +import { emitAgentEvent } from "../infra/agent-events.js"; const DEFAULT_CHAT_RUN_ABORT_GRACE_MS = 60_000; diff --git a/src/gateway/chat-attachments.ts b/src/gateway/chat-attachments.ts index 5c222e8d74c..6344566926d 100644 --- a/src/gateway/chat-attachments.ts +++ b/src/gateway/chat-attachments.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { formatErrorMessage } from "../infra/errors.js"; import { estimateBase64DecodedBytes } from "../media/base64.js"; @@ -6,7 +7,6 @@ import { extensionForMime, mimeTypeFromFilePath } from "../media/mime.js"; import type { PromptImageOrderEntry } from "../media/prompt-image-order.js"; import { sniffMimeFromBase64 } from "../media/sniff-mime-from-base64.js"; import { deleteMediaBuffer, saveMediaBuffer } from "../media/store.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; export type ChatAttachment = { type?: string; diff --git a/src/gateway/chat-display-projection.ts b/src/gateway/chat-display-projection.ts index f50dbbab61e..d7ea6b05263 100644 --- a/src/gateway/chat-display-projection.ts +++ b/src/gateway/chat-display-projection.ts @@ -1,4 +1,7 @@ import { createHash } from "node:crypto"; +import { asFiniteNumber } from "@openclaw/normalization-core/number-coercion"; +import { asOptionalRecord as readRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { OPENCLAW_RUNTIME_CONTEXT_CUSTOM_TYPE } from "../agents/internal-runtime-context.js"; import { isHeartbeatOkResponse, isHeartbeatUserMessage } from "../auto-reply/heartbeat-filter.js"; import { HEARTBEAT_PROMPT } from "../auto-reply/heartbeat.js"; @@ -10,9 +13,6 @@ import { parseAssistantTextSignature, resolveAssistantMessagePhase, } from "../shared/chat-message-content.js"; -import { asFiniteNumber } from "../shared/number-coercion.js"; -import { asOptionalRecord as readRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { stripInlineDirectiveTagsForDisplay } from "../utils/directive-tags.js"; import { stripEnvelopeFromMessages } from "./chat-sanitize.js"; import { isSuppressedControlReplyText } from "./control-reply-text.js"; diff --git a/src/gateway/chat-sanitize.ts b/src/gateway/chat-sanitize.ts index 8b81725aaec..d568251e7d4 100644 --- a/src/gateway/chat-sanitize.ts +++ b/src/gateway/chat-sanitize.ts @@ -1,10 +1,10 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { stripInternalMetadataForDisplay, stripUserEnvelopeForDisplay, } from "../auto-reply/reply/display-text-sanitize.js"; import { extractInboundSenderLabel } from "../auto-reply/reply/strip-inbound-meta.js"; import { stripEnvelope } from "../shared/chat-envelope.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; export { stripEnvelope }; diff --git a/src/gateway/cli-session-history.claude.ts b/src/gateway/cli-session-history.claude.ts index d97b5d45843..86658af8fe5 100644 --- a/src/gateway/cli-session-history.claude.ts +++ b/src/gateway/cli-session-history.claude.ts @@ -1,6 +1,8 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; +import { asFiniteNumber } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { isToolCallBlock, isToolResultBlock, @@ -8,8 +10,6 @@ import { type ToolContentBlock, } from "../chat/tool-content.js"; import type { SessionEntry } from "../config/sessions.js"; -import { asFiniteNumber } from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { attachOpenClawTranscriptMeta } from "./session-utils.fs.js"; export const CLAUDE_CLI_PROVIDER = "claude-cli"; diff --git a/src/gateway/cli-session-history.merge.ts b/src/gateway/cli-session-history.merge.ts index a9d88aca522..eeb0d4140d7 100644 --- a/src/gateway/cli-session-history.merge.ts +++ b/src/gateway/cli-session-history.merge.ts @@ -1,6 +1,9 @@ +import { asFiniteNumber } from "@openclaw/normalization-core/number-coercion"; +import { + normalizeOptionalString, + readStringValue, +} from "@openclaw/normalization-core/string-coerce"; import { stripInboundMetadata } from "../auto-reply/reply/strip-inbound-meta.js"; -import { asFiniteNumber } from "../shared/number-coercion.js"; -import { normalizeOptionalString, readStringValue } from "../shared/string-coerce.js"; const DEDUPE_TIMESTAMP_WINDOW_MS = 5 * 60 * 1000; diff --git a/src/gateway/connection-details.ts b/src/gateway/connection-details.ts index f6be61524e5..9ee4095f1fa 100644 --- a/src/gateway/connection-details.ts +++ b/src/gateway/connection-details.ts @@ -1,7 +1,7 @@ import { redactSensitiveUrlLikeString } from "@openclaw/net-policy/redact-sensitive-url"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveConfigPath, resolveGatewayPort } from "../config/paths.js"; import type { OpenClawConfig } from "../config/types.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { isSecureWebSocketUrl } from "./net.js"; export type GatewayConnectionDetails = { diff --git a/src/gateway/control-ui-csp.ts b/src/gateway/control-ui-csp.ts index 1b116005054..eb7dbd36aa8 100644 --- a/src/gateway/control-ui-csp.ts +++ b/src/gateway/control-ui-csp.ts @@ -1,5 +1,5 @@ import { createHash } from "node:crypto"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; const SCRIPT_ATTRIBUTE_NAME_RE = /\s([^\s=/>]+)(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+))?/g; diff --git a/src/gateway/control-ui.ts b/src/gateway/control-ui.ts index cc726be7ba5..7be2f265e7b 100644 --- a/src/gateway/control-ui.ts +++ b/src/gateway/control-ui.ts @@ -2,6 +2,10 @@ import { createHmac, randomBytes, timingSafeEqual } from "node:crypto"; import fs from "node:fs"; import type { IncomingMessage, ServerResponse } from "node:http"; import path from "node:path"; +import { + asDateTimestampMs, + resolveTimestampMsToIsoString, +} from "@openclaw/normalization-core/number-coercion"; import { resolveAgentAvatar, resolvePublicAgentAvatarSource } from "../agents/identity-avatar.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { matchRootFileOpenFailure, openRootFileSync } from "../infra/boundary-file-read.js"; @@ -19,7 +23,6 @@ import { getAgentScopedMediaLocalRoots } from "../media/local-roots.js"; import { resolveMediaReferenceLocalPath } from "../media/media-reference.js"; import { detectMime } from "../media/mime.js"; import { AVATAR_MAX_BYTES } from "../shared/avatar-policy.js"; -import { asDateTimestampMs, resolveTimestampMsToIsoString } from "../shared/number-coercion.js"; import { resolveUserPath } from "../utils.js"; import { resolveRuntimeServiceVersion } from "../version.js"; import { DEFAULT_ASSISTANT_IDENTITY, resolveAssistantIdentity } from "./assistant-identity.js"; diff --git a/src/gateway/credential-planner.ts b/src/gateway/credential-planner.ts index c89771a7e06..3bfe719aabb 100644 --- a/src/gateway/credential-planner.ts +++ b/src/gateway/credential-planner.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalString } from "../../packages/normalization-core/src/string-coerce.js"; import { containsEnvVarReference } from "../config/env-substitution.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { hasConfiguredSecretInput, resolveSecretInputRef } from "../config/types.secrets.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; type GatewayCredentialInputPath = | "gateway.auth.token" diff --git a/src/gateway/device-metadata-normalization.ts b/src/gateway/device-metadata-normalization.ts index 27260eccc2c..691735ea948 100644 --- a/src/gateway/device-metadata-normalization.ts +++ b/src/gateway/device-metadata-normalization.ts @@ -29,4 +29,4 @@ export function normalizeDeviceMetadataForPolicy(value?: string | null): string // tokens where possible before matching platform/family rules. return normalizeLowercaseStringOrEmpty(trimmed.normalize("NFKD").replace(/\p{M}/gu, "")); } -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; diff --git a/src/gateway/embeddings-http.ts b/src/gateway/embeddings-http.ts index 678cb372413..fa080cb0b91 100644 --- a/src/gateway/embeddings-http.ts +++ b/src/gateway/embeddings-http.ts @@ -1,5 +1,9 @@ import { Buffer } from "node:buffer"; import type { IncomingMessage, ServerResponse } from "node:http"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveAgentDir } from "../agents/agent-scope.js"; import { resolveMemorySearchConfig } from "../agents/memory-search.js"; import { getRuntimeConfig } from "../config/io.js"; @@ -16,10 +20,6 @@ import type { MemoryEmbeddingProvider, MemoryEmbeddingProviderAdapter, } from "../plugins/memory-embedding-providers.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import type { AuthRateLimiter } from "./auth-rate-limit.js"; import type { ResolvedGatewayAuth } from "./auth.js"; import { sendJson } from "./http-common.js"; diff --git a/src/gateway/exec-approval-ios-push.ts b/src/gateway/exec-approval-ios-push.ts index 12ea05ae22f..21e53189dc6 100644 --- a/src/gateway/exec-approval-ios-push.ts +++ b/src/gateway/exec-approval-ios-push.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { getRuntimeConfig } from "../config/io.js"; import { hasEffectivePairedDeviceRole, @@ -20,7 +21,6 @@ import { type ApnsRelayConfig, } from "../infra/push-apns.js"; import { roleScopesAllow } from "../shared/operator-scope-compat.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; const APPROVALS_SCOPE = "operator.approvals"; const OPERATOR_ROLE = "operator"; diff --git a/src/gateway/exec-approval-manager.ts b/src/gateway/exec-approval-manager.ts index 5399403a254..1ff3f1dae6e 100644 --- a/src/gateway/exec-approval-manager.ts +++ b/src/gateway/exec-approval-manager.ts @@ -1,10 +1,10 @@ import { randomUUID } from "node:crypto"; +import { resolveExpiresAtMsFromDurationMs } from "@openclaw/normalization-core/number-coercion"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { ExecApprovalDecision, ExecApprovalRequestPayload as InfraExecApprovalRequestPayload, } from "../infra/exec-approvals.js"; -import { resolveExpiresAtMsFromDurationMs } from "../shared/number-coercion.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; // Grace period to keep resolved entries for late awaitDecision calls const RESOLVED_ENTRY_GRACE_MS = 15_000; diff --git a/src/gateway/gateway-cli-backend.live-helpers.ts b/src/gateway/gateway-cli-backend.live-helpers.ts index 2e27455d7eb..bf5135c8e25 100644 --- a/src/gateway/gateway-cli-backend.live-helpers.ts +++ b/src/gateway/gateway-cli-backend.live-helpers.ts @@ -1,6 +1,7 @@ import { randomUUID } from "node:crypto"; import fs from "node:fs/promises"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { EventFrame } from "../../packages/gateway-protocol/src/index.js"; import { listCliRuntimeModelBackendBindings, @@ -18,7 +19,6 @@ import { requestDevicePairing, } from "../infra/device-pairing.js"; import { isTruthyEnvValue } from "../infra/env.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { getFreePortBlockWithPermissionFallback } from "../test-utils/ports.js"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js"; import { startGatewayClientWhenEventLoopReady } from "./client-start-readiness.js"; diff --git a/src/gateway/gateway-cli-backend.live-probe-helpers.ts b/src/gateway/gateway-cli-backend.live-probe-helpers.ts index e00ac161fb8..eed337bef6b 100644 --- a/src/gateway/gateway-cli-backend.live-probe-helpers.ts +++ b/src/gateway/gateway-cli-backend.live-probe-helpers.ts @@ -1,8 +1,8 @@ import { randomUUID } from "node:crypto"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { renderCatFacePngBase64 } from "../../test/helpers/live-image-probe.js"; import { isTruthyEnvValue } from "../infra/env.js"; import { parseStrictPositiveInteger } from "../infra/parse-finite-number.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import type { GatewayClient } from "./client.js"; import { shouldRetryCliCronMcpProbeReply, diff --git a/src/gateway/gateway-config-prompts.shared.ts b/src/gateway/gateway-config-prompts.shared.ts index e63c4d8a486..50cc03a4a3a 100644 --- a/src/gateway/gateway-config-prompts.shared.ts +++ b/src/gateway/gateway-config-prompts.shared.ts @@ -1,7 +1,7 @@ import { isIpv6Address, parseCanonicalIpAddress } from "@openclaw/net-policy/ip"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { getTailnetHostname } from "../infra/tailscale.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; export const TAILSCALE_EXPOSURE_OPTIONS = [ { value: "off", label: "Off", hint: "No Tailscale exposure" }, diff --git a/src/gateway/hooks-mapping.ts b/src/gateway/hooks-mapping.ts index 2e1ddafa18a..da7fa6d50c7 100644 --- a/src/gateway/hooks-mapping.ts +++ b/src/gateway/hooks-mapping.ts @@ -1,9 +1,12 @@ import fs from "node:fs"; import path from "node:path"; +import { + normalizeOptionalString, + readStringValue, +} from "@openclaw/normalization-core/string-coerce"; import { resolveConfigPathCandidate } from "../config/paths.js"; import type { HookMappingConfig, HooksConfig } from "../config/types.hooks.js"; import { importFileModule, resolveFunctionModuleExport } from "../hooks/module-loader.js"; -import { normalizeOptionalString, readStringValue } from "../shared/string-coerce.js"; import type { HookMessageChannel } from "./hooks.types.js"; export type HookMappingResolved = { diff --git a/src/gateway/hooks.ts b/src/gateway/hooks.ts index 7e911cc516c..6469210385d 100644 --- a/src/gateway/hooks.ts +++ b/src/gateway/hooks.ts @@ -1,15 +1,15 @@ import { randomUUID } from "node:crypto"; import type { IncomingMessage } from "node:http"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { listAgentIds, resolveDefaultAgentId } from "../agents/agent-scope-config.js"; import { listChannelPlugins } from "../channels/plugins/index.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { readJsonBodyWithLimit, requestBodyErrorToText } from "../infra/http-body.js"; import { normalizeAgentId, parseAgentSessionKey } from "../routing/session-key.js"; import type { HookExternalContentSource } from "../security/external-content.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { normalizeMessageChannel } from "../utils/message-channel-core.js"; import { hasHookTemplateExpressions, diff --git a/src/gateway/http-auth-utils.ts b/src/gateway/http-auth-utils.ts index 76546117c88..c6b68137c81 100644 --- a/src/gateway/http-auth-utils.ts +++ b/src/gateway/http-auth-utils.ts @@ -1,10 +1,10 @@ import type { IncomingMessage, ServerResponse } from "node:http"; -import { getRuntimeConfig } from "../config/io.js"; -import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { getRuntimeConfig } from "../config/io.js"; +import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { AuthRateLimiter } from "./auth-rate-limit.js"; import { authorizeHttpGatewayConnect, diff --git a/src/gateway/http-utils.ts b/src/gateway/http-utils.ts index a723837e6c4..f61ef4147ca 100644 --- a/src/gateway/http-utils.ts +++ b/src/gateway/http-utils.ts @@ -1,15 +1,15 @@ import { randomUUID } from "node:crypto"; import type { IncomingMessage } from "node:http"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveDefaultAgentId } from "../agents/agent-scope.js"; import { modelKey, parseModelRef, resolveDefaultModelForAgent } from "../agents/model-selection.js"; import { createModelVisibilityPolicy } from "../agents/model-visibility-policy.js"; import { getRuntimeConfig } from "../config/io.js"; import { loadManifestMetadataSnapshot } from "../plugins/manifest-contract-eligibility.js"; import { buildAgentMainSessionKey, normalizeAgentId } from "../routing/session-key.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { normalizeMessageChannel } from "../utils/message-channel.js"; import { getHeader } from "./http-auth-utils.js"; import { loadGatewayModelCatalog } from "./server-model-catalog.js"; diff --git a/src/gateway/input-allowlist.ts b/src/gateway/input-allowlist.ts index 11e0d9633d7..f225c8f505e 100644 --- a/src/gateway/input-allowlist.ts +++ b/src/gateway/input-allowlist.ts @@ -1,4 +1,4 @@ -import { normalizeTrimmedStringList } from "../shared/string-normalization.js"; +import { normalizeTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; /** * Normalize optional gateway URL-input hostname allowlists. diff --git a/src/gateway/live-agent-probes.ts b/src/gateway/live-agent-probes.ts index ad63ee94d3d..37ad9d37fac 100644 --- a/src/gateway/live-agent-probes.ts +++ b/src/gateway/live-agent-probes.ts @@ -4,8 +4,8 @@ import { promisify } from "node:util"; import { resolveExpiresAtMsFromDurationSeconds, resolveTimestampMsToIsoString, -} from "../shared/number-coercion.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; const execFileAsync = promisify(execFile); const LIVE_CRON_PROBE_DELAY_SECONDS = 7 * 24 * 60 * 60; diff --git a/src/gateway/live-tool-probe-utils.ts b/src/gateway/live-tool-probe-utils.ts index ed85b86719d..08695900bc8 100644 --- a/src/gateway/live-tool-probe-utils.ts +++ b/src/gateway/live-tool-probe-utils.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export function hasExpectedToolNonce(text: string, nonceA: string, nonceB: string): boolean { return text.includes(nonceA) && text.includes(nonceB); diff --git a/src/gateway/mcp-http.request.ts b/src/gateway/mcp-http.request.ts index d9b3e18cdb1..c8a5f608fd1 100644 --- a/src/gateway/mcp-http.request.ts +++ b/src/gateway/mcp-http.request.ts @@ -1,11 +1,11 @@ import type { IncomingMessage, ServerResponse } from "node:http"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { SourceReplyDeliveryMode } from "../auto-reply/get-reply-options.types.js"; import type { InboundEventKind } from "../channels/inbound-event/kind.js"; import { resolveMainSessionKey } from "../config/sessions.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { isTruthyEnvValue } from "../infra/env.js"; import { safeEqualSecret } from "../security/secret-equal.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { normalizeMessageChannel } from "../utils/message-channel.js"; import { getHeader } from "./http-utils.js"; import { isLoopbackAddress } from "./net.js"; diff --git a/src/gateway/mcp-http.schema.ts b/src/gateway/mcp-http.schema.ts index 4063d26fdbb..d0203258e37 100644 --- a/src/gateway/mcp-http.schema.ts +++ b/src/gateway/mcp-http.schema.ts @@ -1,5 +1,5 @@ +import { uniqueValues } from "@openclaw/normalization-core/string-normalization"; import { logWarn } from "../logger.js"; -import { uniqueValues } from "../shared/string-normalization.js"; import { resolveGatewayScopedTools } from "./tool-resolution.js"; export type McpLoopbackTool = ReturnType["tools"][number]; diff --git a/src/gateway/mcp-http.ts b/src/gateway/mcp-http.ts index 4e982c036ac..43e10c488fb 100644 --- a/src/gateway/mcp-http.ts +++ b/src/gateway/mcp-http.ts @@ -4,11 +4,11 @@ import { type IncomingMessage, type ServerResponse, } from "node:http"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { getRuntimeConfig } from "../config/io.js"; import { isTruthyEnvValue } from "../infra/env.js"; import { formatErrorMessage } from "../infra/errors.js"; import { logDebug, logWarn } from "../logger.js"; -import { isRecord } from "../shared/record-coerce.js"; import { handleMcpJsonRpc } from "./mcp-http.handlers.js"; import { clearActiveMcpLoopbackRuntimeByOwnerToken, diff --git a/src/gateway/method-scopes.ts b/src/gateway/method-scopes.ts index 9e851dad1ef..a7cbc8cb4b0 100644 --- a/src/gateway/method-scopes.ts +++ b/src/gateway/method-scopes.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString as normalizeSessionActionParam } from "@openclaw/normalization-core/string-coerce"; import { getPluginRegistryState } from "../plugins/runtime-state.js"; import { resolveReservedGatewayMethodScope } from "../shared/gateway-method-policy.js"; -import { normalizeOptionalString as normalizeSessionActionParam } from "../shared/string-coerce.js"; import { isCoreGatewayMethodClassified, isCoreNodeGatewayMethod, diff --git a/src/gateway/model-pricing-cache-state.ts b/src/gateway/model-pricing-cache-state.ts index 1911e48b80b..0a684fbe5aa 100644 --- a/src/gateway/model-pricing-cache-state.ts +++ b/src/gateway/model-pricing-cache-state.ts @@ -1,6 +1,6 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { normalizeModelRef } from "../agents/model-selection.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; export type CachedPricingTier = { input: number; diff --git a/src/gateway/model-pricing-cache.ts b/src/gateway/model-pricing-cache.ts index 031afd31a5c..27acbc2b8d5 100644 --- a/src/gateway/model-pricing-cache.ts +++ b/src/gateway/model-pricing-cache.ts @@ -26,7 +26,7 @@ import { } from "../plugins/plugin-metadata-snapshot.js"; import type { PluginMetadataRegistryView } from "../plugins/plugin-metadata-snapshot.types.js"; import type { PluginRegistrySnapshot } from "../plugins/plugin-registry.js"; -import { normalizeOptionalString, resolvePrimaryStringValue } from "../shared/string-coerce.js"; +import { normalizeOptionalString, resolvePrimaryStringValue } from "../../packages/normalization-core/src/string-coerce.js"; import { clearGatewayModelPricingCacheState, clearGatewayModelPricingFailures, diff --git a/src/gateway/net.ts b/src/gateway/net.ts index 7aabe2c0c23..a08277a44b9 100644 --- a/src/gateway/net.ts +++ b/src/gateway/net.ts @@ -7,6 +7,7 @@ import { isPrivateOrLoopbackIpAddress, normalizeIpAddress, } from "@openclaw/net-policy/ip"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { GatewayBindMode } from "../config/types.gateway.js"; import { resetContainerEnvironmentCacheForTest, @@ -19,7 +20,6 @@ import { type NetworkInterfacesSnapshot, } from "../infra/network-interfaces.js"; import { pickPrimaryTailnetIPv4 } from "../infra/tailnet.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; /** * Pick the primary non-internal IPv4 address (LAN IP). diff --git a/src/gateway/node-catalog.ts b/src/gateway/node-catalog.ts index 004f22493fe..cbcc4db1366 100644 --- a/src/gateway/node-catalog.ts +++ b/src/gateway/node-catalog.ts @@ -1,8 +1,8 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { normalizeSortedUniqueTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import { hasEffectivePairedDeviceRole, type PairedDevice } from "../infra/device-pairing.js"; import type { NodePairingPairedNode } from "../infra/node-pairing.js"; import type { NodeListNode } from "../shared/node-list-types.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { normalizeSortedUniqueTrimmedStringList } from "../shared/string-normalization.js"; import type { NodeSession } from "./node-registry.js"; type KnownNodeDevicePairingSource = { diff --git a/src/gateway/node-command-policy.ts b/src/gateway/node-command-policy.ts index 8dadef262a4..5cc2fccc20e 100644 --- a/src/gateway/node-command-policy.ts +++ b/src/gateway/node-command-policy.ts @@ -1,3 +1,5 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { NODE_BROWSER_PROXY_COMMAND, @@ -5,8 +7,6 @@ import { NODE_SYSTEM_RUN_COMMANDS, } from "../infra/node-commands.js"; import { getActiveRuntimePluginRegistry } from "../plugins/active-runtime-registry.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { normalizeUniqueStringEntries } from "../shared/string-normalization.js"; import { normalizeDeviceMetadataForPolicy } from "./device-metadata-normalization.js"; import type { NodeSession } from "./node-registry.js"; diff --git a/src/gateway/node-invoke-plugin-policy.ts b/src/gateway/node-invoke-plugin-policy.ts index 9dfc3bf692a..2f6342ed066 100644 --- a/src/gateway/node-invoke-plugin-policy.ts +++ b/src/gateway/node-invoke-plugin-policy.ts @@ -1,4 +1,5 @@ import { randomUUID } from "node:crypto"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { PluginApprovalRequestPayload } from "../infra/plugin-approvals.js"; import { DEFAULT_PLUGIN_APPROVAL_TIMEOUT_MS } from "../infra/plugin-approvals.js"; import { getActiveRuntimePluginRegistry } from "../plugins/active-runtime-registry.js"; @@ -8,7 +9,6 @@ import type { OpenClawPluginNodeInvokePolicyResult, OpenClawPluginNodeInvokeTransportResult, } from "../plugins/types.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { NodeSession } from "./node-registry.js"; import { resolveApprovalRequestRecipientConnIds } from "./server-methods/approval-shared.js"; import type { GatewayClient, GatewayRequestContext } from "./server-methods/types.js"; diff --git a/src/gateway/node-invoke-system-run-approval.ts b/src/gateway/node-invoke-system-run-approval.ts index 1d8cbea9c6e..509860dc78a 100644 --- a/src/gateway/node-invoke-system-run-approval.ts +++ b/src/gateway/node-invoke-system-run-approval.ts @@ -1,11 +1,11 @@ +import { asNullableRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeNullableString } from "@openclaw/normalization-core/string-coerce"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES, } from "../../packages/gateway-protocol/src/client-info.js"; import { resolveSystemRunApprovalRuntimeContext } from "../infra/system-run-approval-context.js"; import { resolveSystemRunCommandRequest } from "../infra/system-run-command.js"; -import { asNullableRecord } from "../shared/record-coerce.js"; -import { normalizeNullableString } from "../shared/string-coerce.js"; import type { ExecApprovalRecord } from "./exec-approval-manager.js"; import { systemRunApprovalGuardError, diff --git a/src/gateway/node-pending-work.ts b/src/gateway/node-pending-work.ts index d3e2ee02423..6190a579623 100644 --- a/src/gateway/node-pending-work.ts +++ b/src/gateway/node-pending-work.ts @@ -4,7 +4,7 @@ import { isFutureDateTimestampMs, resolveDateTimestampMs, resolveExpiresAtMsFromDurationMs, -} from "../shared/number-coercion.js"; +} from "@openclaw/normalization-core/number-coercion"; const NODE_PENDING_WORK_TYPES = ["status.request", "location.request"] as const; export type NodePendingWorkType = (typeof NODE_PENDING_WORK_TYPES)[number]; diff --git a/src/gateway/node-registry.test.ts b/src/gateway/node-registry.test.ts index 7280292a4d2..5d5119889fe 100644 --- a/src/gateway/node-registry.test.ts +++ b/src/gateway/node-registry.test.ts @@ -1,7 +1,10 @@ import { EventEmitter } from "node:events"; +import { + MAX_DATE_TIMESTAMP_MS, + MAX_TIMER_TIMEOUT_MS, +} from "@openclaw/normalization-core/number-coercion"; import { describe, expect, it, vi } from "vitest"; import { onDiagnosticEvent, resetDiagnosticEventsForTest } from "../infra/diagnostic-events.js"; -import { MAX_DATE_TIMESTAMP_MS, MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { NodeRegistry, serializeEventPayload } from "./node-registry.js"; import { MAX_BUFFERED_BYTES } from "./server-constants.js"; import type { GatewayWsClient } from "./server/ws-types.js"; diff --git a/src/gateway/node-registry.ts b/src/gateway/node-registry.ts index cd64b5d4195..66406d85800 100644 --- a/src/gateway/node-registry.ts +++ b/src/gateway/node-registry.ts @@ -1,11 +1,11 @@ import { randomUUID } from "node:crypto"; -import { logRejectedLargePayload } from "../logging/diagnostic-payload.js"; import { addTimerTimeoutGraceMs, isFutureDateTimestampMs, resolveExpiresAtMsFromDurationMs, resolveTimerTimeoutMs, -} from "../shared/number-coercion.js"; +} from "@openclaw/normalization-core/number-coercion"; +import { logRejectedLargePayload } from "../logging/diagnostic-payload.js"; import { MAX_BUFFERED_BYTES } from "./server-constants.js"; import type { GatewayWsClient } from "./server/ws-types.js"; diff --git a/src/gateway/openai-http.ts b/src/gateway/openai-http.ts index fc978ed5392..12a06bd2242 100644 --- a/src/gateway/openai-http.ts +++ b/src/gateway/openai-http.ts @@ -1,5 +1,10 @@ import { randomUUID } from "node:crypto"; import type { IncomingMessage, ServerResponse } from "node:http"; +import { resolveIntegerOption } from "@openclaw/normalization-core/number-coercion"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { isClientToolNameConflictError } from "../agents/agent-tool-definition-adapter.js"; import type { AgentStreamParams, ClientToolDefinition } from "../agents/command/shared-types.js"; import type { ImageContent } from "../agents/command/types.js"; @@ -28,11 +33,6 @@ import { type InputImageSource, } from "../media/input-files.js"; import { defaultRuntime } from "../runtime.js"; -import { resolveIntegerOption } from "../shared/number-coercion.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { resolveAssistantStreamDeltaText } from "./agent-event-assistant-text.js"; import { buildAgentMessageFromConversationEntries, diff --git a/src/gateway/openresponses-http.ts b/src/gateway/openresponses-http.ts index b2a49098e40..7f08fd38c77 100644 --- a/src/gateway/openresponses-http.ts +++ b/src/gateway/openresponses-http.ts @@ -8,6 +8,7 @@ import { createHash, randomUUID } from "node:crypto"; import type { IncomingMessage, ServerResponse } from "node:http"; +import { resolveIntegerOption } from "@openclaw/normalization-core/number-coercion"; import { isClientToolNameConflictError } from "../agents/agent-tool-definition-adapter.js"; import type { ImageContent } from "../agents/command/types.js"; import type { ClientToolDefinition } from "../agents/embedded-agent-runner/run/params.js"; @@ -32,7 +33,6 @@ import { type InputImageSource, } from "../media/input-files.js"; import { defaultRuntime } from "../runtime.js"; -import { resolveIntegerOption } from "../shared/number-coercion.js"; import { resolveAssistantStreamDeltaText } from "./agent-event-assistant-text.js"; import type { AuthRateLimiter } from "./auth-rate-limit.js"; import type { ResolvedGatewayAuth } from "./auth.js"; diff --git a/src/gateway/origin-check.ts b/src/gateway/origin-check.ts index d09cd7c9f00..6f340551203 100644 --- a/src/gateway/origin-check.ts +++ b/src/gateway/origin-check.ts @@ -3,7 +3,7 @@ import { isPrivateOrLoopbackIpAddress } from "@openclaw/net-policy/ip"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; import { isLoopbackHost, normalizeHostHeader, resolveHostName } from "./net.js"; type OriginCheckResult = diff --git a/src/gateway/plugin-channel-reload-targets.ts b/src/gateway/plugin-channel-reload-targets.ts index 4bad088f674..dcd63b55b46 100644 --- a/src/gateway/plugin-channel-reload-targets.ts +++ b/src/gateway/plugin-channel-reload-targets.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { ChannelId } from "../channels/plugins/index.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; export type ChannelPluginReloadTarget = { channelId: ChannelId; diff --git a/src/gateway/plugin-node-capability.ts b/src/gateway/plugin-node-capability.ts index ce3e829c98c..138d64b9ec8 100644 --- a/src/gateway/plugin-node-capability.ts +++ b/src/gateway/plugin-node-capability.ts @@ -1,11 +1,11 @@ import { randomBytes } from "node:crypto"; -import { safeEqualSecret } from "../security/secret-equal.js"; import { asDateTimestampMs, asPositiveSafeInteger, isFutureDateTimestampMs, resolveExpiresAtMsFromDurationMs, -} from "../shared/number-coercion.js"; +} from "@openclaw/normalization-core/number-coercion"; +import { safeEqualSecret } from "../security/secret-equal.js"; export const PLUGIN_NODE_CAPABILITY_PATH_PREFIX = "/__openclaw__/cap"; const PLUGIN_NODE_CAPABILITY_QUERY_PARAM = "oc_cap"; diff --git a/src/gateway/probe-auth.ts b/src/gateway/probe-auth.ts index d984319342c..e24934d3f2f 100644 --- a/src/gateway/probe-auth.ts +++ b/src/gateway/probe-auth.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resolveGatewayCredentialsWithSecretInputs } from "./credentials-secret-inputs.js"; import { type ExplicitGatewayAuth, diff --git a/src/gateway/probe-target.ts b/src/gateway/probe-target.ts index b8f4e62ef36..b48a133c434 100644 --- a/src/gateway/probe-target.ts +++ b/src/gateway/probe-target.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; export type GatewayProbeTargetResolution = { gatewayMode: "local" | "remote"; diff --git a/src/gateway/resolve-configured-secret-input-string.ts b/src/gateway/resolve-configured-secret-input-string.ts index 59ae8632799..089a2c40ad4 100644 --- a/src/gateway/resolve-configured-secret-input-string.ts +++ b/src/gateway/resolve-configured-secret-input-string.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { resolveSecretInputRef } from "../config/types.secrets.js"; import type { PluginManifestRegistry } from "../plugins/manifest-registry.js"; import { secretRefKey } from "../secrets/ref-contract.js"; import { resolveSecretRefValues } from "../secrets/resolve.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; export type SecretInputUnresolvedReasonStyle = "generic" | "detailed"; // pragma: allowlist secret type ConfiguredSecretInputSource = diff --git a/src/gateway/security-path.ts b/src/gateway/security-path.ts index 133a3fac7bb..6c51f3258f5 100644 --- a/src/gateway/security-path.ts +++ b/src/gateway/security-path.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; type SecurityPathCanonicalization = { canonicalPath: string; diff --git a/src/gateway/server-close.ts b/src/gateway/server-close.ts index 0d82296c0e1..c4fb7dcb2d2 100644 --- a/src/gateway/server-close.ts +++ b/src/gateway/server-close.ts @@ -1,4 +1,5 @@ import type { Server as HttpServer } from "node:http"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { WebSocketServer } from "ws"; import { disposeAllSessionMcpRuntimes } from "../agents/agent-bundle-mcp-tools.js"; import { disposeRegisteredAgentHarnesses } from "../agents/harness/registry.js"; @@ -8,7 +9,6 @@ import type { HeartbeatRunner } from "../infra/heartbeat-runner.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { closePluginStateSqliteStore } from "../plugin-state/plugin-state-store.js"; import type { PluginServicesHandle } from "../plugins/services.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { abortChatRunById, type ChatAbortControllerEntry } from "./chat-abort.js"; import { collectGatewayProcessMemoryUsageMb, diff --git a/src/gateway/server-cron-notifications.ts b/src/gateway/server-cron-notifications.ts index adc5409b3db..994251ca61c 100644 --- a/src/gateway/server-cron-notifications.ts +++ b/src/gateway/server-cron-notifications.ts @@ -1,3 +1,7 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { CliDeps } from "../cli/deps.types.js"; import type { CronFailureDestinationConfig } from "../config/types.cron.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; @@ -14,10 +18,6 @@ import { normalizeHttpWebhookUrl } from "../cron/webhook-url.js"; import { formatErrorMessage } from "../infra/errors.js"; import { fetchWithSsrFGuard } from "../infra/net/fetch-guard.js"; import { SsrFBlockedError } from "../infra/net/ssrf.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; const CRON_WEBHOOK_TIMEOUT_MS = 10_000; diff --git a/src/gateway/server-json.ts b/src/gateway/server-json.ts index 7a83633cb9c..44d153a57b7 100644 --- a/src/gateway/server-json.ts +++ b/src/gateway/server-json.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export function safeParseJson(value: string | null | undefined): unknown { const trimmed = normalizeOptionalString(value); diff --git a/src/gateway/server-maintenance.ts b/src/gateway/server-maintenance.ts index 9a68c38adf1..90823ef9dc2 100644 --- a/src/gateway/server-maintenance.ts +++ b/src/gateway/server-maintenance.ts @@ -1,7 +1,7 @@ +import { isFutureDateTimestampMs } from "@openclaw/normalization-core/number-coercion"; import type { HealthSummary } from "../commands/health.js"; import { sweepStaleRunContexts } from "../infra/agent-events.js"; import { cleanOldMedia } from "../media/store.js"; -import { isFutureDateTimestampMs } from "../shared/number-coercion.js"; import { abortChatRunById, type ChatAbortControllerEntry } from "./chat-abort.js"; import { pruneStaleControlPlaneBuckets } from "./control-plane-rate-limit.js"; import type { ChatRunState } from "./server-chat-state.js"; diff --git a/src/gateway/server-methods/agent-wait-dedupe.ts b/src/gateway/server-methods/agent-wait-dedupe.ts index e454c8f1d25..e9f5c4c76d6 100644 --- a/src/gateway/server-methods/agent-wait-dedupe.ts +++ b/src/gateway/server-methods/agent-wait-dedupe.ts @@ -1,3 +1,5 @@ +import { asFiniteNumber } from "@openclaw/normalization-core/number-coercion"; +import { asOptionalRecord } from "@openclaw/normalization-core/record-coerce"; import { buildAgentRunTerminalOutcome, isStickyAgentRunTerminalOutcome, @@ -6,8 +8,6 @@ import { } from "../../agents/agent-run-terminal-outcome.js"; import { normalizeBlockedLivenessWaitStatus } from "../../shared/agent-liveness.js"; import { isNonTerminalAgentRunStatus } from "../../shared/agent-run-status.js"; -import { asFiniteNumber } from "../../shared/number-coercion.js"; -import { asOptionalRecord } from "../../shared/record-coerce.js"; import { setSafeTimeout } from "../../utils/timer-delay.js"; import type { DedupeEntry } from "../server-shared.js"; diff --git a/src/gateway/server-methods/agent.ts b/src/gateway/server-methods/agent.ts index 47b1052a726..38d42d51e27 100644 --- a/src/gateway/server-methods/agent.ts +++ b/src/gateway/server-methods/agent.ts @@ -1,5 +1,13 @@ import { randomUUID } from "node:crypto"; import { existsSync } from "node:fs"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { + normalizeStringEntries, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { GATEWAY_CLIENT_CAPS, GATEWAY_CLIENT_MODES, @@ -101,11 +109,6 @@ import { parseRawSessionConversationRef, parseThreadSessionSuffix, } from "../../sessions/session-key-utils.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; -import { normalizeStringEntries, uniqueStrings } from "../../shared/string-normalization.js"; import { createRunningTaskRun, finalizeTaskRunByRunId } from "../../tasks/detached-task-runtime.js"; import type { TaskStatus } from "../../tasks/task-registry.types.js"; import { diff --git a/src/gateway/server-methods/agents.ts b/src/gateway/server-methods/agents.ts index 9b4384374c9..c6ca0fa7d0b 100644 --- a/src/gateway/server-methods/agents.ts +++ b/src/gateway/server-methods/agents.ts @@ -1,5 +1,6 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { normalizeOptionalString as resolveOptionalStringParam } from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, @@ -42,7 +43,6 @@ import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { root, FsSafeError, type ReadResult } from "../../infra/fs-safe.js"; import { movePathToTrash } from "../../plugin-sdk/browser-maintenance.js"; import { DEFAULT_AGENT_ID, normalizeAgentId } from "../../routing/session-key.js"; -import { normalizeOptionalString as resolveOptionalStringParam } from "../../shared/string-coerce.js"; import { resolveUserPath } from "../../utils.js"; import { listAgentsForGateway } from "../session-utils.js"; import { diff --git a/src/gateway/server-methods/approval-shared.ts b/src/gateway/server-methods/approval-shared.ts index a1ee5fd6b08..cd27691bde9 100644 --- a/src/gateway/server-methods/approval-shared.ts +++ b/src/gateway/server-methods/approval-shared.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, @@ -6,7 +7,6 @@ import { import type { ValidationError } from "../../../packages/gateway-protocol/src/index.js"; import { hasApprovalTurnSourceRoute } from "../../infra/approval-turn-source.js"; import type { ExecApprovalDecision } from "../../infra/exec-approvals.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { ExecApprovalIdLookupResult, ExecApprovalManager, diff --git a/src/gateway/server-methods/artifacts.ts b/src/gateway/server-methods/artifacts.ts index ecb739b5c7c..61b475c61e4 100644 --- a/src/gateway/server-methods/artifacts.ts +++ b/src/gateway/server-methods/artifacts.ts @@ -1,4 +1,6 @@ import { createHash } from "node:crypto"; +import { asOptionalRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString as asNonEmptyString } from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, @@ -16,8 +18,6 @@ import { resolveAgentIdFromSessionKey, toAgentStoreSessionKey, } from "../../routing/session-key.js"; -import { asOptionalRecord } from "../../shared/record-coerce.js"; -import { normalizeOptionalString as asNonEmptyString } from "../../shared/string-coerce.js"; import { getTaskSessionLookupByIdForStatus } from "../../tasks/task-status-access.js"; import { resolveSessionKeyForRun } from "../server-session-key.js"; import { diff --git a/src/gateway/server-methods/channels.ts b/src/gateway/server-methods/channels.ts index 608411f4f0d..646db75f86f 100644 --- a/src/gateway/server-methods/channels.ts +++ b/src/gateway/server-methods/channels.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, @@ -23,7 +24,6 @@ import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { getChannelActivity } from "../../infra/channel-activity.js"; import { DEFAULT_ACCOUNT_ID } from "../../routing/session-key.js"; import { defaultRuntime } from "../../runtime.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { runTasksWithConcurrency } from "../../utils/run-with-concurrency.js"; import { DEFAULT_CHANNEL_CONNECT_GRACE_MS, diff --git a/src/gateway/server-methods/chat-webchat-media.ts b/src/gateway/server-methods/chat-webchat-media.ts index 33bc373bfd6..ca98cbd8bef 100644 --- a/src/gateway/server-methods/chat-webchat-media.ts +++ b/src/gateway/server-methods/chat-webchat-media.ts @@ -1,4 +1,5 @@ import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { ReplyPayload } from "../../auto-reply/reply-payload.js"; import { openLocalFileSafely } from "../../infra/fs-safe.js"; import { assertNoWindowsNetworkPath, safeFileURLToPath } from "../../infra/local-file-access.js"; @@ -6,7 +7,6 @@ import { estimateBase64DecodedBytes } from "../../media/base64.js"; import { assertLocalMediaAllowed, LocalMediaAccessError } from "../../media/local-media-access.js"; import { isAudioFileName } from "../../media/mime.js"; import { resolveSendableOutboundReplyParts } from "../../plugin-sdk/reply-payload.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { sanitizeReplyDirectiveId } from "../../utils/directive-tags.js"; import { isSuppressedControlReplyText } from "../control-reply-text.js"; diff --git a/src/gateway/server-methods/chat.ts b/src/gateway/server-methods/chat.ts index 3ef48ea5afe..e441e257ec0 100644 --- a/src/gateway/server-methods/chat.ts +++ b/src/gateway/server-methods/chat.ts @@ -1,6 +1,8 @@ import { createHash } from "node:crypto"; import fs from "node:fs"; import path from "node:path"; +import { asOptionalRecord } from "@openclaw/normalization-core/record-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { buildTtsSupplementMediaPayload, getReplyPayloadTtsSupplement, @@ -82,8 +84,6 @@ import { type UserTurnInput, type UserTurnTranscriptRecorder, } from "../../sessions/user-turn-transcript.js"; -import { asOptionalRecord } from "../../shared/record-coerce.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; import { deliveryContextFromSession } from "../../utils/delivery-context.shared.js"; import { stripInlineDirectiveTagsForDisplay, diff --git a/src/gateway/server-methods/commands.ts b/src/gateway/server-methods/commands.ts index fdb4f90ba3a..15fbb8027e3 100644 --- a/src/gateway/server-methods/commands.ts +++ b/src/gateway/server-methods/commands.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { CommandEntry, CommandsListResult, @@ -31,7 +32,6 @@ import { getChannelPlugin } from "../../channels/plugins/index.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { getPluginCommandSpecs } from "../../plugins/command-specs.js"; import { listPluginCommands } from "../../plugins/commands.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { listSkillCommandsForAgents } from "../../skills/discovery/chat-commands.js"; import type { GatewayRequestHandlers, RespondFn } from "./types.js"; diff --git a/src/gateway/server-methods/config.ts b/src/gateway/server-methods/config.ts index c55409ef903..d765ca2d1cd 100644 --- a/src/gateway/server-methods/config.ts +++ b/src/gateway/server-methods/config.ts @@ -1,4 +1,10 @@ import { execFile } from "node:child_process"; +import { + asDateTimestampMs, + resolveExpiresAtMsFromDurationMs, +} from "@openclaw/normalization-core/number-coercion"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { ErrorCodes, errorShape, @@ -37,12 +43,6 @@ import { prepareSecretsRuntimeSnapshot, type PreparedSecretsRuntimeSnapshot, } from "../../secrets/runtime.js"; -import { - asDateTimestampMs, - resolveExpiresAtMsFromDurationMs, -} from "../../shared/number-coercion.js"; -import { isRecord } from "../../shared/record-coerce.js"; -import { normalizeStringEntries } from "../../shared/string-normalization.js"; import { diffConfigPaths } from "../config-diff.js"; import { resolveConfigReloadMetadata } from "../config-reload-plan.js"; import { diff --git a/src/gateway/server-methods/environments.ts b/src/gateway/server-methods/environments.ts index 78fde85becb..1be468f87ab 100644 --- a/src/gateway/server-methods/environments.ts +++ b/src/gateway/server-methods/environments.ts @@ -1,3 +1,4 @@ +import { normalizeSortedUniqueTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import { type EnvironmentSummary, ErrorCodes, @@ -8,7 +9,6 @@ import { import { listDevicePairing } from "../../infra/device-pairing.js"; import { listNodePairing } from "../../infra/node-pairing.js"; import type { NodeListNode } from "../../shared/node-list-types.js"; -import { normalizeSortedUniqueTrimmedStringList } from "../../shared/string-normalization.js"; import { createKnownNodeCatalog, listKnownNodes } from "../node-catalog.js"; import { respondInvalidParams, respondUnavailableOnThrow } from "./nodes.helpers.js"; import type { GatewayRequestContext, GatewayRequestHandlers } from "./types.js"; diff --git a/src/gateway/server-methods/exec-approval.ts b/src/gateway/server-methods/exec-approval.ts index ddcdbad19a5..d0f4f24478b 100644 --- a/src/gateway/server-methods/exec-approval.ts +++ b/src/gateway/server-methods/exec-approval.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { GATEWAY_CLIENT_IDS } from "../../../packages/gateway-protocol/src/client-info.js"; import { ErrorCodes, @@ -28,7 +29,6 @@ import { buildSystemRunApprovalEnvBinding, } from "../../infra/system-run-approval-binding.js"; import { resolveSystemRunApprovalRequestContext } from "../../infra/system-run-approval-context.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { ExecApprovalManager } from "../exec-approval-manager.js"; import { handleApprovalWaitDecision, diff --git a/src/gateway/server-methods/nodes.helpers.ts b/src/gateway/server-methods/nodes.helpers.ts index 39c0a9c5d37..ade7d0d728f 100644 --- a/src/gateway/server-methods/nodes.helpers.ts +++ b/src/gateway/server-methods/nodes.helpers.ts @@ -1,10 +1,10 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, formatValidationErrors, } from "../../../packages/gateway-protocol/src/index.js"; import type { ValidationError } from "../../../packages/gateway-protocol/src/index.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; export { safeParseJson } from "../server-json.js"; import { formatForLog } from "../ws-log.js"; import type { RespondFn } from "./types.js"; diff --git a/src/gateway/server-methods/nodes.invoke-wake.test.ts b/src/gateway/server-methods/nodes.invoke-wake.test.ts index cdc0163d28b..0d3f7a7010d 100644 --- a/src/gateway/server-methods/nodes.invoke-wake.test.ts +++ b/src/gateway/server-methods/nodes.invoke-wake.test.ts @@ -1,6 +1,6 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { ErrorCodes } from "../../../packages/gateway-protocol/src/index.js"; -import { MAX_TIMER_TIMEOUT_MS } from "../../shared/number-coercion.js"; import { clearNodeWakeState, maybeSendNodeWakeNudge, diff --git a/src/gateway/server-methods/nodes.ts b/src/gateway/server-methods/nodes.ts index e7c76b2a2f5..46065103c84 100644 --- a/src/gateway/server-methods/nodes.ts +++ b/src/gateway/server-methods/nodes.ts @@ -1,4 +1,10 @@ import { randomUUID } from "node:crypto"; +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeUniqueTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import { type ConnectParams, ErrorCodes, @@ -38,12 +44,6 @@ import { resolveApnsAuthConfigFromEnv, resolveApnsRelayConfigFromEnv, } from "../../infra/push-apns.js"; -import { resolveTimerTimeoutMs } from "../../shared/number-coercion.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; -import { normalizeUniqueTrimmedStringList } from "../../shared/string-normalization.js"; import { recordRemoteNodeInfo, refreshRemoteNodeBins, diff --git a/src/gateway/server-methods/plugin-approval.ts b/src/gateway/server-methods/plugin-approval.ts index 17dfeb567a6..29fde8eb8e4 100644 --- a/src/gateway/server-methods/plugin-approval.ts +++ b/src/gateway/server-methods/plugin-approval.ts @@ -1,4 +1,5 @@ import { randomUUID } from "node:crypto"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, @@ -13,7 +14,6 @@ import { MAX_PLUGIN_APPROVAL_TIMEOUT_MS, resolvePluginApprovalRequestAllowedDecisions, } from "../../infra/plugin-approvals.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { ExecApprovalManager } from "../exec-approval-manager.js"; import { bindApprovalRequesterMetadata, diff --git a/src/gateway/server-methods/plugin-host-hooks.ts b/src/gateway/server-methods/plugin-host-hooks.ts index 8b85e973273..21ec85ba63b 100644 --- a/src/gateway/server-methods/plugin-host-hooks.ts +++ b/src/gateway/server-methods/plugin-host-hooks.ts @@ -1,3 +1,5 @@ +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, @@ -15,8 +17,6 @@ import { type JsonSchemaValidationError, type JsonSchemaValue, } from "../../plugins/schema-validator.js"; -import { isRecord } from "../../shared/record-coerce.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { ADMIN_SCOPE, READ_SCOPE, WRITE_SCOPE } from "../operator-scopes.js"; import type { GatewayRequestHandlers } from "./types.js"; diff --git a/src/gateway/server-methods/push.ts b/src/gateway/server-methods/push.ts index bbd78d4a71c..74be95a402e 100644 --- a/src/gateway/server-methods/push.ts +++ b/src/gateway/server-methods/push.ts @@ -1,3 +1,4 @@ +import { normalizeStringifiedOptionalString } from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, @@ -22,7 +23,6 @@ import { registerWebPushSubscription, resolveVapidKeys, } from "../../infra/push-web.js"; -import { normalizeStringifiedOptionalString } from "../../shared/string-coerce.js"; import { respondInvalidParams, respondUnavailableOnThrow } from "./nodes.helpers.js"; import { normalizeTrimmedString } from "./record-shared.js"; import type { GatewayRequestHandlers } from "./types.js"; diff --git a/src/gateway/server-methods/record-shared.ts b/src/gateway/server-methods/record-shared.ts index 04438017a34..a948b9e8531 100644 --- a/src/gateway/server-methods/record-shared.ts +++ b/src/gateway/server-methods/record-shared.ts @@ -1,4 +1,4 @@ -export { asOptionalRecord as asRecord } from "../../shared/record-coerce.js"; +export { asOptionalRecord as asRecord } from "../../../packages/normalization-core/src/record-coerce.js"; export function normalizeTrimmedString(value: unknown): string | undefined { if (typeof value !== "string") { diff --git a/src/gateway/server-methods/restart-request.ts b/src/gateway/server-methods/restart-request.ts index 7b9af5709c5..713723bb85e 100644 --- a/src/gateway/server-methods/restart-request.ts +++ b/src/gateway/server-methods/restart-request.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { stringifyRouteThreadId } from "../../plugin-sdk/channel-route.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; type RestartDeliveryContext = { channel?: string; diff --git a/src/gateway/server-methods/send.ts b/src/gateway/server-methods/send.ts index 94d2a61de42..b858e4aefcf 100644 --- a/src/gateway/server-methods/send.ts +++ b/src/gateway/server-methods/send.ts @@ -1,3 +1,8 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, + readStringValue, +} from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, @@ -38,11 +43,6 @@ import { normalizeSessionKeyPreservingOpaquePeerIds, parseThreadSessionSuffix, } from "../../sessions/session-key-utils.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, - readStringValue, -} from "../../shared/string-coerce.js"; import { ADMIN_SCOPE } from "../operator-scopes.js"; import { resolveGatewayPluginConfig } from "../runtime-plugin-config.js"; import { formatForLog } from "../ws-log.js"; diff --git a/src/gateway/server-methods/server-methods.test.ts b/src/gateway/server-methods/server-methods.test.ts index 6a67aaacc71..5c81098fa31 100644 --- a/src/gateway/server-methods/server-methods.test.ts +++ b/src/gateway/server-methods/server-methods.test.ts @@ -4,6 +4,7 @@ import fsPromises from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { fileURLToPath } from "node:url"; +import { asOptionalRecord } from "@openclaw/normalization-core/record-coerce"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { validateExecApprovalRequestParams } from "../../../packages/gateway-protocol/src/index.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; @@ -21,7 +22,6 @@ import { buildSystemRunApprovalEnvBinding, } from "../../infra/system-run-approval-binding.js"; import { resetLogger, setLoggerOverride } from "../../logging.js"; -import { asOptionalRecord } from "../../shared/record-coerce.js"; import { projectRecentChatDisplayMessages } from "../chat-display-projection.js"; import { ExecApprovalManager } from "../exec-approval-manager.js"; import { waitForAgentJob } from "./agent-job.js"; diff --git a/src/gateway/server-methods/sessions.ts b/src/gateway/server-methods/sessions.ts index 8a8df78ea2e..f4a9317d2d2 100644 --- a/src/gateway/server-methods/sessions.ts +++ b/src/gateway/server-methods/sessions.ts @@ -1,6 +1,11 @@ import { randomUUID } from "node:crypto"; import fs from "node:fs"; import path from "node:path"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, + readStringValue, +} from "@openclaw/normalization-core/string-coerce"; import { GATEWAY_CLIENT_IDS } from "../../../packages/gateway-protocol/src/client-info.js"; import { ErrorCodes, @@ -72,11 +77,6 @@ import { resolveAgentIdFromSessionKey, toAgentStoreSessionKey, } from "../../routing/session-key.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, - readStringValue, -} from "../../shared/string-coerce.js"; import { ADMIN_SCOPE } from "../operator-scopes.js"; import { resolveSessionKeyForRun } from "../server-session-key.js"; import { diff --git a/src/gateway/server-methods/skills.ts b/src/gateway/server-methods/skills.ts index 4fef95dc7ff..ec4f40504f1 100644 --- a/src/gateway/server-methods/skills.ts +++ b/src/gateway/server-methods/skills.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, @@ -27,7 +28,6 @@ import { redactConfigObject } from "../../config/redact-snapshot.js"; import { fetchClawHubSkillDetail } from "../../infra/clawhub.js"; import { formatErrorMessage } from "../../infra/errors.js"; import { normalizeAgentId } from "../../routing/session-key.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { updateSkillConfigEntry } from "../../skills/config/mutations.js"; import { collectSkillBins } from "../../skills/discovery/bins.js"; import { buildWorkspaceSkillStatus } from "../../skills/discovery/status.js"; diff --git a/src/gateway/server-methods/system.ts b/src/gateway/server-methods/system.ts index f3793937d31..3c87ba4f482 100644 --- a/src/gateway/server-methods/system.ts +++ b/src/gateway/server-methods/system.ts @@ -1,3 +1,8 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, + readStringValue, +} from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape } from "../../../packages/gateway-protocol/src/index.js"; import { resolveMainSessionKeyFromConfig } from "../../config/sessions.js"; import { @@ -8,11 +13,6 @@ import { getLastHeartbeatEvent } from "../../infra/heartbeat-events.js"; import { setHeartbeatsEnabled } from "../../infra/heartbeat-runner.js"; import { enqueueSystemEvent, isSystemEventContextChanged } from "../../infra/system-events.js"; import { listSystemPresence, updateSystemPresence } from "../../infra/system-presence.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, - readStringValue, -} from "../../shared/string-coerce.js"; import { broadcastPresenceSnapshot } from "../server/presence-events.js"; import type { GatewayRequestHandlers } from "./types.js"; diff --git a/src/gateway/server-methods/talk-client.ts b/src/gateway/server-methods/talk-client.ts index 06abb72c9b2..1a476dd6fc4 100644 --- a/src/gateway/server-methods/talk-client.ts +++ b/src/gateway/server-methods/talk-client.ts @@ -1,3 +1,7 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, @@ -6,10 +10,6 @@ import { validateTalkClientSteerParams, validateTalkClientToolCallParams, } from "../../../packages/gateway-protocol/src/index.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { REALTIME_VOICE_AGENT_CONSULT_TOOL, REALTIME_VOICE_AGENT_CONSULT_TOOL_NAME, diff --git a/src/gateway/server-methods/talk-session.ts b/src/gateway/server-methods/talk-session.ts index 8c857275607..ea8d3d7b0b8 100644 --- a/src/gateway/server-methods/talk-session.ts +++ b/src/gateway/server-methods/talk-session.ts @@ -1,3 +1,7 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, @@ -12,10 +16,6 @@ import { validateTalkSessionSubmitToolResultParams, validateTalkSessionTurnParams, } from "../../../packages/gateway-protocol/src/index.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { REALTIME_VOICE_AGENT_CONSULT_TOOL } from "../../talk/agent-consult-tool.js"; import { REALTIME_VOICE_AGENT_CONTROL_TOOL } from "../../talk/agent-run-control-shared.js"; import { controlRealtimeVoiceAgentRun } from "../../talk/agent-run-control.js"; diff --git a/src/gateway/server-methods/talk-shared.ts b/src/gateway/server-methods/talk-shared.ts index fb70f3bbdc3..2209615509b 100644 --- a/src/gateway/server-methods/talk-shared.ts +++ b/src/gateway/server-methods/talk-shared.ts @@ -1,3 +1,8 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes } from "../../../packages/gateway-protocol/src/index.js"; import { getVoiceProviderConfig, @@ -8,11 +13,6 @@ import { import type { OpenClawConfig } from "../../config/types.js"; import { listRealtimeTranscriptionProviders } from "../../realtime-transcription/provider-registry.js"; import type { RealtimeTranscriptionProviderConfig } from "../../realtime-transcription/provider-types.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { REALTIME_VOICE_AGENT_CONSULT_TOOL_NAME } from "../../talk/agent-consult-tool.js"; import { REALTIME_VOICE_AGENT_CONTROL_TOOL_NAME } from "../../talk/agent-run-control-shared.js"; import { listRealtimeVoiceProviders } from "../../talk/provider-registry.js"; diff --git a/src/gateway/server-methods/talk.ts b/src/gateway/server-methods/talk.ts index 14cbbe520e7..504e594701b 100644 --- a/src/gateway/server-methods/talk.ts +++ b/src/gateway/server-methods/talk.ts @@ -1,3 +1,8 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, @@ -22,11 +27,6 @@ import { import type { TalkConfigResponse, TalkProviderConfig } from "../../config/types.gateway.js"; import type { OpenClawConfig, TtsConfig, TtsProviderConfigMap } from "../../config/types.js"; import { listRealtimeTranscriptionProviders } from "../../realtime-transcription/provider-registry.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { canonicalizeRealtimeVoiceProviderId, listRealtimeVoiceProviders, diff --git a/src/gateway/server-methods/tasks.ts b/src/gateway/server-methods/tasks.ts index ca8e393bf21..943dc837b6d 100644 --- a/src/gateway/server-methods/tasks.ts +++ b/src/gateway/server-methods/tasks.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, @@ -9,7 +10,6 @@ import { validateTasksListParams, } from "../../../packages/gateway-protocol/src/index.js"; import { parseAgentSessionKey } from "../../routing/session-key.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { cancelDetachedTaskRunById } from "../../tasks/detached-task-runtime.js"; import { getTaskById, listTaskRecords } from "../../tasks/runtime-internal.js"; import type { TaskRecord, TaskStatus } from "../../tasks/task-registry.types.js"; diff --git a/src/gateway/server-methods/tools-catalog.ts b/src/gateway/server-methods/tools-catalog.ts index df4ccfa1990..c2ca3233f74 100644 --- a/src/gateway/server-methods/tools-catalog.ts +++ b/src/gateway/server-methods/tools-catalog.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, @@ -25,7 +26,6 @@ import { getPluginToolMeta, resolvePluginTools, } from "../../plugins/tools.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { GatewayRequestHandlers, RespondFn } from "./types.js"; type ToolCatalogEntry = { diff --git a/src/gateway/server-methods/tools-effective.ts b/src/gateway/server-methods/tools-effective.ts index 587b92cc598..f1bc57a3bcd 100644 --- a/src/gateway/server-methods/tools-effective.ts +++ b/src/gateway/server-methods/tools-effective.ts @@ -1,21 +1,19 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, formatValidationErrors, validateToolsEffectiveParams, } from "../../../packages/gateway-protocol/src/index.js"; -import { - buildEffectiveToolInventoryGroups, -} from "../../agents/tools-effective-inventory-groups.js"; -import { buildRuntimeCompatibleMcpToolInventory } from "../../agents/tools-effective-mcp-inventory.js"; +import { buildEffectiveToolInventoryGroups } from "../../agents/tools-effective-inventory-groups.js"; import type { EffectiveToolInventoryNotice, EffectiveToolInventoryResult, } from "../../agents/tools-effective-inventory.types.js"; +import { buildRuntimeCompatibleMcpToolInventory } from "../../agents/tools-effective-mcp-inventory.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { logDebug, logWarn } from "../../logger.js"; import { stringifyRouteThreadId } from "../../plugin-sdk/channel-route.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { applyFinalEffectiveToolPolicy, buildBundleMcpToolsFromCatalog, diff --git a/src/gateway/server-methods/tools-invoke.ts b/src/gateway/server-methods/tools-invoke.ts index f30019f4d77..a02614ac044 100644 --- a/src/gateway/server-methods/tools-invoke.ts +++ b/src/gateway/server-methods/tools-invoke.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, @@ -5,7 +6,6 @@ import { validateToolsInvokeParams, type ToolsInvokeResult, } from "../../../packages/gateway-protocol/src/index.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { invokeGatewayTool } from "../tools-invoke-shared.js"; import type { GatewayRequestHandlers } from "./types.js"; diff --git a/src/gateway/server-methods/tts.ts b/src/gateway/server-methods/tts.ts index 9418eaa272f..63a5571e017 100644 --- a/src/gateway/server-methods/tts.ts +++ b/src/gateway/server-methods/tts.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape } from "../../../packages/gateway-protocol/src/index.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { canonicalizeSpeechProviderId, getSpeechProvider, diff --git a/src/gateway/server-methods/usage.ts b/src/gateway/server-methods/usage.ts index e3fcb81f30e..bed1d7a7357 100644 --- a/src/gateway/server-methods/usage.ts +++ b/src/gateway/server-methods/usage.ts @@ -1,4 +1,5 @@ import fs from "node:fs"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, @@ -33,7 +34,6 @@ import { } from "../../infra/session-cost-usage.js"; import { normalizeAgentId, parseAgentSessionKey } from "../../routing/session-key.js"; import { resolvePreferredSessionKeyForSessionIdMatches } from "../../sessions/session-id-resolution.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { buildUsageAggregateTail, mergeUsageDailyLatency, diff --git a/src/gateway/server-methods/wizard.ts b/src/gateway/server-methods/wizard.ts index 708e82ee927..d8017eb7117 100644 --- a/src/gateway/server-methods/wizard.ts +++ b/src/gateway/server-methods/wizard.ts @@ -1,4 +1,5 @@ import { randomUUID } from "node:crypto"; +import { readStringValue } from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, errorShape, @@ -8,7 +9,6 @@ import { validateWizardStatusParams, } from "../../../packages/gateway-protocol/src/index.js"; import { defaultRuntime } from "../../runtime.js"; -import { readStringValue } from "../../shared/string-coerce.js"; import { WizardSession } from "../../wizard/session.js"; import { formatForLog } from "../ws-log.js"; import type { GatewayRequestContext, GatewayRequestHandlers, RespondFn } from "./types.js"; diff --git a/src/gateway/server-node-events.ts b/src/gateway/server-node-events.ts index 7c4aa3290d9..db93f7fc3d9 100644 --- a/src/gateway/server-node-events.ts +++ b/src/gateway/server-node-events.ts @@ -1,4 +1,8 @@ import { randomUUID } from "node:crypto"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { updatePairedDeviceMetadata } from "../infra/device-pairing.js"; import { formatErrorMessage } from "../infra/errors.js"; @@ -13,10 +17,6 @@ import { NODE_PRESENCE_ALIVE_EVENT, normalizeNodePresenceAliveReason, } from "../shared/node-presence.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import type { NodeEvent, NodeEventContext } from "./server-node-events-types.js"; import { agentCommandFromIngress, diff --git a/src/gateway/server-plugins.ts b/src/gateway/server-plugins.ts index 6f304d7c55f..4918b481cbf 100644 --- a/src/gateway/server-plugins.ts +++ b/src/gateway/server-plugins.ts @@ -1,5 +1,6 @@ import { randomUUID } from "node:crypto"; import { performance } from "node:perf_hooks"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { GATEWAY_CLIENT_IDS, GATEWAY_CLIENT_MODES, @@ -21,7 +22,6 @@ import { createPluginRuntimeLoaderLogger } from "../plugins/runtime/load-context import type { PluginRuntime } from "../plugins/runtime/types.js"; import type { PluginLogger } from "../plugins/types.js"; import { resolveGlobalSingleton } from "../shared/global-singleton.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { resolveSafeTimeoutDelayMs } from "../utils/timer-delay.js"; import { ADMIN_SCOPE, APPROVALS_SCOPE, WRITE_SCOPE } from "./method-scopes.js"; import type { diff --git a/src/gateway/server-session-events.ts b/src/gateway/server-session-events.ts index e260f47497a..d3c7268f4f3 100644 --- a/src/gateway/server-session-events.ts +++ b/src/gateway/server-session-events.ts @@ -1,10 +1,10 @@ +import { asPositiveSafeInteger } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveDefaultAgentId } from "../agents/agent-scope.js"; import { getRuntimeConfig } from "../config/io.js"; import { normalizeAgentId } from "../routing/session-key.js"; import type { SessionLifecycleEvent } from "../sessions/session-lifecycle-events.js"; import type { SessionTranscriptUpdate } from "../sessions/transcript-events.js"; -import { asPositiveSafeInteger } from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { projectChatDisplayMessage } from "./chat-display-projection.js"; import type { GatewayBroadcastToConnIdsFn } from "./server-broadcast-types.js"; import type { diff --git a/src/gateway/server-session-key.ts b/src/gateway/server-session-key.ts index 6f9a92ad25d..d61d6751dff 100644 --- a/src/gateway/server-session-key.ts +++ b/src/gateway/server-session-key.ts @@ -1,3 +1,7 @@ +import { + asDateTimestampMs, + resolveExpiresAtMsFromDurationMs, +} from "@openclaw/normalization-core/number-coercion"; import { resolveDefaultAgentId } from "../agents/agent-scope.js"; import { getRuntimeConfig } from "../config/io.js"; import type { SessionEntry } from "../config/sessions.js"; @@ -9,7 +13,6 @@ import { toAgentRequestSessionKey, } from "../routing/session-key.js"; import { resolvePreferredSessionKeyForSessionIdMatches } from "../sessions/session-id-resolution.js"; -import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "../shared/number-coercion.js"; import { resolveSessionStoreAgentId, resolveSessionStoreKey } from "./session-store-key.js"; import { loadCombinedSessionStoreForGateway } from "./session-utils.js"; diff --git a/src/gateway/server-startup-log.ts b/src/gateway/server-startup-log.ts index 1cf41bece50..cb72849197b 100644 --- a/src/gateway/server-startup-log.ts +++ b/src/gateway/server-startup-log.ts @@ -1,3 +1,4 @@ +import { normalizeSortedUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import chalk from "chalk"; import { resolveDefaultAgentId, resolveAgentConfig } from "../agents/agent-scope.js"; import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../agents/defaults.js"; @@ -12,7 +13,6 @@ import { resolveThinkingDefault } from "../agents/model-thinking-default.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { getResolvedLoggerSettings } from "../logging.js"; import { collectEnabledInsecureOrDangerousFlagsFromCurrentSnapshot } from "../security/dangerous-config-flags-current.js"; -import { normalizeSortedUniqueStringEntries } from "../shared/string-normalization.js"; type StartupThinkLevel = | "off" diff --git a/src/gateway/server-talk-nodes.ts b/src/gateway/server-talk-nodes.ts index 84f7b86d708..8e84b0263b0 100644 --- a/src/gateway/server-talk-nodes.ts +++ b/src/gateway/server-talk-nodes.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { NodeRegistry, NodeSession } from "./node-registry.js"; const TALK_CAPABILITY = "talk"; diff --git a/src/gateway/server-utils.ts b/src/gateway/server-utils.ts index 13b780a3dcb..4c0fcfbee22 100644 --- a/src/gateway/server-utils.ts +++ b/src/gateway/server-utils.ts @@ -1,5 +1,5 @@ +import { normalizeTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import { defaultVoiceWakeTriggers } from "../infra/voicewake.js"; -import { normalizeTrimmedStringList } from "../shared/string-normalization.js"; export function normalizeVoiceWakeTriggers(input: unknown): string[] { const cleaned = normalizeTrimmedStringList(input) diff --git a/src/gateway/server.impl.ts b/src/gateway/server.impl.ts index 3f232847329..29d6eeab0fc 100644 --- a/src/gateway/server.impl.ts +++ b/src/gateway/server.impl.ts @@ -1,4 +1,5 @@ import { monitorEventLoopDelay, performance } from "node:perf_hooks"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { getActiveEmbeddedRunCount } from "../agents/embedded-agent-runner/run-state.js"; import { getTotalPendingReplies } from "../auto-reply/reply/dispatcher-registry.js"; import { @@ -51,7 +52,6 @@ import { clearSecretsRuntimeSnapshot, getActiveSecretsRuntimeConfigSnapshot, } from "../secrets/runtime-state.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { createAuthRateLimiter, type AuthRateLimiter } from "./auth-rate-limit.js"; import { resolveGatewayAuth } from "./auth.js"; import { ADMIN_SCOPE } from "./method-scopes.js"; diff --git a/src/gateway/server/hooks.ts b/src/gateway/server/hooks.ts index 9020f33f1f1..621baa994ed 100644 --- a/src/gateway/server/hooks.ts +++ b/src/gateway/server/hooks.ts @@ -1,4 +1,9 @@ import { randomUUID } from "node:crypto"; +import { + resolveDateTimestampMs, + resolveTimestampMsToIsoString, +} from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { sanitizeInboundSystemTags } from "../../auto-reply/reply/inbound-text.js"; import type { CliDeps } from "../../cli/deps.types.js"; import { getRuntimeConfig } from "../../config/io.js"; @@ -13,11 +18,6 @@ import type { CronJob } from "../../cron/types.js"; import { requestHeartbeat } from "../../infra/heartbeat-wake.js"; import { enqueueSystemEvent } from "../../infra/system-events.js"; import type { createSubsystemLogger } from "../../logging/subsystem.js"; -import { - resolveDateTimestampMs, - resolveTimestampMsToIsoString, -} from "../../shared/number-coercion.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { type HookAgentDispatchPayload, type HooksConfigResolved } from "../hooks.js"; import { createHooksRequestHandler, type HookClientIpConfig } from "./hooks-request-handler.js"; diff --git a/src/gateway/server/plugins-http/path-context.ts b/src/gateway/server/plugins-http/path-context.ts index 0b04edf2557..2f2271dfef8 100644 --- a/src/gateway/server/plugins-http/path-context.ts +++ b/src/gateway/server/plugins-http/path-context.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { PROTECTED_PLUGIN_ROUTE_PREFIXES, canonicalizePathForSecurity, diff --git a/src/gateway/server/preauth-connection-budget.ts b/src/gateway/server/preauth-connection-budget.ts index bf3913bbc16..fcccd5044b0 100644 --- a/src/gateway/server/preauth-connection-budget.ts +++ b/src/gateway/server/preauth-connection-budget.ts @@ -1,4 +1,7 @@ -import { parseStrictPositiveInteger, resolveIntegerOption } from "../../shared/number-coercion.js"; +import { + parseStrictPositiveInteger, + resolveIntegerOption, +} from "@openclaw/normalization-core/number-coercion"; const DEFAULT_MAX_PREAUTH_CONNECTIONS_PER_IP = 32; const UNKNOWN_CLIENT_IP_BUDGET_KEY = "__openclaw_unknown_client_ip__"; diff --git a/src/gateway/server/ws-connection.ts b/src/gateway/server/ws-connection.ts index 7a06fcbaa8d..43b31f483ae 100644 --- a/src/gateway/server/ws-connection.ts +++ b/src/gateway/server/ws-connection.ts @@ -1,5 +1,6 @@ import { randomUUID } from "node:crypto"; import type { Socket } from "node:net"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { RawData, WebSocket, WebSocketServer } from "ws"; import { GATEWAY_STARTUP_CLOSE_CODE, @@ -9,7 +10,6 @@ import { getRuntimeConfig } from "../../config/io.js"; import { upsertPresence } from "../../infra/system-presence.js"; import { logRejectedLargePayload } from "../../logging/diagnostic-payload.js"; import type { createSubsystemLogger } from "../../logging/subsystem.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { removeRemoteNodeInfo } from "../../skills/runtime/remote.js"; import { truncateUtf16Safe } from "../../utils.js"; import { isWebchatClient } from "../../utils/message-channel.js"; diff --git a/src/gateway/server/ws-connection/auth-context.ts b/src/gateway/server/ws-connection/auth-context.ts index b5dcb8fff74..f48c7a4a3e1 100644 --- a/src/gateway/server/ws-connection/auth-context.ts +++ b/src/gateway/server/ws-connection/auth-context.ts @@ -1,5 +1,5 @@ import type { IncomingMessage } from "node:http"; -import { normalizeOptionalString } from "../../../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { AUTH_RATE_LIMIT_SCOPE_DEVICE_TOKEN, AUTH_RATE_LIMIT_SCOPE_SHARED_SECRET, diff --git a/src/gateway/server/ws-connection/handshake-auth-helpers.ts b/src/gateway/server/ws-connection/handshake-auth-helpers.ts index c283568fb1a..cadf2e44162 100644 --- a/src/gateway/server/ws-connection/handshake-auth-helpers.ts +++ b/src/gateway/server/ws-connection/handshake-auth-helpers.ts @@ -1,10 +1,10 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { GATEWAY_CLIENT_IDS, GATEWAY_CLIENT_MODES, } from "../../../../packages/gateway-protocol/src/client-info.js"; import type { ConnectParams } from "../../../../packages/gateway-protocol/src/index.js"; import { verifyDeviceSignature } from "../../../infra/device-identity.js"; -import { normalizeLowercaseStringOrEmpty } from "../../../shared/string-coerce.js"; import type { AuthRateLimiter } from "../../auth-rate-limit.js"; import type { GatewayAuthResult } from "../../auth.js"; import { buildDeviceAuthPayload, buildDeviceAuthPayloadV3 } from "../../device-auth.js"; diff --git a/src/gateway/server/ws-connection/handshake-auth-log-limiter.ts b/src/gateway/server/ws-connection/handshake-auth-log-limiter.ts index 066cea76dd7..8093853ceb4 100644 --- a/src/gateway/server/ws-connection/handshake-auth-log-limiter.ts +++ b/src/gateway/server/ws-connection/handshake-auth-log-limiter.ts @@ -1,4 +1,4 @@ -import { resolveIntegerOption } from "../../../shared/number-coercion.js"; +import { resolveIntegerOption } from "@openclaw/normalization-core/number-coercion"; export type HandshakeAuthLogDecision = { shouldLog: boolean; diff --git a/src/gateway/server/ws-connection/message-handler.ts b/src/gateway/server/ws-connection/message-handler.ts index dad7a105c83..d479638d956 100644 --- a/src/gateway/server/ws-connection/message-handler.ts +++ b/src/gateway/server/ws-connection/message-handler.ts @@ -2,6 +2,7 @@ import fs from "node:fs"; import type { IncomingMessage } from "node:http"; import os from "node:os"; import path from "node:path"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { RawData, WebSocket } from "ws"; import { GATEWAY_CLIENT_IDS, @@ -83,7 +84,6 @@ import { type DeviceBootstrapProfile, } from "../../../shared/device-bootstrap-profile.js"; import { roleScopesAllow } from "../../../shared/operator-scope-compat.js"; -import { uniqueStrings } from "../../../shared/string-normalization.js"; import { recordRemoteNodeInfo, refreshRemoteNodeBins } from "../../../skills/runtime/remote.js"; import { isBrowserOperatorUiClient, diff --git a/src/gateway/server/ws-connection/unauthorized-flood-guard.ts b/src/gateway/server/ws-connection/unauthorized-flood-guard.ts index 48f27593c1f..1f66f569ad2 100644 --- a/src/gateway/server/ws-connection/unauthorized-flood-guard.ts +++ b/src/gateway/server/ws-connection/unauthorized-flood-guard.ts @@ -1,5 +1,5 @@ +import { resolveIntegerOption } from "@openclaw/normalization-core/number-coercion"; import { ErrorCodes, type ErrorShape } from "../../../../packages/gateway-protocol/src/index.js"; -import { resolveIntegerOption } from "../../../shared/number-coercion.js"; export type UnauthorizedFloodGuardOptions = { closeAfter?: number; diff --git a/src/gateway/session-child-sessions.ts b/src/gateway/session-child-sessions.ts index 1f6a48569d5..5ac3a937c12 100644 --- a/src/gateway/session-child-sessions.ts +++ b/src/gateway/session-child-sessions.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { loadCombinedSessionStoreForGateway } from "../config/sessions/combined-store-gateway.js"; import type { SessionEntry } from "../config/sessions/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; export type DirectChildSessionEntry = { sessionKey: string; diff --git a/src/gateway/session-history-state.ts b/src/gateway/session-history-state.ts index 3b277da66a8..b31bc5d11a4 100644 --- a/src/gateway/session-history-state.ts +++ b/src/gateway/session-history-state.ts @@ -1,4 +1,4 @@ -import { asPositiveSafeInteger } from "../shared/number-coercion.js"; +import { asPositiveSafeInteger } from "@openclaw/normalization-core/number-coercion"; import { DEFAULT_CHAT_HISTORY_TEXT_MAX_CHARS, projectChatDisplayMessages, diff --git a/src/gateway/session-kill-http.ts b/src/gateway/session-kill-http.ts index ce9058386c7..a547e3e686e 100644 --- a/src/gateway/session-kill-http.ts +++ b/src/gateway/session-kill-http.ts @@ -1,4 +1,5 @@ import type { IncomingMessage, ServerResponse } from "node:http"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { killControlledSubagentRun, killSubagentRunAdmin, @@ -6,7 +7,6 @@ import { } from "../agents/subagent-control.js"; import { getLatestSubagentRunByChildSessionKey } from "../agents/subagent-registry.js"; import { getRuntimeConfig } from "../config/io.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { AuthRateLimiter } from "./auth-rate-limit.js"; import { isLocalDirectRequest, type ResolvedGatewayAuth } from "./auth.js"; import { diff --git a/src/gateway/session-store-key.ts b/src/gateway/session-store-key.ts index 66082493f5c..6741e3c7fca 100644 --- a/src/gateway/session-store-key.ts +++ b/src/gateway/session-store-key.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { listAgentIds, resolveDefaultAgentId } from "../agents/agent-scope.js"; import { canonicalizeMainSessionAlias, @@ -12,10 +16,6 @@ import { type ParsedAgentSessionKey, } from "../routing/session-key.js"; import { normalizeSessionKeyPreservingOpaquePeerIds } from "../sessions/session-key-utils.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; export function canonicalizeSessionKeyForAgent(agentId: string, key: string): string { const lowered = normalizeLowercaseStringOrEmpty(key); diff --git a/src/gateway/session-transcript-files.fs.ts b/src/gateway/session-transcript-files.fs.ts index 24e47ab3de7..327fb3e9534 100644 --- a/src/gateway/session-transcript-files.fs.ts +++ b/src/gateway/session-transcript-files.fs.ts @@ -1,6 +1,7 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { formatSessionArchiveTimestamp, parseSessionArchiveTimestamp, @@ -13,7 +14,6 @@ import { } from "../config/sessions/paths.js"; import { resolveRequiredHomeDir } from "../infra/home-dir.js"; import { emitSessionTranscriptUpdate } from "../sessions/transcript-events.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; type ArchiveFileReason = SessionArchiveReason; export type ArchivedSessionTranscript = { diff --git a/src/gateway/session-transcript-key.ts b/src/gateway/session-transcript-key.ts index a92bd048b04..1415af6fa88 100644 --- a/src/gateway/session-transcript-key.ts +++ b/src/gateway/session-transcript-key.ts @@ -1,11 +1,11 @@ import fs from "node:fs"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { getRuntimeConfig } from "../config/io.js"; import type { SessionEntry } from "../config/sessions/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeAgentId } from "../routing/session-key.js"; import { resolvePreferredSessionKeyForSessionIdMatches } from "../sessions/session-id-resolution.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { loadCombinedSessionStoreForGateway, resolveGatewaySessionStoreTarget, diff --git a/src/gateway/session-utils.fs.ts b/src/gateway/session-utils.fs.ts index bce66a38c36..8fe0cbda1c0 100644 --- a/src/gateway/session-utils.fs.ts +++ b/src/gateway/session-utils.fs.ts @@ -1,15 +1,15 @@ import fs from "node:fs"; import { StringDecoder } from "node:string_decoder"; +import { + resolveIntegerOption, + resolveNonNegativeIntegerOption, +} from "@openclaw/normalization-core/number-coercion"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { deriveSessionTotalTokens, hasNonzeroUsage, normalizeUsage } from "../agents/usage.js"; import { jsonUtf8Bytes } from "../infra/json-utf8-bytes.js"; import { hasInterSessionUserProvenance } from "../sessions/input-provenance.js"; import { extractAssistantVisibleText } from "../shared/chat-message-content.js"; -import { - resolveIntegerOption, - resolveNonNegativeIntegerOption, -} from "../shared/number-coercion.js"; import { escapeRegExp } from "../shared/regexp.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { estimateStringChars, estimateTokensFromChars } from "../utils/cjk-chars.js"; import { stripInlineDirectiveTagsForDisplay } from "../utils/directive-tags.js"; import { extractToolCallNames, hasToolCall } from "../utils/transcript-tools.js"; diff --git a/src/gateway/session-utils.ts b/src/gateway/session-utils.ts index 1d0256d71f1..1825a72df0b 100644 --- a/src/gateway/session-utils.ts +++ b/src/gateway/session-utils.ts @@ -1,5 +1,11 @@ import fs from "node:fs"; import path from "node:path"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, + normalizeOptionalLowercaseString, +} from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { SessionsListParams } from "../../packages/gateway-protocol/src/index.js"; import { resolveModelAgentRuntimeMetadata } from "../agents/agent-runtime-metadata.js"; import { @@ -76,12 +82,6 @@ import { isWorkspaceRelativeAvatarPath, resolveAvatarMime, } from "../shared/avatar-policy.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, - normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { normalizeSessionDeliveryFields } from "../utils/delivery-context.shared.js"; import type { ModelCostConfig } from "../utils/usage-format.js"; import { estimateUsageCost, resolveModelCostConfig } from "../utils/usage-format.js"; diff --git a/src/gateway/sessions-history-http.ts b/src/gateway/sessions-history-http.ts index c06f38a11e6..faf07147603 100644 --- a/src/gateway/sessions-history-http.ts +++ b/src/gateway/sessions-history-http.ts @@ -1,14 +1,14 @@ import fs from "node:fs"; import type { IncomingMessage, ServerResponse } from "node:http"; import path from "node:path"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { getRuntimeConfig } from "../config/io.js"; import { loadSessionStore } from "../config/sessions.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { onSessionTranscriptUpdate } from "../sessions/transcript-events.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import type { AuthRateLimiter } from "./auth-rate-limit.js"; import type { ResolvedGatewayAuth } from "./auth.js"; import { diff --git a/src/gateway/sessions-patch.ts b/src/gateway/sessions-patch.ts index 0c6042901db..ab34ab3e6e5 100644 --- a/src/gateway/sessions-patch.ts +++ b/src/gateway/sessions-patch.ts @@ -1,4 +1,8 @@ import { randomUUID } from "node:crypto"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, type ErrorShape, @@ -47,10 +51,6 @@ import { import { applyModelOverrideToSessionEntry } from "../sessions/model-overrides.js"; import { normalizeSendPolicy } from "../sessions/send-policy.js"; import { parseSessionLabel } from "../sessions/session-label.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; function invalid(message: string): { ok: false; error: ErrorShape } { return { ok: false, error: errorShape(ErrorCodes.INVALID_REQUEST, message) }; diff --git a/src/gateway/sessions-resolve.ts b/src/gateway/sessions-resolve.ts index 0b198a7c078..6644cb9c366 100644 --- a/src/gateway/sessions-resolve.ts +++ b/src/gateway/sessions-resolve.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { ErrorCodes, type ErrorShape, @@ -8,7 +9,6 @@ import { loadSessionStore, updateSessionStore, type SessionEntry } from "../conf import type { OpenClawConfig } from "../config/types.openclaw.js"; import { resolveSessionIdMatchSelection } from "../sessions/session-id-resolution.js"; import { parseSessionLabel } from "../sessions/session-label.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { filterAndSortSessionEntries, listSessionsFromStore, diff --git a/src/gateway/startup-auth.ts b/src/gateway/startup-auth.ts index b885b653108..cd077923ed6 100644 --- a/src/gateway/startup-auth.ts +++ b/src/gateway/startup-auth.ts @@ -1,7 +1,7 @@ import crypto from "node:crypto"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { GatewayAuthConfig, GatewayTailscaleConfig } from "../config/types.gateway.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { hasConfiguredGatewayAuthSecretInput, resolveGatewayPasswordSecretRefValue, diff --git a/src/gateway/talk-handoff.ts b/src/gateway/talk-handoff.ts index fac646ff14b..7c20d33046f 100644 --- a/src/gateway/talk-handoff.ts +++ b/src/gateway/talk-handoff.ts @@ -4,8 +4,8 @@ import { isFutureDateTimestampMs, resolveDateTimestampMs, resolveExpiresAtMsFromDurationMs, -} from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { recordTalkObservabilityEvent } from "../talk/observability.js"; import { createTalkSessionController, diff --git a/src/gateway/talk-realtime-relay.ts b/src/gateway/talk-realtime-relay.ts index 1e5c0565a9c..c2a4c1a9868 100644 --- a/src/gateway/talk-realtime-relay.ts +++ b/src/gateway/talk-realtime-relay.ts @@ -1,7 +1,10 @@ import { randomUUID } from "node:crypto"; +import { + asDateTimestampMs, + resolveExpiresAtMsFromDurationMs, +} from "@openclaw/normalization-core/number-coercion"; import type { OpenClawConfig } from "../config/types.js"; import type { RealtimeVoiceProviderPlugin } from "../plugins/types.js"; -import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "../shared/number-coercion.js"; import { REALTIME_VOICE_AGENT_CONSULT_TOOL_NAME, buildRealtimeVoiceAgentConsultWorkingResponse, diff --git a/src/gateway/talk-transcription-relay.ts b/src/gateway/talk-transcription-relay.ts index 30aabc5f5f6..ddafc15f5c5 100644 --- a/src/gateway/talk-transcription-relay.ts +++ b/src/gateway/talk-transcription-relay.ts @@ -1,11 +1,11 @@ import { randomUUID } from "node:crypto"; -import type { RealtimeTranscriptionProviderPlugin } from "../plugins/types.js"; -import type { RealtimeTranscriptionProviderConfig } from "../realtime-transcription/provider-types.js"; import { asDateTimestampMs, parseFiniteNumber as readFiniteNumber, resolveExpiresAtMsFromDurationMs, -} from "../shared/number-coercion.js"; +} from "@openclaw/normalization-core/number-coercion"; +import type { RealtimeTranscriptionProviderPlugin } from "../plugins/types.js"; +import type { RealtimeTranscriptionProviderConfig } from "../realtime-transcription/provider-types.js"; import { recordTalkObservabilityEvent } from "../talk/observability.js"; import { type TalkEvent, diff --git a/src/gateway/test-helpers.e2e.ts b/src/gateway/test-helpers.e2e.ts index 9c774c91f5a..e0d13613a56 100644 --- a/src/gateway/test-helpers.e2e.ts +++ b/src/gateway/test-helpers.e2e.ts @@ -1,6 +1,7 @@ import { writeFile } from "node:fs/promises"; import os from "node:os"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { WebSocket } from "ws"; import { PROTOCOL_VERSION } from "../../packages/gateway-protocol/src/index.js"; import { clearConfigCache, clearRuntimeConfigSnapshot } from "../config/config.js"; @@ -12,7 +13,6 @@ import { signDevicePayload, } from "../infra/device-identity.js"; import { rawDataToString } from "../infra/ws.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { getDeterministicFreePortBlock } from "../test-utils/ports.js"; import { GATEWAY_CLIENT_MODES, diff --git a/src/gateway/test-helpers.server.ts b/src/gateway/test-helpers.server.ts index eb00c2347c4..537b951e0c3 100644 --- a/src/gateway/test-helpers.server.ts +++ b/src/gateway/test-helpers.server.ts @@ -1,9 +1,11 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import "./test-helpers.mocks.js"; import { afterAll, afterEach, beforeAll, beforeEach, expect, vi } from "vitest"; import { WebSocket } from "ws"; -import "./test-helpers.mocks.js"; import { PROTOCOL_VERSION } from "../../packages/gateway-protocol/src/index.js"; import { parseConfigJson5, resetConfigRuntimeState } from "../config/config.js"; import { @@ -32,8 +34,6 @@ import { parseAgentSessionKey, toAgentStoreSessionKey, } from "../routing/session-key.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resetTaskRegistryForTests } from "../tasks/runtime-internal.js"; import { resetTaskFlowRegistryForTests } from "../tasks/task-flow-runtime-internal.js"; import { captureEnv } from "../test-utils/env.js"; diff --git a/src/gateway/test-helpers.speech.ts b/src/gateway/test-helpers.speech.ts index 4d8d2f33d5c..ef22325efc6 100644 --- a/src/gateway/test-helpers.speech.ts +++ b/src/gateway/test-helpers.speech.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { SpeechProviderPlugin } from "../plugins/types.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { TALK_TEST_PROVIDER_ID, TALK_TEST_PROVIDER_LABEL, diff --git a/src/gateway/tools-invoke-http.ts b/src/gateway/tools-invoke-http.ts index 4bc2e89d104..ff9db4b4713 100644 --- a/src/gateway/tools-invoke-http.ts +++ b/src/gateway/tools-invoke-http.ts @@ -1,5 +1,5 @@ import type { IncomingMessage, ServerResponse } from "node:http"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { normalizeMessageChannel } from "../utils/message-channel.js"; import type { AuthRateLimiter } from "./auth-rate-limit.js"; import type { ResolvedGatewayAuth } from "./auth.js"; diff --git a/src/gateway/tools-invoke-shared.ts b/src/gateway/tools-invoke-shared.ts index aa782c8dfa9..54cdd1357f5 100644 --- a/src/gateway/tools-invoke-shared.ts +++ b/src/gateway/tools-invoke-shared.ts @@ -1,3 +1,7 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { runBeforeToolCallHook } from "../agents/agent-tools.before-tool-call.js"; import { resolveToolLoopDetectionConfig } from "../agents/agent-tools.js"; import { getChannelAgentToolMeta } from "../agents/channel-tools.js"; @@ -9,10 +13,6 @@ import { logWarn } from "../logger.js"; import { isTestDefaultMemorySlotDisabled } from "../plugins/config-state.js"; import { defaultSlotIdForKey } from "../plugins/slots.js"; import { getPluginToolMeta } from "../plugins/tools.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { canonicalizeSessionKeyForAgent } from "./session-store-key.js"; import { resolveGatewayScopedTools } from "./tool-resolution.js"; diff --git a/src/gateway/ws-log.ts b/src/gateway/ws-log.ts index 86119cda139..0b01dd24229 100644 --- a/src/gateway/ws-log.ts +++ b/src/gateway/ws-log.ts @@ -1,3 +1,4 @@ +import { readStringValue } from "@openclaw/normalization-core/string-coerce"; import chalk from "chalk"; import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload"; import { isVerbose } from "../globals.js"; @@ -6,7 +7,6 @@ import { shouldLogSubsystemToConsole } from "../logging/console.js"; import { getDefaultRedactPatterns, redactSensitiveText } from "../logging/redact.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { parseAgentSessionKey } from "../routing/session-key.js"; -import { readStringValue } from "../shared/string-coerce.js"; import { DEFAULT_WS_SLOW_MS, getGatewayWsLogStyle } from "./ws-logging.js"; const LOG_VALUE_LIMIT = 240; diff --git a/src/hooks/bundled/bootstrap-extra-files/handler.ts b/src/hooks/bundled/bootstrap-extra-files/handler.ts index 741190baa7b..f603745d455 100644 --- a/src/hooks/bundled/bootstrap-extra-files/handler.ts +++ b/src/hooks/bundled/bootstrap-extra-files/handler.ts @@ -1,9 +1,9 @@ +import { normalizeTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import { filterBootstrapFilesForSession, loadExtraBootstrapFilesWithDiagnostics, } from "../../../agents/workspace.js"; import { createSubsystemLogger } from "../../../logging/subsystem.js"; -import { normalizeTrimmedStringList } from "../../../shared/string-normalization.js"; import { resolveHookConfig } from "../../config.js"; import { isAgentBootstrapEvent, type HookHandler } from "../../hooks.js"; diff --git a/src/hooks/bundled/compaction-notifier/handler.ts b/src/hooks/bundled/compaction-notifier/handler.ts index 4726e3348a7..ffb9f40f9f3 100644 --- a/src/hooks/bundled/compaction-notifier/handler.ts +++ b/src/hooks/bundled/compaction-notifier/handler.ts @@ -1,4 +1,4 @@ -import { asFiniteNumber } from "../../../shared/number-coercion.js"; +import { asFiniteNumber } from "@openclaw/normalization-core/number-coercion"; import type { HookHandler } from "../../hooks.js"; function readOptionalNumber(context: Record, key: string): number | undefined { diff --git a/src/hooks/frontmatter.ts b/src/hooks/frontmatter.ts index e2a75bf5a08..f0c8c46a9b6 100644 --- a/src/hooks/frontmatter.ts +++ b/src/hooks/frontmatter.ts @@ -1,3 +1,4 @@ +import { readStringValue } from "@openclaw/normalization-core/string-coerce"; import { parseFrontmatterBlock } from "../../packages/markdown-core/src/frontmatter.js"; import { applyOpenClawManifestInstallCommonFields, @@ -10,7 +11,6 @@ import { resolveOpenClawManifestOs, resolveOpenClawManifestRequires, } from "../shared/frontmatter.js"; -import { readStringValue } from "../shared/string-coerce.js"; import type { OpenClawHookMetadata, HookEntry, diff --git a/src/hooks/gmail.ts b/src/hooks/gmail.ts index ce86762ed16..6683c44ea43 100644 --- a/src/hooks/gmail.ts +++ b/src/hooks/gmail.ts @@ -1,5 +1,7 @@ import { randomBytes } from "node:crypto"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import { type OpenClawConfig, DEFAULT_GATEWAY_PORT, @@ -8,8 +10,6 @@ import { } from "../config/config.js"; import { resolveExecutable } from "../infra/executable-path.js"; import { getWindowsInstallRoots } from "../infra/windows-install-roots.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { normalizeUniqueStringEntries } from "../shared/string-normalization.js"; export const DEFAULT_GMAIL_LABEL = "INBOX"; export const DEFAULT_GMAIL_TOPIC = "gog-gmail-watch"; diff --git a/src/hooks/install.ts b/src/hooks/install.ts index 9d7fe5cadf9..6e831734c44 100644 --- a/src/hooks/install.ts +++ b/src/hooks/install.ts @@ -1,10 +1,10 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { normalizeTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import { MANIFEST_KEY } from "../compat/legacy-names.js"; import { resolveSafeInstallDir, unscopedPackageName } from "../infra/install-safe-path.js"; import { type NpmIntegrityDrift, type NpmSpecResolution } from "../infra/install-source-utils.js"; import type { InstallSafetyOverrides } from "../plugins/install-security-scan.js"; -import { normalizeTrimmedStringList } from "../shared/string-normalization.js"; import { CONFIG_DIR, resolveUserPath } from "../utils.js"; import { parseFrontmatter } from "./frontmatter.js"; diff --git a/src/hooks/llm-slug-generator.ts b/src/hooks/llm-slug-generator.ts index 245dac4e90d..3dd589d7cb3 100644 --- a/src/hooks/llm-slug-generator.ts +++ b/src/hooks/llm-slug-generator.ts @@ -5,6 +5,7 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { resolveDefaultAgentId, resolveAgentWorkspaceDir, @@ -15,7 +16,6 @@ import { resolveDefaultModelForAgent } from "../agents/model-selection.js"; import { resolveAgentTimeoutMs } from "../agents/timeout.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; const log = createSubsystemLogger("llm-slug-generator"); const DEFAULT_SLUG_GENERATOR_TIMEOUT_MS = 15_000; diff --git a/src/hooks/message-hook-mappers.ts b/src/hooks/message-hook-mappers.ts index 8597fb06a20..7bffba8a22d 100644 --- a/src/hooks/message-hook-mappers.ts +++ b/src/hooks/message-hook-mappers.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { FinalizedMsgContext } from "../auto-reply/templating.js"; import { getChannelPlugin, normalizeChannelId } from "../channels/plugins/index.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; @@ -12,10 +16,6 @@ import type { PluginHookMessageReceivedEvent, PluginHookMessageSentEvent, } from "../plugins/hook-message.types.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import type { MessagePreprocessedHookContext, MessageReceivedHookContext, diff --git a/src/hooks/workspace.ts b/src/hooks/workspace.ts index ebb0c32acdc..cb3f7baffe0 100644 --- a/src/hooks/workspace.ts +++ b/src/hooks/workspace.ts @@ -1,11 +1,11 @@ import fs from "node:fs"; import path from "node:path"; +import { normalizeTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import { MANIFEST_KEY } from "../compat/legacy-names.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { openRootFileSync } from "../infra/boundary-file-read.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { isPathInsideWithRealpath } from "../security/scan-paths.js"; -import { normalizeTrimmedStringList } from "../shared/string-normalization.js"; import { CONFIG_DIR, resolveUserPath } from "../utils.js"; import { resolveBundledHooksDir } from "./bundled-dir.js"; import { diff --git a/src/image-generation/image-assets.ts b/src/image-generation/image-assets.ts index 100cb238a39..da7918cde4a 100644 --- a/src/image-generation/image-assets.ts +++ b/src/image-generation/image-assets.ts @@ -1,9 +1,9 @@ -import { canonicalizeBase64 } from "../media/base64.js"; -import { isRecord } from "../shared/record-coerce.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { canonicalizeBase64 } from "../media/base64.js"; import type { GeneratedImageAsset, ImageGenerationSourceImage } from "./types.js"; const DEFAULT_IMAGE_MIME_TYPE = "image/png"; diff --git a/src/image-generation/live-test-helpers.ts b/src/image-generation/live-test-helpers.ts index 9586f9c285b..7dbaa55c5d1 100644 --- a/src/image-generation/live-test-helpers.ts +++ b/src/image-generation/live-test-helpers.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { parseLiveCsvFilter, @@ -6,7 +7,6 @@ import { resolveConfiguredLiveProviderModels, resolveLiveAuthStore, } from "../media-generation/live-test-helpers.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; export { parseProviderModelMap, redactLiveApiKey }; diff --git a/src/infra/approval-errors.ts b/src/infra/approval-errors.ts index 4a05f2d318b..899f31357f4 100644 --- a/src/infra/approval-errors.ts +++ b/src/infra/approval-errors.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; const INVALID_REQUEST = "INVALID_REQUEST"; const APPROVAL_NOT_FOUND = "APPROVAL_NOT_FOUND"; diff --git a/src/infra/approval-native-route-coordinator.ts b/src/infra/approval-native-route-coordinator.ts index b0b65e712bf..f5bdcf9bf8a 100644 --- a/src/infra/approval-native-route-coordinator.ts +++ b/src/infra/approval-native-route-coordinator.ts @@ -1,7 +1,7 @@ import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; import type { ChannelApprovalNativeDeliveryPlan, ChannelApprovalNativePlannedTarget, diff --git a/src/infra/approval-native-route-notice.ts b/src/infra/approval-native-route-notice.ts index 09a0bd5f110..717fd938cec 100644 --- a/src/infra/approval-native-route-notice.ts +++ b/src/infra/approval-native-route-notice.ts @@ -1,5 +1,5 @@ +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { formatHumanList } from "../shared/human-list.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; import type { ChannelApprovalNativePlannedTarget } from "./approval-native-delivery.js"; export function describeApprovalDeliveryDestination(params: { diff --git a/src/infra/approval-request-account-binding.ts b/src/infra/approval-request-account-binding.ts index 29f625f2008..e3ab21471fe 100644 --- a/src/infra/approval-request-account-binding.ts +++ b/src/infra/approval-request-account-binding.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveStorePath } from "../config/sessions/paths.js"; import { loadSessionStore } from "../config/sessions/store-load.js"; import { resolveMaintenanceConfigFromInput } from "../config/sessions/store-maintenance.js"; @@ -5,7 +6,6 @@ import type { SessionEntry } from "../config/sessions/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeOptionalAccountId } from "../routing/account-id.js"; import { parseAgentSessionKey } from "../routing/session-key.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { normalizeMessageChannel } from "../utils/message-channel.js"; import type { ExecApprovalRequest } from "./exec-approvals.js"; import type { PluginApprovalRequest } from "./plugin-approvals.js"; diff --git a/src/infra/approval-request-filters.ts b/src/infra/approval-request-filters.ts index ce03fc0ab00..62c1a501834 100644 --- a/src/infra/approval-request-filters.ts +++ b/src/infra/approval-request-filters.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { parseAgentSessionKey } from "../routing/session-key.js"; import { compileSafeRegex, testRegexWithBoundedInput } from "../security/safe-regex.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; export type ApprovalRequestFilterInput = { agentId?: string | null; diff --git a/src/infra/backup-create.ts b/src/infra/backup-create.ts index e5e7885f93e..d80f1332c41 100644 --- a/src/infra/backup-create.ts +++ b/src/infra/backup-create.ts @@ -3,6 +3,7 @@ import { constants as fsConstants } from "node:fs"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; +import { resolveDateTimestampMs } from "@openclaw/normalization-core/number-coercion"; import { buildBackupArchiveBasename, buildBackupArchivePath, @@ -11,7 +12,6 @@ import { resolveBackupPlanFromDisk, } from "../commands/backup-shared.js"; import { isPathWithin } from "../commands/cleanup-utils.js"; -import { resolveDateTimestampMs } from "../shared/number-coercion.js"; import { resolveHomeDir, resolveUserPath } from "../utils.js"; import { resolveRuntimeServiceVersion } from "../version.js"; import { isVolatileBackupPath } from "./backup-volatile-filter.js"; diff --git a/src/infra/bonjour-discovery.ts b/src/infra/bonjour-discovery.ts index 1a5a5139b53..fda5bfffb12 100644 --- a/src/infra/bonjour-discovery.ts +++ b/src/infra/bonjour-discovery.ts @@ -1,6 +1,9 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; +import { + normalizeStringEntries, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { runCommandWithTimeout } from "../process/exec.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { normalizeStringEntries, uniqueStrings } from "../shared/string-normalization.js"; import { parseStrictInteger } from "./parse-finite-number.js"; import { isTailnetIPv4 } from "./tailnet.js"; import { resolveWideAreaDiscoveryDomain } from "./widearea-dns.js"; diff --git a/src/infra/clawhub-spec.ts b/src/infra/clawhub-spec.ts index 0f5f0421491..cdd038a1225 100644 --- a/src/infra/clawhub-spec.ts +++ b/src/infra/clawhub-spec.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export function parseClawHubPluginSpec(raw: string): { name: string; diff --git a/src/infra/clawhub.ts b/src/infra/clawhub.ts index 8e6f9878479..28375601f75 100644 --- a/src/infra/clawhub.ts +++ b/src/infra/clawhub.ts @@ -2,12 +2,12 @@ import { createHash } from "node:crypto"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; -import { readResponseWithLimit } from "../media/read-response-with-limit.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; +import { readResponseWithLimit } from "../media/read-response-with-limit.js"; import { parseStrictPositiveInteger } from "./parse-finite-number.js"; import { isAtLeast, parseSemver } from "./runtime-guard.js"; import { compareComparableSemver, parseComparableSemver } from "./semver-compare.js"; diff --git a/src/infra/command-analysis/explain.ts b/src/infra/command-analysis/explain.ts index cdb70100165..ab689d13280 100644 --- a/src/infra/command-analysis/explain.ts +++ b/src/infra/command-analysis/explain.ts @@ -1,4 +1,4 @@ -import { uniqueStrings } from "../../shared/string-normalization.js"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { CommandExplanation, CommandRisk } from "../command-explainer/types.js"; import type { ExecCommandSegment } from "../exec-approvals-analysis.js"; import { analyzeCommandForPolicy } from "./policy.js"; diff --git a/src/infra/command-analysis/inline-eval.ts b/src/infra/command-analysis/inline-eval.ts index 8c21ec01213..44e73b00908 100644 --- a/src/infra/command-analysis/inline-eval.ts +++ b/src/infra/command-analysis/inline-eval.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { normalizeExecutableToken } from "../exec-wrapper-resolution.js"; export type InterpreterInlineEvalHit = { diff --git a/src/infra/command-analysis/risks.ts b/src/infra/command-analysis/risks.ts index 5f06eca206a..6ec205bbf4c 100644 --- a/src/infra/command-analysis/risks.ts +++ b/src/infra/command-analysis/risks.ts @@ -1,4 +1,4 @@ -import { uniqueStrings } from "../../shared/string-normalization.js"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { splitShellArgs } from "../../utils/shell-argv.js"; import { COMMAND_CARRIER_EXECUTABLES, diff --git a/src/infra/control-ui-assets.ts b/src/infra/control-ui-assets.ts index 01ebe81a903..4acd06c75c0 100644 --- a/src/infra/control-ui-assets.ts +++ b/src/infra/control-ui-assets.ts @@ -1,8 +1,8 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { runCommandWithTimeout } from "../process/exec.js"; import { defaultRuntime, type RuntimeEnv } from "../runtime.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import * as controlUiFsRuntime from "./control-ui-assets.fs.runtime.js"; import { resolveOpenClawPackageRoot, resolveOpenClawPackageRootSync } from "./openclaw-root.js"; diff --git a/src/infra/device-bootstrap.ts b/src/infra/device-bootstrap.ts index c9316e170ff..677e3336bae 100644 --- a/src/infra/device-bootstrap.ts +++ b/src/infra/device-bootstrap.ts @@ -1,4 +1,8 @@ import path from "node:path"; +import { + asDateTimestampMs, + resolveExpiresAtMsFromDurationMs, +} from "@openclaw/normalization-core/number-coercion"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { normalizeDeviceBootstrapHandoffProfile, @@ -8,7 +12,6 @@ import { type DeviceBootstrapProfile, type DeviceBootstrapProfileInput, } from "../shared/device-bootstrap-profile.js"; -import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "../shared/number-coercion.js"; import { roleScopesAllow } from "../shared/operator-scope-compat.js"; import { normalizeDevicePublicKeyBase64Url } from "./device-identity.js"; import { resolvePairingPaths } from "./pairing-files.js"; diff --git a/src/infra/device-pairing.ts b/src/infra/device-pairing.ts index 23641b6fc4d..9329cdda051 100644 --- a/src/infra/device-pairing.ts +++ b/src/infra/device-pairing.ts @@ -1,4 +1,5 @@ import { randomUUID } from "node:crypto"; +import { normalizeUniqueSingleOrTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import { normalizeDeviceAuthScopes } from "../shared/device-auth.js"; import { resolveBootstrapProfileScopesForRole, @@ -10,7 +11,6 @@ import { resolveScopeOutsideRequestedRoles, roleScopesAllow, } from "../shared/operator-scope-compat.js"; -import { normalizeUniqueSingleOrTrimmedStringList } from "../shared/string-normalization.js"; import { revokeDeviceBootstrapTokensForDevice } from "./device-bootstrap.js"; import { createAsyncLock, diff --git a/src/infra/diagnostic-flags.ts b/src/infra/diagnostic-flags.ts index 716232b8700..2d0fe5af29f 100644 --- a/src/infra/diagnostic-flags.ts +++ b/src/infra/diagnostic-flags.ts @@ -1,6 +1,6 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { normalizeUniqueStringEntriesLower } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { normalizeUniqueStringEntriesLower } from "../shared/string-normalization.js"; const DIAGNOSTICS_ENV = "OPENCLAW_DIAGNOSTICS"; diff --git a/src/infra/dispatch-wrapper-resolution.ts b/src/infra/dispatch-wrapper-resolution.ts index ed73363aab2..51d2d9e1447 100644 --- a/src/infra/dispatch-wrapper-resolution.ts +++ b/src/infra/dispatch-wrapper-resolution.ts @@ -1,5 +1,5 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { envInvocationUsesModifiers, parseEnvInvocationPrelude, diff --git a/src/infra/env.ts b/src/infra/env.ts index 5c1e72d8744..a297b783913 100644 --- a/src/infra/env.ts +++ b/src/infra/env.ts @@ -1,5 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { SubsystemLogger } from "../logging/subsystem.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; let log: SubsystemLogger | null = null; let logPromise: Promise | null = null; diff --git a/src/infra/event-session-routing.ts b/src/infra/event-session-routing.ts index 4c6b4172c25..7af17bb92a5 100644 --- a/src/infra/event-session-routing.ts +++ b/src/infra/event-session-routing.ts @@ -1,3 +1,5 @@ +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { SessionScope } from "../config/types.base.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { resolveAgentRoute } from "../routing/resolve-route.js"; @@ -10,8 +12,6 @@ import { import { resolveEventSessionKey, scopedHeartbeatWakeOptions } from "../routing/session-key.js"; import { resolvePinnedMainDmOwnerFromAllowlist } from "../security/dm-policy-shared.js"; import { deriveSessionChatTypeFromKey } from "../sessions/session-chat-type-shared.js"; -import { isRecord } from "../shared/record-coerce.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; type UnknownRecord = Record; diff --git a/src/infra/exec-allowlist-pattern.ts b/src/infra/exec-allowlist-pattern.ts index af6285d6d07..24cb00669ef 100644 --- a/src/infra/exec-allowlist-pattern.ts +++ b/src/infra/exec-allowlist-pattern.ts @@ -1,6 +1,6 @@ import fs from "node:fs"; import path from "node:path"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { expandHomePrefix } from "./home-dir.js"; const GLOB_REGEX_CACHE_LIMIT = 512; diff --git a/src/infra/exec-approval-forwarder.ts b/src/infra/exec-approval-forwarder.ts index d5358ad6637..f4174e802f9 100644 --- a/src/infra/exec-approval-forwarder.ts +++ b/src/infra/exec-approval-forwarder.ts @@ -1,3 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { ReplyPayload } from "../auto-reply/types.js"; import { getLoadedChannelPlugin, @@ -17,8 +19,6 @@ import { buildPluginApprovalResolvedReplyPayload, } from "../plugin-sdk/approval-renderers.js"; import { channelRouteDedupeKey } from "../plugin-sdk/channel-route.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { isDeliverableMessageChannel, normalizeMessageChannel, diff --git a/src/infra/exec-approval-reply.ts b/src/infra/exec-approval-reply.ts index 6f97d9fe255..bee16a46571 100644 --- a/src/infra/exec-approval-reply.ts +++ b/src/infra/exec-approval-reply.ts @@ -1,3 +1,7 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { ReplyPayload } from "../auto-reply/types.js"; import type { InteractiveReply, @@ -6,10 +10,6 @@ import type { MessagePresentationButton, } from "../interactive/payload.js"; import { formatHumanList } from "../shared/human-list.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { formatApprovalDisplayPath } from "./approval-display-paths.js"; import { describeNativeExecApprovalClientSetup, diff --git a/src/infra/exec-approval-session-target.ts b/src/infra/exec-approval-session-target.ts index c3fc061b444..b40a2a39ee0 100644 --- a/src/infra/exec-approval-session-target.ts +++ b/src/infra/exec-approval-session-target.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveSessionConversationRef } from "../channels/plugins/session-conversation.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { normalizeMessageChannel } from "../utils/message-channel.js"; import { doesApprovalRequestMatchChannelAccount, diff --git a/src/infra/exec-approval-surface.ts b/src/infra/exec-approval-surface.ts index a22e578a3f5..ed397507c28 100644 --- a/src/infra/exec-approval-surface.ts +++ b/src/infra/exec-approval-surface.ts @@ -1,10 +1,10 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { getChannelPlugin, listChannelPlugins, resolveChannelApprovalCapability, } from "../channels/plugins/index.js"; import { getRuntimeConfig, type OpenClawConfig } from "../config/config.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { INTERNAL_MESSAGE_CHANNEL, isDeliverableMessageChannel, diff --git a/src/infra/exec-approvals-allowlist.ts b/src/infra/exec-approvals-allowlist.ts index 778ca651358..f8e512995a5 100644 --- a/src/infra/exec-approvals-allowlist.ts +++ b/src/infra/exec-approvals-allowlist.ts @@ -3,7 +3,7 @@ import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; import { isInterpreterLikeAllowlistPattern } from "./command-analysis/inline-eval.js"; import { detectInlineEvalArgv } from "./command-analysis/risks.js"; import { diff --git a/src/infra/exec-approvals-analysis.ts b/src/infra/exec-approvals-analysis.ts index 18c492eaddf..1d4992fdc43 100644 --- a/src/infra/exec-approvals-analysis.ts +++ b/src/infra/exec-approvals-analysis.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { splitShellArgs } from "../utils/shell-argv.js"; import { resolveCommandResolutionFromArgv, diff --git a/src/infra/exec-approvals-effective.ts b/src/infra/exec-approvals-effective.ts index 71b6ee000fe..acee54d968b 100644 --- a/src/infra/exec-approvals-effective.ts +++ b/src/infra/exec-approvals-effective.ts @@ -1,6 +1,6 @@ +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { DEFAULT_AGENT_ID } from "../routing/session-key.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; import { DEFAULT_EXEC_APPROVAL_ASK_FALLBACK, resolveExecApprovalAllowedDecisions, diff --git a/src/infra/exec-approvals.ts b/src/infra/exec-approvals.ts index 6be5719590d..c1369293b07 100644 --- a/src/infra/exec-approvals.ts +++ b/src/infra/exec-approvals.ts @@ -1,13 +1,13 @@ import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; -import { DEFAULT_AGENT_ID } from "../routing/session-key.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, readStringValue, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { DEFAULT_AGENT_ID } from "../routing/session-key.js"; import type { CommandExplanationSummary } from "./command-analysis/explain.js"; import { resolveAllowAlwaysPatternEntries } from "./exec-approvals-allowlist.js"; import { analyzeShellCommand, type ExecCommandSegment } from "./exec-approvals-analysis.js"; diff --git a/src/infra/exec-command-resolution.ts b/src/infra/exec-command-resolution.ts index 149a39dd2b8..508dad2a0e4 100644 --- a/src/infra/exec-command-resolution.ts +++ b/src/infra/exec-command-resolution.ts @@ -1,6 +1,6 @@ import fs from "node:fs"; import path from "node:path"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { matchesExecAllowlistPattern } from "./exec-allowlist-pattern.js"; import type { ExecAllowlistEntry } from "./exec-approvals.types.js"; import { resolveExecWrapperTrustPlan } from "./exec-wrapper-trust-plan.js"; diff --git a/src/infra/exec-safe-bin-policy-profiles.ts b/src/infra/exec-safe-bin-policy-profiles.ts index a678b7a8d95..529848de5ae 100644 --- a/src/infra/exec-safe-bin-policy-profiles.ts +++ b/src/infra/exec-safe-bin-policy-profiles.ts @@ -1,5 +1,5 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; export type SafeBinProfile = { minPositional?: number; diff --git a/src/infra/exec-safe-bin-semantics.ts b/src/infra/exec-safe-bin-semantics.ts index 63eddfb1814..12669d4caf3 100644 --- a/src/infra/exec-safe-bin-semantics.ts +++ b/src/infra/exec-safe-bin-semantics.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; type SafeBinSemanticValidationParams = { binName?: string; diff --git a/src/infra/exec-safe-bin-trust.ts b/src/infra/exec-safe-bin-trust.ts index 70c34fef1c3..c84bd12b78e 100644 --- a/src/infra/exec-safe-bin-trust.ts +++ b/src/infra/exec-safe-bin-trust.ts @@ -4,7 +4,7 @@ import { normalizeSortedUniqueStringEntries, sortUniqueStrings, uniqueStrings, -} from "../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-normalization"; // Keep defaults to OS-managed immutable bins only. // User/package-manager bins must be opted in via tools.exec.safeBinTrustedDirs. diff --git a/src/infra/exec-wrapper-tokens.ts b/src/infra/exec-wrapper-tokens.ts index 337ed09ff63..dbc0a5e73a2 100644 --- a/src/infra/exec-wrapper-tokens.ts +++ b/src/infra/exec-wrapper-tokens.ts @@ -1,5 +1,5 @@ import path from "node:path"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; const WINDOWS_EXECUTABLE_SUFFIXES = [".exe", ".cmd", ".bat", ".com"] as const; diff --git a/src/infra/executable-path.ts b/src/infra/executable-path.ts index 12ccc026ccd..951d875fb4f 100644 --- a/src/infra/executable-path.ts +++ b/src/infra/executable-path.ts @@ -1,6 +1,6 @@ import fs from "node:fs"; import path from "node:path"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { expandHomePrefix } from "./home-dir.js"; function isDriveLessWindowsRootedPath(value: string): boolean { diff --git a/src/infra/gateway-discovery-targets.ts b/src/infra/gateway-discovery-targets.ts index 028643f55a8..ad5ee520de2 100644 --- a/src/infra/gateway-discovery-targets.ts +++ b/src/infra/gateway-discovery-targets.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveGatewayDiscoveryEndpoint, type GatewayBonjourBeacon, diff --git a/src/infra/gateway-lock.ts b/src/infra/gateway-lock.ts index 56c13fd5984..7c5cf36ea67 100644 --- a/src/infra/gateway-lock.ts +++ b/src/infra/gateway-lock.ts @@ -4,9 +4,9 @@ import fsSync from "node:fs"; import fs from "node:fs/promises"; import net from "node:net"; import path from "node:path"; +import { resolveTimestampMsToIsoString } from "@openclaw/normalization-core/number-coercion"; import { z } from "zod"; import { resolveConfigPath, resolveGatewayLockDir, resolveStateDir } from "../config/paths.js"; -import { resolveTimestampMsToIsoString } from "../shared/number-coercion.js"; import { isPidAlive } from "../shared/pid-alive.js"; import { safeParseJsonWithSchema } from "../utils/zod-parse.js"; import { isGatewayArgv, parseProcCmdline, parseWindowsCmdline } from "./gateway-process-argv.js"; diff --git a/src/infra/gateway-process-argv.ts b/src/infra/gateway-process-argv.ts index ae091c81c3f..1681b08a396 100644 --- a/src/infra/gateway-process-argv.ts +++ b/src/infra/gateway-process-argv.ts @@ -1,5 +1,5 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; function normalizeProcArg(arg: string): string { return normalizeLowercaseStringOrEmpty(arg.replaceAll("\\", "/")); diff --git a/src/infra/gateway-processes.ts b/src/infra/gateway-processes.ts index 7b2d47e4184..40fea27c24f 100644 --- a/src/infra/gateway-processes.ts +++ b/src/infra/gateway-processes.ts @@ -1,6 +1,6 @@ import { spawnSync } from "node:child_process"; import fsSync from "node:fs"; -import { uniqueValues } from "../shared/string-normalization.js"; +import { uniqueValues } from "@openclaw/normalization-core/string-normalization"; import { isGatewayArgv, parseProcCmdline } from "./gateway-process-argv.js"; import { findGatewayPidsOnPortSync as findUnixGatewayPidsOnPortSync } from "./restart-stale-pids.js"; import { diff --git a/src/infra/git-commit.ts b/src/infra/git-commit.ts index 28342f1953f..89ef4ebd34c 100644 --- a/src/infra/git-commit.ts +++ b/src/infra/git-commit.ts @@ -2,7 +2,7 @@ import fs from "node:fs"; import { createRequire } from "node:module"; import path from "node:path"; import { fileURLToPath } from "node:url"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { resolveGitHeadPath } from "./git-root.js"; import { resolveOpenClawPackageRootSync } from "./openclaw-root.js"; diff --git a/src/infra/heartbeat-events-filter.ts b/src/infra/heartbeat-events-filter.ts index 5b806ba23a1..5d3ff26b88c 100644 --- a/src/infra/heartbeat-events-filter.ts +++ b/src/infra/heartbeat-events-filter.ts @@ -1,6 +1,6 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { HEARTBEAT_RESPONSE_TOOL_INSTRUCTIONS } from "../auto-reply/heartbeat.js"; import { HEARTBEAT_TOKEN } from "../auto-reply/tokens.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; const MAX_EXEC_EVENT_PROMPT_CHARS = 8_000; const STRUCTURED_EXEC_COMPLETION_EVENT_RE = diff --git a/src/infra/heartbeat-reason.ts b/src/infra/heartbeat-reason.ts index 742f2ad01fa..451de1d37bd 100644 --- a/src/infra/heartbeat-reason.ts +++ b/src/infra/heartbeat-reason.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export function normalizeHeartbeatWakeReason(reason?: string): string { return normalizeOptionalString(reason) ?? "requested"; diff --git a/src/infra/heartbeat-runner.ts b/src/infra/heartbeat-runner.ts index 788fae49068..5932468fa66 100644 --- a/src/infra/heartbeat-runner.ts +++ b/src/infra/heartbeat-runner.ts @@ -1,6 +1,11 @@ import { createHash } from "node:crypto"; import fs from "node:fs/promises"; import path from "node:path"; +import { timestampMsToIsoString } from "@openclaw/normalization-core/number-coercion"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { hasOutboundReplyContent, resolveSendableOutboundReplyParts, @@ -89,11 +94,6 @@ import { toAgentStoreSessionKey, } from "../routing/session-key.js"; import { defaultRuntime, type RuntimeEnv } from "../runtime.js"; -import { timestampMsToIsoString } from "../shared/number-coercion.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { escapeRegExp } from "../utils.js"; import { MAX_SAFE_TIMEOUT_DELAY_MS, resolveSafeTimeoutDelayMs } from "../utils/timer-delay.js"; import { loadOrCreateDeviceIdentity } from "./device-identity.js"; diff --git a/src/infra/heartbeat-summary.ts b/src/infra/heartbeat-summary.ts index 21ac979cfb7..bdbb0ff8d0b 100644 --- a/src/infra/heartbeat-summary.ts +++ b/src/infra/heartbeat-summary.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveAgentConfig, resolveDefaultAgentId } from "../agents/agent-scope.js"; import { DEFAULT_HEARTBEAT_ACK_MAX_CHARS, @@ -8,7 +9,6 @@ import { parseDurationMs } from "../cli/parse-duration.js"; import type { AgentDefaultsConfig } from "../config/types.agent-defaults.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeAgentId } from "../routing/session-key.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; type HeartbeatConfig = AgentDefaultsConfig["heartbeat"]; diff --git a/src/infra/heartbeat-wake.ts b/src/infra/heartbeat-wake.ts index a3cbd6102a5..4ed329d7a93 100644 --- a/src/infra/heartbeat-wake.ts +++ b/src/infra/heartbeat-wake.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { normalizeHeartbeatWakeReason } from "./heartbeat-reason.js"; export type HeartbeatRunResult = diff --git a/src/infra/host-env-security.policy-parity.test.ts b/src/infra/host-env-security.policy-parity.test.ts index 1e47b374de4..a5ba801a864 100644 --- a/src/infra/host-env-security.policy-parity.test.ts +++ b/src/infra/host-env-security.policy-parity.test.ts @@ -1,7 +1,7 @@ import fs from "node:fs"; import path from "node:path"; +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { describe, expect, it } from "vitest"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; import { loadHostEnvSecurityPolicy } from "./host-env-security-policy.js"; function parseSwiftStringArray(source: string, marker: string): string[] { diff --git a/src/infra/host-env-security.reported-baseline.test.ts b/src/infra/host-env-security.reported-baseline.test.ts index f1f9f0dc08d..3934f14e8fa 100644 --- a/src/infra/host-env-security.reported-baseline.test.ts +++ b/src/infra/host-env-security.reported-baseline.test.ts @@ -1,7 +1,7 @@ import fs from "node:fs"; import path from "node:path"; +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { describe, expect, it } from "vitest"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; import { isDangerousHostEnvOverrideVarName, isDangerousHostEnvVarName, diff --git a/src/infra/host-env-security.ts b/src/infra/host-env-security.ts index ba1cf34adc9..46d68b4299a 100644 --- a/src/infra/host-env-security.ts +++ b/src/infra/host-env-security.ts @@ -1,4 +1,4 @@ -import { sortUniqueStrings } from "../shared/string-normalization.js"; +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { HOST_ENV_SECURITY_POLICY } from "./host-env-security-policy.js"; import { markOpenClawExecEnv } from "./openclaw-exec-env.js"; diff --git a/src/infra/http-body.test.ts b/src/infra/http-body.test.ts index 5e1f43b944d..7bf892cb324 100644 --- a/src/infra/http-body.test.ts +++ b/src/infra/http-body.test.ts @@ -1,7 +1,7 @@ import { EventEmitter } from "node:events"; import type { IncomingMessage } from "node:http"; +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { beforeEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { createMockServerResponse } from "../test-utils/mock-http-response.js"; import { installRequestBodyLimitGuard, diff --git a/src/infra/http-body.ts b/src/infra/http-body.ts index f89eb844a06..293fb27c7ab 100644 --- a/src/infra/http-body.ts +++ b/src/infra/http-body.ts @@ -1,6 +1,6 @@ import type { IncomingMessage, ServerResponse } from "node:http"; import { clearTimeout as clearNodeTimeout, setTimeout as setNodeTimeout } from "node:timers"; -import { resolveTimerTimeoutMs } from "../shared/number-coercion.js"; +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; import { formatErrorMessage } from "./errors.js"; import { parseStrictNonNegativeInteger } from "./parse-finite-number.js"; diff --git a/src/infra/install-package-dir.ts b/src/infra/install-package-dir.ts index 64aaccac235..c58cb51080f 100644 --- a/src/infra/install-package-dir.ts +++ b/src/infra/install-package-dir.ts @@ -1,7 +1,7 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { isRecord as isObjectRecord } from "@openclaw/normalization-core/record-coerce"; import { runCommandWithTimeout } from "../process/exec.js"; -import { isRecord as isObjectRecord } from "../shared/record-coerce.js"; import { pathExists } from "./fs-safe.js"; import { assertCanonicalPathWithinBase } from "./install-safe-path.js"; import { tryReadJson, writeJson } from "./json-files.js"; diff --git a/src/infra/install-source-utils.ts b/src/infra/install-source-utils.ts index 7d959a7b4bd..25a060fd416 100644 --- a/src/infra/install-source-utils.ts +++ b/src/infra/install-source-utils.ts @@ -1,8 +1,8 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { runCommandWithTimeout } from "../process/exec.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { resolveUserPath } from "../utils.js"; import { resolveArchiveKind } from "./archive.js"; import { pathExists } from "./fs-safe.js"; diff --git a/src/infra/jsonl-socket.test.ts b/src/infra/jsonl-socket.test.ts index 9381cffd37e..bc927b2b88e 100644 --- a/src/infra/jsonl-socket.test.ts +++ b/src/infra/jsonl-socket.test.ts @@ -1,7 +1,7 @@ import net from "node:net"; import path from "node:path"; +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { describe, expect, it } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { withTempDir } from "../test-helpers/temp-dir.js"; import { requestJsonlSocket, testApi } from "./jsonl-socket.js"; diff --git a/src/infra/jsonl-socket.ts b/src/infra/jsonl-socket.ts index 20efa17b8bc..194aa6994cc 100644 --- a/src/infra/jsonl-socket.ts +++ b/src/infra/jsonl-socket.ts @@ -1,6 +1,6 @@ import net from "node:net"; import { clearTimeout as clearNodeTimeout, setTimeout as setNodeTimeout } from "node:timers"; -import { resolveTimerTimeoutMs } from "../shared/number-coercion.js"; +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; /** * Sends one JSONL request line, half-closes the write side, and waits for an accepted response line. diff --git a/src/infra/machine-name.ts b/src/infra/machine-name.ts index 4a7420e0a46..0299a936c93 100644 --- a/src/infra/machine-name.ts +++ b/src/infra/machine-name.ts @@ -1,7 +1,7 @@ import { execFile } from "node:child_process"; import os from "node:os"; import { promisify } from "node:util"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; const execFileAsync = promisify(execFile); diff --git a/src/infra/net/hostname.ts b/src/infra/net/hostname.ts index febe5bcd5fe..3993e07ef5f 100644 --- a/src/infra/net/hostname.ts +++ b/src/infra/net/hostname.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export function normalizeHostname(hostname: string): string { const normalized = normalizeLowercaseStringOrEmpty(hostname).replace(/\.+$/, ""); diff --git a/src/infra/net/http-connect-tunnel.test.ts b/src/infra/net/http-connect-tunnel.test.ts index bcfdd103720..f4dc750dc63 100644 --- a/src/infra/net/http-connect-tunnel.test.ts +++ b/src/infra/net/http-connect-tunnel.test.ts @@ -1,6 +1,6 @@ import { EventEmitter } from "node:events"; +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../../shared/number-coercion.js"; class FakeSocket extends EventEmitter { public readonly writes: string[] = []; diff --git a/src/infra/net/http-connect-tunnel.ts b/src/infra/net/http-connect-tunnel.ts index 0a4ce846d1a..9c72105433f 100644 --- a/src/infra/net/http-connect-tunnel.ts +++ b/src/infra/net/http-connect-tunnel.ts @@ -1,6 +1,6 @@ import * as net from "node:net"; import * as tls from "node:tls"; -import { resolveTimerTimeoutMs } from "../../shared/number-coercion.js"; +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; import type { ManagedProxyTlsOptions } from "./proxy/proxy-tls.js"; export type HttpConnectTunnelParams = { diff --git a/src/infra/net/proxy/managed-proxy-undici.ts b/src/infra/net/proxy/managed-proxy-undici.ts index ce5060075b6..b8f04835aea 100644 --- a/src/infra/net/proxy/managed-proxy-undici.ts +++ b/src/infra/net/proxy/managed-proxy-undici.ts @@ -1,5 +1,5 @@ +import { isRecord as isProxyTlsRecord } from "@openclaw/normalization-core/record-coerce"; import type { EnvHttpProxyAgent } from "undici"; -import { isRecord as isProxyTlsRecord } from "../../../shared/record-coerce.js"; import { resolveEnvHttpProxyAgentOptions, resolveEnvHttpProxyUrl } from "../proxy-env.js"; import { getActiveManagedProxyTlsOptions, getActiveManagedProxyUrl } from "./active-proxy-state.js"; import { diff --git a/src/infra/net/redirect-headers.ts b/src/infra/net/redirect-headers.ts index d708c4e5975..3e865197883 100644 --- a/src/infra/net/redirect-headers.ts +++ b/src/infra/net/redirect-headers.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { normalizeHeadersInitForFetch } from "../fetch-headers.js"; const CROSS_ORIGIN_REDIRECT_SAFE_HEADERS = new Set([ diff --git a/src/infra/net/ssrf.ts b/src/infra/net/ssrf.ts index 24a88616d69..9c1d1794ba0 100644 --- a/src/infra/net/ssrf.ts +++ b/src/infra/net/ssrf.ts @@ -14,8 +14,8 @@ import { parseCanonicalIpAddress, parseLooseIpAddress, } from "@openclaw/net-policy/ip"; +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { Dispatcher } from "undici"; -import { normalizeUniqueStringEntries } from "../../shared/string-normalization.js"; import { normalizeHostname } from "./hostname.js"; import { createHttp1Agent, diff --git a/src/infra/net/undici-runtime.ts b/src/infra/net/undici-runtime.ts index ba49cb854a3..a47cfe95fd0 100644 --- a/src/infra/net/undici-runtime.ts +++ b/src/infra/net/undici-runtime.ts @@ -1,6 +1,6 @@ import { createRequire } from "node:module"; import net from "node:net"; -import { isRecord as isObjectRecord } from "../../shared/record-coerce.js"; +import { isRecord as isObjectRecord } from "@openclaw/normalization-core/record-coerce"; import { addActiveManagedProxyTlsOptions } from "./proxy/managed-proxy-undici.js"; import { resolveUndiciAutoSelectFamilyConnectOptions } from "./undici-family-policy.js"; diff --git a/src/infra/node-pairing-surface.ts b/src/infra/node-pairing-surface.ts index 34fd309fcd7..3daa998b783 100644 --- a/src/infra/node-pairing-surface.ts +++ b/src/infra/node-pairing-surface.ts @@ -1,4 +1,4 @@ -import { normalizeArrayBackedTrimmedStringList } from "../shared/string-normalization.js"; +import { normalizeArrayBackedTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; export function normalizeNodeApprovalSurfaceList(value: readonly string[] | undefined): string[] { return normalizeArrayBackedTrimmedStringList(value) ?? []; diff --git a/src/infra/node-pairing.ts b/src/infra/node-pairing.ts index 113721bf41b..02254e9c689 100644 --- a/src/infra/node-pairing.ts +++ b/src/infra/node-pairing.ts @@ -1,6 +1,6 @@ import { randomUUID } from "node:crypto"; +import { normalizeArrayBackedTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import { resolveMissingRequestedScope } from "../shared/operator-scope-compat.js"; -import { normalizeArrayBackedTrimmedStringList } from "../shared/string-normalization.js"; import { type NodeApprovalScope, resolveNodePairApprovalScopes } from "./node-pairing-authz.js"; import { sameNodeApprovalSurfaceSet, sameNodePermissionSurface } from "./node-pairing-surface.js"; import { diff --git a/src/infra/node-shell.ts b/src/infra/node-shell.ts index 0e61593cbfd..b25d3a1fc2c 100644 --- a/src/infra/node-shell.ts +++ b/src/infra/node-shell.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export function buildNodeShellCommand(command: string, platform?: string | null) { const normalized = normalizeLowercaseStringOrEmpty((platform ?? "").trim()); diff --git a/src/infra/npm-install-env.ts b/src/infra/npm-install-env.ts index 835a2ff73fd..f6ac1fa070e 100644 --- a/src/infra/npm-install-env.ts +++ b/src/infra/npm-install-env.ts @@ -2,7 +2,7 @@ import { execFileSync } from "node:child_process"; import fsSync from "node:fs"; import os from "node:os"; import path from "node:path"; -import { uniqueStrings } from "../shared/string-normalization.js"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; export type NpmProjectInstallEnvOptions = { cacheDir?: string; diff --git a/src/infra/npm-managed-root.ts b/src/infra/npm-managed-root.ts index 466abe45c34..8f6bb51ec6b 100644 --- a/src/infra/npm-managed-root.ts +++ b/src/infra/npm-managed-root.ts @@ -2,9 +2,9 @@ import type { Stats } from "node:fs"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString as readOptionalString } from "@openclaw/normalization-core/string-coerce"; import { runCommandWithTimeout } from "../process/exec.js"; -import { isRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalString as readOptionalString } from "../shared/string-coerce.js"; import type { NpmSpecResolution } from "./install-source-utils.js"; import { readJson, readJsonIfExists, writeJson } from "./json-files.js"; import type { ParsedRegistryNpmSpec } from "./npm-registry-spec.js"; diff --git a/src/infra/npm-registry-spec.ts b/src/infra/npm-registry-spec.ts index 9d09463284b..929c7fc9138 100644 --- a/src/infra/npm-registry-spec.ts +++ b/src/infra/npm-registry-spec.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; const EXACT_SEMVER_VERSION_RE = /^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z.-]+))?(?:\+([0-9A-Za-z.-]+))?$/; diff --git a/src/infra/numeric-options.ts b/src/infra/numeric-options.ts index 6699c6cc3f7..9d0f5146f47 100644 --- a/src/infra/numeric-options.ts +++ b/src/infra/numeric-options.ts @@ -1,7 +1,7 @@ import { resolveIntegerOption as resolveSharedIntegerOption, resolveNonNegativeIntegerOption as resolveSharedNonNegativeIntegerOption, -} from "../shared/number-coercion.js"; +} from "@openclaw/normalization-core/number-coercion"; export function resolveNonNegativeIntegerOption(value: number, fallback: number): number { return resolveSharedNonNegativeIntegerOption(value, fallback); diff --git a/src/infra/os-summary.ts b/src/infra/os-summary.ts index 4cbb5775210..82e3c3b275d 100644 --- a/src/infra/os-summary.ts +++ b/src/infra/os-summary.ts @@ -1,6 +1,6 @@ import { spawnSync } from "node:child_process"; import os from "node:os"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; type OsSummary = { platform: NodeJS.Platform; diff --git a/src/infra/outbound/agent-delivery.ts b/src/infra/outbound/agent-delivery.ts index d8bac147763..b40c094780e 100644 --- a/src/infra/outbound/agent-delivery.ts +++ b/src/infra/outbound/agent-delivery.ts @@ -1,8 +1,8 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { ChannelOutboundTargetMode } from "../../channels/plugins/types.public.js"; import type { ChannelId } from "../../channels/plugins/types.public.js"; import type { SessionEntry } from "../../config/sessions.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { normalizeAccountId } from "../../utils/account-id.js"; import { INTERNAL_MESSAGE_CHANNEL, diff --git a/src/infra/outbound/best-effort-delivery.ts b/src/infra/outbound/best-effort-delivery.ts index c53b494f15a..75924f03612 100644 --- a/src/infra/outbound/best-effort-delivery.ts +++ b/src/infra/outbound/best-effort-delivery.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { stringifyRouteThreadId } from "../../plugin-sdk/channel-route.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { INTERNAL_MESSAGE_CHANNEL, isDeliverableMessageChannel, diff --git a/src/infra/outbound/channel-target-prefix.ts b/src/infra/outbound/channel-target-prefix.ts index bfd172f5acc..7c720dcb9a7 100644 --- a/src/infra/outbound/channel-target-prefix.ts +++ b/src/infra/outbound/channel-target-prefix.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { getActivePluginChannelRegistryFromState } from "../../plugins/runtime-channel-state.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { normalizeMessageChannel } from "../../utils/message-channel-core.js"; const TARGET_KIND_PREFIXES = new Set([ diff --git a/src/infra/outbound/channel-target.ts b/src/infra/outbound/channel-target.ts index f52eb2d6c27..93e7a7219a9 100644 --- a/src/infra/outbound/channel-target.ts +++ b/src/infra/outbound/channel-target.ts @@ -1,7 +1,7 @@ import { hasNonEmptyString as sharedHasNonEmptyString, normalizeOptionalString, -} from "../../shared/string-coerce.js"; +} from "../../../packages/normalization-core/src/string-coerce.js"; import { MESSAGE_ACTION_TARGET_MODE } from "./message-action-spec.js"; export const hasNonEmptyString = sharedHasNonEmptyString; diff --git a/src/infra/outbound/conversation-id.ts b/src/infra/outbound/conversation-id.ts index f0e1d315a28..e6294253723 100644 --- a/src/infra/outbound/conversation-id.ts +++ b/src/infra/outbound/conversation-id.ts @@ -1,8 +1,8 @@ -import { stringifyRouteThreadId } from "../../plugin-sdk/channel-route.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { stringifyRouteThreadId } from "../../plugin-sdk/channel-route.js"; function resolveExplicitConversationTargetId(target: string): string | undefined { for (const prefix of ["channel:", "conversation:", "group:", "room:", "dm:"]) { diff --git a/src/infra/outbound/current-conversation-bindings.ts b/src/infra/outbound/current-conversation-bindings.ts index c298bd80930..83d572cc307 100644 --- a/src/infra/outbound/current-conversation-bindings.ts +++ b/src/infra/outbound/current-conversation-bindings.ts @@ -1,17 +1,17 @@ import fs from "node:fs"; import path from "node:path"; +import { + asDateTimestampMs, + isFutureDateTimestampMs, + resolveExpiresAtMsFromDurationMs, +} from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { normalizeConversationText } from "../../acp/conversation-id.js"; import { normalizeAnyChannelId } from "../../channels/registry.js"; import { resolveStateDir } from "../../config/paths.js"; import { loadJsonFile } from "../../infra/json-file.js"; import { saveJsonFile } from "../../plugin-sdk/json-store.js"; import { getActivePluginChannelRegistryFromState } from "../../plugins/runtime-channel-state.js"; -import { - asDateTimestampMs, - isFutureDateTimestampMs, - resolveExpiresAtMsFromDurationMs, -} from "../../shared/number-coercion.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { normalizeConversationRef } from "./session-binding-normalization.js"; import type { ConversationRef, diff --git a/src/infra/outbound/delivery-queue-recovery.ts b/src/infra/outbound/delivery-queue-recovery.ts index 2ddb32a26f7..ea03f3c2855 100644 --- a/src/infra/outbound/delivery-queue-recovery.ts +++ b/src/infra/outbound/delivery-queue-recovery.ts @@ -1,12 +1,12 @@ +import { + resolveDateTimestampMs, + resolveExpiresAtMsFromDurationMs, +} from "@openclaw/normalization-core/number-coercion"; import type { ChannelMessageSendCommitContext, ChannelMessageUnknownSendReconciliationResult, } from "../../channels/message/types.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { - resolveDateTimestampMs, - resolveExpiresAtMsFromDurationMs, -} from "../../shared/number-coercion.js"; import { formatErrorMessage } from "../errors.js"; import { resolveOutboundChannelMessageAdapter } from "./channel-resolution.js"; import type { OutboundDeliveryResult } from "./deliver-types.js"; diff --git a/src/infra/outbound/delivery-queue.recovery.test.ts b/src/infra/outbound/delivery-queue.recovery.test.ts index 5d89a72e0e3..9f2af735dff 100644 --- a/src/infra/outbound/delivery-queue.recovery.test.ts +++ b/src/infra/outbound/delivery-queue.recovery.test.ts @@ -1,7 +1,7 @@ import fs from "node:fs"; import path from "node:path"; +import { MAX_DATE_TIMESTAMP_MS } from "@openclaw/normalization-core/number-coercion"; import { beforeEach, describe, expect, it, vi } from "vitest"; -import { MAX_DATE_TIMESTAMP_MS } from "../../shared/number-coercion.js"; import { attachOutboundDeliveryCommitHook } from "./delivery-commit-hooks.js"; import { enqueueDelivery, diff --git a/src/infra/outbound/identity.ts b/src/infra/outbound/identity.ts index 596a33b413d..b1cd9037dae 100644 --- a/src/infra/outbound/identity.ts +++ b/src/infra/outbound/identity.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveAgentAvatar } from "../../agents/identity-avatar.js"; import { resolveAgentIdentity } from "../../agents/identity.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { OutboundIdentity } from "./identity-types.js"; export type { OutboundIdentity } from "./identity-types.js"; diff --git a/src/infra/outbound/message-action-normalization.ts b/src/infra/outbound/message-action-normalization.ts index c90eb9d5b98..288890e3b7e 100644 --- a/src/infra/outbound/message-action-normalization.ts +++ b/src/infra/outbound/message-action-normalization.ts @@ -1,8 +1,8 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { ChannelMessageActionName, ChannelThreadingToolContext, } from "../../channels/plugins/types.public.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { isDeliverableMessageChannel, normalizeMessageChannel, diff --git a/src/infra/outbound/message-action-param-keys.ts b/src/infra/outbound/message-action-param-keys.ts index 3134a955f9c..bbe409d6e8f 100644 --- a/src/infra/outbound/message-action-param-keys.ts +++ b/src/infra/outbound/message-action-param-keys.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; const STANDARD_MESSAGE_ACTION_PARAM_KEYS = new Set([ "accountId", diff --git a/src/infra/outbound/message-action-params.ts b/src/infra/outbound/message-action-params.ts index f5225c31688..057abcc1ad6 100644 --- a/src/infra/outbound/message-action-params.ts +++ b/src/infra/outbound/message-action-params.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { assertMediaNotDataUrl, resolveSandboxedMediaSource } from "../../agents/sandbox-paths.js"; import { readStringParam } from "../../agents/tools/common.js"; import { resolveChannelMessageToolMediaSourceParamKeys } from "../../channels/plugins/message-action-discovery.js"; @@ -18,7 +19,6 @@ import { extensionForMime } from "../../media/mime.js"; import { loadWebMedia } from "../../media/web-media.js"; import { resolveSnakeCaseParamKey } from "../../param-key.js"; import { readBooleanParam as readBooleanParamShared } from "../../plugin-sdk/boolean-param.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { hasPotentialPluginActionParam } from "./message-action-param-keys.js"; export const readBooleanParam = readBooleanParamShared; diff --git a/src/infra/outbound/message-action-runner.ts b/src/infra/outbound/message-action-runner.ts index 481c38a2c90..f94a3200d04 100644 --- a/src/infra/outbound/message-action-runner.ts +++ b/src/infra/outbound/message-action-runner.ts @@ -1,3 +1,7 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload"; import { stripPlainTextToolCallBlocks } from "../../../packages/tool-call-repair/src/index.js"; import { resolveSessionAgentId } from "../../agents/agent-scope.js"; @@ -33,10 +37,6 @@ import { resolveAgentScopedOutboundMediaAccess } from "../../media/read-capabili import { hasPollCreationParams } from "../../poll-params.js"; import { resolvePollMaxSelections } from "../../polls.js"; import { resolveFirstBoundAccountId } from "../../routing/bound-account-read.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; import { stripUnsupportedCitationControlMarkers } from "../../shared/text/citation-control-markers.js"; import { stripFormattedReasoningMessage } from "../../shared/text/formatted-reasoning-message.js"; import { parseInlineDirectives } from "../../utils/directive-tags.js"; diff --git a/src/infra/outbound/message-action-spec.ts b/src/infra/outbound/message-action-spec.ts index fef1bd9254f..a6c9b2078f2 100644 --- a/src/infra/outbound/message-action-spec.ts +++ b/src/infra/outbound/message-action-spec.ts @@ -1,9 +1,9 @@ -import { getBootstrapChannelPlugin } from "../../channels/plugins/bootstrap-registry.js"; -import type { ChannelMessageActionName } from "../../channels/plugins/types.public.js"; import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { getBootstrapChannelPlugin } from "../../channels/plugins/bootstrap-registry.js"; +import type { ChannelMessageActionName } from "../../channels/plugins/types.public.js"; import { hasPotentialPluginActionParam } from "./message-action-param-keys.js"; export type MessageActionTargetMode = "to" | "channelId" | "none"; diff --git a/src/infra/outbound/outbound-policy.ts b/src/infra/outbound/outbound-policy.ts index 81a2b80b04e..3efbc96316a 100644 --- a/src/infra/outbound/outbound-policy.ts +++ b/src/infra/outbound/outbound-policy.ts @@ -1,3 +1,4 @@ +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import { getChannelPlugin } from "../../channels/plugins/index.js"; import type { ChannelId, @@ -7,7 +8,6 @@ import type { import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { MessageToolsConfig } from "../../config/types.tools.js"; import type { MessagePresentation } from "../../interactive/payload.js"; -import { normalizeUniqueStringEntries } from "../../shared/string-normalization.js"; import { normalizeTargetForProvider } from "./target-normalization.js"; import { formatTargetDisplay, lookupDirectoryDisplay } from "./target-resolver.js"; diff --git a/src/infra/outbound/outbound-session.test-helpers.ts b/src/infra/outbound/outbound-session.test-helpers.ts index 4608a019d40..0b5117c0975 100644 --- a/src/infra/outbound/outbound-session.test-helpers.ts +++ b/src/infra/outbound/outbound-session.test-helpers.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, +} from "@openclaw/normalization-core/string-coerce"; import type { ChannelPlugin } from "../../channels/plugins/types.plugin.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { @@ -13,10 +17,6 @@ import { type RoutePeer, } from "../../plugin-sdk/routing.js"; import { setActivePluginRegistry } from "../../plugins/runtime.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, -} from "../../shared/string-coerce.js"; import { createChannelTestPluginBase, createTestRegistry, diff --git a/src/infra/outbound/outbound-session.ts b/src/infra/outbound/outbound-session.ts index fb73f729f8d..85a1733decb 100644 --- a/src/infra/outbound/outbound-session.ts +++ b/src/infra/outbound/outbound-session.ts @@ -1,3 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { MsgContext } from "../../auto-reply/templating.js"; import type { ChatType } from "../../channels/chat-type.js"; import { getChannelPlugin } from "../../channels/plugins/index.js"; @@ -9,8 +11,6 @@ import { import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { RoutePeer } from "../../routing/resolve-route.js"; import { resolveAgentIdFromSessionKey } from "../../routing/session-key.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; import { buildOutboundBaseSessionKey } from "./base-session-key.js"; import type { ResolvedMessagingTarget } from "./target-resolver.js"; diff --git a/src/infra/outbound/reply-payload-normalize.ts b/src/infra/outbound/reply-payload-normalize.ts index fa5cb9b9cbd..4f5e8d6f6db 100644 --- a/src/infra/outbound/reply-payload-normalize.ts +++ b/src/infra/outbound/reply-payload-normalize.ts @@ -1,5 +1,5 @@ +import { readStringValue } from "@openclaw/normalization-core/string-coerce"; import type { ReplyPayload as InternalReplyPayload } from "../../auto-reply/reply-payload.js"; -import { readStringValue } from "../../shared/string-coerce.js"; export type OutboundReplyPayload = { text?: string; diff --git a/src/infra/outbound/session-binding-normalization.ts b/src/infra/outbound/session-binding-normalization.ts index 3773f11655f..49afd933aad 100644 --- a/src/infra/outbound/session-binding-normalization.ts +++ b/src/infra/outbound/session-binding-normalization.ts @@ -1,8 +1,8 @@ -import { normalizeAccountId } from "../../routing/session-key.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeAccountId } from "../../routing/session-key.js"; export type ConversationRefShape = { channel: string; diff --git a/src/infra/outbound/session-binding-service.ts b/src/infra/outbound/session-binding-service.ts index 97e654c9f51..92df0fbad7b 100644 --- a/src/infra/outbound/session-binding-service.ts +++ b/src/infra/outbound/session-binding-service.ts @@ -1,5 +1,5 @@ +import { uniqueValues } from "@openclaw/normalization-core/string-normalization"; import { resolveGlobalMap } from "../../shared/global-singleton.js"; -import { uniqueValues } from "../../shared/string-normalization.js"; import { testing as genericCurrentConversationBindingTesting, bindGenericCurrentConversation, diff --git a/src/infra/outbound/session-context.ts b/src/infra/outbound/session-context.ts index aae1319ae83..eec93cdd900 100644 --- a/src/infra/outbound/session-context.ts +++ b/src/infra/outbound/session-context.ts @@ -1,8 +1,8 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveSessionAgentId } from "../../agents/agent-scope.js"; import { normalizeChatType } from "../../channels/chat-type.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { SilentReplyConversationType } from "../../shared/silent-reply-policy.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; export type OutboundSessionContext = { /** diff --git a/src/infra/outbound/source-reply-mirror.ts b/src/infra/outbound/source-reply-mirror.ts index c6eeaf265fa..9773b375f54 100644 --- a/src/infra/outbound/source-reply-mirror.ts +++ b/src/infra/outbound/source-reply-mirror.ts @@ -1,3 +1,8 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeOptionalTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import type { ReplyPayload } from "../../auto-reply/types.js"; import { getChannelPlugin } from "../../channels/plugins/index.js"; import type { @@ -6,11 +11,6 @@ import type { } from "../../channels/plugins/types.public.js"; import { appendAssistantMessageToSessionTranscript } from "../../config/sessions.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; -import { normalizeOptionalTrimmedStringList } from "../../shared/string-normalization.js"; import { createOutboundPayloadPlan, projectOutboundPayloadPlanForMirror } from "./payloads.js"; type SourceReplyTranscriptMirrorParams = { diff --git a/src/infra/outbound/target-normalization.ts b/src/infra/outbound/target-normalization.ts index 453cc1719c7..6a8a170767d 100644 --- a/src/infra/outbound/target-normalization.ts +++ b/src/infra/outbound/target-normalization.ts @@ -1,13 +1,13 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { getChannelPlugin } from "../../channels/plugins/index.js"; import { getLoadedChannelPluginForRead } from "../../channels/plugins/registry-loaded-read.js"; import type { ChannelPlugin } from "../../channels/plugins/types.plugin.js"; import type { ChannelDirectoryEntryKind, ChannelId } from "../../channels/plugins/types.public.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { getActivePluginChannelRegistryVersion } from "../../plugins/runtime.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; export function normalizeChannelTargetInput(raw: string): string { return raw.trim(); diff --git a/src/infra/outbound/target-resolver.ts b/src/infra/outbound/target-resolver.ts index 19488b16f3d..16e41ded97f 100644 --- a/src/infra/outbound/target-resolver.ts +++ b/src/infra/outbound/target-resolver.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { getChannelPlugin } from "../../channels/plugins/index.js"; import type { ChannelDirectoryEntry, @@ -6,7 +7,6 @@ import type { } from "../../channels/plugins/types.public.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { defaultRuntime, type RuntimeEnv } from "../../runtime.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { buildDirectoryCacheKey, DirectoryCache } from "./directory-cache.js"; import { ambiguousTargetError, unknownTargetError } from "./target-errors.js"; import { maybeResolveIdLikeTarget, type ResolvedIdLikeTarget } from "./target-id-resolution.js"; diff --git a/src/infra/outbound/targets-loaded.ts b/src/infra/outbound/targets-loaded.ts index 4f30e8668a0..72a656b9907 100644 --- a/src/infra/outbound/targets-loaded.ts +++ b/src/infra/outbound/targets-loaded.ts @@ -1,8 +1,8 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { getLoadedChannelPluginForRead } from "../../channels/plugins/registry-loaded-read.js"; import type { ChannelPlugin } from "../../channels/plugins/types.plugin.js"; import type { ChannelOutboundTargetMode } from "../../channels/plugins/types.public.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import type { GatewayMessageChannel } from "../../utils/message-channel.js"; import { resolveOutboundTargetWithPlugin, diff --git a/src/infra/outbound/targets-session.ts b/src/infra/outbound/targets-session.ts index 41a347ef076..d30b4c8a7c7 100644 --- a/src/infra/outbound/targets-session.ts +++ b/src/infra/outbound/targets-session.ts @@ -1,12 +1,12 @@ -import { resolveExplicitDeliveryTargetCompat } from "../../channels/plugins/target-parsing-loaded.js"; -import type { ChannelOutboundTargetMode } from "../../channels/plugins/types.public.js"; -import type { SessionEntry } from "../../config/sessions.js"; -import { channelRouteTargetsShareConversation } from "../../plugin-sdk/channel-route.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalThreadValue, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { resolveExplicitDeliveryTargetCompat } from "../../channels/plugins/target-parsing-loaded.js"; +import type { ChannelOutboundTargetMode } from "../../channels/plugins/types.public.js"; +import type { SessionEntry } from "../../config/sessions.js"; +import { channelRouteTargetsShareConversation } from "../../plugin-sdk/channel-route.js"; import { deliveryContextFromSession } from "../../utils/delivery-context.shared.js"; import { isDeliverableMessageChannel, diff --git a/src/infra/outbound/thread-id.ts b/src/infra/outbound/thread-id.ts index 7b47ee47305..b04237a7853 100644 --- a/src/infra/outbound/thread-id.ts +++ b/src/infra/outbound/thread-id.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalStringifiedId } from "../../shared/string-coerce.js"; +import { normalizeOptionalStringifiedId } from "@openclaw/normalization-core/string-coerce"; export function normalizeOutboundThreadId(value?: string | number | null): string | undefined { return normalizeOptionalStringifiedId(value); diff --git a/src/infra/package-dist-inventory.ts b/src/infra/package-dist-inventory.ts index 26a2c627aca..33a404c9324 100644 --- a/src/infra/package-dist-inventory.ts +++ b/src/infra/package-dist-inventory.ts @@ -1,7 +1,7 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { isLocalBuildMetadataDistPath } from "../../scripts/lib/local-build-metadata-paths.mjs"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; import { readJsonIfExists, writeJson } from "./json-files.js"; export { LOCAL_BUILD_METADATA_DIST_PATHS } from "../../scripts/lib/local-build-metadata-paths.mjs"; diff --git a/src/infra/package-json.ts b/src/infra/package-json.ts index 6aa5cdf2cf2..e060157e4ff 100644 --- a/src/infra/package-json.ts +++ b/src/infra/package-json.ts @@ -1,5 +1,5 @@ import path from "node:path"; -import { normalizeNullableString as normalizeString } from "../shared/string-coerce.js"; +import { normalizeNullableString as normalizeString } from "@openclaw/normalization-core/string-coerce"; import { tryReadJson } from "./json-files.js"; type PackageJson = { diff --git a/src/infra/package-tag.ts b/src/infra/package-tag.ts index 41843209962..62f666a1e9d 100644 --- a/src/infra/package-tag.ts +++ b/src/infra/package-tag.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export function normalizePackageTagInput( value: string | undefined | null, diff --git a/src/infra/package-update-utils.ts b/src/infra/package-update-utils.ts index 97457974c42..d71b5e3bc26 100644 --- a/src/infra/package-update-utils.ts +++ b/src/infra/package-update-utils.ts @@ -1,7 +1,7 @@ import fsSync from "node:fs"; import path from "node:path"; import { readRootJsonObjectSync } from "@openclaw/fs-safe/json"; -import { isRecord } from "../shared/record-coerce.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; export function expectedIntegrityForUpdate( spec: string | undefined, diff --git a/src/infra/parse-finite-number.ts b/src/infra/parse-finite-number.ts index 48f322a96ce..889ccabb381 100644 --- a/src/infra/parse-finite-number.ts +++ b/src/infra/parse-finite-number.ts @@ -13,4 +13,4 @@ export { resolveExpiresAtMsFromDurationSeconds, resolveExpiresAtMsFromDurationOrEpoch, resolveExpiresAtMsFromEpochSeconds, -} from "../shared/number-coercion.js"; +} from "../../packages/normalization-core/src/number-coercion.js"; diff --git a/src/infra/path-env.ts b/src/infra/path-env.ts index 71eb57ca10a..04655c68f7d 100644 --- a/src/infra/path-env.ts +++ b/src/infra/path-env.ts @@ -4,7 +4,7 @@ import path from "node:path"; import { normalizeStringEntries, normalizeUniqueStringEntries, -} from "../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-normalization"; import { resolveBrewPathDirs } from "./brew.js"; import { isTruthyEnvValue } from "./env.js"; diff --git a/src/infra/path-prepend.ts b/src/infra/path-prepend.ts index e06bf345165..177f93e3c1a 100644 --- a/src/infra/path-prepend.ts +++ b/src/infra/path-prepend.ts @@ -2,7 +2,7 @@ import path from "node:path"; import { normalizeStringEntries, normalizeUniqueStringEntries, -} from "../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-normalization"; /** * Find the actual key used for PATH in the env object. diff --git a/src/infra/plugin-install-path-warnings.ts b/src/infra/plugin-install-path-warnings.ts index 70b5eb2e3db..2d0dc6f454d 100644 --- a/src/infra/plugin-install-path-warnings.ts +++ b/src/infra/plugin-install-path-warnings.ts @@ -1,7 +1,7 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { PluginInstallRecord } from "../config/types.plugins.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; type PluginInstallPathIssue = { kind: "custom-path" | "missing-path"; diff --git a/src/infra/ports-format.ts b/src/infra/ports-format.ts index 2198cf0b34a..bf4d37f2726 100644 --- a/src/infra/ports-format.ts +++ b/src/infra/ports-format.ts @@ -1,5 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { formatCliCommand } from "../cli/command-format.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import type { PortListener, PortListenerKind, PortUsage } from "./ports-types.js"; export function classifyPortListener(listener: PortListener, port: number): PortListenerKind { diff --git a/src/infra/ports-inspect.ts b/src/infra/ports-inspect.ts index 500c0f00bd7..d1961c41946 100644 --- a/src/infra/ports-inspect.ts +++ b/src/infra/ports-inspect.ts @@ -1,6 +1,6 @@ import os from "node:os"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { runCommandWithTimeout } from "../process/exec.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { isErrno } from "./errors.js"; import { parseStrictPositiveInteger } from "./parse-finite-number.js"; import { buildPortHints } from "./ports-format.js"; diff --git a/src/infra/process-respawn.ts b/src/infra/process-respawn.ts index e823e35e928..2a73a39d27d 100644 --- a/src/infra/process-respawn.ts +++ b/src/infra/process-respawn.ts @@ -1,5 +1,5 @@ import { spawn, type ChildProcess } from "node:child_process"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { isContainerEnvironment } from "./container-environment.js"; import { formatErrorMessage } from "./errors.js"; import { triggerOpenClawRestart } from "./restart.js"; diff --git a/src/infra/provider-usage.auth.ts b/src/infra/provider-usage.auth.ts index 380fd6a1e2e..c24e2811502 100644 --- a/src/infra/provider-usage.auth.ts +++ b/src/infra/provider-usage.auth.ts @@ -1,3 +1,4 @@ +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import { dedupeProfileIds, ensureAuthProfileStore, @@ -21,7 +22,6 @@ import { import type { PluginManifestRecord } from "../plugins/manifest-registry.js"; import { resolveProviderUsageAuthWithPlugin } from "../plugins/provider-runtime.js"; import { resolveProviderAuthEnvVarCandidates } from "../secrets/provider-env-vars.js"; -import { normalizeUniqueStringEntries } from "../shared/string-normalization.js"; import { normalizeSecretInput } from "../utils/normalize-secret-input.js"; import { isOAuthOnlyUsageProvider } from "./provider-usage.shared.js"; import type { UsageProviderId } from "./provider-usage.types.js"; diff --git a/src/infra/provider-usage.fetch.gemini.ts b/src/infra/provider-usage.fetch.gemini.ts index 044f0725b3e..9c0b04f1e4f 100644 --- a/src/infra/provider-usage.fetch.gemini.ts +++ b/src/infra/provider-usage.fetch.gemini.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { buildUsageHttpErrorSnapshot, fetchJson, diff --git a/src/infra/provider-usage.fetch.minimax.ts b/src/infra/provider-usage.fetch.minimax.ts index 162767a285b..06558df2329 100644 --- a/src/infra/provider-usage.fetch.minimax.ts +++ b/src/infra/provider-usage.fetch.minimax.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { isRecord } from "../utils.js"; import { buildUsageHttpErrorSnapshot, diff --git a/src/infra/provider-usage.fetch.shared.test.ts b/src/infra/provider-usage.fetch.shared.test.ts index ca5eaf3b0d0..d05795909c0 100644 --- a/src/infra/provider-usage.fetch.shared.test.ts +++ b/src/infra/provider-usage.fetch.shared.test.ts @@ -1,5 +1,5 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { withFetchPreconnect } from "../test-utils/fetch-mock.js"; import { buildUsageErrorSnapshot, diff --git a/src/infra/provider-usage.fetch.shared.ts b/src/infra/provider-usage.fetch.shared.ts index 84e1d877e01..469bf94258a 100644 --- a/src/infra/provider-usage.fetch.shared.ts +++ b/src/infra/provider-usage.fetch.shared.ts @@ -1,4 +1,4 @@ -import { resolveTimerTimeoutMs } from "../shared/number-coercion.js"; +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; import { parseFiniteNumber as parseFiniteNumberish } from "./parse-finite-number.js"; import { PROVIDER_LABELS } from "./provider-usage.shared.js"; import type { ProviderUsageSnapshot, UsageProviderId } from "./provider-usage.types.js"; diff --git a/src/infra/push-apns-http2.test.ts b/src/infra/push-apns-http2.test.ts index 60fc6986e60..72697f04d51 100644 --- a/src/infra/push-apns-http2.test.ts +++ b/src/infra/push-apns-http2.test.ts @@ -1,6 +1,6 @@ import type http2 from "node:http2"; +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { beforeEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import type { HttpConnectTunnelParams } from "./net/http-connect-tunnel.js"; import { resetActiveManagedProxyStateForTests, diff --git a/src/infra/push-apns-http2.ts b/src/infra/push-apns-http2.ts index d0108585ae6..e4de639706e 100644 --- a/src/infra/push-apns-http2.ts +++ b/src/infra/push-apns-http2.ts @@ -1,5 +1,5 @@ import http2 from "node:http2"; -import { resolveTimerTimeoutMs } from "../shared/number-coercion.js"; +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; import { openHttpConnectTunnel } from "./net/http-connect-tunnel.js"; import { getActiveManagedProxyUrl, diff --git a/src/infra/push-apns.relay.test.ts b/src/infra/push-apns.relay.test.ts index b1b93dc49b5..344995cde0f 100644 --- a/src/infra/push-apns.relay.test.ts +++ b/src/infra/push-apns.relay.test.ts @@ -1,6 +1,6 @@ import { generateKeyPairSync } from "node:crypto"; +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { deriveDeviceIdFromPublicKey, publicKeyRawBase64UrlFromPem, diff --git a/src/infra/push-apns.relay.ts b/src/infra/push-apns.relay.ts index 5da11c412aa..f6458cc6e3f 100644 --- a/src/infra/push-apns.relay.ts +++ b/src/infra/push-apns.relay.ts @@ -1,10 +1,10 @@ import { URL } from "node:url"; -import type { GatewayConfig } from "../config/types.gateway.js"; -import { resolveTimerTimeoutMs } from "../shared/number-coercion.js"; +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { GatewayConfig } from "../config/types.gateway.js"; import { loadOrCreateDeviceIdentity, signDevicePayload, diff --git a/src/infra/push-apns.test.ts b/src/infra/push-apns.test.ts index ef0caa783c6..b4fe79b72e0 100644 --- a/src/infra/push-apns.test.ts +++ b/src/infra/push-apns.test.ts @@ -2,8 +2,8 @@ import { generateKeyPairSync } from "node:crypto"; import { createServer, type Server as HttpServer } from "node:http"; import http2 from "node:http2"; import net from "node:net"; +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { startProxy, stopProxy, type ProxyHandle } from "./net/proxy/proxy-lifecycle.js"; import { sendApnsAlert, diff --git a/src/infra/push-apns.ts b/src/infra/push-apns.ts index 65d2be7e872..0fa4c091dd1 100644 --- a/src/infra/push-apns.ts +++ b/src/infra/push-apns.ts @@ -1,12 +1,12 @@ import { createHash, createPrivateKey, sign as signJwt } from "node:crypto"; import fs from "node:fs/promises"; import path from "node:path"; -import { resolveStateDir } from "../config/paths.js"; -import { resolveTimerTimeoutMs } from "../shared/number-coercion.js"; +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { resolveStateDir } from "../config/paths.js"; import type { DeviceIdentity } from "./device-identity.js"; import { formatErrorMessage } from "./errors.js"; import { createAsyncLock, tryReadJson, writeJson } from "./json-files.js"; diff --git a/src/infra/restart-handoff.ts b/src/infra/restart-handoff.ts index 99b90c078f2..02ce563ff0a 100644 --- a/src/infra/restart-handoff.ts +++ b/src/infra/restart-handoff.ts @@ -1,9 +1,9 @@ import { randomUUID } from "node:crypto"; import fs from "node:fs"; import path from "node:path"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { resolveStateDir } from "../config/paths.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; -import { isRecord } from "../shared/record-coerce.js"; export const GATEWAY_SUPERVISOR_RESTART_HANDOFF_FILENAME = "gateway-supervisor-restart-handoff.json"; diff --git a/src/infra/restart-sentinel.ts b/src/infra/restart-sentinel.ts index 05df064fe6d..3ba2a9c2d73 100644 --- a/src/infra/restart-sentinel.ts +++ b/src/infra/restart-sentinel.ts @@ -1,8 +1,8 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { isRecord as isPlainRecord } from "@openclaw/normalization-core/record-coerce"; import { formatCliCommand } from "../cli/command-format.js"; import { resolveStateDir } from "../config/paths.js"; -import { isRecord as isPlainRecord } from "../shared/record-coerce.js"; import { resolveRuntimeServiceVersion } from "../version.js"; import { writeJson } from "./json-files.js"; diff --git a/src/infra/restart-stale-pids.ts b/src/infra/restart-stale-pids.ts index f82c07a167a..cd5097dfce5 100644 --- a/src/infra/restart-stale-pids.ts +++ b/src/infra/restart-stale-pids.ts @@ -1,10 +1,10 @@ import { spawnSync } from "node:child_process"; import { readFileSync } from "node:fs"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { uniqueValues } from "@openclaw/normalization-core/string-normalization"; import { resolveGatewayPort } from "../config/paths.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { uniqueValues } from "../shared/string-normalization.js"; import { isGatewayArgv, parseProcCmdline } from "./gateway-process-argv.js"; import { parseStrictPositiveInteger } from "./parse-finite-number.js"; import { resolveLsofCommandSync } from "./ports-lsof.js"; diff --git a/src/infra/retry.ts b/src/infra/retry.ts index 5029484f833..a3f6db7e67b 100644 --- a/src/infra/retry.ts +++ b/src/infra/retry.ts @@ -1,4 +1,4 @@ -import { asFiniteNumber } from "../shared/number-coercion.js"; +import { asFiniteNumber } from "@openclaw/normalization-core/number-coercion"; import { sleep } from "../utils.js"; import { MAX_SAFE_TIMEOUT_DELAY_MS, resolveSafeTimeoutDelayMs } from "../utils/timer-delay.js"; import { generateSecureFraction } from "./secure-random.js"; diff --git a/src/infra/runtime-status.ts b/src/infra/runtime-status.ts index fcb28ecf815..79d88053e9f 100644 --- a/src/infra/runtime-status.ts +++ b/src/infra/runtime-status.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; type RuntimeStatusFormatInput = { status?: string; diff --git a/src/infra/scp-host.ts b/src/infra/scp-host.ts index 527c2cb3765..c3df0403266 100644 --- a/src/infra/scp-host.ts +++ b/src/infra/scp-host.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; const SSH_TOKEN = /^[A-Za-z0-9._-]+$/; const BRACKETED_IPV6 = /^\[[0-9A-Fa-f:.%]+\]$/; diff --git a/src/infra/session-cost-usage.ts b/src/infra/session-cost-usage.ts index ae311124be2..169317102a6 100644 --- a/src/infra/session-cost-usage.ts +++ b/src/infra/session-cost-usage.ts @@ -1,6 +1,8 @@ import fs from "node:fs"; import path from "node:path"; import readline from "node:readline"; +import { asFiniteNumber } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { NormalizedUsage, UsageLike } from "../agents/usage.js"; import { normalizeUsage } from "../agents/usage.js"; import { stripInboundMetadata } from "../auto-reply/reply/strip-inbound-meta.js"; @@ -19,8 +21,6 @@ import type { SessionEntry } from "../config/sessions/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { stripEnvelope, stripMessageIdHints } from "../shared/chat-envelope.js"; -import { asFiniteNumber } from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { runTasksWithConcurrency } from "../utils/run-with-concurrency.js"; import { countToolResults, extractToolCallNames } from "../utils/transcript-tools.js"; import { diff --git a/src/infra/session-delivery-queue-recovery.ts b/src/infra/session-delivery-queue-recovery.ts index f37a6a2fc35..b19e24b944e 100644 --- a/src/infra/session-delivery-queue-recovery.ts +++ b/src/infra/session-delivery-queue-recovery.ts @@ -2,7 +2,7 @@ import { resolveDateTimestampMs, resolveExpiresAtMsFromDurationMs, resolveNonNegativeIntegerOption, -} from "../shared/number-coercion.js"; +} from "@openclaw/normalization-core/number-coercion"; import { formatErrorMessage } from "./errors.js"; import { ackSessionDelivery, diff --git a/src/infra/session-delivery-queue.recovery.test.ts b/src/infra/session-delivery-queue.recovery.test.ts index d48742c8903..4d21ce47d38 100644 --- a/src/infra/session-delivery-queue.recovery.test.ts +++ b/src/infra/session-delivery-queue.recovery.test.ts @@ -1,5 +1,5 @@ +import { MAX_DATE_TIMESTAMP_MS } from "@openclaw/normalization-core/number-coercion"; import { describe, expect, it, vi } from "vitest"; -import { MAX_DATE_TIMESTAMP_MS } from "../shared/number-coercion.js"; import { withTempDir } from "../test-helpers/temp-dir.js"; import { drainPendingSessionDeliveries, diff --git a/src/infra/shell-env.test.ts b/src/infra/shell-env.test.ts index c869eaab417..81fe3c17157 100644 --- a/src/infra/shell-env.test.ts +++ b/src/infra/shell-env.test.ts @@ -1,7 +1,7 @@ import fs from "node:fs"; import os from "node:os"; +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { getShellEnvAppliedKeys, getShellPathFromLoginShell, diff --git a/src/infra/shell-env.ts b/src/infra/shell-env.ts index f65019a00c7..c9ea02cafbc 100644 --- a/src/infra/shell-env.ts +++ b/src/infra/shell-env.ts @@ -2,7 +2,7 @@ import { execFileSync } from "node:child_process"; import fs from "node:fs"; import os from "node:os"; import path from "node:path"; -import { resolveTimerTimeoutMs } from "../shared/number-coercion.js"; +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; import { isTruthyEnvValue } from "./env.js"; import { formatErrorMessage } from "./errors.js"; import { sanitizeHostExecEnv } from "./host-env-security.js"; diff --git a/src/infra/shell-inline-command.ts b/src/infra/shell-inline-command.ts index ed6ff7a8045..701bfe13772 100644 --- a/src/infra/shell-inline-command.ts +++ b/src/infra/shell-inline-command.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export const POSIX_INLINE_COMMAND_FLAGS = new Set(["-lc", "-c", "--command"]); diff --git a/src/infra/shell-wrapper-resolution.ts b/src/infra/shell-wrapper-resolution.ts index e3c253ea7b5..e252d3ec52c 100644 --- a/src/infra/shell-wrapper-resolution.ts +++ b/src/infra/shell-wrapper-resolution.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { MAX_DISPATCH_WRAPPER_DEPTH, hasDispatchEnvManipulation, diff --git a/src/infra/ssh-tunnel.ts b/src/infra/ssh-tunnel.ts index b590c100ae7..3d80f5dfa67 100644 --- a/src/infra/ssh-tunnel.ts +++ b/src/infra/ssh-tunnel.ts @@ -1,6 +1,6 @@ import { spawn } from "node:child_process"; import net from "node:net"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { formatErrorMessage, isErrno } from "./errors.js"; import { parseStrictPositiveInteger } from "./parse-finite-number.js"; import { ensurePortAvailable } from "./ports.js"; diff --git a/src/infra/state-migrations.ts b/src/infra/state-migrations.ts index 1f4b3c50893..79ee8cabfec 100644 --- a/src/infra/state-migrations.ts +++ b/src/infra/state-migrations.ts @@ -2,6 +2,7 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import type { DatabaseSync, SQLInputValue } from "node:sqlite"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { resolveDefaultAgentId } from "../agents/agent-scope.js"; import { listBundledChannelLegacySessionSurfaces, @@ -40,7 +41,6 @@ import { parseAgentSessionKey, } from "../routing/session-key.js"; import { normalizeSessionKeyPreservingOpaquePeerIds } from "../sessions/session-key-utils.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import type { DB as OpenClawStateKyselyDatabase } from "../state/openclaw-state-db.generated.js"; import { runOpenClawStateWriteTransaction } from "../state/openclaw-state-db.js"; import { expandHomePrefix } from "./home-dir.js"; diff --git a/src/infra/system-events.ts b/src/infra/system-events.ts index 6cae9c9a10f..7e180d046cd 100644 --- a/src/infra/system-events.ts +++ b/src/infra/system-events.ts @@ -2,13 +2,13 @@ // prefixed to the next prompt. We intentionally avoid persistence to keep // events ephemeral. Events are session-scoped and require an explicit key. -import { channelRouteDedupeKey } from "../plugin-sdk/channel-route.js"; -import { sanitizeInboundSystemTags } from "../security/system-tags.js"; -import { resolveGlobalMap } from "../shared/global-singleton.js"; import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { channelRouteDedupeKey } from "../plugin-sdk/channel-route.js"; +import { sanitizeInboundSystemTags } from "../security/system-tags.js"; +import { resolveGlobalMap } from "../shared/global-singleton.js"; import { mergeDeliveryContext, normalizeDeliveryContext, diff --git a/src/infra/system-presence.ts b/src/infra/system-presence.ts index 1fb7398431e..529f2760f86 100644 --- a/src/infra/system-presence.ts +++ b/src/infra/system-presence.ts @@ -4,7 +4,7 @@ import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; import { resolveRuntimeServiceVersion } from "../version.js"; import { pickBestEffortPrimaryLanIPv4 } from "./network-discovery-display.js"; diff --git a/src/infra/system-run-normalize.ts b/src/infra/system-run-normalize.ts index b80516af07b..6b053347d77 100644 --- a/src/infra/system-run-normalize.ts +++ b/src/infra/system-run-normalize.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { mapAllowFromEntries } from "openclaw/plugin-sdk/channel-config-helpers"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; export function normalizeNonEmptyString(value: unknown): string | null { return typeof value === "string" ? (normalizeOptionalString(value) ?? null) : null; diff --git a/src/infra/tailnet.ts b/src/infra/tailnet.ts index d0eb0c5ad4c..fce4f7dfd2b 100644 --- a/src/infra/tailnet.ts +++ b/src/infra/tailnet.ts @@ -1,5 +1,5 @@ import { isIpInCidr } from "@openclaw/net-policy/ip"; -import { uniqueStrings } from "../shared/string-normalization.js"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { listExternalInterfaceAddresses, readNetworkInterfaces } from "./network-interfaces.js"; type TailnetAddresses = { diff --git a/src/infra/tailscale.ts b/src/infra/tailscale.ts index 4ff1cab8379..4d1c8ecb4dc 100644 --- a/src/infra/tailscale.ts +++ b/src/infra/tailscale.ts @@ -1,16 +1,19 @@ import { existsSync } from "node:fs"; +import { + asDateTimestampMs, + resolveExpiresAtMsFromDurationMs, +} from "@openclaw/normalization-core/number-coercion"; +import { asNullableObjectRecord as readRecord } from "@openclaw/normalization-core/record-coerce"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { colorize, isRich, theme } from "../../packages/terminal-core/src/theme.js"; import { formatCliCommand } from "../cli/command-format.js"; import { promptYesNo } from "../cli/prompt.js"; import { danger, info, logVerbose, shouldLogVerbose, warn } from "../globals.js"; import { runExec } from "../process/exec.js"; import { defaultRuntime, type RuntimeEnv } from "../runtime.js"; -import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "../shared/number-coercion.js"; -import { asNullableObjectRecord as readRecord } from "../shared/record-coerce.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { ensureBinary } from "./binaries.js"; function parsePossiblyNoisyJsonObject(stdout: string): Record { diff --git a/src/infra/tls/fingerprint.ts b/src/infra/tls/fingerprint.ts index 5ffc3804976..85cdd14b1c8 100644 --- a/src/infra/tls/fingerprint.ts +++ b/src/infra/tls/fingerprint.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export function normalizeFingerprint(input: string): string { const trimmed = input.trim(); diff --git a/src/infra/transport-ready.test.ts b/src/infra/transport-ready.test.ts index 7a67dc49a4c..aa0bd2d5949 100644 --- a/src/infra/transport-ready.test.ts +++ b/src/infra/transport-ready.test.ts @@ -1,5 +1,5 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; const transportReadyMocks = vi.hoisted(() => ({ injectedSleepError: null as Error | null, diff --git a/src/infra/transport-ready.ts b/src/infra/transport-ready.ts index 16875bab68c..f09de7188bd 100644 --- a/src/infra/transport-ready.ts +++ b/src/infra/transport-ready.ts @@ -1,6 +1,6 @@ +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; import { danger } from "../globals.js"; import type { RuntimeEnv } from "../runtime.js"; -import { resolveTimerTimeoutMs } from "../shared/number-coercion.js"; import { sleepWithAbort } from "./backoff.js"; export type TransportReadyResult = { diff --git a/src/infra/unhandled-rejections.ts b/src/infra/unhandled-rejections.ts index 243c5a8be16..863a1d0db2b 100644 --- a/src/infra/unhandled-rejections.ts +++ b/src/infra/unhandled-rejections.ts @@ -1,6 +1,6 @@ import process from "node:process"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { restoreTerminalState } from "../../packages/terminal-core/src/restore.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { collectErrorGraphCandidates, extractErrorCode, diff --git a/src/infra/update-channels.ts b/src/infra/update-channels.ts index a30105f7fd4..d71b82002a5 100644 --- a/src/infra/update-channels.ts +++ b/src/infra/update-channels.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { parseComparableSemver } from "./semver-compare.js"; export type UpdateChannel = "stable" | "beta" | "dev"; diff --git a/src/infra/update-control-plane-sentinel.ts b/src/infra/update-control-plane-sentinel.ts index be74a798b81..1e30d59d39b 100644 --- a/src/infra/update-control-plane-sentinel.ts +++ b/src/infra/update-control-plane-sentinel.ts @@ -1,5 +1,5 @@ import fs from "node:fs/promises"; -import { isRecord } from "../shared/record-coerce.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { markUpdateRestartSentinelFailure, writeRestartSentinel, diff --git a/src/infra/update-global.ts b/src/infra/update-global.ts index 8fbf0c4954e..82378fc8133 100644 --- a/src/infra/update-global.ts +++ b/src/infra/update-global.ts @@ -2,8 +2,8 @@ import fsSync from "node:fs"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { BUNDLED_RUNTIME_SIDECAR_PATHS } from "../plugins/runtime-sidecar-paths.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { pathExists } from "../utils.js"; import { applyNpmFreshnessBypassEnv, diff --git a/src/infra/update-runner.ts b/src/infra/update-runner.ts index c41bb101c0f..d4d26bb4936 100644 --- a/src/infra/update-runner.ts +++ b/src/infra/update-runner.ts @@ -1,9 +1,12 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; +import { + normalizeStringEntries, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { resolveGatewayInstallEntrypoint } from "../daemon/gateway-entrypoint.js"; import { type CommandOptions, runCommandWithTimeout } from "../process/exec.js"; -import { normalizeStringEntries, uniqueStrings } from "../shared/string-normalization.js"; import { resolveControlUiDistIndexHealth, resolveControlUiDistIndexPathForRoot, diff --git a/src/infra/update-startup.ts b/src/infra/update-startup.ts index 7f3f186f7bf..17861231cbb 100644 --- a/src/infra/update-startup.ts +++ b/src/infra/update-startup.ts @@ -1,12 +1,15 @@ import { createHash, randomUUID } from "node:crypto"; import fs from "node:fs/promises"; import path from "node:path"; +import { + asDateTimestampMs, + timestampMsToIsoString, +} from "@openclaw/normalization-core/number-coercion"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { formatCliCommand } from "../cli/command-format.js"; import { resolveStateDir } from "../config/paths.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { runCommandWithTimeout } from "../process/exec.js"; -import { asDateTimestampMs, timestampMsToIsoString } from "../shared/number-coercion.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { VERSION } from "../version.js"; import { isTruthyEnvValue } from "./env.js"; import { writeJson } from "./json-files.js"; diff --git a/src/infra/voicewake-routing.ts b/src/infra/voicewake-routing.ts index 6af738db8b7..63046f13986 100644 --- a/src/infra/voicewake-routing.ts +++ b/src/infra/voicewake-routing.ts @@ -1,12 +1,12 @@ import path from "node:path"; +import { isRecord as isPlainObject } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveStateDir } from "../config/paths.js"; import { classifySessionKeyShape, isValidAgentId, normalizeAgentId, } from "../routing/session-key.js"; -import { isRecord as isPlainObject } from "../shared/record-coerce.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { createAsyncLock, tryReadJson, writeJson } from "./json-files.js"; type VoiceWakeRouteTarget = diff --git a/src/infra/voicewake.ts b/src/infra/voicewake.ts index f53da3f651d..faf71324670 100644 --- a/src/infra/voicewake.ts +++ b/src/infra/voicewake.ts @@ -1,6 +1,6 @@ import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveStateDir } from "../config/paths.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { createAsyncLock, tryReadJson, writeJson } from "./json-files.js"; type VoiceWakeConfig = { diff --git a/src/infra/widearea-dns.ts b/src/infra/widearea-dns.ts index 30b60431d85..d0b4ea413eb 100644 --- a/src/infra/widearea-dns.ts +++ b/src/infra/widearea-dns.ts @@ -1,7 +1,7 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { CONFIG_DIR, ensureDir } from "../utils.js"; const DNS_LABEL_RE = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$/; diff --git a/src/infra/windows-encoding.ts b/src/infra/windows-encoding.ts index 3b2421a93ff..62afe62de0f 100644 --- a/src/infra/windows-encoding.ts +++ b/src/infra/windows-encoding.ts @@ -1,5 +1,5 @@ import { spawnSync } from "node:child_process"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; const WINDOWS_CODEPAGE_ENCODING_MAP: Record = { 65001: "utf-8", diff --git a/src/infra/windows-install-roots.ts b/src/infra/windows-install-roots.ts index fe7939ea04b..c0e526f1062 100644 --- a/src/infra/windows-install-roots.ts +++ b/src/infra/windows-install-roots.ts @@ -1,7 +1,7 @@ import { execFileSync } from "node:child_process"; import fs from "node:fs"; import path from "node:path"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export const DEFAULT_WINDOWS_SYSTEM_ROOT = "C:\\Windows"; const DEFAULT_PROGRAM_FILES = "C:\\Program Files"; diff --git a/src/infra/windows-port-pids.ts b/src/infra/windows-port-pids.ts index 6e0bc044b5a..ad1a976e27f 100644 --- a/src/infra/windows-port-pids.ts +++ b/src/infra/windows-port-pids.ts @@ -1,7 +1,7 @@ import { spawnSync } from "node:child_process"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { parseCmdScriptCommandLine } from "../daemon/cmd-argv.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { parseStrictPositiveInteger } from "./parse-finite-number.js"; const DEFAULT_TIMEOUT_MS = 5_000; diff --git a/src/infra/wsl.ts b/src/infra/wsl.ts index 3258163a5f2..67953961fc9 100644 --- a/src/infra/wsl.ts +++ b/src/infra/wsl.ts @@ -1,6 +1,6 @@ import { readFileSync } from "node:fs"; import fs from "node:fs/promises"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; let wslCached: boolean | null = null; diff --git a/src/interactive/payload.ts b/src/interactive/payload.ts index 42b947d3908..2eab8d96609 100644 --- a/src/interactive/payload.ts +++ b/src/interactive/payload.ts @@ -1,8 +1,8 @@ -import { asOptionalRecord as toRecord } from "../shared/record-coerce.js"; +import { asOptionalRecord as toRecord } from "@openclaw/normalization-core/record-coerce"; import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; export type InteractiveButtonStyle = "primary" | "secondary" | "success" | "danger"; diff --git a/src/link-understanding/format.ts b/src/link-understanding/format.ts index 2fb1545ed04..0efe209cf49 100644 --- a/src/link-understanding/format.ts +++ b/src/link-understanding/format.ts @@ -1,4 +1,4 @@ -import { normalizeStringEntries } from "../shared/string-normalization.js"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; export function formatLinkUnderstandingBody(params: { body?: string; outputs: string[] }): string { const outputs = normalizeStringEntries(params.outputs); diff --git a/src/llm/providers/openai-chatgpt-responses.test.ts b/src/llm/providers/openai-chatgpt-responses.test.ts index fc9243cc5ac..f89a30a902d 100644 --- a/src/llm/providers/openai-chatgpt-responses.test.ts +++ b/src/llm/providers/openai-chatgpt-responses.test.ts @@ -1,5 +1,5 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../../shared/number-coercion.js"; import type { Context, Model } from "../types.js"; import { extractOpenAICodexAccountId, diff --git a/src/llm/providers/openai-chatgpt-responses.ts b/src/llm/providers/openai-chatgpt-responses.ts index ab2bccc9490..ba0720af984 100644 --- a/src/llm/providers/openai-chatgpt-responses.ts +++ b/src/llm/providers/openai-chatgpt-responses.ts @@ -20,7 +20,10 @@ if (typeof process !== "undefined" && (process.versions?.node || process.version }); } -import { resolveTimerTimeoutMs, clampTimerTimeoutMs } from "../../shared/number-coercion.js"; +import { + resolveTimerTimeoutMs, + clampTimerTimeoutMs, +} from "@openclaw/normalization-core/number-coercion"; import { getEnvApiKey } from "../env-api-keys.js"; import { clampThinkingLevel } from "../model-utils.js"; import { registerSessionResourceCleanup } from "../session-resources.js"; diff --git a/src/llm/providers/stream-wrappers/anthropic-family-cache-semantics.ts b/src/llm/providers/stream-wrappers/anthropic-family-cache-semantics.ts index 33d60805a58..e0923eaca05 100644 --- a/src/llm/providers/stream-wrappers/anthropic-family-cache-semantics.ts +++ b/src/llm/providers/stream-wrappers/anthropic-family-cache-semantics.ts @@ -1,7 +1,7 @@ import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, -} from "../../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; type AnthropicCacheRetentionFamily = | "anthropic-direct" diff --git a/src/llm/providers/stream-wrappers/anthropic-family-tool-payload-compat.ts b/src/llm/providers/stream-wrappers/anthropic-family-tool-payload-compat.ts index 45459592c5f..423eead785c 100644 --- a/src/llm/providers/stream-wrappers/anthropic-family-tool-payload-compat.ts +++ b/src/llm/providers/stream-wrappers/anthropic-family-tool-payload-compat.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { StreamFn } from "../../../agents/runtime/index.js"; -import { normalizeOptionalString } from "../../../shared/string-coerce.js"; import { streamSimple } from "../../stream.js"; type AnthropicToolSchemaMode = "openai-functions"; type AnthropicToolChoiceMode = "openai-string-modes"; diff --git a/src/llm/providers/stream-wrappers/moonshot-thinking.ts b/src/llm/providers/stream-wrappers/moonshot-thinking.ts index 3bf70536ae7..a33b6a606f1 100644 --- a/src/llm/providers/stream-wrappers/moonshot-thinking.ts +++ b/src/llm/providers/stream-wrappers/moonshot-thinking.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { StreamFn } from "../../../agents/runtime/index.js"; import type { ThinkLevel } from "../../../auto-reply/thinking.js"; import { createLazyImportLoader } from "../../../shared/lazy-promise.js"; -import { normalizeOptionalLowercaseString } from "../../../shared/string-coerce.js"; import { streamWithPayloadPatch } from "./stream-payload-utils.js"; type MoonshotThinkingType = "enabled" | "disabled"; diff --git a/src/llm/providers/stream-wrappers/openai.ts b/src/llm/providers/stream-wrappers/openai.ts index 7262565f05b..38c8b038a39 100644 --- a/src/llm/providers/stream-wrappers/openai.ts +++ b/src/llm/providers/stream-wrappers/openai.ts @@ -1,3 +1,7 @@ +import { + normalizeOptionalLowercaseString, + readStringValue, +} from "@openclaw/normalization-core/string-coerce"; import { patchCodexNativeWebSearchPayload, resolveCodexNativeSearchActivation, @@ -22,10 +26,6 @@ import type { StreamFn } from "../../../agents/runtime/index.js"; import type { ThinkLevel } from "../../../auto-reply/thinking.js"; import type { OpenClawConfig } from "../../../config/types.openclaw.js"; import { createSubsystemLogger } from "../../../logging/subsystem.js"; -import { - normalizeOptionalLowercaseString, - readStringValue, -} from "../../../shared/string-coerce.js"; import { streamSimple } from "../../stream.js"; import type { SimpleStreamOptions } from "../../types.js"; import { mapThinkingLevelToReasoningEffort } from "./reasoning-effort-utils.js"; diff --git a/src/llm/providers/stream-wrappers/proxy.ts b/src/llm/providers/stream-wrappers/proxy.ts index ab2d79e5b3a..6398a7afd14 100644 --- a/src/llm/providers/stream-wrappers/proxy.ts +++ b/src/llm/providers/stream-wrappers/proxy.ts @@ -1,12 +1,12 @@ +import { + normalizeOptionalLowercaseString, + readStringValue, +} from "@openclaw/normalization-core/string-coerce"; import { resolveProviderRequestPolicy } from "../../../agents/provider-attribution.js"; import { resolveProviderRequestPolicyConfig } from "../../../agents/provider-request-config.js"; import type { StreamFn } from "../../../agents/runtime/index.js"; import type { ThinkLevel } from "../../../auto-reply/thinking.js"; import { parseStrictFiniteNumber } from "../../../infra/parse-finite-number.js"; -import { - normalizeOptionalLowercaseString, - readStringValue, -} from "../../../shared/string-coerce.js"; import { streamSimple } from "../../stream.js"; import { applyAnthropicEphemeralCacheControlMarkers } from "./anthropic-cache-control-payload.js"; import { isAnthropicModelRef } from "./anthropic-family-cache-semantics.js"; diff --git a/src/llm/utils/oauth/abort.test.ts b/src/llm/utils/oauth/abort.test.ts index 0ef3968793c..459221c0923 100644 --- a/src/llm/utils/oauth/abort.test.ts +++ b/src/llm/utils/oauth/abort.test.ts @@ -1,5 +1,5 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../../../shared/number-coercion.js"; import { buildOAuthRequestSignal } from "./abort.js"; describe("buildOAuthRequestSignal", () => { diff --git a/src/llm/utils/oauth/github-copilot.test.ts b/src/llm/utils/oauth/github-copilot.test.ts index edfea49b9d7..03d2bf6ac17 100644 --- a/src/llm/utils/oauth/github-copilot.test.ts +++ b/src/llm/utils/oauth/github-copilot.test.ts @@ -1,5 +1,5 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../../../shared/number-coercion.js"; import { refreshGitHubCopilotToken, testing } from "./github-copilot.js"; function stubHangingFetch(timeoutMs: number): void { diff --git a/src/llm/utils/oauth/github-copilot.ts b/src/llm/utils/oauth/github-copilot.ts index 8cf02421bec..8325f98037d 100644 --- a/src/llm/utils/oauth/github-copilot.ts +++ b/src/llm/utils/oauth/github-copilot.ts @@ -2,13 +2,13 @@ * GitHub Copilot OAuth flow */ +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; import { nonNegativeSecondsToSafeMilliseconds, positiveSecondsToSafeMilliseconds, resolveExpiresAtMsFromDurationSeconds, resolveExpiresAtMsFromEpochSeconds, } from "../../../infra/parse-finite-number.js"; -import { resolveTimerTimeoutMs } from "../../../shared/number-coercion.js"; import type { Model } from "../../types.js"; import type { OAuthCredentials, OAuthLoginCallbacks, OAuthProviderInterface } from "./types.js"; diff --git a/src/logging/config.ts b/src/logging/config.ts index f0aa94310b2..ea3936380b4 100644 --- a/src/logging/config.ts +++ b/src/logging/config.ts @@ -1,9 +1,9 @@ import fs from "node:fs"; +import { isRecord as isObjectRecord } from "@openclaw/normalization-core/record-coerce"; import JSON5 from "json5"; import { getCommandPathWithRootOptions } from "../cli/argv.js"; import { resolveConfigPath } from "../config/paths.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { isRecord as isObjectRecord } from "../shared/record-coerce.js"; type LoggingConfig = OpenClawConfig["logging"]; diff --git a/src/logging/diagnostic-support-export.ts b/src/logging/diagnostic-support-export.ts index bad474257dd..2d1c0aa5791 100644 --- a/src/logging/diagnostic-support-export.ts +++ b/src/logging/diagnostic-support-export.ts @@ -1,11 +1,11 @@ import fs from "node:fs"; import path from "node:path"; import process from "node:process"; +import { asOptionalRecord } from "@openclaw/normalization-core/record-coerce"; import { parseConfigJson5 } from "../config/io.js"; import { resolveConfigPath, resolveStateDir } from "../config/paths.js"; import { redactConfigObject } from "../config/redact-snapshot.js"; import { resolveHomeRelativePath } from "../infra/home-dir.js"; -import { asOptionalRecord } from "../shared/record-coerce.js"; import { VERSION } from "../version.js"; import { readDiagnosticStabilityBundleFileSync, diff --git a/src/logging/diagnostic-support-log-redaction.ts b/src/logging/diagnostic-support-log-redaction.ts index 241ec6eef2e..edfaf233f91 100644 --- a/src/logging/diagnostic-support-log-redaction.ts +++ b/src/logging/diagnostic-support-log-redaction.ts @@ -1,5 +1,5 @@ +import { asOptionalRecord } from "@openclaw/normalization-core/record-coerce"; import { isBlockedObjectKey } from "../infra/prototype-keys.js"; -import { asOptionalRecord } from "../shared/record-coerce.js"; import { redactSupportString, type SupportRedactionContext, diff --git a/src/logging/diagnostic-support-redaction.ts b/src/logging/diagnostic-support-redaction.ts index 59df01e0bf5..67c18850442 100644 --- a/src/logging/diagnostic-support-redaction.ts +++ b/src/logging/diagnostic-support-redaction.ts @@ -1,8 +1,8 @@ import path from "node:path"; import { isSensitiveUrlQueryParamName } from "@openclaw/net-policy/redact-sensitive-url"; +import { asOptionalRecord } from "@openclaw/normalization-core/record-coerce"; import { isSecretRefShape } from "../config/redact-snapshot.secret-ref.js"; import { isBlockedObjectKey } from "../infra/prototype-keys.js"; -import { asOptionalRecord } from "../shared/record-coerce.js"; import { redactSensitiveText } from "./redact.js"; const SECRET_SUPPORT_FIELD_RE = diff --git a/src/logging/env-log-level.ts b/src/logging/env-log-level.ts index f070bdf1313..290aa036a8d 100644 --- a/src/logging/env-log-level.ts +++ b/src/logging/env-log-level.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { ALLOWED_LOG_LEVELS, type LogLevel, tryParseLogLevel } from "./levels.js"; import { loggingState } from "./state.js"; diff --git a/src/logging/parse-log-line.ts b/src/logging/parse-log-line.ts index 8959faca799..c4b100c4b1a 100644 --- a/src/logging/parse-log-line.ts +++ b/src/logging/parse-log-line.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; type ParsedLogLine = { time?: string; diff --git a/src/logging/redact-identifier.ts b/src/logging/redact-identifier.ts index 8921976e5be..fbe2432c6d6 100644 --- a/src/logging/redact-identifier.ts +++ b/src/logging/redact-identifier.ts @@ -1,5 +1,5 @@ import crypto from "node:crypto"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export function sha256HexPrefix(value: string, len = 12): string { const safeLen = Number.isFinite(len) ? Math.max(1, Math.floor(len)) : 12; diff --git a/src/logging/subsystem.ts b/src/logging/subsystem.ts index a0aa3b5228c..74afa7e6319 100644 --- a/src/logging/subsystem.ts +++ b/src/logging/subsystem.ts @@ -1,9 +1,9 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { Chalk } from "chalk"; import type { Logger as TsLogger } from "tslog"; import { clearActiveProgressLine } from "../../packages/terminal-core/src/progress-line.js"; import { isVerbose } from "../global-state.js"; import { defaultRuntime, type OutputRuntimeEnv, type RuntimeEnv } from "../runtime.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { formatConsoleTimestamp, getConsoleSettings, diff --git a/src/mcp/channel-bridge.ts b/src/mcp/channel-bridge.ts index fa8cf21a228..2c325865b61 100644 --- a/src/mcp/channel-bridge.ts +++ b/src/mcp/channel-bridge.ts @@ -1,13 +1,13 @@ import { randomUUID } from "node:crypto"; import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, +} from "@openclaw/normalization-core/string-coerce"; import type { EventFrame } from "../../packages/gateway-protocol/src/index.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { GatewayClient } from "../gateway/client.js"; import { extractFirstTextBlock } from "../shared/chat-message-content.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; import { VERSION } from "../version.js"; import type { ApprovalDecision, diff --git a/src/mcp/channel-shared.ts b/src/mcp/channel-shared.ts index 87818d4c81e..77a8c4b983e 100644 --- a/src/mcp/channel-shared.ts +++ b/src/mcp/channel-shared.ts @@ -1,8 +1,8 @@ -import { z } from "zod"; import { normalizeOptionalLowercaseString, normalizeOptionalString as toText, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { z } from "zod"; export type ClaudeChannelMode = "off" | "on" | "auto"; diff --git a/src/media-generation/live-test-helpers.ts b/src/media-generation/live-test-helpers.ts index bf3c83b4159..4863e14970c 100644 --- a/src/media-generation/live-test-helpers.ts +++ b/src/media-generation/live-test-helpers.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { AuthProfileStore } from "../agents/auth-profiles/types.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; type LiveProviderModelConfig = | string diff --git a/src/media-generation/runtime-shared.test.ts b/src/media-generation/runtime-shared.test.ts index f8869ba4da8..b64367f6c76 100644 --- a/src/media-generation/runtime-shared.test.ts +++ b/src/media-generation/runtime-shared.test.ts @@ -1,6 +1,6 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../config/types.js"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { deriveAspectRatioFromSize, normalizeDurationToClosestMax, diff --git a/src/media-generation/runtime-shared.ts b/src/media-generation/runtime-shared.ts index 03358eec616..67cc71a95f8 100644 --- a/src/media-generation/runtime-shared.ts +++ b/src/media-generation/runtime-shared.ts @@ -1,3 +1,5 @@ +import { clampTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveCapabilityModelRefForProviders } from "../../packages/media-generation-core/src/capability-model-ref.js"; import type { MediaGenerationNormalizationMetadataInput } from "../../packages/media-generation-core/src/normalization.js"; import { listProfilesForProvider } from "../agents/auth-profiles.js"; @@ -14,8 +16,6 @@ import type { AgentModelConfig } from "../config/types.agents-shared.js"; import type { OpenClawConfig } from "../config/types.js"; import { formatErrorMessage } from "../infra/errors.js"; import { getProviderEnvVars as getDefaultProviderEnvVars } from "../secrets/provider-env-vars.js"; -import { clampTimerTimeoutMs } from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; export type { MediaGenerationNormalizationMetadataInput, MediaNormalizationEntry, diff --git a/src/media-understanding/apply.ts b/src/media-understanding/apply.ts index 1d506b7b18a..be725d69294 100644 --- a/src/media-understanding/apply.ts +++ b/src/media-understanding/apply.ts @@ -1,4 +1,8 @@ import path from "node:path"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { finalizeInboundContext } from "../auto-reply/reply/inbound-context.js"; import type { MsgContext } from "../auto-reply/templating.js"; import type { OpenClawConfig } from "../config/types.js"; @@ -10,10 +14,6 @@ import { resolveInputFileLimits, } from "../media/input-files.js"; import { wrapExternalContent } from "../security/external-content.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import type { ActiveMediaModel } from "./active-model.types.js"; import { resolveAttachmentKind } from "./attachments.js"; import { runWithConcurrency } from "./concurrency.js"; diff --git a/src/media-understanding/attachments.normalize.ts b/src/media-understanding/attachments.normalize.ts index 110ff3fab3e..27facfb4b4c 100644 --- a/src/media-understanding/attachments.normalize.ts +++ b/src/media-understanding/attachments.normalize.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { MsgContext } from "../auto-reply/templating.js"; import { assertNoWindowsNetworkPath, safeFileURLToPath } from "../infra/local-file-access.js"; import { getFileExtension, isAudioFileName, kindFromMime } from "../media/mime.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { MediaAttachment } from "./types.js"; export function normalizeAttachmentPath(raw?: string | null): string | undefined { diff --git a/src/media-understanding/defaults.ts b/src/media-understanding/defaults.ts index 0123c2cc547..7fc5080c023 100644 --- a/src/media-understanding/defaults.ts +++ b/src/media-understanding/defaults.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { resolveRuntimeConfigCacheKey } from "../config/runtime-snapshot.js"; import type { OpenClawConfig } from "../config/types.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { buildMediaUnderstandingManifestMetadataRegistry } from "./manifest-metadata.js"; import { normalizeMediaExecutionProviderId, diff --git a/src/media-understanding/echo-transcript.ts b/src/media-understanding/echo-transcript.ts index 11ae4f3d40c..1924ae41669 100644 --- a/src/media-understanding/echo-transcript.ts +++ b/src/media-understanding/echo-transcript.ts @@ -1,7 +1,7 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { MsgContext } from "../auto-reply/templating.js"; import type { OpenClawConfig } from "../config/types.js"; import { logVerbose, shouldLogVerbose } from "../globals.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { isDeliverableMessageChannel } from "../utils/message-channel.js"; let messageRuntimePromise: Promise | null = null; diff --git a/src/media-understanding/resolve.test.ts b/src/media-understanding/resolve.test.ts index e835ff645bc..5b76e87bdce 100644 --- a/src/media-understanding/resolve.test.ts +++ b/src/media-understanding/resolve.test.ts @@ -1,6 +1,6 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../config/types.js"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { resolveEntriesWithActiveFallback, resolveMediaRuntimeTimeoutMs, diff --git a/src/media-understanding/resolve.ts b/src/media-understanding/resolve.ts index de33fa0af1b..340262a01b7 100644 --- a/src/media-understanding/resolve.ts +++ b/src/media-understanding/resolve.ts @@ -1,3 +1,7 @@ +import { + MAX_TIMER_TIMEOUT_MS, + resolveTimerTimeoutMs, +} from "@openclaw/normalization-core/number-coercion"; import type { MsgContext } from "../auto-reply/templating.js"; import type { OpenClawConfig } from "../config/types.js"; import type { @@ -6,7 +10,6 @@ import type { MediaUnderstandingScopeConfig, } from "../config/types.tools.js"; import { logVerbose, shouldLogVerbose } from "../globals.js"; -import { MAX_TIMER_TIMEOUT_MS, resolveTimerTimeoutMs } from "../shared/number-coercion.js"; import { DEFAULT_MAX_BYTES, DEFAULT_MAX_CHARS_BY_CAPABILITY, diff --git a/src/media-understanding/runner.entries.ts b/src/media-understanding/runner.entries.ts index 8bd05af7327..9870a75943f 100644 --- a/src/media-understanding/runner.entries.ts +++ b/src/media-understanding/runner.entries.ts @@ -1,5 +1,10 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { + normalizeLowercaseStringOrEmpty, + normalizeNullableString, +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { collectProviderApiKeysForExecution, executeWithApiKeyRotation, @@ -23,11 +28,6 @@ import { resolvePreferredOpenClawTmpDir } from "../infra/tmp-openclaw-dir.js"; import { runFfmpeg } from "../media/media-services.js"; import { runExec } from "../process/exec.js"; import { providerOperationRetryConfig } from "../provider-runtime/operation-retry.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeNullableString, -} from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { MediaAttachmentCache } from "./attachments.js"; import { CLI_OUTPUT_MAX_BUFFER, diff --git a/src/media-understanding/runner.ts b/src/media-understanding/runner.ts index c40eb5235eb..a6afd4c882a 100644 --- a/src/media-understanding/runner.ts +++ b/src/media-understanding/runner.ts @@ -3,6 +3,15 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { findNormalizedProviderValue } from "@openclaw/model-catalog-core/provider-id"; +import { + normalizeLowercaseStringOrEmpty, + normalizeNullableString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { + normalizeStringEntries, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { isMinimaxVlmModel, isMinimaxVlmProvider } from "../agents/minimax-vlm.js"; import { buildModelAliasIndex, @@ -27,12 +36,6 @@ import { resolveChannelInboundAttachmentRoots } from "../media/channel-inbound-r import { mergeInboundPathRoots } from "../media/inbound-path-policy.js"; import { getDefaultMediaLocalRoots } from "../media/local-roots.js"; import { runExec } from "../process/exec.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeNullableString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; -import { normalizeStringEntries, uniqueStrings } from "../shared/string-normalization.js"; import type { ActiveMediaModel } from "./active-model.types.js"; import { MediaAttachmentCache, selectAttachments } from "./attachments.js"; import { isMediaUnderstandingSkipError } from "./errors.js"; diff --git a/src/media-understanding/runtime.test.ts b/src/media-understanding/runtime.test.ts index 5510c3db8ff..d8aef247710 100644 --- a/src/media-understanding/runtime.test.ts +++ b/src/media-understanding/runtime.test.ts @@ -1,8 +1,8 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, describe, expect, it, vi } from "vitest"; import type { AuthProfileStore } from "../agents/auth-profiles/types.js"; import type { OpenClawConfig } from "../config/types.js"; import type { MediaAttachment, MediaUnderstandingOutput } from "../media-understanding/types.js"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { describeVideoFile, describeImageFile, diff --git a/src/media-understanding/scope.ts b/src/media-understanding/scope.ts index 3dbd30bae27..72e07dcb13e 100644 --- a/src/media-understanding/scope.ts +++ b/src/media-understanding/scope.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { normalizeChatType } from "../channels/chat-type.js"; import type { MediaUnderstandingScopeConfig } from "../config/types.tools.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; type MediaUnderstandingScopeDecision = "allow" | "deny"; diff --git a/src/media-understanding/shared.test.ts b/src/media-understanding/shared.test.ts index 9aa4e5f8303..dfe61bc2c54 100644 --- a/src/media-understanding/shared.test.ts +++ b/src/media-understanding/shared.test.ts @@ -1,5 +1,8 @@ +import { + MAX_DATE_TIMESTAMP_MS, + MAX_TIMER_TIMEOUT_MS, +} from "@openclaw/normalization-core/number-coercion"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { MAX_DATE_TIMESTAMP_MS, MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { VERSION } from "../version.js"; const { fetchWithSsrFGuardMock, shouldUseEnvHttpProxyForUrlMock } = vi.hoisted(() => ({ diff --git a/src/media-understanding/shared.ts b/src/media-understanding/shared.ts index 51459a40151..4209b3f50d8 100644 --- a/src/media-understanding/shared.ts +++ b/src/media-understanding/shared.ts @@ -9,6 +9,11 @@ export { readProviderJsonObjectResponse, readProviderJsonResponse, } from "../agents/provider-http-errors.js"; +import { + resolveDateTimestampMs, + resolveExpiresAtMsFromDurationMs, + resolveTimerTimeoutMs, +} from "@openclaw/normalization-core/number-coercion"; import type { ProviderRequestCapability, ProviderRequestTransport, @@ -28,11 +33,6 @@ import { type ProviderOperationRetryStage, type TransientProviderRetryConfig, } from "../provider-runtime/operation-retry.js"; -import { - resolveDateTimestampMs, - resolveExpiresAtMsFromDurationMs, - resolveTimerTimeoutMs, -} from "../shared/number-coercion.js"; import { fetchWithTimeout } from "../utils/fetch-timeout.js"; export { fetchWithTimeout }; export { normalizeBaseUrl } from "../agents/provider-request-config.js"; diff --git a/src/media/audio.ts b/src/media/audio.ts index 408bb9bd7e5..01aa4fdb28e 100644 --- a/src/media/audio.ts +++ b/src/media/audio.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { getFileExtension, normalizeMimeType } from "./mime.js"; export const VOICE_MESSAGE_AUDIO_EXTENSIONS = new Set([".oga", ".ogg", ".opus", ".mp3", ".m4a"]); diff --git a/src/media/channel-inbound-roots.ts b/src/media/channel-inbound-roots.ts index a91bb91d4b7..25037f34056 100644 --- a/src/media/channel-inbound-roots.ts +++ b/src/media/channel-inbound-roots.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { MsgContext } from "../auto-reply/templating.js"; import type { OpenClawConfig } from "../config/types.js"; import { loadBundledPluginPublicArtifactModuleSync } from "../plugins/public-surface-loader.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; type ChannelMediaContractApi = { resolveInboundAttachmentRoots?: (params: { diff --git a/src/media/document-extractors.runtime.ts b/src/media/document-extractors.runtime.ts index 36d2d5fe26c..fd3cc27e79b 100644 --- a/src/media/document-extractors.runtime.ts +++ b/src/media/document-extractors.runtime.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { DocumentExtractionRequest, @@ -5,7 +6,6 @@ import type { } from "../plugins/document-extractor-types.js"; import { resolvePluginDocumentExtractors } from "../plugins/document-extractors.runtime.js"; import { createConfigScopedPromiseLoader } from "../plugins/plugin-cache-primitives.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; const documentExtractorLoader = createConfigScopedPromiseLoader((config?: OpenClawConfig) => resolvePluginDocumentExtractors(config ? { config } : undefined), diff --git a/src/media/ffmpeg-exec.ts b/src/media/ffmpeg-exec.ts index 1c8e54f6ff3..14fff6f6966 100644 --- a/src/media/ffmpeg-exec.ts +++ b/src/media/ffmpeg-exec.ts @@ -1,7 +1,7 @@ import { execFile, type ExecFileOptions } from "node:child_process"; import { promisify } from "node:util"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { resolveSystemBin } from "../infra/resolve-system-bin.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { MEDIA_FFMPEG_MAX_BUFFER_BYTES, MEDIA_FFMPEG_TIMEOUT_MS, diff --git a/src/media/file-context.ts b/src/media/file-context.ts index 0dab8b55f46..649c727a641 100644 --- a/src/media/file-context.ts +++ b/src/media/file-context.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { sanitizeUntrustedFileName } from "../infra/fs-safe-advanced.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; const XML_ESCAPE_MAP: Record = { "<": "<", diff --git a/src/media/input-files.ts b/src/media/input-files.ts index f5ec5f8d992..a0d2dcf62c6 100644 --- a/src/media/input-files.ts +++ b/src/media/input-files.ts @@ -1,11 +1,11 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { fetchWithSsrFGuard } from "../infra/net/fetch-guard.js"; import type { SsrFPolicy } from "../infra/net/ssrf.js"; import { logWarn } from "../logger.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { canonicalizeBase64, estimateBase64DecodedBytes } from "./base64.js"; import { parseMediaContentLength } from "./content-length.js"; import { convertHeicToJpeg } from "./media-services.js"; diff --git a/src/media/local-roots.ts b/src/media/local-roots.ts index 859f6ed0441..f4fce713438 100644 --- a/src/media/local-roots.ts +++ b/src/media/local-roots.ts @@ -1,4 +1,6 @@ import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { resolveAgentWorkspaceDir } from "../agents/agent-scope.js"; import { resolveEffectiveToolFsRootExpansionAllowed, @@ -8,8 +10,6 @@ import { resolveStateDir } from "../config/paths.js"; import type { OpenClawConfig } from "../config/types.js"; import { safeFileURLToPath } from "../infra/local-file-access.js"; import { resolvePreferredOpenClawTmpDir } from "../infra/tmp-openclaw-dir.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { resolveConfigDir, resolveUserPath } from "../utils.js"; import { isPassThroughRemoteMediaSource } from "./media-source-url.js"; diff --git a/src/media/read-capability.ts b/src/media/read-capability.ts index 7a4d9504133..b1bab615247 100644 --- a/src/media/read-capability.ts +++ b/src/media/read-capability.ts @@ -1,4 +1,5 @@ import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveAgentWorkspaceDir } from "../agents/agent-scope.js"; import { resolveGroupToolPolicy } from "../agents/agent-tools.policy.js"; import { resolvePathFromInput } from "../agents/path-policy.js"; @@ -7,7 +8,6 @@ import { isToolAllowedByPolicies } from "../agents/tool-policy-match.js"; import { resolveWorkspaceRoot } from "../agents/workspace-dir.js"; import type { OpenClawConfig } from "../config/types.js"; import { readLocalFileSafely } from "../infra/fs-safe.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { OutboundMediaAccess, OutboundMediaReadFile } from "./load-options.js"; import { getAgentScopedMediaLocalRoots, diff --git a/src/media/store.ts b/src/media/store.ts index f3cabab730e..521420bf6de 100644 --- a/src/media/store.ts +++ b/src/media/store.ts @@ -6,13 +6,13 @@ import { request as httpRequest } from "node:http"; import { request as httpsRequest } from "node:https"; import path from "node:path"; import { pipeline } from "node:stream/promises"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { fileStore } from "../infra/file-store.js"; import { sanitizeUntrustedFileName } from "../infra/fs-safe-advanced.js"; import { isPathInside } from "../infra/fs-safe.js"; import { retainSafeHeadersForCrossOriginRedirect } from "../infra/net/redirect-headers.js"; import { resolvePinnedHostname } from "../infra/net/ssrf.js"; import { writeSiblingTempFile } from "../infra/sibling-temp-file.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resolveConfigDir } from "../utils.js"; import { basenameFromAnyPath, extnameFromAnyPath, nameFromAnyPath } from "./file-name.js"; import { detectMime, extensionForMime } from "./mime.js"; diff --git a/src/media/web-media.ts b/src/media/web-media.ts index fca5b366a8d..ffaf82eab8a 100644 --- a/src/media/web-media.ts +++ b/src/media/web-media.ts @@ -1,5 +1,6 @@ import { lstat, realpath } from "node:fs/promises"; import path from "node:path"; +import { uniqueValues } from "@openclaw/normalization-core/string-normalization"; import { logVerbose, shouldLogVerbose } from "../globals.js"; import { formatErrorMessage } from "../infra/errors.js"; import { FsSafeError, readLocalFileSafely } from "../infra/fs-safe.js"; @@ -7,7 +8,6 @@ import { assertNoWindowsNetworkPath, safeFileURLToPath } from "../infra/local-fi import type { PinnedDispatcherPolicy, SsrFPolicy } from "../infra/net/ssrf.js"; import { resolvePreferredOpenClawTmpDir } from "../infra/tmp-openclaw-dir.js"; import { getActivePluginRegistry } from "../plugins/runtime.js"; -import { uniqueValues } from "../shared/string-normalization.js"; import { resolveUserPath } from "../utils.js"; import { maxBytesForKind, type MediaKind } from "./constants.js"; import { readRemoteMediaBuffer } from "./fetch.js"; diff --git a/src/memory-host-sdk/dreaming.ts b/src/memory-host-sdk/dreaming.ts index 586ac80afb1..8f01c6e734f 100644 --- a/src/memory-host-sdk/dreaming.ts +++ b/src/memory-host-sdk/dreaming.ts @@ -1,13 +1,13 @@ import path from "node:path"; -import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js"; -import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { asNullableRecord } from "../shared/record-coerce.js"; +import { asNullableRecord } from "@openclaw/normalization-core/record-coerce"; import { lowercasePreservingWhitespace, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeStringifiedOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js"; +import type { OpenClawConfig } from "../config/types.openclaw.js"; export const DEFAULT_MEMORY_DREAMING_ENABLED = false; export const DEFAULT_MEMORY_DREAMING_TIMEZONE = undefined; diff --git a/src/model-catalog/manifest-planner.ts b/src/model-catalog/manifest-planner.ts index d607dc9c641..cb5568d0938 100644 --- a/src/model-catalog/manifest-planner.ts +++ b/src/model-catalog/manifest-planner.ts @@ -9,8 +9,8 @@ import type { ModelCatalogDiscovery, NormalizedModelCatalogRow, } from "@openclaw/model-catalog-core/model-catalog-types"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { normalizeUniqueStringEntries } from "../shared/string-normalization.js"; +import { normalizeLowercaseStringOrEmpty } from "../../packages/normalization-core/src/string-coerce.js"; +import { normalizeUniqueStringEntries } from "../../packages/normalization-core/src/string-normalization.js"; type ManifestModelCatalogPlugin = { id: string; diff --git a/src/model-catalog/provider-index/normalize.ts b/src/model-catalog/provider-index/normalize.ts index 76e0a367c01..8fa5560dee0 100644 --- a/src/model-catalog/provider-index/normalize.ts +++ b/src/model-catalog/provider-index/normalize.ts @@ -4,9 +4,9 @@ import type { ModelCatalogProvider } from "@openclaw/model-catalog-core/model-ca import { parseClawHubPluginSpec } from "../../infra/clawhub-spec.js"; import { parseRegistryNpmSpec } from "../../infra/npm-registry-spec.js"; import { isBlockedObjectKey } from "../../infra/prototype-keys.js"; -import { asFiniteNumber } from "../../shared/number-coercion.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; -import { normalizeUniqueTrimmedStringList } from "../../shared/string-normalization.js"; +import { asFiniteNumber } from "../../../packages/normalization-core/src/number-coercion.js"; +import { normalizeOptionalString } from "../../../packages/normalization-core/src/string-coerce.js"; +import { normalizeUniqueTrimmedStringList } from "../../../packages/normalization-core/src/string-normalization.js"; import { isRecord } from "../../utils.js"; import type { OpenClawProviderIndex, diff --git a/src/music-generation/provider-assets.ts b/src/music-generation/provider-assets.ts index 6f047995452..924fe75ac22 100644 --- a/src/music-generation/provider-assets.ts +++ b/src/music-generation/provider-assets.ts @@ -1,9 +1,9 @@ +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { fetchProviderDownloadResponse } from "../media-understanding/shared.js"; import { maxBytesForKind } from "../media/constants.js"; import { extensionForMime } from "../media/mime.js"; import { readResponseWithLimit } from "../media/read-response-with-limit.js"; -import { isRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { GeneratedMusicAsset } from "./types.js"; export type GeneratedMusicFileCandidate = { diff --git a/src/node-host/invoke-system-run-plan.ts b/src/node-host/invoke-system-run-plan.ts index a0fb97480c8..5f6f15a3c90 100644 --- a/src/node-host/invoke-system-run-plan.ts +++ b/src/node-host/invoke-system-run-plan.ts @@ -1,6 +1,10 @@ import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; +import { + normalizeLowercaseStringOrEmpty, + normalizeNullableString, +} from "@openclaw/normalization-core/string-coerce"; import type { SystemRunApprovalFileOperand, SystemRunApprovalPlan, @@ -22,10 +26,6 @@ import { resolveInlineCommandMatch, } from "../infra/shell-inline-command.js"; import { formatExecCommand, resolveSystemRunCommandRequest } from "../infra/system-run-command.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeNullableString, -} from "../shared/string-coerce.js"; import { splitShellArgs } from "../utils/shell-argv.js"; export type ApprovedCwdSnapshot = { diff --git a/src/node-host/invoke-system-run.ts b/src/node-host/invoke-system-run.ts index 0d8ec9103ef..8664c577330 100644 --- a/src/node-host/invoke-system-run.ts +++ b/src/node-host/invoke-system-run.ts @@ -1,4 +1,5 @@ import crypto from "node:crypto"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { GatewayClient } from "../gateway/client.js"; import { @@ -42,7 +43,6 @@ import { normalizeSystemRunApprovalPlan } from "../infra/system-run-approval-bin import { formatExecCommand, resolveSystemRunCommandRequest } from "../infra/system-run-command.js"; import { logWarn } from "../logger.js"; import { normalizeAgentId } from "../routing/session-key.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { evaluateSystemRunPolicy, resolveExecApprovalDecision } from "./exec-policy.js"; import { applyOutputTruncation, diff --git a/src/node-host/invoke.ts b/src/node-host/invoke.ts index 750fd8325b2..4c43f54d51e 100644 --- a/src/node-host/invoke.ts +++ b/src/node-host/invoke.ts @@ -1,6 +1,8 @@ import { spawn } from "node:child_process"; import fs from "node:fs"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { GatewayClient } from "../gateway/client.js"; import { ensureExecApprovals, @@ -23,8 +25,6 @@ import { decodeWindowsOutputBuffer, resolveWindowsConsoleEncoding, } from "../infra/windows-encoding.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { buildSystemRunApprovalPlan, handleSystemRunInvoke, diff --git a/src/node-host/with-timeout.test.ts b/src/node-host/with-timeout.test.ts index ac70924daee..f040fc00bbd 100644 --- a/src/node-host/with-timeout.test.ts +++ b/src/node-host/with-timeout.test.ts @@ -1,5 +1,5 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { withTimeout } from "./with-timeout.js"; describe("node-host withTimeout", () => { diff --git a/src/node-host/with-timeout.ts b/src/node-host/with-timeout.ts index 46a92814eb2..841c601b067 100644 --- a/src/node-host/with-timeout.ts +++ b/src/node-host/with-timeout.ts @@ -1,4 +1,4 @@ -import { resolveTimerTimeoutMs } from "../shared/number-coercion.js"; +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; export async function withTimeout( work: (signal: AbortSignal | undefined) => Promise, diff --git a/src/pairing/allow-from-store-file.ts b/src/pairing/allow-from-store-file.ts index 4d0f63b9e7a..f76e0de850b 100644 --- a/src/pairing/allow-from-store-file.ts +++ b/src/pairing/allow-from-store-file.ts @@ -1,14 +1,14 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; -import { resolveOAuthDir, resolveStateDir } from "../config/paths.js"; -import { resolveRequiredHomeDir } from "../infra/home-dir.js"; -import { DEFAULT_ACCOUNT_ID } from "../routing/session-key.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; -import { normalizeUniqueStringEntries } from "../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; +import { resolveOAuthDir, resolveStateDir } from "../config/paths.js"; +import { resolveRequiredHomeDir } from "../infra/home-dir.js"; +import { DEFAULT_ACCOUNT_ID } from "../routing/session-key.js"; import type { PairingChannel } from "./pairing-store.types.js"; export type AllowFromStore = { diff --git a/src/pairing/pairing-store.ts b/src/pairing/pairing-store.ts index b437513c732..be72b750bb5 100644 --- a/src/pairing/pairing-store.ts +++ b/src/pairing/pairing-store.ts @@ -1,18 +1,18 @@ import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; -import { getPairingAdapter } from "../channels/plugins/pairing.js"; -import type { ChannelPairingAdapter } from "../channels/plugins/pairing.types.js"; -import { withFileLock as withPathLock } from "../infra/file-lock.js"; -import { readJsonFileWithFallback, writeJsonFileAtomically } from "../plugin-sdk/json-store.js"; -import { DEFAULT_ACCOUNT_ID } from "../routing/session-key.js"; -import { isRecord } from "../shared/record-coerce.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { normalizeLowercaseStringOrEmpty, normalizeNullableString, normalizeOptionalString, normalizeStringifiedOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { getPairingAdapter } from "../channels/plugins/pairing.js"; +import type { ChannelPairingAdapter } from "../channels/plugins/pairing.types.js"; +import { withFileLock as withPathLock } from "../infra/file-lock.js"; +import { readJsonFileWithFallback, writeJsonFileAtomically } from "../plugin-sdk/json-store.js"; +import { DEFAULT_ACCOUNT_ID } from "../routing/session-key.js"; import { clearAllowFromFileReadCacheForNamespace, dedupePreserveOrder, diff --git a/src/pairing/setup-code.ts b/src/pairing/setup-code.ts index 2a8254f73fb..b5c6a5de820 100644 --- a/src/pairing/setup-code.ts +++ b/src/pairing/setup-code.ts @@ -7,6 +7,10 @@ import { isRfc1918Ipv4Address, parseCanonicalIpAddress, } from "@openclaw/net-policy/ip"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveGatewayPort } from "../config/paths.js"; import type { OpenClawConfig } from "../config/types.js"; import { normalizeSecretInputString, resolveSecretInputRef } from "../config/types.secrets.js"; @@ -19,10 +23,6 @@ import { } from "../infra/network-interfaces.js"; import { PAIRING_SETUP_BOOTSTRAP_PROFILE } from "../shared/device-bootstrap-profile.js"; import { resolveGatewayBindUrl } from "../shared/gateway-bind-url.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { resolveTailnetHostWithRunner } from "../shared/tailscale-status.js"; export type PairingSetupPayload = { diff --git a/src/param-key.ts b/src/param-key.ts index 41b215695b0..b3bc067a71b 100644 --- a/src/param-key.ts +++ b/src/param-key.ts @@ -1,4 +1,4 @@ -import { lowercasePreservingWhitespace } from "./shared/string-coerce.js"; +import { lowercasePreservingWhitespace } from "@openclaw/normalization-core/string-coerce"; function toSnakeCaseKey(key: string): string { const snakeKey = key diff --git a/src/plugin-sdk/access-groups.ts b/src/plugin-sdk/access-groups.ts index e4b1b647446..03e15f2faa6 100644 --- a/src/plugin-sdk/access-groups.ts +++ b/src/plugin-sdk/access-groups.ts @@ -1,3 +1,4 @@ +import { uniqueStrings } from "../../packages/normalization-core/src/string-normalization.js"; import { ACCESS_GROUP_ALLOW_FROM_PREFIX, parseAccessGroupAllowFromEntry, @@ -5,7 +6,6 @@ import { import type { ChannelId } from "../channels/plugins/types.public.js"; import type { AccessGroupConfig } from "../config/types.access-groups.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; export { ACCESS_GROUP_ALLOW_FROM_PREFIX, parseAccessGroupAllowFromEntry }; diff --git a/src/plugin-sdk/acp-runtime-backend.ts b/src/plugin-sdk/acp-runtime-backend.ts index fbfdc77a28b..5c03637a438 100644 --- a/src/plugin-sdk/acp-runtime-backend.ts +++ b/src/plugin-sdk/acp-runtime-backend.ts @@ -1,11 +1,11 @@ // Lightweight ACP runtime backend helpers for startup-loaded plugins. +import { normalizeOptionalString } from "../../packages/normalization-core/src/string-coerce.js"; import type { PluginHookReplyDispatchContext, PluginHookReplyDispatchEvent, PluginHookReplyDispatchResult, } from "../plugins/types.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; export { AcpRuntimeError, isAcpRuntimeError } from "../acp/runtime/errors.js"; export type { AcpRuntimeErrorCode } from "../acp/runtime/errors.js"; diff --git a/src/plugin-sdk/agent-harness-task-runtime.ts b/src/plugin-sdk/agent-harness-task-runtime.ts index 84bd15ee425..c05efc966f3 100644 --- a/src/plugin-sdk/agent-harness-task-runtime.ts +++ b/src/plugin-sdk/agent-harness-task-runtime.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "../../packages/normalization-core/src/string-coerce.js"; import { buildAnnounceIdempotencyKey } from "../agents/announce-idempotency.js"; import { AGENT_INTERNAL_EVENT_TYPE_TASK_COMPLETION, @@ -14,7 +15,6 @@ import { resolveSubagentCompletionOrigin, } from "../agents/subagent-announce-delivery.js"; import { resolveAnnounceOrigin } from "../agents/subagent-announce-origin.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { assertAgentHarnessTaskRuntimeScope, type AgentHarnessTaskRuntimeScope, diff --git a/src/plugin-sdk/allow-from.ts b/src/plugin-sdk/allow-from.ts index fcf0d48843e..8199b0556e6 100644 --- a/src/plugin-sdk/allow-from.ts +++ b/src/plugin-sdk/allow-from.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalLowercaseString } from "../../packages/normalization-core/src/string-coerce.js"; +import { normalizeStringEntries } from "../../packages/normalization-core/src/string-normalization.js"; import { isAllowedParsedChatSender as isAllowedParsedChatSenderShared } from "../channels/plugins/chat-target-prefixes.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; export type { AllowlistMatch, diff --git a/src/plugin-sdk/anthropic-vertex-auth-presence.ts b/src/plugin-sdk/anthropic-vertex-auth-presence.ts index 79d72e5f6cb..4dff81710e3 100644 --- a/src/plugin-sdk/anthropic-vertex-auth-presence.ts +++ b/src/plugin-sdk/anthropic-vertex-auth-presence.ts @@ -4,7 +4,7 @@ import { join } from "node:path"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "../../packages/normalization-core/src/string-coerce.js"; import { normalizeOptionalSecretInput } from "../utils/normalize-secret-input.js"; const GCLOUD_DEFAULT_ADC_PATH = join( diff --git a/src/plugin-sdk/approval-approvers.ts b/src/plugin-sdk/approval-approvers.ts index b7581daa73a..efd26d6c29b 100644 --- a/src/plugin-sdk/approval-approvers.ts +++ b/src/plugin-sdk/approval-approvers.ts @@ -1,4 +1,4 @@ -import { uniqueStrings } from "../shared/string-normalization.js"; +import { uniqueStrings } from "../../packages/normalization-core/src/string-normalization.js"; type ApproverInput = string | number; diff --git a/src/plugin-sdk/approval-auth-helpers.ts b/src/plugin-sdk/approval-auth-helpers.ts index 6d1a522d364..b2817ec7226 100644 --- a/src/plugin-sdk/approval-auth-helpers.ts +++ b/src/plugin-sdk/approval-auth-helpers.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "../../packages/normalization-core/src/string-coerce.js"; import type { OpenClawConfig } from "./config-runtime.js"; type ApprovalKind = "exec" | "plugin"; diff --git a/src/plugin-sdk/approval-client-helpers.ts b/src/plugin-sdk/approval-client-helpers.ts index e4f6b956b7b..7eaa55b5471 100644 --- a/src/plugin-sdk/approval-client-helpers.ts +++ b/src/plugin-sdk/approval-client-helpers.ts @@ -1,12 +1,12 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "../../packages/normalization-core/src/string-coerce.js"; import type { ExecApprovalForwardTarget } from "../config/types.approvals.js"; import { matchesApprovalRequestFilters } from "../infra/approval-request-filters.js"; import { getExecApprovalReplyMetadata } from "../infra/exec-approval-reply.js"; import type { ExecApprovalRequest } from "../infra/exec-approvals.js"; import type { PluginApprovalRequest } from "../infra/plugin-approvals.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import type { OpenClawConfig } from "./config-runtime.js"; import type { ReplyPayload } from "./reply-payload.js"; import { normalizeAccountId } from "./routing.js"; diff --git a/src/plugin-sdk/approval-handler-runtime.ts b/src/plugin-sdk/approval-handler-runtime.ts index a47db3dcab8..9612335b952 100644 --- a/src/plugin-sdk/approval-handler-runtime.ts +++ b/src/plugin-sdk/approval-handler-runtime.ts @@ -29,6 +29,7 @@ export { type ResolvedApprovalView, } from "../infra/approval-handler-runtime.js"; export { resolveApprovalOverGateway } from "./approval-gateway-runtime.js"; +import { normalizeOptionalString } from "../../packages/normalization-core/src/string-coerce.js"; import type { ExpiredApprovalView, ResolvedApprovalView, @@ -40,7 +41,6 @@ import { type PluginApprovalRequest, type PluginApprovalResolved, } from "../infra/plugin-approvals.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { buildApprovalResolvedReplyPayload } from "./approval-renderers.js"; type ApprovalRequest = ExecApprovalRequest | PluginApprovalRequest; diff --git a/src/plugin-sdk/approval-native-helpers.ts b/src/plugin-sdk/approval-native-helpers.ts index f526fd9c609..cdd474d9eb6 100644 --- a/src/plugin-sdk/approval-native-helpers.ts +++ b/src/plugin-sdk/approval-native-helpers.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "../../packages/normalization-core/src/string-coerce.js"; import type { ExecApprovalForwardingConfig, ExecApprovalForwardingMode, @@ -16,10 +20,6 @@ import { import type { ExecApprovalRequest } from "../infra/exec-approvals.js"; import type { PluginApprovalRequest } from "../infra/plugin-approvals.js"; import { normalizeAccountId } from "../routing/session-key.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import type { ChannelApprovalCapability, ChannelOutboundPayloadHint } from "./channel-contract.js"; import { channelRouteTargetsMatchExact } from "./channel-route.js"; import type { OpenClawConfig } from "./config-runtime.js"; diff --git a/src/plugin-sdk/approval-renderers.ts b/src/plugin-sdk/approval-renderers.ts index 97a01d434cc..9bddd80487e 100644 --- a/src/plugin-sdk/approval-renderers.ts +++ b/src/plugin-sdk/approval-renderers.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "../../packages/normalization-core/src/string-coerce.js"; import { buildApprovalPresentation, type ExecApprovalReplyDecision, @@ -9,7 +10,6 @@ import { type PluginApprovalRequest, type PluginApprovalResolved, } from "../infra/plugin-approvals.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { ReplyPayload } from "./reply-payload.js"; const DEFAULT_ALLOWED_DECISIONS = ["allow-once", "allow-always", "deny"] as const; diff --git a/src/plugin-sdk/boolean-param.ts b/src/plugin-sdk/boolean-param.ts index 40752b8f805..25bf91d1c28 100644 --- a/src/plugin-sdk/boolean-param.ts +++ b/src/plugin-sdk/boolean-param.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "../../packages/normalization-core/src/string-coerce.js"; /** Read loose boolean params from tool input that may arrive as booleans or "true"/"false" strings. */ export function readBooleanParam( diff --git a/src/plugin-sdk/channel-config-helpers.ts b/src/plugin-sdk/channel-config-helpers.ts index e71b6fa0119..3eb74584360 100644 --- a/src/plugin-sdk/channel-config-helpers.ts +++ b/src/plugin-sdk/channel-config-helpers.ts @@ -1,3 +1,5 @@ +import { normalizeOptionalLowercaseString } from "../../packages/normalization-core/src/string-coerce.js"; +import { normalizeStringEntries } from "../../packages/normalization-core/src/string-normalization.js"; import { deleteAccountFromConfigSection as deleteAccountFromConfigSectionInSection, setAccountEnabledInConfigSection as setAccountEnabledInConfigSectionInSection, @@ -15,8 +17,6 @@ import { buildAccountScopedDmSecurityPolicy } from "../channels/plugins/helpers. import type { ChannelConfigAdapter } from "../channels/plugins/types.adapters.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../routing/session-key.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; export { ensureOpenDmPolicyAllowFromWildcard, diff --git a/src/plugin-sdk/channel-entry-contract.ts b/src/plugin-sdk/channel-entry-contract.ts index 74b8aa48930..4473706cb1e 100644 --- a/src/plugin-sdk/channel-entry-contract.ts +++ b/src/plugin-sdk/channel-entry-contract.ts @@ -1,6 +1,7 @@ import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; +import { normalizeLowercaseStringOrEmpty } from "../../packages/normalization-core/src/string-coerce.js"; import { emptyChannelConfigSchema } from "../channels/plugins/config-schema.js"; import type { ChannelOutboundAdapter } from "../channels/plugins/types.adapters.js"; import type { ChannelConfigSchema } from "../channels/plugins/types.config.js"; @@ -28,7 +29,6 @@ import type { PluginCommandContext, } from "../plugins/types.js"; import { toSafeImportPath } from "../shared/import-specifier.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; export type { AnyAgentTool, diff --git a/src/plugin-sdk/channel-ingress.ts b/src/plugin-sdk/channel-ingress.ts index ad0daa2d85c..b36b83e291a 100644 --- a/src/plugin-sdk/channel-ingress.ts +++ b/src/plugin-sdk/channel-ingress.ts @@ -1,3 +1,4 @@ +import { normalizeStringEntries } from "../../packages/normalization-core/src/string-normalization.js"; import { decideChannelIngress, resolveChannelIngressState as resolveChannelIngressStateInternal, @@ -23,7 +24,6 @@ import type { DmGroupAccessDecision, DmGroupAccessReasonCode, } from "../security/dm-policy-shared.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; export { decideChannelIngress }; export type { diff --git a/src/plugin-sdk/channel-policy.ts b/src/plugin-sdk/channel-policy.ts index 78954b708fe..e3471aa085d 100644 --- a/src/plugin-sdk/channel-policy.ts +++ b/src/plugin-sdk/channel-policy.ts @@ -1,10 +1,13 @@ +import { + normalizeStringEntries, + uniqueStrings, +} from "../../packages/normalization-core/src/string-normalization.js"; import { sanitizeForLog } from "../../packages/terminal-core/src/ansi.js"; import { createAllowlistProviderRestrictSendersWarningCollector } from "../channels/plugins/group-policy-warnings.js"; import type { ChannelSecurityAdapter } from "../channels/plugins/types.adapters.js"; import { collectProviderDangerousNameMatchingScopes } from "../config/dangerous-name-matching.js"; import type { GroupPolicy } from "../config/types.base.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeStringEntries, uniqueStrings } from "../shared/string-normalization.js"; import { createScopedDmSecurityResolver } from "./channel-config-helpers.js"; /** Shared policy warnings and DM/group policy helpers for channel plugins. */ export type { diff --git a/src/plugin-sdk/channel-route.ts b/src/plugin-sdk/channel-route.ts index 50e5d11d441..2662e2ec456 100644 --- a/src/plugin-sdk/channel-route.ts +++ b/src/plugin-sdk/channel-route.ts @@ -1,9 +1,9 @@ -import { normalizeOptionalAccountId } from "../routing/account-id.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalThreadValue, -} from "../shared/string-coerce.js"; +} from "../../packages/normalization-core/src/string-coerce.js"; +import { normalizeOptionalAccountId } from "../routing/account-id.js"; export type ChannelRouteChatType = "direct" | "group" | "channel"; diff --git a/src/plugin-sdk/core.ts b/src/plugin-sdk/core.ts index 93d3a4fc619..129ad06b8de 100644 --- a/src/plugin-sdk/core.ts +++ b/src/plugin-sdk/core.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "../../packages/normalization-core/src/string-coerce.js"; import type { ResolvedConfiguredAcpBinding } from "../acp/persistent-bindings.types.js"; import { buildChatChannelMetaById } from "../channels/chat-meta-shared.js"; import type { ChatChannelId } from "../channels/ids.js"; @@ -34,7 +35,6 @@ import { normalizeSessionKeyPreservingOpaquePeerIds, parseThreadSessionSuffix, } from "../sessions/session-key-utils.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; export type { AgentPromptGuidance, @@ -257,7 +257,10 @@ export { resolveGatewayBindUrl } from "../shared/gateway-bind-url.js"; export type { GatewayBindUrlResult } from "../shared/gateway-bind-url.js"; export { resolveGatewayPort } from "../config/paths.js"; export { createSubsystemLogger } from "../logging/subsystem.js"; -export { normalizeAtHashSlug, normalizeHyphenSlug } from "../shared/string-normalization.js"; +export { + normalizeAtHashSlug, + normalizeHyphenSlug, +} from "../../packages/normalization-core/src/string-normalization.js"; export { createActionGate } from "../agents/tools/common.js"; export { jsonResult, diff --git a/src/plugin-sdk/migration.ts b/src/plugin-sdk/migration.ts index 0f711aba97d..d93947179e7 100644 --- a/src/plugin-sdk/migration.ts +++ b/src/plugin-sdk/migration.ts @@ -1,5 +1,6 @@ // Shared migration-provider helpers for plan/apply item bookkeeping. +import { isRecord } from "../../packages/normalization-core/src/record-coerce.js"; import type { MigrationDetection, MigrationItem, @@ -8,7 +9,6 @@ import type { MigrationProviderPlugin, MigrationSummary, } from "../plugins/types.js"; -import { isRecord } from "../shared/record-coerce.js"; export type { MigrationDetection, diff --git a/src/plugin-sdk/number-runtime.ts b/src/plugin-sdk/number-runtime.ts index 1eb7f026591..ce559cbc873 100644 --- a/src/plugin-sdk/number-runtime.ts +++ b/src/plugin-sdk/number-runtime.ts @@ -31,5 +31,5 @@ export { resolveExpiresAtMsFromDurationSeconds, resolveExpiresAtMsFromDurationOrEpoch, resolveExpiresAtMsFromEpochSeconds, -} from "../shared/number-coercion.js"; +} from "../../packages/normalization-core/src/number-coercion.js"; export { MAX_TCP_PORT, parseTcpPort } from "../infra/tcp-port.js"; diff --git a/src/plugin-sdk/provider-auth-result.test.ts b/src/plugin-sdk/provider-auth-result.test.ts index 5f9fa226286..c75de961af8 100644 --- a/src/plugin-sdk/provider-auth-result.test.ts +++ b/src/plugin-sdk/provider-auth-result.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import { MAX_DATE_TIMESTAMP_MS } from "../shared/number-coercion.js"; +import { MAX_DATE_TIMESTAMP_MS } from "../../packages/normalization-core/src/number-coercion.js"; import { buildOauthProviderAuthResult } from "./provider-auth-result.js"; describe("buildOauthProviderAuthResult", () => { diff --git a/src/plugin-sdk/provider-auth-result.ts b/src/plugin-sdk/provider-auth-result.ts index 0e52ad4aa42..541b2e634b4 100644 --- a/src/plugin-sdk/provider-auth-result.ts +++ b/src/plugin-sdk/provider-auth-result.ts @@ -1,3 +1,4 @@ +import { asDateTimestampMs } from "../../packages/normalization-core/src/number-coercion.js"; import { buildAuthProfileId } from "../agents/auth-profiles/identity.js"; import type { AuthProfileCredential } from "../agents/auth-profiles/types.js"; import { normalizeConfiguredProviderCatalogModelId } from "../agents/model-ref-shared.js"; @@ -8,7 +9,6 @@ import { import type { ModelProviderConfig } from "../config/types.models.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { ProviderAuthResult } from "../plugins/types.js"; -import { asDateTimestampMs } from "../shared/number-coercion.js"; function normalizeAgentModelConfigForAuthResult(value: unknown): unknown { if (typeof value === "string") { diff --git a/src/plugin-sdk/provider-auth.ts b/src/plugin-sdk/provider-auth.ts index 65572663079..7dcccd1b829 100644 --- a/src/plugin-sdk/provider-auth.ts +++ b/src/plugin-sdk/provider-auth.ts @@ -1,6 +1,12 @@ // Public auth/onboarding helpers for provider plugins. import path from "node:path"; +import { + asDateTimestampMs, + resolveExpiresAtMsFromEpochSeconds, + parseStrictNonNegativeInteger, +} from "../../packages/normalization-core/src/number-coercion.js"; +import { normalizeLowercaseStringOrEmpty } from "../../packages/normalization-core/src/string-coerce.js"; import { resolveDefaultAgentDir } from "../agents/agent-scope-config.js"; import { externalCliDiscoveryForProviderAuth } from "../agents/auth-profiles/external-cli-discovery.js"; import { resolveApiKeyForProfile } from "../agents/auth-profiles/oauth.js"; @@ -21,12 +27,6 @@ import { resolveEnvApiKey } from "../agents/model-auth-env.js"; import type { OpenClawConfig } from "../config/config.js"; import { resolveStateDir } from "../config/paths.js"; import { loadJsonFile, saveJsonFile } from "../infra/json-file.js"; -import { - asDateTimestampMs, - resolveExpiresAtMsFromEpochSeconds, - parseStrictNonNegativeInteger, -} from "../shared/number-coercion.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { resolveProviderEndpoint } from "./provider-model-shared.js"; export type { OpenClawConfig } from "../config/config.js"; diff --git a/src/plugin-sdk/provider-catalog-shared.ts b/src/plugin-sdk/provider-catalog-shared.ts index 342c43b7350..c8e8ec5a6b1 100644 --- a/src/plugin-sdk/provider-catalog-shared.ts +++ b/src/plugin-sdk/provider-catalog-shared.ts @@ -18,7 +18,7 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; import { isFutureDateTimestampMs, resolveExpiresAtMsFromDurationMs, -} from "../shared/number-coercion.js"; +} from "../../packages/normalization-core/src/number-coercion.js"; import type { ModelProviderConfig } from "./provider-model-shared.js"; export type { ProviderCatalogContext, ProviderCatalogResult } from "../plugins/types.js"; diff --git a/src/plugin-sdk/provider-entry.ts b/src/plugin-sdk/provider-entry.ts index d0ad0e7a377..766fdc68f3d 100644 --- a/src/plugin-sdk/provider-entry.ts +++ b/src/plugin-sdk/provider-entry.ts @@ -10,7 +10,7 @@ import type { UnifiedModelCatalogProviderContext, ProviderPluginWizardSetup, } from "../plugins/types.js"; -import { normalizeStringEntries, uniqueStrings } from "../shared/string-normalization.js"; +import { normalizeStringEntries, uniqueStrings } from "../../packages/normalization-core/src/string-normalization.js"; import { definePluginEntry } from "./plugin-entry.js"; import type { OpenClawPluginApi, diff --git a/src/plugin-sdk/provider-model-shared.ts b/src/plugin-sdk/provider-model-shared.ts index 69ffec4dce3..ee30f0603c8 100644 --- a/src/plugin-sdk/provider-model-shared.ts +++ b/src/plugin-sdk/provider-model-shared.ts @@ -96,7 +96,7 @@ export { cloneFirstTemplateModel, matchesExactOrPrefix, } from "../plugins/provider-model-helpers.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "../../packages/normalization-core/src/string-coerce.js"; const CLAUDE_OPUS_48_MODEL_PREFIXES = ["claude-opus-4-8", "claude-opus-4.8"] as const; const CLAUDE_OPUS_47_MODEL_PREFIXES = ["claude-opus-4-7", "claude-opus-4.7"] as const; diff --git a/src/plugin-sdk/provider-oauth-runtime.ts b/src/plugin-sdk/provider-oauth-runtime.ts index 6dbce210d01..a0edaaaeaf3 100644 --- a/src/plugin-sdk/provider-oauth-runtime.ts +++ b/src/plugin-sdk/provider-oauth-runtime.ts @@ -1,9 +1,9 @@ -import type { Model } from "../llm/types.js"; import { positiveSecondsToSafeMilliseconds, resolveExpiresAtMsFromDurationMs, resolveTimerTimeoutMs, -} from "../shared/number-coercion.js"; +} from "../../packages/normalization-core/src/number-coercion.js"; +import type { Model } from "../llm/types.js"; const LOGO_SVG = ``; diff --git a/src/plugin-sdk/provider-onboard.ts b/src/plugin-sdk/provider-onboard.ts index e2647833450..37d516684f3 100644 --- a/src/plugin-sdk/provider-onboard.ts +++ b/src/plugin-sdk/provider-onboard.ts @@ -2,6 +2,7 @@ // do not pull heavyweight runtime graphs at activation time. import { findNormalizedProviderKey } from "@openclaw/model-catalog-core/provider-id"; +import { resolvePrimaryStringValue } from "../../packages/normalization-core/src/string-coerce.js"; import { ensureStaticModelAllowlistEntry } from "../agents/model-allowlist-entry.js"; import { normalizeConfiguredProviderCatalogModelId } from "../agents/model-ref-shared.js"; import { @@ -15,7 +16,6 @@ import type { ModelProviderConfig, } from "../config/types.models.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { resolvePrimaryStringValue } from "../shared/string-coerce.js"; export type { OpenClawConfig, ModelApi, ModelDefinitionConfig, ModelProviderConfig }; export { diff --git a/src/plugin-sdk/provider-openai-chatgpt-auth.ts b/src/plugin-sdk/provider-openai-chatgpt-auth.ts index a2257554283..5b887653a28 100644 --- a/src/plugin-sdk/provider-openai-chatgpt-auth.ts +++ b/src/plugin-sdk/provider-openai-chatgpt-auth.ts @@ -1,5 +1,5 @@ -import { resolveExpiresAtMsFromEpochSeconds } from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { resolveExpiresAtMsFromEpochSeconds } from "../../packages/normalization-core/src/number-coercion.js"; +import { normalizeOptionalString } from "../../packages/normalization-core/src/string-coerce.js"; const OPENAI_CODEX_AUTH_CLAIM = "https://api.openai.com/auth"; const OPENAI_CODEX_PROFILE_CLAIM = "https://api.openai.com/profile"; diff --git a/src/plugin-sdk/provider-selection-runtime.ts b/src/plugin-sdk/provider-selection-runtime.ts index 090071e32fd..5c9fc8334e5 100644 --- a/src/plugin-sdk/provider-selection-runtime.ts +++ b/src/plugin-sdk/provider-selection-runtime.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "../../packages/normalization-core/src/string-coerce.js"; export type AutoSelectableProvider = { id: string; diff --git a/src/plugin-sdk/provider-stream-shared.ts b/src/plugin-sdk/provider-stream-shared.ts index 69404814779..84db5d046a8 100644 --- a/src/plugin-sdk/provider-stream-shared.ts +++ b/src/plugin-sdk/provider-stream-shared.ts @@ -11,7 +11,7 @@ import type { StreamFn } from "../agents/runtime/index.js"; import { streamWithPayloadPatch } from "../llm/providers/stream-wrappers/stream-payload-utils.js"; import { streamSimple } from "../llm/stream.js"; import { createAssistantMessageEventStream } from "../llm/utils/event-stream.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "../../packages/normalization-core/src/string-coerce.js"; import type { ProviderWrapStreamFnContext } from "./plugin-entry.js"; export type ProviderStreamWrapperFactory = diff --git a/src/plugin-sdk/qa-channel-protocol.ts b/src/plugin-sdk/qa-channel-protocol.ts index fee2fff5aee..ccbda1ccf8a 100644 --- a/src/plugin-sdk/qa-channel-protocol.ts +++ b/src/plugin-sdk/qa-channel-protocol.ts @@ -1,4 +1,4 @@ -import { isRecord } from "../shared/record-coerce.js"; +import { isRecord } from "../../packages/normalization-core/src/record-coerce.js"; export type QaBusConversationKind = "direct" | "channel" | "group"; diff --git a/src/plugin-sdk/reply-payload.ts b/src/plugin-sdk/reply-payload.ts index fe8602bd575..53aba81f012 100644 --- a/src/plugin-sdk/reply-payload.ts +++ b/src/plugin-sdk/reply-payload.ts @@ -1,10 +1,10 @@ +import { normalizeLowercaseStringOrEmpty } from "../../packages/normalization-core/src/string-coerce.js"; +import { normalizeStringEntries } from "../../packages/normalization-core/src/string-normalization.js"; import type { ReplyPayload as InternalReplyPayload } from "../auto-reply/reply-payload.js"; import type { ChannelOutboundAdapter } from "../channels/plugins/outbound.types.js"; import { normalizeOutboundReplyPayload as normalizeCoreOutboundReplyPayload } from "../infra/outbound/reply-payload-normalize.js"; import { createReplyToFanout } from "../infra/outbound/reply-policy.js"; import { hasReplyPayloadContent } from "../interactive/payload.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; export type { MediaPayload, MediaPayloadInput } from "../channels/plugins/media-payload.js"; export { buildMediaPayload } from "../channels/plugins/media-payload.js"; diff --git a/src/plugin-sdk/session-transcript-hit.ts b/src/plugin-sdk/session-transcript-hit.ts index e2e7a74c42e..375f536ca53 100644 --- a/src/plugin-sdk/session-transcript-hit.ts +++ b/src/plugin-sdk/session-transcript-hit.ts @@ -1,9 +1,9 @@ import path from "node:path"; +import { normalizeOptionalString } from "../../packages/normalization-core/src/string-coerce.js"; +import { uniqueStrings } from "../../packages/normalization-core/src/string-normalization.js"; import { parseUsageCountedSessionIdFromFileName } from "../config/sessions/artifacts.js"; import type { SessionEntry } from "../config/sessions/types.js"; import { normalizeAgentId } from "../routing/session-key.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; export { loadCombinedSessionStoreForGateway } from "../config/sessions/combined-store-gateway.js"; diff --git a/src/plugin-sdk/session-visibility.ts b/src/plugin-sdk/session-visibility.ts index 516b4b46e61..a0df7456b31 100644 --- a/src/plugin-sdk/session-visibility.ts +++ b/src/plugin-sdk/session-visibility.ts @@ -1,11 +1,11 @@ -import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { callGateway as defaultCallGateway } from "../gateway/call.js"; -import { resolveAgentIdFromSessionKey } from "../routing/session-key.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; -import { normalizeTrimmedStringList } from "../shared/string-normalization.js"; +} from "../../packages/normalization-core/src/string-coerce.js"; +import { normalizeTrimmedStringList } from "../../packages/normalization-core/src/string-normalization.js"; +import type { OpenClawConfig } from "../config/types.openclaw.js"; +import { callGateway as defaultCallGateway } from "../gateway/call.js"; +import { resolveAgentIdFromSessionKey } from "../routing/session-key.js"; type GatewayCaller = typeof defaultCallGateway; diff --git a/src/plugin-sdk/ssrf-policy.ts b/src/plugin-sdk/ssrf-policy.ts index babfd6db314..731404d03a6 100644 --- a/src/plugin-sdk/ssrf-policy.ts +++ b/src/plugin-sdk/ssrf-policy.ts @@ -1,3 +1,6 @@ +import { asNullableRecord } from "../../packages/normalization-core/src/record-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "../../packages/normalization-core/src/string-coerce.js"; +import { normalizeUniqueStringEntries } from "../../packages/normalization-core/src/string-normalization.js"; import { isBlockedHostnameOrIp, isPrivateIpAddress, @@ -6,9 +9,6 @@ import { type LookupFn, type SsrFPolicy, } from "../infra/net/ssrf.js"; -import { asNullableRecord } from "../shared/record-coerce.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { normalizeUniqueStringEntries } from "../shared/string-normalization.js"; import type { ChannelDoctorConfigMutation, ChannelDoctorLegacyConfigRule, diff --git a/src/plugin-sdk/status-helpers.ts b/src/plugin-sdk/status-helpers.ts index 0811ab58ed2..996b514bdf1 100644 --- a/src/plugin-sdk/status-helpers.ts +++ b/src/plugin-sdk/status-helpers.ts @@ -1,8 +1,8 @@ +import { normalizeOptionalString } from "../../packages/normalization-core/src/string-coerce.js"; import type { ChannelStatusAdapter } from "../channels/plugins/types.adapters.js"; import type { ChannelAccountSnapshot } from "../channels/plugins/types.core.js"; import type { ChannelStatusIssue } from "../channels/plugins/types.public.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; export type { ChannelAccountSnapshot } from "../channels/plugins/types.core.js"; export type { ChannelStatusIssue } from "../channels/plugins/types.public.js"; export { isRecord } from "../channels/plugins/status-issues/shared.js"; diff --git a/src/plugin-sdk/string-coerce-runtime.ts b/src/plugin-sdk/string-coerce-runtime.ts index b7299319497..32081a863d0 100644 --- a/src/plugin-sdk/string-coerce-runtime.ts +++ b/src/plugin-sdk/string-coerce-runtime.ts @@ -13,7 +13,7 @@ export { normalizeStringifiedEntries, normalizeStringifiedOptionalString, readStringValue, -} from "../shared/string-coerce.js"; +} from "../../packages/normalization-core/src/string-coerce.js"; export { asFiniteNumberInRange, asFiniteNumber, @@ -24,14 +24,14 @@ export { parseStrictInteger, parseStrictNonNegativeInteger, parseStrictPositiveInteger, -} from "../shared/number-coercion.js"; +} from "../../packages/normalization-core/src/number-coercion.js"; export { asBoolean, parseBooleanValue } from "../utils/boolean.js"; export { asRecord, asNullableRecord, asOptionalRecord, readStringField, -} from "../shared/record-coerce.js"; +} from "../../packages/normalization-core/src/record-coerce.js"; export { isRecord } from "../utils.js"; export { normalizeAtHashSlug, @@ -47,5 +47,5 @@ export { sortUniqueStrings, uniqueStrings, uniqueValues, -} from "../shared/string-normalization.js"; +} from "../../packages/normalization-core/src/string-normalization.js"; export { summarizeStringEntries } from "../shared/string-sample.js"; diff --git a/src/plugin-sdk/string-normalization-runtime.ts b/src/plugin-sdk/string-normalization-runtime.ts index 4871e2f69ef..035b8865245 100644 --- a/src/plugin-sdk/string-normalization-runtime.ts +++ b/src/plugin-sdk/string-normalization-runtime.ts @@ -3,4 +3,4 @@ export { normalizeHyphenSlug, normalizeStringEntries, normalizeStringEntriesLower, -} from "../shared/string-normalization.js"; +} from "../../packages/normalization-core/src/string-normalization.js"; diff --git a/src/plugin-sdk/test-helpers/public-artifacts.ts b/src/plugin-sdk/test-helpers/public-artifacts.ts index 36db6816f87..645bfac4f8d 100644 --- a/src/plugin-sdk/test-helpers/public-artifacts.ts +++ b/src/plugin-sdk/test-helpers/public-artifacts.ts @@ -1,8 +1,8 @@ +import { uniqueStrings } from "../../../packages/normalization-core/src/string-normalization.js"; import { assertUniqueValues, BUNDLED_RUNTIME_SIDECAR_PATHS, } from "../../plugins/runtime-sidecar-paths.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; export function getPublicArtifactBasename(relativePath: string): string { return relativePath.split("/").at(-1) ?? relativePath; diff --git a/src/plugin-sdk/test-helpers/string-utils.ts b/src/plugin-sdk/test-helpers/string-utils.ts index 1afa1537d9b..8ca6f903f15 100644 --- a/src/plugin-sdk/test-helpers/string-utils.ts +++ b/src/plugin-sdk/test-helpers/string-utils.ts @@ -1,4 +1,4 @@ -import { sortUniqueStrings } from "../../shared/string-normalization.js"; +import { sortUniqueStrings } from "../../../packages/normalization-core/src/string-normalization.js"; export function uniqueSortedStrings(values: readonly string[]) { return sortUniqueStrings(values); diff --git a/src/plugin-sdk/text-runtime.ts b/src/plugin-sdk/text-runtime.ts index 12505c166fa..63d5c9e8072 100644 --- a/src/plugin-sdk/text-runtime.ts +++ b/src/plugin-sdk/text-runtime.ts @@ -13,10 +13,10 @@ export * from "../../packages/markdown-core/src/render-aware-chunking.js"; export * from "../../packages/markdown-core/src/render.js"; export * from "../../packages/markdown-core/src/tables.js"; export * from "../shared/global-singleton.js"; -export * from "../shared/record-coerce.js"; +export * from "../../packages/normalization-core/src/record-coerce.js"; export * from "../shared/scoped-expiring-id-cache.js"; -export * from "../shared/string-coerce.js"; -export * from "../shared/string-normalization.js"; +export * from "../../packages/normalization-core/src/string-coerce.js"; +export * from "../../packages/normalization-core/src/string-normalization.js"; export * from "../shared/string-sample.js"; export * from "../shared/text/assistant-visible-text.js"; export * from "../shared/text/auto-linked-file-ref.js"; @@ -40,7 +40,7 @@ export { normalizeOptionalString, normalizeStringifiedOptionalString, readStringValue, -} from "../shared/string-coerce.js"; +} from "../../packages/normalization-core/src/string-coerce.js"; export { CONFIG_DIR, clamp, diff --git a/src/plugin-sdk/tool-send.ts b/src/plugin-sdk/tool-send.ts index 4a43ec337d1..e6e1ed4e600 100644 --- a/src/plugin-sdk/tool-send.ts +++ b/src/plugin-sdk/tool-send.ts @@ -1,4 +1,4 @@ -import { readStringValue } from "../shared/string-coerce.js"; +import { readStringValue } from "../../packages/normalization-core/src/string-coerce.js"; export type { ChannelToolSend } from "../channels/plugins/types.public.js"; diff --git a/src/plugin-sdk/webhook-request-guards.ts b/src/plugin-sdk/webhook-request-guards.ts index 982d04d485c..3f869dbf3bd 100644 --- a/src/plugin-sdk/webhook-request-guards.ts +++ b/src/plugin-sdk/webhook-request-guards.ts @@ -1,4 +1,5 @@ import type { IncomingMessage, ServerResponse } from "node:http"; +import { normalizeOptionalLowercaseString } from "../../packages/normalization-core/src/string-coerce.js"; import { formatErrorMessage } from "../infra/errors.js"; import { isRequestBodyLimitError, @@ -7,7 +8,6 @@ import { requestBodyErrorToText, } from "../infra/http-body.js"; import { pruneMapToMaxSize } from "../infra/map-size.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import type { FixedWindowRateLimiter } from "./webhook-memory-guards.js"; import { resolveWebhookIntegerOption } from "./webhook-numeric-options.js"; diff --git a/src/plugin-sdk/windows-spawn.ts b/src/plugin-sdk/windows-spawn.ts index 49408d13b27..88ee6695edf 100644 --- a/src/plugin-sdk/windows-spawn.ts +++ b/src/plugin-sdk/windows-spawn.ts @@ -3,8 +3,8 @@ import path from "node:path"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; +} from "../../packages/normalization-core/src/string-coerce.js"; +import { normalizeStringEntries } from "../../packages/normalization-core/src/string-normalization.js"; export type WindowsSpawnResolution = | "direct" diff --git a/src/plugin-state/plugin-state-store.sqlite.ts b/src/plugin-state/plugin-state-store.sqlite.ts index b90c29a346f..e10c1992ba0 100644 --- a/src/plugin-state/plugin-state-store.sqlite.ts +++ b/src/plugin-state/plugin-state-store.sqlite.ts @@ -1,4 +1,5 @@ import type { DatabaseSync } from "node:sqlite"; +import { resolveExpiresAtMsFromDurationMs } from "@openclaw/normalization-core/number-coercion"; import type { Insertable, Selectable } from "kysely"; import { executeSqliteQuerySync, @@ -6,7 +7,6 @@ import { getNodeSqliteKysely, } from "../infra/kysely-sync.js"; import { requireNodeSqlite } from "../infra/node-sqlite.js"; -import { resolveExpiresAtMsFromDurationMs } from "../shared/number-coercion.js"; import type { DB as OpenClawStateKyselyDatabase } from "../state/openclaw-state-db.generated.js"; import { closeOpenClawStateDatabase, diff --git a/src/plugin-state/plugin-state-store.test.ts b/src/plugin-state/plugin-state-store.test.ts index b901ae7bab2..8e7cd6183f9 100644 --- a/src/plugin-state/plugin-state-store.test.ts +++ b/src/plugin-state/plugin-state-store.test.ts @@ -1,7 +1,7 @@ import { rmSync, statSync } from "node:fs"; import path from "node:path"; +import { MAX_DATE_TIMESTAMP_MS } from "@openclaw/normalization-core/number-coercion"; import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { MAX_DATE_TIMESTAMP_MS } from "../shared/number-coercion.js"; import { openOpenClawStateDatabase } from "../state/openclaw-state-db.js"; import { resolveOpenClawStateSqlitePath } from "../state/openclaw-state-db.paths.js"; import { diff --git a/src/plugins/activation-planner.ts b/src/plugins/activation-planner.ts index 2a8381d44ff..c6d3adcc58c 100644 --- a/src/plugins/activation-planner.ts +++ b/src/plugins/activation-planner.ts @@ -1,7 +1,7 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { normalizePluginsConfig } from "./config-state.js"; import { passesManifestOwnerBasePolicy } from "./manifest-owner-policy.js"; import type { PluginManifestRecord } from "./manifest-registry.js"; diff --git a/src/plugins/active-runtime-registry.ts b/src/plugins/active-runtime-registry.ts index 4e6efd9e411..4ca77e5325d 100644 --- a/src/plugins/active-runtime-registry.ts +++ b/src/plugins/active-runtime-registry.ts @@ -1,4 +1,4 @@ -import { normalizeSortedUniqueStringEntries } from "../shared/string-normalization.js"; +import { normalizeSortedUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import { resolveCompatibleRuntimePluginRegistry, type PluginLoadOptions } from "./loader.js"; import type { PluginRegistry } from "./registry-types.js"; import { diff --git a/src/plugins/agent-event-emission.ts b/src/plugins/agent-event-emission.ts index 5505b53daf1..3ce42854e43 100644 --- a/src/plugins/agent-event-emission.ts +++ b/src/plugins/agent-event-emission.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { emitAgentEvent } from "../infra/agent-events.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { isPluginJsonValue, type PluginAgentEventEmitParams, diff --git a/src/plugins/bundle-commands.ts b/src/plugins/bundle-commands.ts index 9dea69c911e..417e2f0e089 100644 --- a/src/plugins/bundle-commands.ts +++ b/src/plugins/bundle-commands.ts @@ -1,13 +1,13 @@ import fs from "node:fs"; import path from "node:path"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { parseFrontmatterBlock } from "../../packages/markdown-core/src/frontmatter.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { readRootJsonObjectSync } from "../infra/json-files.js"; import { isPathInsideWithRealpath } from "../security/scan-paths.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { CLAUDE_BUNDLE_MANIFEST_RELATIVE_PATH, mergeBundlePathLists, diff --git a/src/plugins/bundle-manifest.ts b/src/plugins/bundle-manifest.ts index 8b3c2c741a9..fd23f5f2509 100644 --- a/src/plugins/bundle-manifest.ts +++ b/src/plugins/bundle-manifest.ts @@ -1,13 +1,13 @@ import fs from "node:fs"; import path from "node:path"; -import JSON5 from "json5"; -import { matchRootFileOpenFailure } from "../infra/boundary-file-read.js"; -import { readRootStructuredFileSync } from "../infra/json-files.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; -import { normalizeUniqueSingleOrTrimmedStringList } from "../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeUniqueSingleOrTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; +import JSON5 from "json5"; +import { matchRootFileOpenFailure } from "../infra/boundary-file-read.js"; +import { readRootStructuredFileSync } from "../infra/json-files.js"; import { isRecord } from "../utils.js"; import type { PluginBundleFormat } from "./manifest-types.js"; import type { PluginManifestActivation } from "./manifest.js"; diff --git a/src/plugins/bundled-dir.ts b/src/plugins/bundled-dir.ts index aa6845b83da..3dad0d355e1 100644 --- a/src/plugins/bundled-dir.ts +++ b/src/plugins/bundled-dir.ts @@ -2,10 +2,10 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import { fileURLToPath } from "node:url"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { resolveOpenClawPackageRootSync } from "../infra/openclaw-root.js"; import { isPathInside } from "../infra/path-guards.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { resolveUserPath } from "../utils.js"; const DISABLED_BUNDLED_PLUGINS_DIR = path.join(os.tmpdir(), "openclaw-empty-bundled-plugins"); diff --git a/src/plugins/bundled-plugin-metadata.ts b/src/plugins/bundled-plugin-metadata.ts index 3ed764729b8..00e0712e266 100644 --- a/src/plugins/bundled-plugin-metadata.ts +++ b/src/plugins/bundled-plugin-metadata.ts @@ -1,8 +1,8 @@ import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { tryReadJsonSync } from "../infra/json-files.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { collectBundledChannelConfigs } from "./bundled-channel-config-metadata.js"; import { collectBundledPluginPublicSurfaceArtifacts, diff --git a/src/plugins/bundled-plugin-scan.ts b/src/plugins/bundled-plugin-scan.ts index 42e40729979..8c1e190b18d 100644 --- a/src/plugins/bundled-plugin-scan.ts +++ b/src/plugins/bundled-plugin-scan.ts @@ -1,7 +1,7 @@ import fs from "node:fs"; import path from "node:path"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { normalizeTrimmedStringList } from "../shared/string-normalization.js"; +import { normalizeOptionalString } from "../../packages/normalization-core/src/string-coerce.js"; +import { normalizeTrimmedStringList } from "../../packages/normalization-core/src/string-normalization.js"; import { PUBLIC_SURFACE_SOURCE_EXTENSIONS } from "./public-surface-runtime.js"; const RUNTIME_SIDECAR_ARTIFACTS = new Set([ diff --git a/src/plugins/bundled-source-overlays.ts b/src/plugins/bundled-source-overlays.ts index b8d549bc0fa..398f6a9f50b 100644 --- a/src/plugins/bundled-source-overlays.ts +++ b/src/plugins/bundled-source-overlays.ts @@ -1,6 +1,6 @@ import fs from "node:fs"; import path from "node:path"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { buildLegacyBundledRootPath } from "./bundled-load-path-aliases.js"; function decodeMountInfoPath(value: string): string { diff --git a/src/plugins/bundled-sources.ts b/src/plugins/bundled-sources.ts index 69d31d56e63..5fc3018eae7 100644 --- a/src/plugins/bundled-sources.ts +++ b/src/plugins/bundled-sources.ts @@ -1,5 +1,5 @@ -import { isRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { discoverOpenClawPlugins, type PluginDiscoveryResult } from "./discovery.js"; import { loadPluginManifest } from "./manifest.js"; diff --git a/src/plugins/capability-provider-runtime.ts b/src/plugins/capability-provider-runtime.ts index 9702e30ed20..27e3ddd2110 100644 --- a/src/plugins/capability-provider-runtime.ts +++ b/src/plugins/capability-provider-runtime.ts @@ -1,6 +1,6 @@ +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { resolveVoiceModelRefs } from "../../packages/speech-core/voice-models.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; import { getLoadedRuntimePluginRegistry } from "./active-runtime-registry.js"; import { loadBundledCapabilityRuntimeRegistry } from "./bundled-capability-runtime.js"; import { diff --git a/src/plugins/captured-registration.ts b/src/plugins/captured-registration.ts index b53bd5ad0ce..b9ef6913c5b 100644 --- a/src/plugins/captured-registration.ts +++ b/src/plugins/captured-registration.ts @@ -1,5 +1,5 @@ +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import type { AgentToolResultMiddleware, AgentToolResultMiddlewareOptions, diff --git a/src/plugins/channel-catalog-registry.ts b/src/plugins/channel-catalog-registry.ts index 845101c9b7c..8206360dc6d 100644 --- a/src/plugins/channel-catalog-registry.ts +++ b/src/plugins/channel-catalog-registry.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString as resolveOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { PluginInstallRecord } from "../config/types.plugins.js"; -import { normalizeOptionalString as resolveOptionalString } from "../shared/string-coerce.js"; import { discoverOpenClawPlugins, type PluginDiscoveryResult } from "./discovery.js"; import { loadInstalledPluginIndexInstallRecordsSync } from "./installed-plugin-index-record-reader.js"; import type { PluginPackageChannel, PluginPackageInstall } from "./manifest.js"; diff --git a/src/plugins/channel-presence-policy.ts b/src/plugins/channel-presence-policy.ts index 4ec0c223282..93c290b272c 100644 --- a/src/plugins/channel-presence-policy.ts +++ b/src/plugins/channel-presence-policy.ts @@ -1,3 +1,5 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js"; import { hasMeaningfulChannelConfig, @@ -7,8 +9,6 @@ import { } from "../channels/config-presence.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { isSafeChannelEnvVarTriggerName } from "../secrets/channel-env-var-names.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; import { resolveManifestActivationPluginIds } from "./activation-planner.js"; import { createPluginActivationSource, diff --git a/src/plugins/channel-validation.ts b/src/plugins/channel-validation.ts index 81f9baf525c..3ffa3a71116 100644 --- a/src/plugins/channel-validation.ts +++ b/src/plugins/channel-validation.ts @@ -1,12 +1,12 @@ +import { + normalizeOptionalString, + normalizeStringifiedOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { listChatChannels } from "../channels/chat-meta.js"; import { normalizeChannelMeta } from "../channels/plugins/meta-normalization.js"; import type { ChannelPlugin } from "../channels/plugins/types.plugin.js"; import type { ChannelMeta } from "../channels/plugins/types.public.js"; import { GENERATED_BUNDLED_CHANNEL_CONFIG_METADATA } from "../config/bundled-channel-config-metadata.generated.js"; -import { - normalizeOptionalString, - normalizeStringifiedOptionalString, -} from "../shared/string-coerce.js"; import type { PluginDiagnostic } from "./manifest-types.js"; import { pushPluginValidationDiagnostic } from "./validation-diagnostics.js"; diff --git a/src/plugins/clawhub.ts b/src/plugins/clawhub.ts index 50cae607db0..4908a41fa0c 100644 --- a/src/plugins/clawhub.ts +++ b/src/plugins/clawhub.ts @@ -1,5 +1,6 @@ import { createHash } from "node:crypto"; import fs from "node:fs/promises"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import JSZip from "jszip"; import { ARCHIVE_LIMIT_ERROR_CODE, @@ -31,7 +32,6 @@ import { type ClawHubPackageVersion, } from "../infra/clawhub.js"; import { formatErrorMessage } from "../infra/errors.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resolveCompatibilityHostVersion } from "../version.js"; import type { RuntimeVersionEnv } from "../version.js"; import { CLAWHUB_INSTALL_ERROR_CODE, type ClawHubInstallErrorCode } from "./clawhub-error-codes.js"; diff --git a/src/plugins/cli-gateway-nodes-runtime.test.ts b/src/plugins/cli-gateway-nodes-runtime.test.ts index 0ebac8cff4c..b9c6f42cd00 100644 --- a/src/plugins/cli-gateway-nodes-runtime.test.ts +++ b/src/plugins/cli-gateway-nodes-runtime.test.ts @@ -1,5 +1,5 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { beforeEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; import { createPluginCliGatewayNodesRuntime, resolvePluginCliNodeInvokeGatewayTimeoutMs, diff --git a/src/plugins/cli-gateway-nodes-runtime.ts b/src/plugins/cli-gateway-nodes-runtime.ts index 7255e253700..3c78cafce34 100644 --- a/src/plugins/cli-gateway-nodes-runtime.ts +++ b/src/plugins/cli-gateway-nodes-runtime.ts @@ -1,10 +1,10 @@ import { randomUUID } from "node:crypto"; +import { addTimerTimeoutGraceMs } from "@openclaw/normalization-core/number-coercion"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES, } from "../../packages/gateway-protocol/src/client-info.js"; import { callGateway } from "../gateway/call.js"; -import { addTimerTimeoutGraceMs } from "../shared/number-coercion.js"; import type { PluginRuntime } from "./runtime/types.js"; export function resolvePluginCliNodeInvokeGatewayTimeoutMs( diff --git a/src/plugins/cli-registry-loader.ts b/src/plugins/cli-registry-loader.ts index 6ab2f6fdcea..b9c2842de67 100644 --- a/src/plugins/cli-registry-loader.ts +++ b/src/plugins/cli-registry-loader.ts @@ -1,7 +1,7 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { collectUniqueCommandDescriptors } from "../cli/program/command-descriptor-utils.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { resolveManifestActivationPluginIds } from "./activation-planner.js"; import { createPluginCliGatewayNodesRuntime } from "./cli-gateway-nodes-runtime.js"; import type { PluginLoadOptions } from "./loader.js"; diff --git a/src/plugins/command-registration.ts b/src/plugins/command-registration.ts index cc76916ca52..f762d903a15 100644 --- a/src/plugins/command-registration.ts +++ b/src/plugins/command-registration.ts @@ -1,9 +1,9 @@ -import { isOperatorScope } from "../gateway/operator-scopes.js"; -import { logVerbose } from "../globals.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { isOperatorScope } from "../gateway/operator-scopes.js"; +import { logVerbose } from "../globals.js"; import { isRecord } from "../utils.js"; import { normalizeAgentPromptSurfaceKind } from "./agent-prompt-surface-kind.js"; import { diff --git a/src/plugins/command-registry-state.ts b/src/plugins/command-registry-state.ts index cc78273696b..3135878e8c9 100644 --- a/src/plugins/command-registry-state.ts +++ b/src/plugins/command-registry-state.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { resolveGlobalSingleton } from "../shared/global-singleton.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import { normalizeAgentPromptSurfaceKind } from "./agent-prompt-surface-kind.js"; import type { AgentPromptGuidance, diff --git a/src/plugins/command-specs.ts b/src/plugins/command-specs.ts index d682a92669a..597e0a89dc0 100644 --- a/src/plugins/command-specs.ts +++ b/src/plugins/command-specs.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { getLoadedChannelPlugin } from "../channels/plugins/index.js"; import { resolveReadOnlyChannelCommandDefaults } from "../channels/plugins/read-only-command-defaults.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import { pluginCommandSupportsChannel } from "./command-registration.js"; import { pluginCommands } from "./command-registry-state.js"; import type { OpenClawPluginCommandDefinition } from "./types.js"; diff --git a/src/plugins/commands.ts b/src/plugins/commands.ts index 7fb21bb6df6..06d1558e210 100644 --- a/src/plugins/commands.ts +++ b/src/plugins/commands.ts @@ -5,12 +5,12 @@ * These commands are processed before built-in commands and before agent invocation. */ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { resolveBoundAgentIdForSession } from "../agents/session-agent-binding.js"; import { resolveConversationBindingContext } from "../channels/conversation-binding-context.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { ADMIN_SCOPE, isOperatorScope } from "../gateway/operator-scopes.js"; import { logVerbose } from "../globals.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { clearPluginCommands, clearPluginCommandsForPlugin, diff --git a/src/plugins/config-contract-matches.ts b/src/plugins/config-contract-matches.ts index 85c5c3db851..3b3764ac3f2 100644 --- a/src/plugins/config-contract-matches.ts +++ b/src/plugins/config-contract-matches.ts @@ -1,5 +1,5 @@ +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { parseConfigPathArrayIndex } from "../shared/path-array-index.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { isRecord } from "../utils.js"; export type PluginConfigContractMatch = { diff --git a/src/plugins/config-contracts.ts b/src/plugins/config-contracts.ts index dde652e4628..412b9370fa5 100644 --- a/src/plugins/config-contracts.ts +++ b/src/plugins/config-contracts.ts @@ -1,5 +1,5 @@ +import { normalizeSortedUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeSortedUniqueStringEntries } from "../shared/string-normalization.js"; import { discoverOpenClawPlugins, type PluginDiscoveryResult } from "./discovery.js"; import { loadPluginManifestRegistry } from "./manifest-registry.js"; import type { PluginManifestConfigContracts } from "./manifest.js"; diff --git a/src/plugins/config-normalization-shared.ts b/src/plugins/config-normalization-shared.ts index 756c6b559e4..c56b4a55f1e 100644 --- a/src/plugins/config-normalization-shared.ts +++ b/src/plugins/config-normalization-shared.ts @@ -1,10 +1,10 @@ -import { normalizeChatChannelId } from "../channels/ids.js"; -import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; -import { normalizeArrayBackedTrimmedStringList } from "../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeArrayBackedTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; +import { normalizeChatChannelId } from "../channels/ids.js"; +import type { OpenClawConfig } from "../config/types.openclaw.js"; import { defaultSlotIdForKey } from "./slots.js"; export type NormalizedPluginsConfig = { diff --git a/src/plugins/config-state.ts b/src/plugins/config-state.ts index 829098b078f..79ff70c5d66 100644 --- a/src/plugins/config-state.ts +++ b/src/plugins/config-state.ts @@ -1,8 +1,8 @@ -import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { OpenClawConfig } from "../config/types.openclaw.js"; import { createEffectiveEnableStateResolver, createPluginEnableStateResolver, diff --git a/src/plugins/contracts/extension-package-project-boundaries.test.ts b/src/plugins/contracts/extension-package-project-boundaries.test.ts index c75e34ab2e3..f7bfc125ac8 100644 --- a/src/plugins/contracts/extension-package-project-boundaries.test.ts +++ b/src/plugins/contracts/extension-package-project-boundaries.test.ts @@ -197,6 +197,7 @@ describe("opt-in extension package boundaries", () => { "../../packages/markdown-core/src/**/*.ts", "../../packages/media-generation-core/src/**/*.ts", "../../packages/model-catalog-core/src/**/*.ts", + "../../packages/normalization-core/src/**/*.ts", "../../packages/terminal-core/src/**/*.ts", "../../src/plugin-sdk/**/*.ts", "../../src/video-generation/dashscope-compatible.ts", diff --git a/src/plugins/contracts/registry.ts b/src/plugins/contracts/registry.ts index 1fee3d91c3b..f8f0a9626f5 100644 --- a/src/plugins/contracts/registry.ts +++ b/src/plugins/contracts/registry.ts @@ -1,5 +1,5 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { loadBundledCapabilityRuntimeRegistry } from "../bundled-capability-runtime.js"; import { discoverOpenClawPlugins } from "../discovery.js"; import { loadPluginManifestRegistry } from "../manifest-registry.js"; diff --git a/src/plugins/contracts/scheduled-turns.contract.test.ts b/src/plugins/contracts/scheduled-turns.contract.test.ts index 842ecb592a3..952d9a2e4f8 100644 --- a/src/plugins/contracts/scheduled-turns.contract.test.ts +++ b/src/plugins/contracts/scheduled-turns.contract.test.ts @@ -1,3 +1,4 @@ +import { MAX_DATE_TIMESTAMP_MS } from "@openclaw/normalization-core/number-coercion"; import { createPluginRegistryFixture, registerTestPlugin, @@ -9,7 +10,6 @@ import type { GatewayRequestHandler, GatewayRequestHandlerOptions, } from "../../gateway/server-methods/types.js"; -import { MAX_DATE_TIMESTAMP_MS } from "../../shared/number-coercion.js"; import { withEnv } from "../../test-utils/env.js"; import { cleanupReplacedPluginHostRegistry } from "../host-hook-cleanup.js"; import { diff --git a/src/plugins/conversation-binding.ts b/src/plugins/conversation-binding.ts index d62b44df977..617edcfbf4f 100644 --- a/src/plugins/conversation-binding.ts +++ b/src/plugins/conversation-binding.ts @@ -1,6 +1,10 @@ import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { ReplyPayload } from "../auto-reply/reply-payload.js"; import { createConversationBindingRecord, @@ -14,10 +18,6 @@ import { writeJson } from "../infra/json-files.js"; import { type ConversationRef } from "../infra/outbound/session-binding-service.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { resolveGlobalMap, resolveGlobalSingleton } from "../shared/global-singleton.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import type { PluginConversationBinding, PluginConversationBindingResolvedEvent, diff --git a/src/plugins/dependency-denylist.ts b/src/plugins/dependency-denylist.ts index 84975e0718d..1824cf086de 100644 --- a/src/plugins/dependency-denylist.ts +++ b/src/plugins/dependency-denylist.ts @@ -1,4 +1,4 @@ -import { normalizeStringEntries } from "../shared/string-normalization.js"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; const BLOCKED_INSTALL_DEPENDENCY_PACKAGE_NAMES = ["plain-crypto-js"] as const; diff --git a/src/plugins/discovery.ts b/src/plugins/discovery.ts index d35099f38c2..92df3b698d8 100644 --- a/src/plugins/discovery.ts +++ b/src/plugins/discovery.ts @@ -1,13 +1,13 @@ import fs from "node:fs"; import path from "node:path"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { PluginInstallRecord } from "../config/types.plugins.js"; import { satisfiesPluginApiRange } from "../infra/clawhub.js"; import { readRootJsonObjectSync } from "../infra/json-files.js"; import { tryReadJsonSync } from "../infra/json-files.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { resolveUserPath } from "../utils.js"; import { resolveCompatibilityHostVersion } from "../version.js"; import { detectBundleManifestFormat, loadBundleManifest } from "./bundle-manifest.js"; diff --git a/src/plugins/doctor-contract-registry.ts b/src/plugins/doctor-contract-registry.ts index 2232012cb85..c4c348be354 100644 --- a/src/plugins/doctor-contract-registry.ts +++ b/src/plugins/doctor-contract-registry.ts @@ -1,14 +1,14 @@ import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; +import { asNullableRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import type { LegacyConfigRule } from "../config/legacy.shared.js"; import type { OpenClawConfig } from "../config/types.js"; import type { OpenKeyedStoreOptions, PluginStateKeyedStore, } from "../plugin-state/plugin-state-store.js"; -import { asNullableRecord } from "../shared/record-coerce.js"; -import { normalizeTrimmedStringList } from "../shared/string-normalization.js"; import type { DoctorSessionRouteStateOwner } from "./doctor-session-route-state-owner-types.js"; import type { PluginManifestRegistry } from "./manifest-registry.js"; import { diff --git a/src/plugins/document-extractor-public-artifacts.ts b/src/plugins/document-extractor-public-artifacts.ts index d6d13f97d96..65da50fa57e 100644 --- a/src/plugins/document-extractor-public-artifacts.ts +++ b/src/plugins/document-extractor-public-artifacts.ts @@ -1,4 +1,4 @@ -import { isRecord } from "../shared/record-coerce.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import type { DocumentExtractorPlugin, PluginDocumentExtractorEntry, diff --git a/src/plugins/document-extractors.runtime.ts b/src/plugins/document-extractors.runtime.ts index f3e10db534b..def189412c7 100644 --- a/src/plugins/document-extractors.runtime.ts +++ b/src/plugins/document-extractors.runtime.ts @@ -1,5 +1,8 @@ +import { + normalizeStringEntries, + sortUniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeStringEntries, sortUniqueStrings } from "../shared/string-normalization.js"; import { resolveEnabledBundledManifestContractPlugins } from "./bundled-manifest-contract-plugins.js"; import { loadBundledDocumentExtractorEntriesFromDir } from "./document-extractor-public-artifacts.js"; import type { PluginDocumentExtractorEntry } from "./document-extractor-types.js"; diff --git a/src/plugins/effective-plugin-ids.ts b/src/plugins/effective-plugin-ids.ts index 9fa4a00fed9..644c1c4af2d 100644 --- a/src/plugins/effective-plugin-ids.ts +++ b/src/plugins/effective-plugin-ids.ts @@ -1,11 +1,11 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { listExplicitlyDisabledChannelIdsForConfig, listPotentialConfiguredChannelIds, } from "../channels/config-presence.js"; import { applyPluginAutoEnable } from "../config/plugin-auto-enable.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; import { listExplicitConfiguredChannelIdsForConfig, loadGatewayStartupPluginPlan, diff --git a/src/plugins/gateway-startup-plugin-ids.ts b/src/plugins/gateway-startup-plugin-ids.ts index 3a1d9405145..7ae64fe19d2 100644 --- a/src/plugins/gateway-startup-plugin-ids.ts +++ b/src/plugins/gateway-startup-plugin-ids.ts @@ -1,5 +1,7 @@ import { buildModelCatalogMergeKey } from "@openclaw/model-catalog-core/model-catalog-refs"; import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { collectConfiguredAgentHarnessRuntimes } from "../agents/harness-runtimes.js"; import { listExplicitlyDisabledChannelIdsForConfig, @@ -13,8 +15,6 @@ import { resolveMemoryDreamingPluginId, } from "../memory-host-sdk/dreaming.js"; import { planManifestModelCatalogRows } from "../model-catalog/manifest-planner.js"; -import { isRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import { hasExplicitChannelConfig } from "./channel-presence-policy.js"; import { collectPluginConfigContractMatches } from "./config-contracts.js"; import { resolveEffectivePluginActivationState } from "./config-state.js"; diff --git a/src/plugins/gateway-startup-speech-providers.ts b/src/plugins/gateway-startup-speech-providers.ts index f4bb9a7b4b6..d170bf40312 100644 --- a/src/plugins/gateway-startup-speech-providers.ts +++ b/src/plugins/gateway-startup-speech-providers.ts @@ -1,6 +1,6 @@ +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { isRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import { resolveEffectiveTtsConfig } from "../tts/tts-config.js"; const TTS_PROVIDER_CONFIG_RESERVED_KEYS = new Set([ diff --git a/src/plugins/git-install.ts b/src/plugins/git-install.ts index 2ef22f0647c..b16e243eda5 100644 --- a/src/plugins/git-install.ts +++ b/src/plugins/git-install.ts @@ -2,6 +2,7 @@ import "../infra/fs-safe-defaults.js"; import { createHash } from "node:crypto"; import path from "node:path"; import { redactSensitiveUrlLikeString } from "@openclaw/net-policy/redact-sensitive-url"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { sanitizeForLog } from "../../packages/terminal-core/src/ansi.js"; import { withTempDir } from "../infra/install-source-utils.js"; import { replaceDirectoryAtomic } from "../infra/replace-file.js"; @@ -10,7 +11,6 @@ import { createSafeNpmInstallEnv, } from "../infra/safe-package-install.js"; import { runCommandWithTimeout } from "../process/exec.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resolveUserPath } from "../utils.js"; import { resolveDefaultPluginGitDir } from "./install-paths.js"; import type { InstallSafetyOverrides } from "./install-security-scan.js"; diff --git a/src/plugins/hook-agent-context.ts b/src/plugins/hook-agent-context.ts index 0832b3db411..18ecb1f2ab0 100644 --- a/src/plugins/hook-agent-context.ts +++ b/src/plugins/hook-agent-context.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { parseRawSessionConversationRef } from "../sessions/session-key-utils.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { PluginHookAgentContext } from "./hook-types.js"; const TARGET_PREFIXES = new Set(["channel", "chat", "direct", "dm", "group", "thread", "user"]); diff --git a/src/plugins/hooks.test-helpers.ts b/src/plugins/hooks.test-helpers.ts index 15a920f104b..66b4c93fcff 100644 --- a/src/plugins/hooks.test-helpers.ts +++ b/src/plugins/hooks.test-helpers.ts @@ -1,4 +1,4 @@ -import { uniqueStrings } from "../shared/string-normalization.js"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { createHookRunner } from "./hooks.js"; import type { PluginRegistry } from "./registry.js"; import { createPluginRecord } from "./status.test-helpers.js"; diff --git a/src/plugins/host-hook-attachments.ts b/src/plugins/host-hook-attachments.ts index 7ca1e3390a2..a975d33375a 100644 --- a/src/plugins/host-hook-attachments.ts +++ b/src/plugins/host-hook-attachments.ts @@ -1,5 +1,6 @@ import * as fsPromises from "node:fs/promises"; import { lstat } from "node:fs/promises"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveAgentWorkspaceDir } from "../agents/agent-scope.js"; import { resolvePathFromInput } from "../agents/path-policy.js"; import { resolveWorkspaceRoot } from "../agents/workspace-dir.js"; @@ -8,7 +9,6 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; import { formatErrorMessage } from "../infra/errors.js"; import { detectMime, FILE_TYPE_SNIFF_MAX_BYTES, normalizeMimeType } from "../media/mime.js"; import { resolveAgentIdFromSessionKey } from "../routing/session-key.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { isDeliverableMessageChannel, normalizeMessageChannel } from "../utils/message-channel.js"; import type { PluginAttachmentChannelHints, diff --git a/src/plugins/host-hook-cleanup.ts b/src/plugins/host-hook-cleanup.ts index 13010b783bb..a9334520ccf 100644 --- a/src/plugins/host-hook-cleanup.ts +++ b/src/plugins/host-hook-cleanup.ts @@ -1,10 +1,10 @@ import fs from "node:fs"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { getRuntimeConfig } from "../config/config.js"; import { updateSessionStore } from "../config/sessions/store.js"; import { resolveAllAgentSessionStoreTargetsSync } from "../config/sessions/targets.js"; import type { SessionEntry } from "../config/sessions/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { withPluginHostCleanupTimeout } from "./host-hook-cleanup-timeout.js"; import { cleanupPluginSessionSchedulerJobs, diff --git a/src/plugins/host-hook-runtime.ts b/src/plugins/host-hook-runtime.ts index 92323b4f5ee..23e022fe930 100644 --- a/src/plugins/host-hook-runtime.ts +++ b/src/plugins/host-hook-runtime.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { AgentEventPayload } from "../infra/agent-events.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { resolveGlobalSingleton } from "../shared/global-singleton.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { withPluginHostCleanupTimeout } from "./host-hook-cleanup-timeout.js"; import { isPluginJsonValue, diff --git a/src/plugins/host-hook-scheduled-turns.ts b/src/plugins/host-hook-scheduled-turns.ts index 67e486bf097..4a7fec8b05b 100644 --- a/src/plugins/host-hook-scheduled-turns.ts +++ b/src/plugins/host-hook-scheduled-turns.ts @@ -1,13 +1,13 @@ import { randomUUID } from "node:crypto"; +import { + resolveExpiresAtMsFromDurationMs, + timestampMsToIsoString, +} from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { CronServiceContract } from "../cron/service-contract.js"; import type { CronJob, CronJobCreate } from "../cron/types.js"; import { formatErrorMessage } from "../infra/errors.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; -import { - resolveExpiresAtMsFromDurationMs, - timestampMsToIsoString, -} from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { deletePluginSessionSchedulerJob, registerPluginSessionSchedulerJob, diff --git a/src/plugins/host-hook-state.ts b/src/plugins/host-hook-state.ts index 79cfbe0ea5f..b8170543742 100644 --- a/src/plugins/host-hook-state.ts +++ b/src/plugins/host-hook-state.ts @@ -1,4 +1,8 @@ import { randomUUID } from "node:crypto"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { loadSessionStore, updateSessionStore, type SessionEntry } from "../config/sessions.js"; import { resolveAgentMainSessionKey } from "../config/sessions/main-session.js"; import { resolveStorePath } from "../config/sessions/paths.js"; @@ -12,10 +16,6 @@ import { resolveSessionStoreKey, } from "../gateway/session-store-key.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; export { clearPluginOwnedSessionState } from "./host-hook-cleanup.js"; import { buildPluginAgentTurnPrepareContext, diff --git a/src/plugins/http-path.ts b/src/plugins/http-path.ts index d4afb692fed..1dfef3967ee 100644 --- a/src/plugins/http-path.ts +++ b/src/plugins/http-path.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export function normalizePluginHttpPath( path?: string | null, diff --git a/src/plugins/install-security-scan.runtime.ts b/src/plugins/install-security-scan.runtime.ts index eb383a2f8e1..41ec42996c4 100644 --- a/src/plugins/install-security-scan.runtime.ts +++ b/src/plugins/install-security-scan.runtime.ts @@ -1,11 +1,14 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { + normalizeTrimmedStringList, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { tryReadJson } from "../infra/json-files.js"; import { resolveOpenClawPackageRootSync } from "../infra/openclaw-root.js"; import { parseStrictPositiveInteger } from "../infra/parse-finite-number.js"; import { extensionUsesSkippedScannerPath, isPathInside } from "../security/scan-paths.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { normalizeTrimmedStringList, uniqueStrings } from "../shared/string-normalization.js"; import { scanDirectoryWithSummary } from "../skills/security/scanner.js"; import { findBlockedPackageDirectoryInPath, diff --git a/src/plugins/install-source-info.ts b/src/plugins/install-source-info.ts index 2a3a2a81468..f019852b717 100644 --- a/src/plugins/install-source-info.ts +++ b/src/plugins/install-source-info.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { parseClawHubPluginSpec } from "../infra/clawhub-spec.js"; import { parseRegistryNpmSpec, type ParsedRegistryNpmSpec } from "../infra/npm-registry-spec.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { PluginPackageInstall } from "./manifest.js"; export type PluginInstallSourceWarning = diff --git a/src/plugins/install.ts b/src/plugins/install.ts index 7e40dcf312a..a199a31f2cf 100644 --- a/src/plugins/install.ts +++ b/src/plugins/install.ts @@ -2,6 +2,7 @@ import { createHash } from "node:crypto"; import type { Dirent } from "node:fs"; import fs from "node:fs/promises"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { satisfiesPluginApiRange } from "../infra/clawhub.js"; import { packageNameMatchesId } from "../infra/install-safe-path.js"; import { @@ -43,7 +44,6 @@ import { import { compareComparableSemver, parseComparableSemver } from "../infra/semver-compare.js"; import { runCommandWithTimeout } from "../process/exec.js"; import { createLazyImportLoader } from "../shared/lazy-promise.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resolveUserPath } from "../utils.js"; import { encodePluginInstallDirName, diff --git a/src/plugins/installed-plugin-index-record-builder.ts b/src/plugins/installed-plugin-index-record-builder.ts index fd17fefb19f..83a2759d106 100644 --- a/src/plugins/installed-plugin-index-record-builder.ts +++ b/src/plugins/installed-plugin-index-record-builder.ts @@ -1,6 +1,6 @@ import path from "node:path"; +import { normalizeSortedUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.js"; -import { normalizeSortedUniqueStringEntries } from "../shared/string-normalization.js"; import type { PluginCompatCode } from "./compat/registry.js"; import { normalizePluginsConfig, resolveEffectiveEnableState } from "./config-state.js"; import { isPluginEnabledByDefaultForPlatform } from "./default-enablement.js"; diff --git a/src/plugins/installed-plugin-index-record-reader.ts b/src/plugins/installed-plugin-index-record-reader.ts index b0118dc0890..c3c5e23fcc5 100644 --- a/src/plugins/installed-plugin-index-record-reader.ts +++ b/src/plugins/installed-plugin-index-record-reader.ts @@ -1,8 +1,8 @@ import fs from "node:fs"; import path from "node:path"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import type { PluginInstallRecord } from "../config/types.plugins.js"; import { tryReadJson, tryReadJsonSync } from "../infra/json-files.js"; -import { isRecord } from "../shared/record-coerce.js"; import { resolveDefaultPluginNpmDir, validatePluginId } from "./install-paths.js"; import { resolveInstalledPluginIndexStorePath, diff --git a/src/plugins/interactive-registry.ts b/src/plugins/interactive-registry.ts index 1563b84c913..33352fdb614 100644 --- a/src/plugins/interactive-registry.ts +++ b/src/plugins/interactive-registry.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { normalizePluginInteractiveNamespace, resolvePluginInteractiveMatch, diff --git a/src/plugins/interactive-shared.ts b/src/plugins/interactive-shared.ts index 26a9bf39aa5..3364fa307a9 100644 --- a/src/plugins/interactive-shared.ts +++ b/src/plugins/interactive-shared.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; export function toPluginInteractiveRegistryKey(channel: string, namespace: string): string { return `${normalizeOptionalLowercaseString(channel) ?? ""}:${namespace.trim()}`; diff --git a/src/plugins/legacy-npm-declaration.ts b/src/plugins/legacy-npm-declaration.ts index 0937d199b72..63763066ba6 100644 --- a/src/plugins/legacy-npm-declaration.ts +++ b/src/plugins/legacy-npm-declaration.ts @@ -1,7 +1,7 @@ import path from "node:path"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { tryReadJsonSync } from "../infra/json-files.js"; import { parseRegistryNpmSpec } from "../infra/npm-registry-spec.js"; -import { isRecord } from "../shared/record-coerce.js"; import { validatePluginId } from "./install-paths.js"; export const LEGACY_NPM_DECLARATION_FILE = "openclaw.extension.json"; diff --git a/src/plugins/loader-provenance.ts b/src/plugins/loader-provenance.ts index 02065d37e3f..a758d4010dd 100644 --- a/src/plugins/loader-provenance.ts +++ b/src/plugins/loader-provenance.ts @@ -1,5 +1,5 @@ +import { normalizeTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import type { PluginInstallRecord } from "../config/types.plugins.js"; -import { normalizeTrimmedStringList } from "../shared/string-normalization.js"; import { resolveUserPath } from "../utils.js"; import type { PluginCandidate } from "./discovery.js"; import { loadInstalledPluginIndexInstallRecordsSync } from "./installed-plugin-index-records.js"; diff --git a/src/plugins/loader-records.ts b/src/plugins/loader-records.ts index c7996aa7911..c914a9c10c6 100644 --- a/src/plugins/loader-records.ts +++ b/src/plugins/loader-records.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { PluginCompatCode } from "./compat/registry.js"; import type { PluginActivationState } from "./config-state.js"; import type { PluginBundleFormat, PluginFormat } from "./manifest-types.js"; diff --git a/src/plugins/loader.ts b/src/plugins/loader.ts index f7d1b323192..879f99897d3 100644 --- a/src/plugins/loader.ts +++ b/src/plugins/loader.ts @@ -1,6 +1,7 @@ import { createHash } from "node:crypto"; import fs from "node:fs"; import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { clearAgentHarnesses, listRegisteredAgentHarnesses, @@ -19,7 +20,6 @@ import { resolveMemoryDreamingConfig, resolveMemoryDreamingPluginConfig, } from "../memory-host-sdk/dreaming.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { clearDetachedTaskLifecycleRuntimeRegistration, getDetachedTaskLifecycleRuntimeRegistration, diff --git a/src/plugins/manifest-command-aliases.runtime.ts b/src/plugins/manifest-command-aliases.runtime.ts index 0b0d1fc3d9e..3db4ac0120a 100644 --- a/src/plugins/manifest-command-aliases.runtime.ts +++ b/src/plugins/manifest-command-aliases.runtime.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import { resolveManifestActivationPluginIds } from "./activation-planner.js"; import { resolveManifestCommandAliasOwnerInRegistry, diff --git a/src/plugins/manifest-command-aliases.ts b/src/plugins/manifest-command-aliases.ts index 6b9f152922d..8046b64e3f9 100644 --- a/src/plugins/manifest-command-aliases.ts +++ b/src/plugins/manifest-command-aliases.ts @@ -1,7 +1,7 @@ import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; import { isRecord } from "../utils.js"; export type PluginManifestCommandAliasKind = "runtime-slash"; diff --git a/src/plugins/manifest-contract-eligibility.ts b/src/plugins/manifest-contract-eligibility.ts index e130b0ea063..4376cb4018c 100644 --- a/src/plugins/manifest-contract-eligibility.ts +++ b/src/plugins/manifest-contract-eligibility.ts @@ -1,5 +1,5 @@ +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; import { isInstalledPluginEnabled } from "./installed-plugin-index.js"; import type { PluginManifestContractListKey, PluginManifestRecord } from "./manifest-registry.js"; import { resolvePluginMetadataSnapshot } from "./plugin-metadata-snapshot.js"; diff --git a/src/plugins/manifest-contract-runtime.ts b/src/plugins/manifest-contract-runtime.ts index 997bb82b263..e20d09762e0 100644 --- a/src/plugins/manifest-contract-runtime.ts +++ b/src/plugins/manifest-contract-runtime.ts @@ -1,5 +1,5 @@ +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; import { hasManifestContractValue, listAvailableManifestContractPlugins, diff --git a/src/plugins/manifest-metadata-scan.ts b/src/plugins/manifest-metadata-scan.ts index 575d3fb24bc..869af8fda4a 100644 --- a/src/plugins/manifest-metadata-scan.ts +++ b/src/plugins/manifest-metadata-scan.ts @@ -2,8 +2,8 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import { fileURLToPath } from "node:url"; -import { isRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalString as normalizeTrimmedString } from "../shared/string-coerce.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString as normalizeTrimmedString } from "@openclaw/normalization-core/string-coerce"; import { parseJsonWithJson5Fallback } from "../utils/parse-json-compat.js"; type PluginManifestMetadataRecord = { diff --git a/src/plugins/manifest-model-suppression.ts b/src/plugins/manifest-model-suppression.ts index d14a42b3656..60d7a5625c9 100644 --- a/src/plugins/manifest-model-suppression.ts +++ b/src/plugins/manifest-model-suppression.ts @@ -1,10 +1,10 @@ import { buildModelCatalogMergeKey } from "@openclaw/model-catalog-core/model-catalog-refs"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { planManifestModelCatalogSuppressions, type ManifestModelCatalogSuppressionEntry, } from "../model-catalog/index.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { isManifestPluginAvailableForControlPlane, loadManifestMetadataSnapshot, diff --git a/src/plugins/manifest-registry-installed.ts b/src/plugins/manifest-registry-installed.ts index e986f61328c..d24bf7b623a 100644 --- a/src/plugins/manifest-registry-installed.ts +++ b/src/plugins/manifest-registry-installed.ts @@ -1,10 +1,10 @@ import fs from "node:fs"; import path from "node:path"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeOptionalTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { tryReadJsonSync } from "../infra/json-files.js"; -import { isRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { normalizeOptionalTrimmedStringList } from "../shared/string-normalization.js"; import type { PluginCandidate } from "./discovery.js"; import { hashJson } from "./installed-plugin-index-hash.js"; import type { InstalledPluginFileSignature } from "./installed-plugin-index-hash.js"; diff --git a/src/plugins/manifest-registry.ts b/src/plugins/manifest-registry.ts index 0079ab8765b..b54507c9eed 100644 --- a/src/plugins/manifest-registry.ts +++ b/src/plugins/manifest-registry.ts @@ -1,15 +1,15 @@ import fs from "node:fs"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { + normalizeOptionalTrimmedStringList, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { sanitizeForLog } from "../../packages/terminal-core/src/ansi.js"; import type { OpenClawConfig } from "../config/types.js"; import type { PluginInstallRecord } from "../config/types.plugins.js"; import { satisfiesPluginApiRange } from "../infra/clawhub.js"; import { isBlockedObjectKey } from "../infra/prototype-keys.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { - normalizeOptionalTrimmedStringList, - uniqueStrings, -} from "../shared/string-normalization.js"; import { resolveUserPath } from "../utils.js"; import { resolveCompatibilityHostVersion } from "../version.js"; import { loadBundleManifest } from "./bundle-manifest.js"; diff --git a/src/plugins/manifest-tool-availability.ts b/src/plugins/manifest-tool-availability.ts index b288bacf1c0..880b392716e 100644 --- a/src/plugins/manifest-tool-availability.ts +++ b/src/plugins/manifest-tool-availability.ts @@ -1,8 +1,8 @@ +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { coerceSecretRef, type SecretRef } from "../config/types.secrets.js"; import { resolveDefaultSecretProviderAlias } from "../secrets/ref-contract.js"; -import { isRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { PluginManifestRecord } from "./manifest-registry.js"; import type { PluginManifestCapabilityProviderAuthSignal, diff --git a/src/plugins/manifest.ts b/src/plugins/manifest.ts index 5057cc57a61..9b782d397ac 100644 --- a/src/plugins/manifest.ts +++ b/src/plugins/manifest.ts @@ -20,8 +20,8 @@ import { ENV_SECRET_REF_ID_RE } from "../config/types.secrets.js"; import { matchRootFileOpenFailure, openRootFileSync } from "../infra/boundary-file-read.js"; import { isBlockedObjectKey } from "../infra/prototype-keys.js"; import type { JsonSchemaObject } from "../shared/json-schema.types.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { normalizeTrimmedStringList } from "../shared/string-normalization.js"; +import { normalizeOptionalString } from "../../packages/normalization-core/src/string-coerce.js"; +import { normalizeTrimmedStringList } from "../../packages/normalization-core/src/string-normalization.js"; import { isRecord } from "../utils.js"; import { parseJsonWithJson5Fallback } from "../utils/parse-json-compat.js"; import { diff --git a/src/plugins/marketplace.ts b/src/plugins/marketplace.ts index c2d40031e85..b33576d2969 100644 --- a/src/plugins/marketplace.ts +++ b/src/plugins/marketplace.ts @@ -2,6 +2,7 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { redactSensitiveUrlLikeString } from "@openclaw/net-policy/redact-sensitive-url"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { sanitizeForLog } from "../../packages/terminal-core/src/ansi.js"; import { resolveArchiveKind } from "../infra/archive.js"; import { formatErrorMessage } from "../infra/errors.js"; @@ -11,7 +12,6 @@ import { tryReadJson } from "../infra/json-files.js"; import { fetchWithSsrFGuard } from "../infra/net/fetch-guard.js"; import { isPathInside } from "../infra/path-guards.js"; import { runCommandWithTimeout } from "../process/exec.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { resolveUserPath } from "../utils.js"; import type { InstallSafetyOverrides } from "./install-security-scan.js"; import { installPluginFromPath, type InstallPluginResult } from "./install.js"; diff --git a/src/plugins/min-host-version.ts b/src/plugins/min-host-version.ts index 29155c3330d..d242b780825 100644 --- a/src/plugins/min-host-version.ts +++ b/src/plugins/min-host-version.ts @@ -11,7 +11,7 @@ export type MinHostVersionRequirement = { minimumLabel: string; }; -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export type MinHostVersionCheckResult = | { ok: true; requirement: MinHostVersionRequirement | null } diff --git a/src/plugins/model-catalog-registration.ts b/src/plugins/model-catalog-registration.ts index e0319628b5c..1bd806d5655 100644 --- a/src/plugins/model-catalog-registration.ts +++ b/src/plugins/model-catalog-registration.ts @@ -12,8 +12,8 @@ import { type VoiceModelCapabilities, type VoiceModelProvider, } from "../../packages/speech-core/voice-models.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { uniqueValues } from "../shared/string-normalization.js"; +import { normalizeOptionalString } from "../../packages/normalization-core/src/string-coerce.js"; +import { uniqueValues } from "../../packages/normalization-core/src/string-normalization.js"; import type { PluginDiagnostic } from "./manifest-types.js"; import { projectProviderCatalogResultToUnifiedTextRows } from "./provider-catalog-unified-text.js"; import type { PluginRecord, PluginRegistry } from "./registry-types.js"; diff --git a/src/plugins/official-external-plugin-catalog.ts b/src/plugins/official-external-plugin-catalog.ts index 0b71795318f..61cea65dd8b 100644 --- a/src/plugins/official-external-plugin-catalog.ts +++ b/src/plugins/official-external-plugin-catalog.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import officialExternalChannelCatalog from "../../scripts/lib/official-external-channel-catalog.json" with { type: "json" }; import officialExternalPluginCatalog from "../../scripts/lib/official-external-plugin-catalog.json" with { type: "json" }; import officialExternalProviderCatalog from "../../scripts/lib/official-external-provider-catalog.json" with { type: "json" }; import { MANIFEST_KEY } from "../compat/legacy-names.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { isRecord } from "../utils.js"; import type { PluginManifestChannelConfig, diff --git a/src/plugins/package-compat.ts b/src/plugins/package-compat.ts index dfc1965ba12..20d5fbc6a82 100644 --- a/src/plugins/package-compat.ts +++ b/src/plugins/package-compat.ts @@ -1,4 +1,4 @@ -import { isRecord } from "../shared/record-coerce.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; export type PackagePluginApiRangeResult = | { ok: true; range?: string } diff --git a/src/plugins/package-entry-resolution.ts b/src/plugins/package-entry-resolution.ts index 3de2ad02e85..f01e5160d65 100644 --- a/src/plugins/package-entry-resolution.ts +++ b/src/plugins/package-entry-resolution.ts @@ -1,12 +1,12 @@ import fs from "node:fs"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { matchRootFileOpenFailure, openRootFile, openRootFileSync, } from "../infra/boundary-file-read.js"; import { resolveRootPath, resolveRootPathSync } from "../infra/boundary-path.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { PluginDiagnostic } from "./manifest-types.js"; import { getPackageManifestMetadata, type PackageManifest } from "./manifest.js"; import { diff --git a/src/plugins/package-entrypoints.ts b/src/plugins/package-entrypoints.ts index 5b0f5e175cc..57b211c9d96 100644 --- a/src/plugins/package-entrypoints.ts +++ b/src/plugins/package-entrypoints.ts @@ -1,5 +1,5 @@ import path from "node:path"; -import { uniqueStrings } from "../shared/string-normalization.js"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; export function isTypeScriptPackageEntry(entryPath: string): boolean { return [".ts", ".mts", ".cts"].includes(path.extname(entryPath).toLowerCase()); diff --git a/src/plugins/plugin-config-trust.ts b/src/plugins/plugin-config-trust.ts index 7ec9f6a0265..aeedcbaf1e3 100644 --- a/src/plugins/plugin-config-trust.ts +++ b/src/plugins/plugin-config-trust.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import type { PluginManifestRecord } from "./manifest-registry.js"; type PluginEntriesConfig = NonNullable["entries"]>; diff --git a/src/plugins/plugin-metadata-snapshot.ts b/src/plugins/plugin-metadata-snapshot.ts index 26d5c9f4be6..e9854a4f72a 100644 --- a/src/plugins/plugin-metadata-snapshot.ts +++ b/src/plugins/plugin-metadata-snapshot.ts @@ -1,13 +1,13 @@ import fs from "node:fs"; import path from "node:path"; import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { resolveIsNixMode } from "../config/paths.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { getActiveDiagnosticsTimelineSpan, measureDiagnosticsTimelineSpanSync, } from "../infra/diagnostics-timeline.js"; -import { isRecord } from "../shared/record-coerce.js"; import { resolveUserPath } from "../utils.js"; import { resolveCompatibilityHostVersion } from "../version.js"; import { getCurrentPluginMetadataSnapshot } from "./current-plugin-metadata-snapshot.js"; diff --git a/src/plugins/plugin-module-loader-cache.ts b/src/plugins/plugin-module-loader-cache.ts index 4deb0b01458..89383b6bccf 100644 --- a/src/plugins/plugin-module-loader-cache.ts +++ b/src/plugins/plugin-module-loader-cache.ts @@ -5,6 +5,7 @@ import type { createJiti } from "jiti"; import { toSafeImportPath } from "../shared/import-specifier.js"; import { tryNativeRequireJavaScriptModule } from "./native-module-require.js"; import { PluginLruCache } from "./plugin-cache-primitives.js"; +import { installOpenClawInternalCorePackageNativeResolver } from "./plugin-sdk-native-resolver.js"; import { buildPluginLoaderJitiOptions, createPluginLoaderModuleCacheKey, @@ -291,6 +292,7 @@ export function getCachedPluginModuleLoader( createLoader?: PluginModuleLoaderFactory; }, ): PluginModuleLoader { + installOpenClawInternalCorePackageNativeResolver({ moduleUrl: params.importerUrl }); const cacheEntry = resolvePluginModuleLoaderCacheEntry(params); const cached = params.cache.get(cacheEntry.scopedCacheKey); if (cached) { diff --git a/src/plugins/plugin-registry-contributions.ts b/src/plugins/plugin-registry-contributions.ts index ab7ef6a04b1..c03c66ba473 100644 --- a/src/plugins/plugin-registry-contributions.ts +++ b/src/plugins/plugin-registry-contributions.ts @@ -1,6 +1,6 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { normalizeSortedUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeSortedUniqueStringEntries } from "../shared/string-normalization.js"; import { normalizePluginsConfigWithResolver, type NormalizedPluginsConfig, diff --git a/src/plugins/plugin-scope.ts b/src/plugins/plugin-scope.ts index e31bcdcf682..58dfb527740 100644 --- a/src/plugins/plugin-scope.ts +++ b/src/plugins/plugin-scope.ts @@ -1,4 +1,4 @@ -import { normalizeStringEntries } from "../shared/string-normalization.js"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; export type PluginIdScope = readonly string[] | undefined; diff --git a/src/plugins/plugin-sdk-native-resolver.test.ts b/src/plugins/plugin-sdk-native-resolver.test.ts index d7c32ba9f7f..6cf9db42bea 100644 --- a/src/plugins/plugin-sdk-native-resolver.test.ts +++ b/src/plugins/plugin-sdk-native-resolver.test.ts @@ -66,6 +66,13 @@ function writeExternalPluginEntry(root: string): string { return entry; } +function writeNormalizationCoreSource(root: string): string { + const sourcePath = path.join(root, "packages", "normalization-core", "src", "string-coerce.ts"); + fs.mkdirSync(path.dirname(sourcePath), { recursive: true }); + fs.writeFileSync(sourcePath, "export const normalizeOptionalString = () => undefined;\n", "utf8"); + return sourcePath; +} + describe("installOpenClawPluginSdkNativeResolver", () => { it("keeps native aliases on JS dist artifacts when source files exist", () => { const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-sdk-native-source-resolver-")); @@ -219,6 +226,30 @@ describe("installOpenClawPluginSdkNativeResolver", () => { expect(() => requireFromOutside.resolve("openclaw/plugin-sdk/channel-outbound")).toThrow(); }); + it("resolves internal core packages only for OpenClaw-owned source parents", () => { + const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-sdk-native-core-internal-")); + const { loaderModulePath } = writeFakeOpenClawPackage(root); + const normalizationSource = writeNormalizationCoreSource(root); + const externalPluginEntry = writeExternalPluginEntry(path.join(root, "external-plugin")); + const coreSourceParent = path.join(root, "src", "config", "plugin-web-search-config.ts"); + fs.mkdirSync(path.dirname(coreSourceParent), { recursive: true }); + fs.writeFileSync(coreSourceParent, "export default {};\n", "utf8"); + + const installedAliases = installOpenClawPluginSdkNativeResolver({ + modulePath: loaderModulePath, + pluginModulePath: externalPluginEntry, + pluginSdkResolution: "dist", + }); + + expect(installedAliases).toContain("@openclaw/normalization-core/string-coerce"); + const requireFromCoreSource = createRequire(coreSourceParent); + const requireFromPlugin = createRequire(externalPluginEntry); + expect( + fs.realpathSync(requireFromCoreSource.resolve("@openclaw/normalization-core/string-coerce")), + ).toBe(fs.realpathSync(normalizationSource)); + expect(() => requireFromPlugin.resolve("@openclaw/normalization-core/string-coerce")).toThrow(); + }); + it("does not register source-only SDK subpaths for native resolution", () => { const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-sdk-native-source-only-")); const { loaderModulePath } = writeFakeOpenClawPackage(root); diff --git a/src/plugins/plugin-sdk-native-resolver.ts b/src/plugins/plugin-sdk-native-resolver.ts index 8467692c74a..199d7a93164 100644 --- a/src/plugins/plugin-sdk-native-resolver.ts +++ b/src/plugins/plugin-sdk-native-resolver.ts @@ -44,6 +44,19 @@ export type InstallOpenClawPluginSdkNativeResolverOptions = { const moduleWithResolver = Module as ModuleWithResolver; const nodeResolveFilenameProperty = "_resolveFilename" as const; const PLUGIN_SDK_PACKAGE_PREFIXES = ["openclaw/plugin-sdk", "@openclaw/plugin-sdk"] as const; +const INTERNAL_CORE_PACKAGE_ALIASES = [ + { + packageName: "@openclaw/normalization-core", + packageDir: "normalization-core", + subpaths: [ + ["", "index.ts"], + ["number-coercion", "number-coercion.ts"], + ["record-coerce", "record-coerce.ts"], + ["string-coerce", "string-coerce.ts"], + ["string-normalization", "string-normalization.ts"], + ], + }, +] as const; const pluginSdkNativeAliases = new Map(); let installed = false; let previousResolveFilename: ResolveFilename | undefined; @@ -174,7 +187,7 @@ function resolveAliasTargetForParentUrl( request: string, parentUrl: string | undefined, ): string | undefined { - if (!isPluginSdkAliasSpecifier(request) || !parentUrl?.startsWith("file:")) { + if (!parentUrl?.startsWith("file:")) { return undefined; } try { @@ -222,6 +235,39 @@ function listPluginSdkNativeAliases( }); } +function listInternalCorePackageNativeAliases( + options: InstallOpenClawPluginSdkNativeResolverOptions, +): Array<{ + request: string; + target: string; + parentRoots: string[]; +}> { + const packageRoot = resolveLoaderPackageRootFromModulePath(resolveLoaderModulePath(options)); + const parentRoots = ["src", "scripts", "packages", "test"] + .map((segment) => path.join(packageRoot, segment)) + .filter((candidate) => fs.existsSync(candidate)) + .map(normalizePathForBoundary); + if (parentRoots.length === 0) { + return []; + } + + const aliases: Array<{ + request: string; + target: string; + parentRoots: string[]; + }> = []; + for (const entry of INTERNAL_CORE_PACKAGE_ALIASES) { + for (const [subpath, srcFile] of entry.subpaths) { + const request = subpath ? `${entry.packageName}/${subpath}` : entry.packageName; + const target = path.join(packageRoot, "packages", entry.packageDir, "src", srcFile); + if (fs.existsSync(target)) { + aliases.push({ request, target, parentRoots }); + } + } + } + return aliases; +} + function installResolver(): void { if (installed || !moduleWithResolver[nodeResolveFilenameProperty]) { return; @@ -275,6 +321,19 @@ export function installOpenClawPluginSdkNativeResolver( for (const [specifier, target] of listPluginSdkNativeAliases(options)) { registerNativeAlias({ request: specifier, target, parentRoots }); } + for (const alias of listInternalCorePackageNativeAliases(options)) { + registerNativeAlias(alias); + } + installResolver(); + return [...pluginSdkNativeAliases.keys()].toSorted(); +} + +export function installOpenClawInternalCorePackageNativeResolver( + options: Pick = {}, +): string[] { + for (const alias of listInternalCorePackageNativeAliases(options)) { + registerNativeAlias(alias); + } installResolver(); return [...pluginSdkNativeAliases.keys()].toSorted(); } diff --git a/src/plugins/provider-api-key-auth.ts b/src/plugins/provider-api-key-auth.ts index b4619d86b5b..52bf04c2556 100644 --- a/src/plugins/provider-api-key-auth.ts +++ b/src/plugins/provider-api-key-auth.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import { upsertAuthProfileWithLock } from "../agents/auth-profiles/profiles.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { SecretInput } from "../config/types.secrets.js"; import { createLazyRuntimeSurface } from "../shared/lazy-runtime.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { normalizeUniqueStringEntries } from "../shared/string-normalization.js"; import { normalizeOptionalSecretInput } from "../utils/normalize-secret-input.js"; import type { ProviderAuthMethod, diff --git a/src/plugins/provider-auth-choice-helpers.ts b/src/plugins/provider-auth-choice-helpers.ts index 26a5827f193..c679f00bce1 100644 --- a/src/plugins/provider-auth-choice-helpers.ts +++ b/src/plugins/provider-auth-choice-helpers.ts @@ -1,3 +1,9 @@ +import { isRecord as isPlainRecord } from "@openclaw/normalization-core/record-coerce"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { normalizeConfiguredProviderCatalogModelId } from "../agents/model-ref-shared.js"; import { normalizeProviderId } from "../agents/model-selection.js"; import { @@ -8,12 +14,6 @@ import { normalizeProviderConfigForConfigDefaults } from "../config/provider-pol import type { AgentModelConfig } from "../config/types.agents-shared.js"; import type { ModelProviderConfig } from "../config/types.models.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { isRecord as isPlainRecord } from "../shared/record-coerce.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import type { ProviderAuthMethod, ProviderPlugin } from "./types.js"; export function resolveProviderMatch( diff --git a/src/plugins/provider-auth-helpers.ts b/src/plugins/provider-auth-helpers.ts index 06be91dc7d4..1b803a94d58 100644 --- a/src/plugins/provider-auth-helpers.ts +++ b/src/plugins/provider-auth-helpers.ts @@ -1,5 +1,6 @@ import fs from "node:fs"; import path from "node:path"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { resolveDefaultAgentDir } from "../agents/agent-scope-config.js"; import { buildAuthProfileId } from "../agents/auth-profiles/identity.js"; import { upsertAuthProfile, upsertAuthProfileWithLock } from "../agents/auth-profiles/profiles.js"; @@ -14,7 +15,6 @@ import { } from "../config/types.secrets.js"; import type { OAuthCredentials } from "../llm/oauth.js"; import { getProviderEnvVars } from "../secrets/provider-env-vars.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { normalizeSecretInput } from "../utils/normalize-secret-input.js"; import type { SecretInputMode } from "./provider-auth-types.js"; diff --git a/src/plugins/provider-auth-input.ts b/src/plugins/provider-auth-input.ts index 232ce5d6982..4dc39dd7a3b 100644 --- a/src/plugins/provider-auth-input.ts +++ b/src/plugins/provider-auth-input.ts @@ -1,10 +1,10 @@ -import { resolveEnvApiKey } from "../agents/model-auth-env.js"; -import type { OpenClawConfig } from "../config/types.js"; -import type { SecretInput } from "../config/types.secrets.js"; import { normalizeOptionalLowercaseString, normalizeStringifiedOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { resolveEnvApiKey } from "../agents/model-auth-env.js"; +import type { OpenClawConfig } from "../config/types.js"; +import type { SecretInput } from "../config/types.secrets.js"; import type { WizardPrompter } from "../wizard/prompts.js"; import { resolveSecretInputModeForEnvSelection } from "./provider-auth-mode.js"; import { diff --git a/src/plugins/provider-auth-ref.ts b/src/plugins/provider-auth-ref.ts index 5d86b5b9a3e..3db8a1667d6 100644 --- a/src/plugins/provider-auth-ref.ts +++ b/src/plugins/provider-auth-ref.ts @@ -1,3 +1,7 @@ +import { + normalizeOptionalString, + normalizeStringifiedOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.js"; import { isValidEnvSecretRefId, type SecretRef } from "../config/types.secrets.js"; import { formatErrorMessage } from "../infra/errors.js"; @@ -10,10 +14,6 @@ import { resolveDefaultSecretProviderAlias, } from "../secrets/ref-contract.js"; import { createLazyImportLoader } from "../shared/lazy-promise.js"; -import { - normalizeOptionalString, - normalizeStringifiedOptionalString, -} from "../shared/string-coerce.js"; import type { WizardPrompter } from "../wizard/prompts.js"; const secretResolveLoader = createLazyImportLoader(() => import("../secrets/resolve.js")); diff --git a/src/plugins/provider-auth-token.ts b/src/plugins/provider-auth-token.ts index 3408ae69fda..0ab554fa432 100644 --- a/src/plugins/provider-auth-token.ts +++ b/src/plugins/provider-auth-token.ts @@ -1,5 +1,5 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export const ANTHROPIC_SETUP_TOKEN_PREFIX = "sk-ant-oat01-"; const ANTHROPIC_SETUP_TOKEN_MIN_LENGTH = 80; diff --git a/src/plugins/provider-catalog.ts b/src/plugins/provider-catalog.ts index f138b1f4b68..94bd43331be 100644 --- a/src/plugins/provider-catalog.ts +++ b/src/plugins/provider-catalog.ts @@ -1,9 +1,9 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; -import type { ModelProviderConfig } from "../config/types.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { ModelProviderConfig } from "../config/types.js"; import type { ProviderCatalogContext, ProviderCatalogResult } from "./types.js"; export function findCatalogTemplate(params: { diff --git a/src/plugins/provider-contract-public-artifacts.ts b/src/plugins/provider-contract-public-artifacts.ts index e38d8f4d950..4f7faa64c8e 100644 --- a/src/plugins/provider-contract-public-artifacts.ts +++ b/src/plugins/provider-contract-public-artifacts.ts @@ -1,5 +1,5 @@ -import { isRecord } from "../shared/record-coerce.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { loadBundledPluginPublicArtifactModuleSync } from "./public-surface-loader.js"; import type { ProviderPlugin } from "./types.js"; diff --git a/src/plugins/provider-discovery.runtime.ts b/src/plugins/provider-discovery.runtime.ts index dbf9b64f97c..ae55c4e66be 100644 --- a/src/plugins/provider-discovery.runtime.ts +++ b/src/plugins/provider-discovery.runtime.ts @@ -4,7 +4,7 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; import type { ModelDefinitionConfig, ModelProviderConfig } from "../config/types.models.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { planManifestModelCatalogRows } from "../model-catalog/manifest-planner.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; +import { sortUniqueStrings } from "../../packages/normalization-core/src/string-normalization.js"; import { loadManifestMetadataSnapshot } from "./manifest-contract-eligibility.js"; import type { PluginManifestRecord } from "./manifest-registry.js"; import { clearNativeRequireJavaScriptModuleCache } from "./native-module-require.js"; diff --git a/src/plugins/provider-discovery.ts b/src/plugins/provider-discovery.ts index c8c42f34338..ad522f7153a 100644 --- a/src/plugins/provider-discovery.ts +++ b/src/plugins/provider-discovery.ts @@ -1,8 +1,8 @@ +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { normalizeProviderId } from "../agents/model-selection.js"; import type { ModelProviderConfig } from "../config/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { createLazyImportLoader } from "../shared/lazy-promise.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; import { listManifestProviderContributionIds } from "./manifest-contribution-ids.js"; import type { PluginMetadataRegistryView } from "./plugin-metadata-snapshot.types.js"; import { type LoadPluginRegistryParams, type PluginRegistrySnapshot } from "./plugin-registry.js"; diff --git a/src/plugins/provider-hook-runtime.ts b/src/plugins/provider-hook-runtime.ts index 4802b9adffc..4a005b7f928 100644 --- a/src/plugins/provider-hook-runtime.ts +++ b/src/plugins/provider-hook-runtime.ts @@ -1,10 +1,10 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; -import { resolveModelCatalogScope } from "../agents/model-catalog-scope.js"; -import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { resolveModelCatalogScope } from "../agents/model-catalog-scope.js"; +import type { OpenClawConfig } from "../config/types.openclaw.js"; import { getLoadedRuntimePluginRegistry } from "./active-runtime-registry.js"; import { PluginLruCache, diff --git a/src/plugins/provider-install-catalog.ts b/src/plugins/provider-install-catalog.ts index c7cc391d854..1575ead2d78 100644 --- a/src/plugins/provider-install-catalog.ts +++ b/src/plugins/provider-install-catalog.ts @@ -1,9 +1,9 @@ +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { loadOpenClawProviderIndex, type OpenClawProviderIndexProvider, } from "../model-catalog/index.js"; -import { isRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { normalizePluginsConfig, resolveEffectiveEnableState } from "./config-state.js"; import { describePluginInstallSource, diff --git a/src/plugins/provider-model-compat.ts b/src/plugins/provider-model-compat.ts index 578feb1e285..5233d56a05b 100644 --- a/src/plugins/provider-model-compat.ts +++ b/src/plugins/provider-model-compat.ts @@ -1,7 +1,7 @@ +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { detectOpenAICompletionsCompat } from "../agents/openai-completions-compat.js"; import type { ModelCompatConfig } from "../config/types.models.js"; import type { Model } from "../llm/types.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; export function extractModelCompat( modelOrCompat: { compat?: unknown } | ModelCompatConfig | undefined, diff --git a/src/plugins/provider-model-helpers.ts b/src/plugins/provider-model-helpers.ts index b142778d073..43749cd9c3e 100644 --- a/src/plugins/provider-model-helpers.ts +++ b/src/plugins/provider-model-helpers.ts @@ -1,5 +1,5 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { normalizeModelCompat } from "./provider-model-compat.js"; import type { ProviderRuntimeModel } from "./provider-runtime-model.types.js"; import type { ProviderResolveDynamicModelContext } from "./types.js"; diff --git a/src/plugins/provider-openai-chatgpt-oauth-tls.ts b/src/plugins/provider-openai-chatgpt-oauth-tls.ts index 321b979a75c..320f3bd6570 100644 --- a/src/plugins/provider-openai-chatgpt-oauth-tls.ts +++ b/src/plugins/provider-openai-chatgpt-oauth-tls.ts @@ -1,9 +1,9 @@ import path from "node:path"; +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; +import { asNullableObjectRecord } from "@openclaw/normalization-core/record-coerce"; import { note } from "../../packages/terminal-core/src/note.js"; import { formatCliCommand } from "../cli/command-format.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { resolveTimerTimeoutMs } from "../shared/number-coercion.js"; -import { asNullableObjectRecord } from "../shared/record-coerce.js"; const TLS_CERT_ERROR_CODES = new Set([ "UNABLE_TO_GET_ISSUER_CERT_LOCALLY", diff --git a/src/plugins/provider-registry-shared.ts b/src/plugins/provider-registry-shared.ts index dc522a55758..2a14df6d1d0 100644 --- a/src/plugins/provider-registry-shared.ts +++ b/src/plugins/provider-registry-shared.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; export function normalizeCapabilityProviderId(providerId: string | undefined): string | undefined { return normalizeOptionalLowercaseString(providerId); diff --git a/src/plugins/provider-replay-helpers.ts b/src/plugins/provider-replay-helpers.ts index ec081992430..b0e240e0d60 100644 --- a/src/plugins/provider-replay-helpers.ts +++ b/src/plugins/provider-replay-helpers.ts @@ -1,7 +1,7 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { AgentMessage } from "../agents/runtime/index.js"; import { isGemma4ModelId } from "../shared/google-models.js"; import { sanitizeGoogleAssistantFirstOrdering } from "../shared/google-turn-ordering.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import type { ProviderReasoningOutputMode, ProviderReplayPolicy, diff --git a/src/plugins/provider-runtime.ts b/src/plugins/provider-runtime.ts index d2602cc78fc..4bdaac93208 100644 --- a/src/plugins/provider-runtime.ts +++ b/src/plugins/provider-runtime.ts @@ -1,4 +1,9 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { + sortUniqueStrings, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { sanitizeForLog } from "../../packages/terminal-core/src/ansi.js"; import type { AuthProfileCredential, OAuthCredential } from "../agents/auth-profiles/types.js"; import { resolveGpt5SystemPromptContribution } from "../agents/gpt5-prompt-overlay.js"; @@ -10,8 +15,6 @@ import type { ProviderSystemPromptContribution } from "../agents/system-prompt-c import type { ModelProviderConfig } from "../config/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { sortUniqueStrings, uniqueStrings } from "../shared/string-normalization.js"; import { normalizeProviderModelIdWithManifest } from "./manifest-model-id-normalization.js"; import { loadPluginMetadataSnapshot } from "./plugin-metadata-snapshot.js"; import { resolvePluginDiscoveryProvidersRuntime } from "./provider-discovery.runtime.js"; diff --git a/src/plugins/provider-self-hosted-setup.ts b/src/plugins/provider-self-hosted-setup.ts index 1efea2770a2..8712a8c1828 100644 --- a/src/plugins/provider-self-hosted-setup.ts +++ b/src/plugins/provider-self-hosted-setup.ts @@ -2,6 +2,11 @@ import { findNormalizedProviderValue, normalizeProviderId, } from "@openclaw/model-catalog-core/provider-id"; +import { + normalizeOptionalString, + normalizeStringifiedOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { ApiKeyCredential, AuthProfileCredential } from "../agents/auth-profiles/types.js"; import { upsertAuthProfileWithLock } from "../agents/auth-profiles/upsert-with-lock.js"; import { parseConfiguredModelVisibilityEntries } from "../agents/model-selection-shared.js"; @@ -15,11 +20,6 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; import { fetchWithSsrFGuard } from "../infra/net/fetch-guard.js"; import type { SsrFPolicy } from "../infra/net/ssrf.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; -import { - normalizeOptionalString, - normalizeStringifiedOptionalString, -} from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { normalizeOptionalSecretInput } from "../utils/normalize-secret-input.js"; import type { WizardPrompter } from "../wizard/prompts.js"; import { applyAuthProfileConfig } from "./provider-auth-helpers.js"; diff --git a/src/plugins/provider-validation.ts b/src/plugins/provider-validation.ts index 6e5f839a0fe..5bd4983385c 100644 --- a/src/plugins/provider-validation.ts +++ b/src/plugins/provider-validation.ts @@ -1,5 +1,5 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { normalizeUniqueTrimmedStringList } from "../shared/string-normalization.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeUniqueTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import type { PluginDiagnostic } from "./manifest-types.js"; import type { ProviderAuthMethod, ProviderPlugin } from "./types.js"; import { pushPluginValidationDiagnostic } from "./validation-diagnostics.js"; diff --git a/src/plugins/provider-wizard.ts b/src/plugins/provider-wizard.ts index a1a71640e49..c0cfa88aeae 100644 --- a/src/plugins/provider-wizard.ts +++ b/src/plugins/provider-wizard.ts @@ -1,10 +1,10 @@ -import { DEFAULT_PROVIDER } from "../agents/defaults.js"; -import { normalizeProviderId } from "../agents/model-selection.js"; -import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { DEFAULT_PROVIDER } from "../agents/defaults.js"; +import { normalizeProviderId } from "../agents/model-selection.js"; +import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { WizardPrompter } from "../wizard/prompts.js"; import { resolvePluginProviders } from "./providers.runtime.js"; import { resolvePluginSetupProvider } from "./setup-registry.js"; diff --git a/src/plugins/providers.runtime.ts b/src/plugins/providers.runtime.ts index 7a996c0721a..5b03157e5d9 100644 --- a/src/plugins/providers.runtime.ts +++ b/src/plugins/providers.runtime.ts @@ -1,4 +1,4 @@ -import { sortUniqueStrings } from "../shared/string-normalization.js"; +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { withActivatedPluginIds } from "./activation-context.js"; import { resolveBundledPluginCompatibleActivationInputs } from "./activation-context.js"; import { resolveManifestActivationPluginIds } from "./activation-planner.js"; diff --git a/src/plugins/providers.test.ts b/src/plugins/providers.test.ts index 5b9bfe098df..19dd417e8c2 100644 --- a/src/plugins/providers.test.ts +++ b/src/plugins/providers.test.ts @@ -1,7 +1,7 @@ +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../config/config.js"; import type { PluginAutoEnableResult } from "../config/plugin-auto-enable.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; import type { PluginManifestRecord } from "./manifest-registry.js"; import type { OpenClawPackageManifest } from "./manifest.js"; import type { PluginMetadataSnapshot } from "./plugin-metadata-snapshot.types.js"; diff --git a/src/plugins/providers.ts b/src/plugins/providers.ts index 53ae2a246e2..e7eb3eab25a 100644 --- a/src/plugins/providers.ts +++ b/src/plugins/providers.ts @@ -1,7 +1,7 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { splitTrailingAuthProfile } from "../agents/model-ref-profile.js"; import { compileSafeRegex } from "../security/safe-regex.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; import { withBundledPluginVitestCompat } from "./bundled-compat.js"; import { resolveEffectivePluginActivationState } from "./config-state.js"; import { getCurrentPluginMetadataSnapshot } from "./current-plugin-metadata-snapshot.js"; diff --git a/src/plugins/registry.ts b/src/plugins/registry.ts index 30d717022f4..0659b848711 100644 --- a/src/plugins/registry.ts +++ b/src/plugins/registry.ts @@ -1,5 +1,14 @@ import path from "node:path"; import { clearCodeModeNamespacesForPlugin } from "../agents/code-mode-namespaces.js"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { uniqueValues } from "@openclaw/normalization-core/string-normalization"; +import { + normalizeStringEntries, + normalizeUniqueStringEntries, +} from "@openclaw/normalization-core/string-normalization"; import { getRegisteredAgentHarness, registerAgentHarness as registerGlobalAgentHarness, @@ -36,15 +45,6 @@ import { } from "../plugin-state/plugin-state-store.js"; import { normalizePluginGatewayMethodScope } from "../shared/gateway-method-policy.js"; import { resolveGlobalSingleton } from "../shared/global-singleton.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; -import { uniqueValues } from "../shared/string-normalization.js"; -import { - normalizeStringEntries, - normalizeUniqueStringEntries, -} from "../shared/string-normalization.js"; import { getDetachedTaskLifecycleRuntimeRegistration, registerDetachedTaskLifecycleRuntime, diff --git a/src/plugins/roots.ts b/src/plugins/roots.ts index f532689a1e7..6445f826592 100644 --- a/src/plugins/roots.ts +++ b/src/plugins/roots.ts @@ -1,5 +1,5 @@ import path from "node:path"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { resolveConfigDir, resolveUserPath } from "../utils.js"; import { resolveBundledPluginsDir } from "./bundled-dir.js"; diff --git a/src/plugins/runtime/channel-runtime-contexts.ts b/src/plugins/runtime/channel-runtime-contexts.ts index a1cdaceb87e..269cd548ff7 100644 --- a/src/plugins/runtime/channel-runtime-contexts.ts +++ b/src/plugins/runtime/channel-runtime-contexts.ts @@ -1,10 +1,10 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { ChannelRuntimeContextEvent, ChannelRuntimeContextKey, ChannelRuntimeContextRegistry, } from "../../channels/plugins/channel-runtime-surface.types.js"; import { createSubsystemLogger } from "../../logging.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; type StoredRuntimeContext = { token: symbol; diff --git a/src/plugins/runtime/runtime-llm.runtime.ts b/src/plugins/runtime/runtime-llm.runtime.ts index 1096d52a5f6..939721cc323 100644 --- a/src/plugins/runtime/runtime-llm.runtime.ts +++ b/src/plugins/runtime/runtime-llm.runtime.ts @@ -1,3 +1,5 @@ +import { asFiniteNumber } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { modelKey } from "../../agents/model-ref-shared.js"; import { normalizeModelRef } from "../../agents/model-selection.js"; import type { NormalizedUsage, UsageLike } from "../../agents/usage.js"; @@ -6,8 +8,6 @@ import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { Api, Message } from "../../llm/types.js"; import { getChildLogger } from "../../logging.js"; import { normalizeAgentId } from "../../routing/session-key.js"; -import { asFiniteNumber } from "../../shared/number-coercion.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { estimateUsageCost, resolveModelCostConfig } from "../../utils/usage-format.js"; import { normalizePluginsConfig } from "../config-state.js"; import { getPluginRuntimeGatewayRequestScope } from "./gateway-request-scope.js"; diff --git a/src/plugins/sdk-alias.ts b/src/plugins/sdk-alias.ts index cf99fc31f09..af45fbdf077 100644 --- a/src/plugins/sdk-alias.ts +++ b/src/plugins/sdk-alias.ts @@ -2,9 +2,9 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import { fileURLToPath } from "node:url"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { tryReadJsonSync } from "../infra/json-files.js"; import { resolveOpenClawPackageRootSync } from "../infra/openclaw-root.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { PluginLruCache } from "./plugin-cache-primitives.js"; type PluginSdkAliasCandidateKind = "dist" | "src"; diff --git a/src/plugins/setup-registry.ts b/src/plugins/setup-registry.ts index 675ab83173c..67238fdd690 100644 --- a/src/plugins/setup-registry.ts +++ b/src/plugins/setup-registry.ts @@ -2,11 +2,11 @@ import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; -import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeStringEntries, normalizeUniqueStringEntries, -} from "../shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-normalization"; +import type { OpenClawConfig } from "../config/types.openclaw.js"; import { buildPluginApi } from "./api-builder.js"; import { collectPluginConfigContractMatches } from "./config-contracts.js"; import type { PluginManifestRecord, PluginManifestRegistry } from "./manifest-registry.js"; diff --git a/src/plugins/tools.ts b/src/plugins/tools.ts index 5142716f0c9..57c18330419 100644 --- a/src/plugins/tools.ts +++ b/src/plugins/tools.ts @@ -1,9 +1,12 @@ +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { + normalizeUniqueStringEntries, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { compileGlobPatterns, matchesAnyGlobPattern } from "../agents/glob-pattern.js"; import { DEFAULT_PLUGIN_TOOLS_ALLOWLIST_ENTRY, normalizeToolName } from "../agents/tool-policy.js"; import type { AnyAgentTool } from "../agents/tools/common.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; -import { isRecord } from "../shared/record-coerce.js"; -import { normalizeUniqueStringEntries, uniqueStrings } from "../shared/string-normalization.js"; import { getLoadedRuntimePluginRegistry } from "./active-runtime-registry.js"; import { applyTestPluginDefaults, normalizePluginsConfig } from "./config-state.js"; import type { PluginLoadOptions } from "./loader.js"; diff --git a/src/plugins/web-content-extractor-public-artifacts.ts b/src/plugins/web-content-extractor-public-artifacts.ts index a66e9285475..f4fac11ffad 100644 --- a/src/plugins/web-content-extractor-public-artifacts.ts +++ b/src/plugins/web-content-extractor-public-artifacts.ts @@ -1,4 +1,4 @@ -import { isRecord } from "../shared/record-coerce.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { loadBundledPluginPublicArtifactModuleSync } from "./public-surface-loader.js"; import type { PluginWebContentExtractorEntry, diff --git a/src/plugins/web-provider-public-artifacts.explicit.ts b/src/plugins/web-provider-public-artifacts.explicit.ts index bd7b7691f21..563aec81250 100644 --- a/src/plugins/web-provider-public-artifacts.explicit.ts +++ b/src/plugins/web-provider-public-artifacts.explicit.ts @@ -1,5 +1,5 @@ -import { isRecord } from "../shared/record-coerce.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { loadBundledPluginPublicArtifactModuleSync, resolveBundledPluginPublicArtifactPath, diff --git a/src/plugins/web-provider-public-artifacts.ts b/src/plugins/web-provider-public-artifacts.ts index 676694916de..b31a92a6dcf 100644 --- a/src/plugins/web-provider-public-artifacts.ts +++ b/src/plugins/web-provider-public-artifacts.ts @@ -1,5 +1,5 @@ import path from "node:path"; -import { normalizeUniqueStringEntries } from "../shared/string-normalization.js"; +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import { normalizePluginId } from "./config-state.js"; import type { PluginLoadOptions } from "./loader.js"; import { loadManifestMetadataSnapshot } from "./manifest-contract-eligibility.js"; diff --git a/src/plugins/web-search-install-catalog.ts b/src/plugins/web-search-install-catalog.ts index 5b76d1bdabb..1fa4b122684 100644 --- a/src/plugins/web-search-install-catalog.ts +++ b/src/plugins/web-search-install-catalog.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalString as normalizeString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalString as normalizeString } from "../shared/string-coerce.js"; -import { normalizeTrimmedStringList } from "../shared/string-normalization.js"; import { isRecord } from "../utils.js"; import { enablePluginInConfig } from "./enable.js"; import type { PluginPackageInstall } from "./manifest.js"; diff --git a/src/poll-params.ts b/src/poll-params.ts index efe5e1c7374..a1527f99793 100644 --- a/src/poll-params.ts +++ b/src/poll-params.ts @@ -1,6 +1,6 @@ +import { parseStrictFiniteNumber } from "@openclaw/normalization-core/number-coercion"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { readSnakeCaseParamRaw } from "./param-key.js"; -import { parseStrictFiniteNumber } from "./shared/number-coercion.js"; -import { normalizeLowercaseStringOrEmpty } from "./shared/string-coerce.js"; type PollCreationParamKind = "string" | "stringArray" | "positiveInteger" | "boolean"; diff --git a/src/process/exec.ts b/src/process/exec.ts index 6f79d3df37e..582fe67c873 100644 --- a/src/process/exec.ts +++ b/src/process/exec.ts @@ -3,6 +3,7 @@ import fs from "node:fs"; import path from "node:path"; import process from "node:process"; import { promisify } from "node:util"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { danger, shouldLogVerbose } from "../globals.js"; import { markOpenClawExecEnv } from "../infra/openclaw-exec-env.js"; import { @@ -11,7 +12,6 @@ import { } from "../infra/windows-encoding.js"; import { getWindowsInstallRoots } from "../infra/windows-install-roots.js"; import { logDebug, logError } from "../logger.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { resolveCommandStdio } from "./spawn-utils.js"; import { resolveWindowsCommandShim } from "./windows-command.js"; diff --git a/src/process/supervisor/supervisor.ts b/src/process/supervisor/supervisor.ts index 3f7ef1587cd..eb86dfc8843 100644 --- a/src/process/supervisor/supervisor.ts +++ b/src/process/supervisor/supervisor.ts @@ -1,6 +1,6 @@ import crypto from "node:crypto"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { getShellConfig } from "../../agents/shell-utils.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { createChildAdapter } from "./adapters/child.js"; import { createPtyAdapter } from "./adapters/pty.js"; import { createRunRegistry } from "./registry.js"; diff --git a/src/process/windows-command.ts b/src/process/windows-command.ts index 6226c25529c..6332129c55a 100644 --- a/src/process/windows-command.ts +++ b/src/process/windows-command.ts @@ -1,6 +1,6 @@ import path from "node:path"; import process from "node:process"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export function resolveWindowsCommandShim(params: { command: string; diff --git a/src/proxy-capture/store.sqlite.ts b/src/proxy-capture/store.sqlite.ts index 8c155b725cd..520eaacb3fd 100644 --- a/src/proxy-capture/store.sqlite.ts +++ b/src/proxy-capture/store.sqlite.ts @@ -1,10 +1,10 @@ import fs from "node:fs"; import path from "node:path"; import type { DatabaseSync } from "node:sqlite"; +import { normalizeNullableString as normalizeObservedValue } from "@openclaw/normalization-core/string-coerce"; +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import { requireNodeSqlite } from "../infra/node-sqlite.js"; import { configureSqliteWalMaintenance, type SqliteWalMaintenance } from "../infra/sqlite-wal.js"; -import { normalizeNullableString as normalizeObservedValue } from "../shared/string-coerce.js"; -import { normalizeUniqueStringEntries } from "../shared/string-normalization.js"; import { readCaptureBlobText, writeCaptureBlob } from "./blob-store.js"; import type { CaptureBlobRecord, diff --git a/src/routing/account-id.ts b/src/routing/account-id.ts index ea77f01afc2..70ea9f6f8a3 100644 --- a/src/routing/account-id.ts +++ b/src/routing/account-id.ts @@ -1,5 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { isBlockedObjectKey } from "../infra/prototype-keys.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; export const DEFAULT_ACCOUNT_ID = "default"; diff --git a/src/routing/account-lookup.ts b/src/routing/account-lookup.ts index 2027f8cf76b..781e4669c44 100644 --- a/src/routing/account-lookup.ts +++ b/src/routing/account-lookup.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export function resolveAccountEntry( accounts: Record | undefined, diff --git a/src/routing/binding-scope.ts b/src/routing/binding-scope.ts index 998edd47b4e..8e9c2428b5a 100644 --- a/src/routing/binding-scope.ts +++ b/src/routing/binding-scope.ts @@ -1,6 +1,6 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { normalizeChatChannelId } from "../channels/ids.js"; import type { AgentRouteBinding } from "../config/types.agents.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { normalizeAccountId, normalizeAgentId } from "./session-key.js"; export type RouteBindingScopeConstraint = { diff --git a/src/routing/channel-route-targets.ts b/src/routing/channel-route-targets.ts index 63a4c20ce40..052901b345a 100644 --- a/src/routing/channel-route-targets.ts +++ b/src/routing/channel-route-targets.ts @@ -1,8 +1,8 @@ +import { isRecord as hasRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { normalizeChatChannelId } from "../channels/ids.js"; import { listRouteBindings } from "../config/bindings.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { isRecord as hasRecord } from "../shared/record-coerce.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { resolveAgentRoute } from "./resolve-route.js"; import { DEFAULT_ACCOUNT_ID, normalizeAccountId, normalizeAgentId } from "./session-key.js"; diff --git a/src/routing/resolve-route.ts b/src/routing/resolve-route.ts index a53ee9dcd09..b93fb7f89b8 100644 --- a/src/routing/resolve-route.ts +++ b/src/routing/resolve-route.ts @@ -1,10 +1,10 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { resolveDefaultAgentId } from "../agents/agent-scope.js"; import type { ChatType } from "../channels/chat-type.js"; import { normalizeChatType } from "../channels/chat-type.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { shouldLogVerbose } from "../globals.js"; import { logDebug } from "../logger.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { normalizeRouteBindingId, normalizeRouteBindingRoles, diff --git a/src/routing/session-key.ts b/src/routing/session-key.ts index d339ac1789a..79bcdb144e5 100644 --- a/src/routing/session-key.ts +++ b/src/routing/session-key.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { ChatType } from "../channels/chat-type.js"; import { isCronRunSessionKey, @@ -5,7 +6,6 @@ import { normalizeSessionKeyPreservingOpaquePeerIds, parseAgentSessionKey, } from "../sessions/session-key-utils.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { normalizeAccountId } from "./account-id.js"; export { diff --git a/src/secrets/channel-env-vars.ts b/src/secrets/channel-env-vars.ts index 0fb23271173..0a4841eaede 100644 --- a/src/secrets/channel-env-vars.ts +++ b/src/secrets/channel-env-vars.ts @@ -1,6 +1,6 @@ +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { loadPluginMetadataSnapshot } from "../plugins/plugin-metadata-snapshot.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; export { isSafeChannelEnvVarTriggerName } from "./channel-env-var-names.js"; type ChannelEnvVarLookupParams = { diff --git a/src/secrets/configure.ts b/src/secrets/configure.ts index 74aa377d96e..10efb82bdaa 100644 --- a/src/secrets/configure.ts +++ b/src/secrets/configure.ts @@ -1,6 +1,11 @@ import path from "node:path"; import { isDeepStrictEqual } from "node:util"; import { confirm, select, text } from "@clack/prompts"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, + normalizeStringifiedOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { listAgentIds, resolveAgentDir, resolveDefaultAgentId } from "../agents/agent-scope.js"; import { AUTH_STORE_VERSION } from "../agents/auth-profiles/constants.js"; import { loadPersistedAuthProfileStore } from "../agents/auth-profiles/persisted.js"; @@ -16,11 +21,6 @@ import { isSafeExecutableValue } from "../infra/exec-safety.js"; import { parseStrictPositiveInteger } from "../infra/parse-finite-number.js"; import { loadPluginManifestRegistry } from "../plugins/manifest-registry.js"; import { normalizeAgentId } from "../routing/session-key.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, - normalizeStringifiedOptionalString, -} from "../shared/string-coerce.js"; import { runSecretsApply, type SecretsApplyResult } from "./apply.js"; import { createSecretsConfigIO } from "./config-io.js"; import { diff --git a/src/secrets/json-pointer.ts b/src/secrets/json-pointer.ts index b54abb0d87c..89024e6abfc 100644 --- a/src/secrets/json-pointer.ts +++ b/src/secrets/json-pointer.ts @@ -1,5 +1,5 @@ +import { isRecord as isJsonObject } from "@openclaw/normalization-core/record-coerce"; import { parseConfigPathArrayIndex } from "../shared/path-array-index.js"; -import { isRecord as isJsonObject } from "../shared/record-coerce.js"; function failOrUndefined(params: { onMissing: "throw" | "undefined"; message: string }): undefined { if (params.onMissing === "throw") { diff --git a/src/secrets/model-provider-header-policy.ts b/src/secrets/model-provider-header-policy.ts index 0f78e4a80d6..cc2ecb668de 100644 --- a/src/secrets/model-provider-header-policy.ts +++ b/src/secrets/model-provider-header-policy.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; const ALWAYS_SENSITIVE_MODEL_PROVIDER_HEADER_NAMES = new Set([ "authorization", diff --git a/src/secrets/plan.ts b/src/secrets/plan.ts index 5708480d51b..b2b92023883 100644 --- a/src/secrets/plan.ts +++ b/src/secrets/plan.ts @@ -1,7 +1,7 @@ +import { isRecord as isObjectRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { SecretProviderConfig, SecretRef } from "../config/types.secrets.js"; import { SecretProviderSchema } from "../config/zod-schema.core.js"; -import { isRecord as isObjectRecord } from "../shared/record-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { isValidExecSecretRefId, isValidSecretProviderAlias } from "./ref-contract.js"; import { parseDotPath, toDotPath } from "./shared.js"; import { resolvePlanTargetAgainstRegistry, type ResolvedPlanTarget } from "./target-registry.js"; diff --git a/src/secrets/provider-env-vars.ts b/src/secrets/provider-env-vars.ts index adec1800394..20e77704024 100644 --- a/src/secrets/provider-env-vars.ts +++ b/src/secrets/provider-env-vars.ts @@ -1,4 +1,5 @@ import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { resolveProviderAuthAliasMap } from "../agents/provider-auth-aliases.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizePluginsConfig } from "../plugins/config-state.js"; @@ -15,7 +16,6 @@ import { } from "../plugins/plugin-metadata-snapshot.js"; import { listSetupProviderIds } from "../plugins/setup-descriptors.js"; import { hasKind } from "../plugins/slots.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; const CORE_PROVIDER_AUTH_ENV_VAR_CANDIDATES = { anthropic: ["ANTHROPIC_OAUTH_TOKEN", "ANTHROPIC_API_KEY"], diff --git a/src/secrets/provider-integrations.ts b/src/secrets/provider-integrations.ts index c854450ee4a..58a02bd18ab 100644 --- a/src/secrets/provider-integrations.ts +++ b/src/secrets/provider-integrations.ts @@ -1,5 +1,6 @@ import fs from "node:fs"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { ManualExecSecretProviderConfig, @@ -10,7 +11,6 @@ import { shouldRejectHardlinkedPluginFiles } from "../plugins/hardlink-policy.js import { isActivatedManifestOwner } from "../plugins/manifest-owner-policy.js"; import type { PluginManifestRecord, PluginManifestRegistry } from "../plugins/manifest-registry.js"; import type { PluginManifestSecretProviderIntegration } from "../plugins/manifest.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { isValidSecretProviderAlias } from "./ref-contract.js"; export type SecretProviderIntegrationPreset = { diff --git a/src/secrets/resolve.ts b/src/secrets/resolve.ts index 9585ac60315..01cabfb257d 100644 --- a/src/secrets/resolve.ts +++ b/src/secrets/resolve.ts @@ -1,6 +1,7 @@ import { spawn } from "node:child_process"; import fs from "node:fs/promises"; import path from "node:path"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { FileSecretProviderConfig, @@ -18,7 +19,6 @@ import { } from "../plugins/manifest-registry.js"; import { inspectPathPermissions, safeStat } from "../security/audit-fs.js"; import { isPathInside } from "../security/scan-paths.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { resolveUserPath } from "../utils.js"; import { runTasksWithConcurrency } from "../utils/run-with-concurrency.js"; import { readJsonPointer } from "./json-pointer.js"; diff --git a/src/secrets/runtime-command-secrets.ts b/src/secrets/runtime-command-secrets.ts index 678e73669dd..93b0dd92ea4 100644 --- a/src/secrets/runtime-command-secrets.ts +++ b/src/secrets/runtime-command-secrets.ts @@ -1,9 +1,9 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { resolveSecretInputRef } from "../config/types.secrets.js"; import { resolveManifestContractOwnerPluginId } from "../plugins/plugin-registry.js"; import { resolveBundledExplicitWebSearchProvidersFromPublicArtifacts } from "../plugins/web-provider-public-artifacts.explicit.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { analyzeCommandSecretAssignmentsFromSnapshot, collectCommandSecretAssignmentsFromSnapshot, diff --git a/src/secrets/runtime-config-collectors-core.ts b/src/secrets/runtime-config-collectors-core.ts index 60aac595e57..11d48eebaa6 100644 --- a/src/secrets/runtime-config-collectors-core.ts +++ b/src/secrets/runtime-config-collectors-core.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { MediaUnderstandingModelConfig } from "../config/types.tools.js"; import { @@ -5,7 +6,6 @@ import { resolveEffectiveMediaEntryCapabilities, } from "../media-understanding/entry-capabilities.js"; import { buildMediaUnderstandingCapabilityRegistry } from "../media-understanding/provider-capability-registry.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import { collectTtsApiKeyAssignments } from "./runtime-config-collectors-tts.js"; import { evaluateGatewayAuthSurfaceStates } from "./runtime-gateway-auth-surfaces.js"; import { diff --git a/src/secrets/runtime-config-collectors-plugins.ts b/src/secrets/runtime-config-collectors-plugins.ts index 200fd8b757c..c3fac2351ef 100644 --- a/src/secrets/runtime-config-collectors-plugins.ts +++ b/src/secrets/runtime-config-collectors-plugins.ts @@ -1,3 +1,4 @@ +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { @@ -7,7 +8,6 @@ import { import { normalizePluginsConfig, resolveEnableState } from "../plugins/config-state.js"; import type { PluginOrigin } from "../plugins/plugin-origin.types.js"; import { parseConfigPathArrayIndex } from "../shared/path-array-index.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { collectSecretInputAssignment, type ResolverContext, diff --git a/src/secrets/runtime-fast-path.ts b/src/secrets/runtime-fast-path.ts index c8122f02b0d..4d4357991d4 100644 --- a/src/secrets/runtime-fast-path.ts +++ b/src/secrets/runtime-fast-path.ts @@ -1,5 +1,6 @@ import { existsSync } from "node:fs"; import path from "node:path"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { listAgentIds, resolveAgentDir, @@ -15,7 +16,6 @@ import { resolveOAuthPath } from "../config/paths.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { PluginManifestRegistry } from "../plugins/manifest-registry.js"; import type { PluginOrigin } from "../plugins/plugin-origin.types.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { resolveUserPath } from "../utils.js"; import { hasCredentialBearingObjectValue, hasSecretRefCandidate } from "./runtime-secret-scan.js"; import type { SecretDefaults } from "./runtime-shared.js"; diff --git a/src/secrets/runtime-web-tools.shared.ts b/src/secrets/runtime-web-tools.shared.ts index 84d7506ffb8..e85b313e9e2 100644 --- a/src/secrets/runtime-web-tools.shared.ts +++ b/src/secrets/runtime-web-tools.shared.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { resolveSecretInputRef } from "../config/types.secrets.js"; import { createLazyRuntimeNamedExport } from "../shared/lazy-runtime.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import { setPathExistingStrict } from "./path-utils.js"; import type { ResolverContext, diff --git a/src/secrets/runtime-web-tools.ts b/src/secrets/runtime-web-tools.ts index 80290ccb061..b84df5eb06c 100644 --- a/src/secrets/runtime-web-tools.ts +++ b/src/secrets/runtime-web-tools.ts @@ -1,3 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { resolveSecretInputRef } from "../config/types.secrets.js"; import { loadInstalledPluginIndexInstallRecordsSync } from "../plugins/installed-plugin-index-records.js"; @@ -14,8 +16,6 @@ import { } from "../plugins/web-provider-public-artifacts.explicit.js"; import { sortWebSearchProvidersForAutoDetect } from "../plugins/web-search-providers.shared.js"; import { createLazyRuntimeSurface } from "../shared/lazy-runtime.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { sortUniqueStrings } from "../shared/string-normalization.js"; import { normalizeSecretInput } from "../utils/normalize-secret-input.js"; import { secretRefKey } from "./ref-contract.js"; import { resolveSecretRefValues } from "./resolve.js"; diff --git a/src/secrets/runtime.ts b/src/secrets/runtime.ts index 99dfeb860b5..01f7e18dbfe 100644 --- a/src/secrets/runtime.ts +++ b/src/secrets/runtime.ts @@ -1,4 +1,5 @@ import { isDeepStrictEqual } from "node:util"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope-config.js"; import { clearRuntimeAuthProfileStoreSnapshots, @@ -10,7 +11,6 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { PluginManifestRegistry } from "../plugins/manifest-registry.js"; import type { PluginMetadataSnapshot } from "../plugins/plugin-metadata-snapshot.js"; import type { PluginOrigin } from "../plugins/plugin-origin.types.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { resolveUserPath } from "../utils.js"; import { canUseSecretsRuntimeFastPath, diff --git a/src/secrets/storage-scan.ts b/src/secrets/storage-scan.ts index d1d3a3f4378..d46c3369f92 100644 --- a/src/secrets/storage-scan.ts +++ b/src/secrets/storage-scan.ts @@ -1,9 +1,9 @@ import fs from "node:fs"; import path from "node:path"; +import { isRecord as isJsonObject } from "@openclaw/normalization-core/record-coerce"; import { listAgentIds, resolveAgentDir } from "../agents/agent-scope.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { formatErrorMessage } from "../infra/errors.js"; -import { isRecord as isJsonObject } from "../shared/record-coerce.js"; import { resolveUserPath } from "../utils.js"; import { listAuthProfileStorePaths as listAuthProfileStorePathsFromAuthStorePaths } from "./auth-store-paths.js"; import { parseEnvValue } from "./shared.js"; diff --git a/src/security/audit-channel.ts b/src/security/audit-channel.ts index 812498af1bc..927fabea0ec 100644 --- a/src/security/audit-channel.ts +++ b/src/security/audit-channel.ts @@ -1,3 +1,4 @@ +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { hasConfiguredUnavailableCredentialStatus, hasResolvedCredentialValue, @@ -11,7 +12,6 @@ import { formatCliCommand } from "../cli/command-format.js"; import { isDangerousNameMatchingEnabled } from "../config/dangerous-name-matching.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { formatErrorMessage } from "../infra/errors.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import type { SecurityAuditFinding, SecurityAuditSeverity } from "./audit.types.js"; function classifyChannelWarningSeverity(message: string): SecurityAuditSeverity { diff --git a/src/security/audit-extra.async.ts b/src/security/audit-extra.async.ts index 6d294ef68b4..9950021291e 100644 --- a/src/security/audit-extra.async.ts +++ b/src/security/audit-extra.async.ts @@ -6,21 +6,21 @@ import fs from "node:fs/promises"; import path from "node:path"; import { clearTimeout as clearNodeTimeout, setTimeout as setNodeTimeout } from "node:timers"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { + normalizeStringEntries, + normalizeTrimmedStringList, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { formatCliCommand } from "../cli/command-format.js"; import { MANIFEST_KEY } from "../compat/legacy-names.js"; import type { OpenClawConfig, ConfigFileSnapshot } from "../config/config.js"; import { collectIncludePathsRecursive } from "../config/includes-scan.js"; import { resolveOAuthDir } from "../config/paths.js"; import { normalizeAgentId } from "../routing/session-key.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; -import { - normalizeStringEntries, - normalizeTrimmedStringList, - uniqueStrings, -} from "../shared/string-normalization.js"; import type { SkillScanFinding } from "../skills/security/scanner.js"; import { shouldIgnoreInstalledPluginDirName } from "./installed-plugin-dirs.js"; import { extensionUsesSkippedScannerPath, isPathInside } from "./scan-paths.js"; diff --git a/src/security/audit-extra.sync.ts b/src/security/audit-extra.sync.ts index ba985f939e0..5169c039005 100644 --- a/src/security/audit-extra.sync.ts +++ b/src/security/audit-extra.sync.ts @@ -1,3 +1,9 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, + normalizeStringifiedOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization"; import { resolveSandboxConfigForAgent } from "../agents/sandbox/config.js"; import { isDangerousNetworkMode, normalizeNetworkMode } from "../agents/sandbox/network-mode.js"; import { resolveSandboxToolPolicyForAgent } from "../agents/sandbox/tool-policy.js"; @@ -16,12 +22,6 @@ import { listDangerousPluginNodeCommands, resolveNodeCommandAllowlist, } from "../gateway/node-command-policy.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, - normalizeStringifiedOptionalString, -} from "../shared/string-coerce.js"; -import { normalizeUniqueStringEntries } from "../shared/string-normalization.js"; import { collectAuditModelRefs } from "./audit-model-refs.js"; import { pickSandboxToolPolicy } from "./audit-tool-policy.js"; diff --git a/src/security/audit-gateway-config.ts b/src/security/audit-gateway-config.ts index 7025c9f759f..ffa0ac27b00 100644 --- a/src/security/audit-gateway-config.ts +++ b/src/security/audit-gateway-config.ts @@ -1,15 +1,15 @@ import { isIP } from "node:net"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { GatewayAuthConfig } from "../config/types.gateway.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { hasConfiguredSecretInput } from "../config/types.secrets.js"; import { resolveGatewayAuth } from "../gateway/auth-resolve.js"; import { resolveGatewayAuthTokenSourceConflict } from "../gateway/auth-token-source-conflict.js"; import { parseStrictNonNegativeInteger } from "../infra/parse-finite-number.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import type { SecurityAuditFinding } from "./audit.types.js"; import { collectCoreInsecureOrDangerousFlags } from "./core-dangerous-config-flags.js"; import { DEFAULT_GATEWAY_HTTP_TOOL_DENY } from "./dangerous-tools.js"; diff --git a/src/security/audit-plugins-trust.ts b/src/security/audit-plugins-trust.ts index fd54abe5188..d1db31d0f5a 100644 --- a/src/security/audit-plugins-trust.ts +++ b/src/security/audit-plugins-trust.ts @@ -1,5 +1,6 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { listReadOnlyChannelPluginsForConfig } from "../channels/plugins/read-only.js"; import type { ChannelPlugin } from "../channels/plugins/types.plugin.js"; import { inspectReadOnlyChannelAccount } from "../channels/read-only-account-inspect.js"; @@ -13,7 +14,6 @@ import { createPluginRegistryIdNormalizer, loadPluginRegistrySnapshot, } from "../plugins/plugin-registry.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import type { SecurityAuditFinding } from "./audit.types.js"; import { shouldIgnoreInstalledPluginDirName } from "./installed-plugin-dirs.js"; diff --git a/src/security/audit.ts b/src/security/audit.ts index aa4907532b1..097f0485575 100644 --- a/src/security/audit.ts +++ b/src/security/audit.ts @@ -1,5 +1,8 @@ import path from "node:path"; import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; +import { asNullableRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js"; import { resolveExecDefaults } from "../agents/exec-defaults.js"; import { resolveSandboxConfigForAgent } from "../agents/sandbox/config.js"; @@ -24,9 +27,6 @@ import { import { listRiskyConfiguredSafeBins } from "../infra/exec-safe-bin-semantics.js"; import { normalizeTrustedSafeBinDirs } from "../infra/exec-safe-bin-trust.js"; import { DEFAULT_AGENT_ID } from "../routing/session-key.js"; -import { asNullableRecord } from "../shared/record-coerce.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { collectDeepCodeSafetyFindings } from "./audit-deep-code-safety.js"; import { collectDeepProbeFindings } from "./audit-deep-probe-findings.js"; import { diff --git a/src/security/channel-metadata.ts b/src/security/channel-metadata.ts index 90ec962b713..8ee95d4af61 100644 --- a/src/security/channel-metadata.ts +++ b/src/security/channel-metadata.ts @@ -1,4 +1,4 @@ -import { uniqueStrings } from "../shared/string-normalization.js"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { wrapExternalContent } from "./external-content.js"; const DEFAULT_MAX_CHARS = 800; diff --git a/src/security/dm-policy-shared.ts b/src/security/dm-policy-shared.ts index cd2c27d3ba7..b0df52aa2cd 100644 --- a/src/security/dm-policy-shared.ts +++ b/src/security/dm-policy-shared.ts @@ -1,3 +1,4 @@ +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { resolveGroupAllowFromSources } from "../channels/allow-from.js"; import { resolveControlCommandGate } from "../channels/command-gating.js"; import { resolveDmAllowAuditState } from "../channels/message-access/dm-allow-state.js"; @@ -8,7 +9,6 @@ import { import type { ChannelId } from "../channels/plugins/types.public.js"; import type { GroupPolicy } from "../config/types.base.js"; import { evaluateMatchedGroupAccessForPolicy } from "../plugin-sdk/group-access.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; export function resolvePinnedMainDmOwnerFromAllowlist(params: { dmScope?: string | null; diff --git a/src/security/external-content-source.ts b/src/security/external-content-source.ts index 7f893b1ad2c..04889829a38 100644 --- a/src/security/external-content-source.ts +++ b/src/security/external-content-source.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export type HookExternalContentSource = "gmail" | "webhook"; diff --git a/src/security/installed-plugin-dirs.ts b/src/security/installed-plugin-dirs.ts index e80aabc14a4..0f4509d8674 100644 --- a/src/security/installed-plugin-dirs.ts +++ b/src/security/installed-plugin-dirs.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; const IGNORED_INSTALLED_PLUGIN_DIR_NAMES = new Set(["node_modules", ".openclaw-install-backups"]); diff --git a/src/sessions/input-provenance.ts b/src/sessions/input-provenance.ts index aa7e4320b6b..aa18517eeb6 100644 --- a/src/sessions/input-provenance.ts +++ b/src/sessions/input-provenance.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { AgentMessage } from "../agents/runtime/index.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; export const INPUT_PROVENANCE_KIND_VALUES = [ "external_user", diff --git a/src/sessions/model-overrides.ts b/src/sessions/model-overrides.ts index 644a84a4930..e52d1eefb3f 100644 --- a/src/sessions/model-overrides.ts +++ b/src/sessions/model-overrides.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { SessionEntry } from "../config/sessions.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; export type ModelOverrideSelection = { provider: string; diff --git a/src/sessions/send-policy.ts b/src/sessions/send-policy.ts index 3456bb41c01..e65fad51b5d 100644 --- a/src/sessions/send-policy.ts +++ b/src/sessions/send-policy.ts @@ -1,10 +1,10 @@ -import { normalizeChatType } from "../channels/chat-type.js"; -import type { SessionChatType, SessionEntry } from "../config/sessions.js"; -import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeChatType } from "../channels/chat-type.js"; +import type { SessionChatType, SessionEntry } from "../config/sessions.js"; +import type { OpenClawConfig } from "../config/types.openclaw.js"; import { deriveSessionChatType } from "./session-chat-type.js"; export type SessionSendPolicyDecision = "allow" | "deny"; diff --git a/src/sessions/session-chat-type-shared.ts b/src/sessions/session-chat-type-shared.ts index fe6c95dc072..13a15bc52ae 100644 --- a/src/sessions/session-chat-type-shared.ts +++ b/src/sessions/session-chat-type-shared.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { parseAgentSessionKey } from "./session-key-utils.js"; export type SessionKeyChatType = "direct" | "group" | "channel" | "unknown"; diff --git a/src/sessions/session-chat-type.ts b/src/sessions/session-chat-type.ts index a90ed8ab01d..46d1fb724db 100644 --- a/src/sessions/session-chat-type.ts +++ b/src/sessions/session-chat-type.ts @@ -1,5 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { getBootstrapChannelPlugin } from "../channels/plugins/bootstrap-registry.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { deriveSessionChatTypeFromKey, type SessionKeyChatType, diff --git a/src/sessions/session-id-resolution.ts b/src/sessions/session-id-resolution.ts index 6bac9f8da81..66482349b18 100644 --- a/src/sessions/session-id-resolution.ts +++ b/src/sessions/session-id-resolution.ts @@ -1,6 +1,6 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { SessionEntry } from "../config/sessions.js"; import { toAgentRequestSessionKey } from "../routing/session-key.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; type SessionIdMatch = [string, SessionEntry]; type NormalizedSessionIdMatch = { diff --git a/src/sessions/session-key-utils.ts b/src/sessions/session-key-utils.ts index 071abf0a8d1..fd255ec5e53 100644 --- a/src/sessions/session-key-utils.ts +++ b/src/sessions/session-key-utils.ts @@ -2,7 +2,7 @@ import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; export type ParsedAgentSessionKey = { agentId: string; diff --git a/src/sessions/transcript-events.ts b/src/sessions/transcript-events.ts index 57fad87b734..9f86a7da89f 100644 --- a/src/sessions/transcript-events.ts +++ b/src/sessions/transcript-events.ts @@ -1,5 +1,5 @@ -import { asPositiveSafeInteger } from "../shared/number-coercion.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { asPositiveSafeInteger } from "@openclaw/normalization-core/number-coercion"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export type SessionTranscriptUpdate = { sessionFile: string; diff --git a/src/shared/assistant-identity-values.ts b/src/shared/assistant-identity-values.ts index f21e507c902..436307c1883 100644 --- a/src/shared/assistant-identity-values.ts +++ b/src/shared/assistant-identity-values.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "./string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export function coerceIdentityValue( value: string | undefined, diff --git a/src/shared/avatar-policy.ts b/src/shared/avatar-policy.ts index 07a3665538b..e4c9bbb1b13 100644 --- a/src/shared/avatar-policy.ts +++ b/src/shared/avatar-policy.ts @@ -1,6 +1,6 @@ import path from "node:path"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { isPathInside } from "../infra/path-guards.js"; -import { normalizeLowercaseStringOrEmpty } from "./string-coerce.js"; export const AVATAR_MAX_BYTES = 2 * 1024 * 1024; diff --git a/src/shared/chat-message-content.ts b/src/shared/chat-message-content.ts index 638a0995fc1..e487e485002 100644 --- a/src/shared/chat-message-content.ts +++ b/src/shared/chat-message-content.ts @@ -1,4 +1,4 @@ -import { readStringValue } from "./string-coerce.js"; +import { readStringValue } from "@openclaw/normalization-core/string-coerce"; export function extractFirstTextBlock(message: unknown): string | undefined { if (!message || typeof message !== "object") { diff --git a/src/shared/custom-command-config.ts b/src/shared/custom-command-config.ts index 995444e5ebd..5664ad3688d 100644 --- a/src/shared/custom-command-config.ts +++ b/src/shared/custom-command-config.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export type CustomCommandInput = { command?: string | null; diff --git a/src/shared/device-auth-store.ts b/src/shared/device-auth-store.ts index 257c82b13e0..29bd4c7e686 100644 --- a/src/shared/device-auth-store.ts +++ b/src/shared/device-auth-store.ts @@ -1,10 +1,10 @@ +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { type DeviceAuthEntry, type DeviceAuthStore, normalizeDeviceAuthRole, normalizeDeviceAuthScopes, } from "./device-auth.js"; -import { isRecord } from "./record-coerce.js"; export type { DeviceAuthEntry, DeviceAuthStore } from "./device-auth.js"; export type DeviceAuthStoreAdapter = { diff --git a/src/shared/entry-metadata.ts b/src/shared/entry-metadata.ts index 265d11c7dba..8664e847142 100644 --- a/src/shared/entry-metadata.ts +++ b/src/shared/entry-metadata.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "./string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export function resolveEmojiAndHomepage(params: { metadata?: { emoji?: string; homepage?: string } | null; diff --git a/src/shared/frontmatter.ts b/src/shared/frontmatter.ts index 8337a20662b..64a1e8be45a 100644 --- a/src/shared/frontmatter.ts +++ b/src/shared/frontmatter.ts @@ -1,8 +1,11 @@ +import { + normalizeOptionalLowercaseString, + readStringValue, +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeCsvOrLooseStringList } from "@openclaw/normalization-core/string-normalization"; import JSON5 from "json5"; import { LEGACY_MANIFEST_KEYS, MANIFEST_KEY } from "../compat/legacy-names.js"; import { parseBooleanValue } from "../utils/boolean.js"; -import { normalizeOptionalLowercaseString, readStringValue } from "./string-coerce.js"; -import { normalizeCsvOrLooseStringList } from "./string-normalization.js"; export function normalizeStringList(input: unknown): string[] { return normalizeCsvOrLooseStringList(input); diff --git a/src/shared/gateway-bind-url.ts b/src/shared/gateway-bind-url.ts index 763195b23b1..2b2e63b74ce 100644 --- a/src/shared/gateway-bind-url.ts +++ b/src/shared/gateway-bind-url.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "./string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export type GatewayBindUrlResult = | { diff --git a/src/shared/google-models.ts b/src/shared/google-models.ts index 2960ed8c86e..c4c0187edcc 100644 --- a/src/shared/google-models.ts +++ b/src/shared/google-models.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "./string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export function isGemma4ModelId(modelId?: string | null): boolean { const normalized = normalizeLowercaseStringOrEmpty(modelId); diff --git a/src/shared/model-param-b.ts b/src/shared/model-param-b.ts index ab52783a1c0..ce66ce5b9d7 100644 --- a/src/shared/model-param-b.ts +++ b/src/shared/model-param-b.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "./string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export function inferParamBFromIdOrName(text: string): number | null { const raw = normalizeLowercaseStringOrEmpty(text); diff --git a/src/shared/node-list-parse.ts b/src/shared/node-list-parse.ts index 5889d55766b..17d52c82d0d 100644 --- a/src/shared/node-list-parse.ts +++ b/src/shared/node-list-parse.ts @@ -1,5 +1,5 @@ +import { asRecord } from "@openclaw/normalization-core/record-coerce"; import type { NodeListNode, PairedNode, PairingList, PendingRequest } from "./node-list-types.js"; -import { asRecord } from "./record-coerce.js"; export function parsePairingList(value: unknown): PairingList { const obj = asRecord(value); diff --git a/src/shared/node-match.ts b/src/shared/node-match.ts index 9cdc894266e..73e7a1f06be 100644 --- a/src/shared/node-match.ts +++ b/src/shared/node-match.ts @@ -2,7 +2,7 @@ import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, -} from "./string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; export type NodeMatchCandidate = { nodeId: string; diff --git a/src/shared/node-presence.ts b/src/shared/node-presence.ts index 3112163380d..c1a6c00cbc3 100644 --- a/src/shared/node-presence.ts +++ b/src/shared/node-presence.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "./string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export const NODE_PRESENCE_ALIVE_EVENT = "node.presence.alive"; diff --git a/src/shared/node-resolve.ts b/src/shared/node-resolve.ts index 93b14f9c7fc..0b9a922c539 100644 --- a/src/shared/node-resolve.ts +++ b/src/shared/node-resolve.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { type NodeMatchCandidate, resolveNodeIdFromCandidates } from "./node-match.js"; -import { normalizeOptionalString } from "./string-coerce.js"; type ResolveNodeFromListOptions = { allowDefault?: boolean; diff --git a/src/shared/silent-reply-policy.ts b/src/shared/silent-reply-policy.ts index ecae64550d7..8654bd07e25 100644 --- a/src/shared/silent-reply-policy.ts +++ b/src/shared/silent-reply-policy.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "./string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export type SilentReplyPolicy = "allow" | "disallow"; export type SilentReplyConversationType = "direct" | "group" | "internal"; diff --git a/src/shared/text/assistant-visible-text.ts b/src/shared/text/assistant-visible-text.ts index 40b822b3539..1a30bebc846 100644 --- a/src/shared/text/assistant-visible-text.ts +++ b/src/shared/text/assistant-visible-text.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { findCodeRegions, isInsideCode } from "./code-regions.js"; import { stripModelSpecialTokens } from "./model-special-tokens.js"; import { stripPlainTextToolCallBlocks } from "./plain-text-tool-call-blocks.js"; diff --git a/src/shared/text/auto-linked-file-ref.ts b/src/shared/text/auto-linked-file-ref.ts index 8efd1ccaa06..bb5d494d462 100644 --- a/src/shared/text/auto-linked-file-ref.ts +++ b/src/shared/text/auto-linked-file-ref.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; const FILE_REF_EXTENSIONS = ["md", "go", "py", "pl", "sh", "am", "at", "be", "cc"] as const; diff --git a/src/shared/text/tool-call-shaped-text.ts b/src/shared/text/tool-call-shaped-text.ts index 22870b3b3e1..0af19af4898 100644 --- a/src/shared/text/tool-call-shaped-text.ts +++ b/src/shared/text/tool-call-shaped-text.ts @@ -1,5 +1,5 @@ -import { asOptionalRecord } from "../record-coerce.js"; -import { normalizeOptionalString as readTrimmedString } from "../string-coerce.js"; +import { asOptionalRecord } from "@openclaw/normalization-core/record-coerce"; +import { normalizeOptionalString as readTrimmedString } from "@openclaw/normalization-core/string-coerce"; export type ToolCallShapedTextDetection = { kind: "json_tool_call" | "xml_tool_call" | "bracketed_tool_call" | "react_action"; diff --git a/src/skills/discovery/bins.ts b/src/skills/discovery/bins.ts index 7bc4686d22e..920142faef2 100644 --- a/src/skills/discovery/bins.ts +++ b/src/skills/discovery/bins.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { SkillEntry } from "../types.js"; export function collectSkillBins(entries: SkillEntry[]): string[] { diff --git a/src/skills/discovery/chat-command-invocation.ts b/src/skills/discovery/chat-command-invocation.ts index 2c62ed2e558..846ccfc1170 100644 --- a/src/skills/discovery/chat-command-invocation.ts +++ b/src/skills/discovery/chat-command-invocation.ts @@ -1,8 +1,8 @@ -import { getChatCommands } from "../../auto-reply/commands-registry.data.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import { getChatCommands } from "../../auto-reply/commands-registry.data.js"; import type { SkillCommandSpec } from "../types.js"; export function listReservedChatSlashCommandNames(extraNames: string[] = []): Set { diff --git a/src/skills/discovery/chat-commands.ts b/src/skills/discovery/chat-commands.ts index f10682ad1cc..3cd4d5f6736 100644 --- a/src/skills/discovery/chat-commands.ts +++ b/src/skills/discovery/chat-commands.ts @@ -1,13 +1,13 @@ import fs from "node:fs"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, +} from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { listAgentIds, resolveAgentWorkspaceDir } from "../../agents/agent-scope.js"; import { canExecRequestNode } from "../../agents/exec-defaults.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { logVerbose } from "../../globals.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, -} from "../../shared/string-coerce.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; import { getRemoteSkillEligibility } from "../runtime/remote.js"; import type { SkillCommandSpec } from "../types.js"; import { resolveEffectiveAgentSkillFilter } from "./agent-filter.js"; diff --git a/src/skills/discovery/command-specs.ts b/src/skills/discovery/command-specs.ts index 2ae29492b29..85b764fe942 100644 --- a/src/skills/discovery/command-specs.ts +++ b/src/skills/discovery/command-specs.ts @@ -1,10 +1,10 @@ -import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { createSubsystemLogger } from "../../logging/subsystem.js"; -import { loadEnabledClaudeBundleCommands } from "../../plugins/bundle-commands.js"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, -} from "../../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { OpenClawConfig } from "../../config/types.openclaw.js"; +import { createSubsystemLogger } from "../../logging/subsystem.js"; +import { loadEnabledClaudeBundleCommands } from "../../plugins/bundle-commands.js"; import { resolveSkillTelemetrySource } from "../loading/source.js"; import { filterWorkspaceSkillEntriesWithOptions, diff --git a/src/skills/discovery/filter.ts b/src/skills/discovery/filter.ts index af912934a56..3c956e44d36 100644 --- a/src/skills/discovery/filter.ts +++ b/src/skills/discovery/filter.ts @@ -1,4 +1,7 @@ -import { normalizeStringEntries, sortUniqueStrings } from "../../shared/string-normalization.js"; +import { + normalizeStringEntries, + sortUniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; export function normalizeSkillFilter(skillFilter?: ReadonlyArray): string[] | undefined { if (skillFilter === undefined) { diff --git a/src/skills/lifecycle/install-download.ts b/src/skills/lifecycle/install-download.ts index fbf3f5b124d..5afba1d01ad 100644 --- a/src/skills/lifecycle/install-download.ts +++ b/src/skills/lifecycle/install-download.ts @@ -4,6 +4,7 @@ import path from "node:path"; import { Readable } from "node:stream"; import { pipeline } from "node:stream/promises"; import type { ReadableStream as NodeReadableStream } from "node:stream/web"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { isWindowsDrivePath } from "../../infra/archive-path.js"; import { formatErrorMessage } from "../../infra/errors.js"; import { root as fsRoot } from "../../infra/fs-safe.js"; @@ -11,7 +12,6 @@ import { assertCanonicalPathWithinBase } from "../../infra/install-safe-path.js" import { fetchWithSsrFGuard } from "../../infra/net/fetch-guard.js"; import { isWithinDir } from "../../infra/path-safety.js"; import { createLazyImportLoader } from "../../shared/lazy-promise.js"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { ensureDir, resolveUserPath } from "../../utils.js"; import { resolveSkillToolsRootDir } from "../runtime/tools-dir.js"; import type { SkillEntry, SkillInstallSpec } from "../types.js"; diff --git a/src/skills/lifecycle/install-extract.ts b/src/skills/lifecycle/install-extract.ts index 713610bde81..5b307fac929 100644 --- a/src/skills/lifecycle/install-extract.ts +++ b/src/skills/lifecycle/install-extract.ts @@ -1,5 +1,6 @@ import { createHash } from "node:crypto"; import fs from "node:fs"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { createTarEntryPreflightChecker, extractArchive as extractArchiveSafe, @@ -9,7 +10,6 @@ import { } from "../../infra/archive.js"; import { formatErrorMessage } from "../../infra/errors.js"; import { runCommandWithTimeout } from "../../process/exec.js"; -import { normalizeStringEntries } from "../../shared/string-normalization.js"; import { hasBinary } from "../loading/config.js"; import { parseTarVerboseMetadata } from "./install-tar-verbose.js"; diff --git a/src/skills/lifecycle/install-output.ts b/src/skills/lifecycle/install-output.ts index 468aa355cc4..e6435f9dd00 100644 --- a/src/skills/lifecycle/install-output.ts +++ b/src/skills/lifecycle/install-output.ts @@ -1,4 +1,4 @@ -import { normalizeStringEntries } from "../../shared/string-normalization.js"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; type InstallCommandResult = { code: number | null; diff --git a/src/skills/lifecycle/install-tar-verbose.ts b/src/skills/lifecycle/install-tar-verbose.ts index 92a51ff93e0..f7bfaeccd1a 100644 --- a/src/skills/lifecycle/install-tar-verbose.ts +++ b/src/skills/lifecycle/install-tar-verbose.ts @@ -1,4 +1,4 @@ -import { normalizeStringEntries } from "../../shared/string-normalization.js"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; const TAR_VERBOSE_MONTHS = new Set([ "Jan", diff --git a/src/skills/lifecycle/source-install.ts b/src/skills/lifecycle/source-install.ts index 93be09759eb..eb6c989b466 100644 --- a/src/skills/lifecycle/source-install.ts +++ b/src/skills/lifecycle/source-install.ts @@ -1,13 +1,13 @@ import fs from "node:fs/promises"; import path from "node:path"; import { redactSensitiveUrlLikeString } from "@openclaw/net-policy/redact-sensitive-url"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { sanitizeForLog } from "../../../packages/terminal-core/src/ansi.js"; import { sanitizeHostExecEnv } from "../../infra/host-env-security.js"; import { withTempDir } from "../../infra/install-source-utils.js"; import { writeJson } from "../../infra/json-files.js"; import { parseGitPluginSpec } from "../../plugins/git-install.js"; import { runCommandWithTimeout } from "../../process/exec.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { resolveUserPath } from "../../utils.js"; import { parseFrontmatter } from "../loading/frontmatter.js"; import { installExtractedSkillRoot, validateRequestedSkillSlug } from "./archive-install.js"; diff --git a/src/skills/lifecycle/upload-store.test.ts b/src/skills/lifecycle/upload-store.test.ts index 6e00b8cd04c..f6e99cfa261 100644 --- a/src/skills/lifecycle/upload-store.test.ts +++ b/src/skills/lifecycle/upload-store.test.ts @@ -2,8 +2,8 @@ import { createHash, randomUUID } from "node:crypto"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; +import { MAX_DATE_TIMESTAMP_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, beforeEach, describe, expect, it } from "vitest"; -import { MAX_DATE_TIMESTAMP_MS } from "../../shared/number-coercion.js"; import { createSkillUploadStore, MAX_ACTIVE_SKILL_UPLOADS, diff --git a/src/skills/lifecycle/upload-store.ts b/src/skills/lifecycle/upload-store.ts index 5c62dbbd830..11dc8721bf5 100644 --- a/src/skills/lifecycle/upload-store.ts +++ b/src/skills/lifecycle/upload-store.ts @@ -2,15 +2,15 @@ import { createHash, randomUUID } from "node:crypto"; import { createReadStream } from "node:fs"; import fs from "node:fs/promises"; import path from "node:path"; -import { resolveStateDir } from "../../config/paths.js"; -import { DEFAULT_MAX_ARCHIVE_BYTES_ZIP } from "../../infra/archive.js"; -import { formatErrorMessage } from "../../infra/errors.js"; -import { createAsyncLock, readDurableJsonFile, writeJsonAtomic } from "../../infra/json-files.js"; import { asDateTimestampMs, isFutureDateTimestampMs, resolveExpiresAtMsFromDurationMs, -} from "../../shared/number-coercion.js"; +} from "@openclaw/normalization-core/number-coercion"; +import { resolveStateDir } from "../../config/paths.js"; +import { DEFAULT_MAX_ARCHIVE_BYTES_ZIP } from "../../infra/archive.js"; +import { formatErrorMessage } from "../../infra/errors.js"; +import { createAsyncLock, readDurableJsonFile, writeJsonAtomic } from "../../infra/json-files.js"; import { validateRequestedSkillSlug } from "./archive-install.js"; export const SKILL_UPLOAD_TTL_MS = 60 * 60 * 1000; diff --git a/src/skills/loading/config.ts b/src/skills/loading/config.ts index a0ee934554d..40b5e3f5d37 100644 --- a/src/skills/loading/config.ts +++ b/src/skills/loading/config.ts @@ -1,3 +1,8 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { SkillConfig } from "../../config/types.skills.js"; import { @@ -7,11 +12,6 @@ import { resolveConfigPath, resolveRuntimePlatform, } from "../../shared/config-eval.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; -import { normalizeStringEntries } from "../../shared/string-normalization.js"; import type { SkillEligibilityContext, SkillEntry, SkillsInstallPreferences } from "../types.js"; import { resolveSkillKey } from "./frontmatter.js"; import { resolveSkillSource } from "./source.js"; diff --git a/src/skills/loading/frontmatter.ts b/src/skills/loading/frontmatter.ts index f2b7e92eec9..dacfc8a2c55 100644 --- a/src/skills/loading/frontmatter.ts +++ b/src/skills/loading/frontmatter.ts @@ -1,3 +1,4 @@ +import { readStringValue } from "@openclaw/normalization-core/string-coerce"; import { parseFrontmatterBlock } from "../../../packages/markdown-core/src/frontmatter.js"; import { validateRegistryNpmSpec } from "../../infra/npm-registry-spec.js"; import { @@ -11,7 +12,6 @@ import { resolveOpenClawManifestOs, resolveOpenClawManifestRequires, } from "../../shared/frontmatter.js"; -import { readStringValue } from "../../shared/string-coerce.js"; import type { OpenClawSkillMetadata, ParsedSkillFrontmatter, diff --git a/src/skills/loading/source.ts b/src/skills/loading/source.ts index 2c59e4a092c..d597610edf2 100644 --- a/src/skills/loading/source.ts +++ b/src/skills/loading/source.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { SkillTelemetrySource } from "../types.js"; import type { Skill } from "./skill-contract.js"; diff --git a/src/skills/loading/workspace.ts b/src/skills/loading/workspace.ts index ceb76ec556e..5409a6d5b1d 100644 --- a/src/skills/loading/workspace.ts +++ b/src/skills/loading/workspace.ts @@ -1,14 +1,17 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { + normalizeTrimmedStringList, + uniqueStrings, +} from "@openclaw/normalization-core/string-normalization"; import { resolveSandboxPath } from "../../agents/sandbox-paths.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { walkDirectorySync } from "../../infra/fs-safe.js"; import { resolveOsHomeDir } from "../../infra/home-dir.js"; import { isPathInside } from "../../infra/path-guards.js"; import { createSubsystemLogger } from "../../logging/subsystem.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; -import { normalizeTrimmedStringList, uniqueStrings } from "../../shared/string-normalization.js"; import { CONFIG_DIR, resolveHomeDir, resolveUserPath } from "../../utils.js"; import { resolveEffectiveAgentSkillFilter, diff --git a/src/skills/runtime/refresh.ts b/src/skills/runtime/refresh.ts index 843aca833ff..50de35a8d04 100644 --- a/src/skills/runtime/refresh.ts +++ b/src/skills/runtime/refresh.ts @@ -1,10 +1,10 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import chokidar, { type FSWatcher } from "chokidar"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { createSubsystemLogger } from "../../logging/subsystem.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { CONFIG_DIR, resolveUserPath } from "../../utils.js"; import { resolvePluginSkillDirs } from "../loading/plugin-skills.js"; import { diff --git a/src/skills/runtime/remote.ts b/src/skills/runtime/remote.ts index d3eb147d55e..47fc6d0402c 100644 --- a/src/skills/runtime/remote.ts +++ b/src/skills/runtime/remote.ts @@ -1,13 +1,13 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import { listAgentWorkspaceDirs } from "../../agents/workspace-dirs.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { NodeRegistry } from "../../gateway/node-registry.js"; import { listNodePairing, updatePairedNodeMetadata } from "../../infra/node-pairing.js"; import { createSubsystemLogger } from "../../logging/subsystem.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../../shared/string-coerce.js"; -import { normalizeStringEntries } from "../../shared/string-normalization.js"; import { loadWorkspaceSkillEntries } from "../loading/workspace.js"; import type { SkillEligibilityContext, SkillEntry } from "../types.js"; import { bumpSkillsSnapshotVersion } from "./refresh-state.js"; diff --git a/src/skills/workshop/config.ts b/src/skills/workshop/config.ts index 9a015db5a81..495172c7683 100644 --- a/src/skills/workshop/config.ts +++ b/src/skills/workshop/config.ts @@ -1,5 +1,5 @@ +import { asNullableRecord } from "@openclaw/normalization-core/record-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { asNullableRecord } from "../../shared/record-coerce.js"; export type SkillWorkshopConfig = { autonomous: { diff --git a/src/skills/workshop/policy.ts b/src/skills/workshop/policy.ts index 1b7e1c6ab22..83be83c6a14 100644 --- a/src/skills/workshop/policy.ts +++ b/src/skills/workshop/policy.ts @@ -1,6 +1,6 @@ +import { asNullableRecord } from "@openclaw/normalization-core/record-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { PluginHookBeforeToolCallResult } from "../../plugins/types.js"; -import { asNullableRecord } from "../../shared/record-coerce.js"; import { resolveSkillWorkshopConfig } from "./config.js"; const SKILL_WORKSHOP_LIFECYCLE_ACTIONS = new Set(["apply", "reject", "quarantine"]); diff --git a/src/skills/workshop/service.ts b/src/skills/workshop/service.ts index 554b45031be..ea37b6bc7dd 100644 --- a/src/skills/workshop/service.ts +++ b/src/skills/workshop/service.ts @@ -1,8 +1,8 @@ import fs from "node:fs/promises"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { readLocalFileSafely, root, walkDirectory } from "../../infra/fs-safe.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { normalizeSkillIndexName } from "../discovery/skill-index.js"; import { buildWorkspaceSkillStatus, diff --git a/src/skills/workshop/store.ts b/src/skills/workshop/store.ts index 34532c063ff..83bef699372 100644 --- a/src/skills/workshop/store.ts +++ b/src/skills/workshop/store.ts @@ -1,12 +1,12 @@ import crypto from "node:crypto"; import fs from "node:fs/promises"; import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveStateDir } from "../../config/paths.js"; import { type FileLockOptions, withFileLock } from "../../infra/file-lock.js"; import { pathExists, root } from "../../infra/fs-safe.js"; import { tryReadJson } from "../../infra/json-files.js"; import { isPathInside } from "../../infra/path-safety.js"; -import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { normalizeSkillIndexName } from "../discovery/skill-index.js"; import { SKILL_WORKSHOP_MANIFEST_SCHEMA, diff --git a/src/status/agent-runtime-label.ts b/src/status/agent-runtime-label.ts index 9aaf8af0c9c..6bff729aa78 100644 --- a/src/status/agent-runtime-label.ts +++ b/src/status/agent-runtime-label.ts @@ -1,11 +1,11 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { sanitizeTerminalText } from "../../packages/terminal-core/src/safe-text.js"; import { isCliProvider } from "../agents/model-selection.js"; import type { SessionEntry } from "../config/sessions/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; const AGENT_RUNTIME_LABELS: Readonly> = { openclaw: "OpenClaw Default", diff --git a/src/status/fallback-notice-state.ts b/src/status/fallback-notice-state.ts index d1f70c0cc71..439c8c04e98 100644 --- a/src/status/fallback-notice-state.ts +++ b/src/status/fallback-notice-state.ts @@ -1,7 +1,7 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { areRuntimeModelRefsEquivalent } from "../agents/model-runtime-aliases.js"; import type { SessionEntry } from "../config/sessions.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; export type FallbackNoticeState = Pick< SessionEntry, diff --git a/src/status/status-message.ts b/src/status/status-message.ts index d8463ac9460..176e76ffc05 100644 --- a/src/status/status-message.ts +++ b/src/status/status-message.ts @@ -1,4 +1,9 @@ import fs from "node:fs"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { resolveContextTokensForModel } from "../agents/context.js"; import { DEFAULT_CONTEXT_TOKENS, DEFAULT_MODEL, DEFAULT_PROVIDER } from "../agents/defaults.js"; import { resolveExtraParams } from "../agents/embedded-agent-runner/extra-params.js"; @@ -46,11 +51,6 @@ import { } from "../media-understanding/runner.entries.js"; import type { MediaUnderstandingDecision } from "../media-understanding/types.js"; import { resolveAgentIdFromSessionKey } from "../routing/session-key.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { resolveStatusTtsSnapshot } from "../tts/status-config.js"; import { estimateUsageCost, diff --git a/src/status/status-text.ts b/src/status/status-text.ts index 30a1fc0387d..c4389c3af7a 100644 --- a/src/status/status-text.ts +++ b/src/status/status-text.ts @@ -1,4 +1,5 @@ import os from "node:os"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { resolveAgentConfig, resolveAgentDir, @@ -32,7 +33,6 @@ import { loadProviderUsageSummary, resolveUsageProviderId, } from "../infra/provider-usage.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import { listTasksForAgentIdForStatus, listTasksForSessionKeyForStatus, diff --git a/src/talk/agent-consult-tool.ts b/src/talk/agent-consult-tool.ts index 7efe14cefd0..558948d305f 100644 --- a/src/talk/agent-consult-tool.ts +++ b/src/talk/agent-consult-tool.ts @@ -1,7 +1,7 @@ import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; import type { RealtimeVoiceTool } from "./provider-types.js"; export const REALTIME_VOICE_AGENT_CONSULT_TOOL_NAME = "openclaw_agent_consult"; diff --git a/src/talk/agent-run-control-shared.ts b/src/talk/agent-run-control-shared.ts index aeb03d7d290..406cfb073d4 100644 --- a/src/talk/agent-run-control-shared.ts +++ b/src/talk/agent-run-control-shared.ts @@ -1,7 +1,7 @@ import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; import type { RealtimeVoiceTool } from "./provider-types.js"; import type { TalkEvent } from "./talk-events.js"; diff --git a/src/talk/event-metrics.ts b/src/talk/event-metrics.ts index 0d280d0074b..d6a4d92ec50 100644 --- a/src/talk/event-metrics.ts +++ b/src/talk/event-metrics.ts @@ -1,4 +1,4 @@ -export { asOptionalRecord as talkEventPayloadRecord } from "../shared/record-coerce.js"; +export { asOptionalRecord as talkEventPayloadRecord } from "../../packages/normalization-core/src/record-coerce.js"; export function firstFiniteTalkEventNumber( record: Record | undefined, diff --git a/src/talk/fast-context-runtime.test.ts b/src/talk/fast-context-runtime.test.ts index 812a408b2f0..82f7175c65c 100644 --- a/src/talk/fast-context-runtime.test.ts +++ b/src/talk/fast-context-runtime.test.ts @@ -1,5 +1,5 @@ +import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion"; import { afterEach, describe, expect, it, vi } from "vitest"; -import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; const mocks = vi.hoisted(() => ({ getActiveMemorySearchManager: vi.fn(), diff --git a/src/talk/fast-context-runtime.ts b/src/talk/fast-context-runtime.ts index 982893a8544..e280253bedc 100644 --- a/src/talk/fast-context-runtime.ts +++ b/src/talk/fast-context-runtime.ts @@ -1,7 +1,7 @@ +import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { formatErrorMessage } from "../infra/errors.js"; import { getActiveMemorySearchManager } from "../plugins/memory-runtime.js"; -import { resolveTimerTimeoutMs } from "../shared/number-coercion.js"; import type { RealtimeVoiceAgentConsultResult } from "./agent-consult-runtime.js"; import { parseRealtimeVoiceAgentConsultArgs } from "./agent-consult-tool.js"; diff --git a/src/talk/session-log-runtime.ts b/src/talk/session-log-runtime.ts index ceb30fbcfea..b3ab9363eb3 100644 --- a/src/talk/session-log-runtime.ts +++ b/src/talk/session-log-runtime.ts @@ -1,4 +1,4 @@ -import { uniqueStrings } from "../shared/string-normalization.js"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { RealtimeVoiceBridgeEvent, RealtimeVoiceRole } from "./provider-types.js"; export type RealtimeVoiceTranscriptEntry = { diff --git a/src/talk/talk-session-controller.ts b/src/talk/talk-session-controller.ts index 8c5f9cd1835..d0fc5519c81 100644 --- a/src/talk/talk-session-controller.ts +++ b/src/talk/talk-session-controller.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { createTalkEventSequencer, type TalkBrain, diff --git a/src/tasks/task-flow-owner-access.ts b/src/tasks/task-flow-owner-access.ts index 5c73793052b..6e1b7143236 100644 --- a/src/tasks/task-flow-owner-access.ts +++ b/src/tasks/task-flow-owner-access.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { findLatestTaskFlowForOwnerKey, getTaskFlowById, diff --git a/src/tasks/task-flow-registry.ts b/src/tasks/task-flow-registry.ts index e462afc6995..e798fc629ee 100644 --- a/src/tasks/task-flow-registry.ts +++ b/src/tasks/task-flow-registry.ts @@ -1,7 +1,7 @@ import crypto from "node:crypto"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { formatErrorMessage } from "../infra/errors.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { getTaskFlowRegistryObservers, getTaskFlowRegistryStore, diff --git a/src/tasks/task-owner-access.ts b/src/tasks/task-owner-access.ts index 041d2d2f365..a8febb60160 100644 --- a/src/tasks/task-owner-access.ts +++ b/src/tasks/task-owner-access.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { findTaskByRunId, getTaskById, diff --git a/src/tasks/task-registry.maintenance.ts b/src/tasks/task-registry.maintenance.ts index 3d9e18e87a6..31987515e70 100644 --- a/src/tasks/task-registry.maintenance.ts +++ b/src/tasks/task-registry.maintenance.ts @@ -1,3 +1,7 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import { getAcpSessionManager } from "../acp/control-plane/manager.js"; import { listAcpSessionEntries, @@ -29,10 +33,6 @@ import { deriveSessionChatTypeFromKey, type SessionKeyChatType, } from "../sessions/session-chat-type-shared.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalString, -} from "../shared/string-coerce.js"; import { CODEX_NATIVE_SUBAGENT_STALE_ERROR, isChildlessCodexNativeSubagentTask, diff --git a/src/tasks/task-registry.ts b/src/tasks/task-registry.ts index 74da8778880..80156f7f95f 100644 --- a/src/tasks/task-registry.ts +++ b/src/tasks/task-registry.ts @@ -1,5 +1,7 @@ import crypto from "node:crypto"; import { createRequire } from "node:module"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { buildAgentRunTerminalOutcome, type AgentRunTerminalOutcome, @@ -12,8 +14,6 @@ import { requestHeartbeat } from "../infra/heartbeat-wake.js"; import { enqueueSystemEvent } from "../infra/system-events.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { parseAgentSessionKey } from "../routing/session-key.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { normalizeDeliveryContext } from "../utils/delivery-context.shared.js"; import { isDeliverableMessageChannel } from "../utils/message-channel.js"; import { isChildlessCodexNativeSubagentTask } from "./codex-native-subagent-task.js"; diff --git a/src/test-utils/bundled-plugin-public-surface.ts b/src/test-utils/bundled-plugin-public-surface.ts index b226404f7ee..6d0ed9be9d4 100644 --- a/src/test-utils/bundled-plugin-public-surface.ts +++ b/src/test-utils/bundled-plugin-public-surface.ts @@ -1,6 +1,7 @@ import fs from "node:fs"; import path from "node:path"; import { fileURLToPath, pathToFileURL } from "node:url"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { loadBundledPluginPublicSurfaceModule, loadBundledPluginPublicSurfaceModuleSync, @@ -16,7 +17,6 @@ import { } from "../plugins/plugin-module-loader-cache.js"; import { normalizeBundledPluginArtifactSubpath } from "../plugins/public-surface-runtime.js"; import { resolveLoaderPackageRoot } from "../plugins/sdk-alias.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; const OPENCLAW_PACKAGE_ROOT = resolveLoaderPackageRoot({ diff --git a/src/test-utils/mock-http-response.ts b/src/test-utils/mock-http-response.ts index 74a6c538cd4..cc0a3192740 100644 --- a/src/test-utils/mock-http-response.ts +++ b/src/test-utils/mock-http-response.ts @@ -1,5 +1,5 @@ import type { ServerResponse } from "node:http"; -import { lowercasePreservingWhitespace } from "../shared/string-coerce.js"; +import { lowercasePreservingWhitespace } from "@openclaw/normalization-core/string-coerce"; export function createMockServerResponse(): ServerResponse & { body?: string } { const headers: Record = {}; diff --git a/src/test-utils/openclaw-test-state.ts b/src/test-utils/openclaw-test-state.ts index 9d8c677c964..a6dc1e5e7db 100644 --- a/src/test-utils/openclaw-test-state.ts +++ b/src/test-utils/openclaw-test-state.ts @@ -1,7 +1,7 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; -import { uniqueStrings } from "../shared/string-normalization.js"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { captureEnv } from "./env.js"; import { cleanupSessionStateForTest } from "./session-state-cleanup.js"; @@ -304,10 +304,11 @@ export async function createOpenClawTestState( }, applyEnv: () => { for (const [key, value] of Object.entries(envVars)) { + // Test fixtures apply a fixed OpenClaw env set, not plugin-provided host env. if (value === undefined) { - delete process.env[key]; + Reflect.deleteProperty(process.env, key); } else { - process.env[key] = value; + Reflect.set(process.env, key, value); } } envApplied = true; diff --git a/src/trajectory/cleanup.ts b/src/trajectory/cleanup.ts index 9ac15d0c9de..831b82e1510 100644 --- a/src/trajectory/cleanup.ts +++ b/src/trajectory/cleanup.ts @@ -1,8 +1,8 @@ import fs from "node:fs"; import path from "node:path"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { resolveSessionFilePath } from "../config/sessions/paths.js"; import { isPathInside } from "../infra/path-guards.js"; -import { isRecord } from "../shared/record-coerce.js"; import { resolveTrajectoryFilePath, resolveTrajectoryPointerFilePath, diff --git a/src/trajectory/export.ts b/src/trajectory/export.ts index a50626f3b7c..f047c8d4edf 100644 --- a/src/trajectory/export.ts +++ b/src/trajectory/export.ts @@ -1,5 +1,6 @@ import fsp from "node:fs/promises"; import path from "node:path"; +import { isRecord } from "@openclaw/normalization-core/record-coerce"; import { sanitizeDiagnosticPayload } from "../agents/payload-redaction.js"; import type { AgentMessage } from "../agents/runtime/index.js"; import type { FileEntry, SessionEntry, SessionHeader } from "../agents/sessions/session-manager.js"; @@ -17,7 +18,6 @@ import { redactSupportString, type SupportRedactionContext, } from "../logging/diagnostic-support-redaction.js"; -import { isRecord } from "../shared/record-coerce.js"; import { safeJsonStringify } from "../utils/safe-json.js"; import { TRAJECTORY_RUNTIME_FILE_MAX_BYTES, safeTrajectorySessionFileName } from "./paths.js"; import { isRegularNonSymlinkFile, resolveTrajectoryRuntimeFile } from "./runtime-file.js"; diff --git a/src/transcripts/config.ts b/src/transcripts/config.ts index a8bd5bea28b..e3892adf19e 100644 --- a/src/transcripts/config.ts +++ b/src/transcripts/config.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString as readString } from "../shared/string-coerce.js"; +import { normalizeOptionalString as readString } from "@openclaw/normalization-core/string-coerce"; export type TranscriptsAutoStartConfig = { providerId: string; diff --git a/src/transcripts/summary.ts b/src/transcripts/summary.ts index 043b85ffe51..3c36182093c 100644 --- a/src/transcripts/summary.ts +++ b/src/transcripts/summary.ts @@ -1,4 +1,4 @@ -import { normalizeStringEntries } from "../shared/string-normalization.js"; +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { TranscriptSessionDescriptor, TranscriptUtterance } from "./provider-types.js"; export type TranscriptsSummary = { diff --git a/src/tts/directive-number.ts b/src/tts/directive-number.ts index 975fa3c1b52..848d2ec7b89 100644 --- a/src/tts/directive-number.ts +++ b/src/tts/directive-number.ts @@ -1,4 +1,4 @@ -import { parseStrictFiniteNumber } from "../shared/number-coercion.js"; +import { parseStrictFiniteNumber } from "@openclaw/normalization-core/number-coercion"; import type { SpeechDirectiveTokenParseContext, SpeechDirectiveTokenParseResult, diff --git a/src/tts/directives.ts b/src/tts/directives.ts index b807f8750a2..8419f69358d 100644 --- a/src/tts/directives.ts +++ b/src/tts/directives.ts @@ -1,6 +1,6 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.js"; import type { SpeechProviderPlugin } from "../plugins/types.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { listSpeechProviders } from "./provider-registry.js"; import type { SpeechModelOverridePolicy, diff --git a/src/tts/openai-compatible-speech-provider.ts b/src/tts/openai-compatible-speech-provider.ts index 8acff05e3f8..ddf29d9c11e 100644 --- a/src/tts/openai-compatible-speech-provider.ts +++ b/src/tts/openai-compatible-speech-provider.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { assertOkOrThrowHttpError, postJsonRequest, @@ -7,7 +8,6 @@ import { import { normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/secret-input"; import { asFiniteNumber, asObject, trimToUndefined } from "../agents/provider-http-errors.js"; import type { SpeechProviderPlugin } from "../plugins/types.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import type { SpeechDirectiveTokenParseContext, SpeechProviderConfig, diff --git a/src/tts/status-config.ts b/src/tts/status-config.ts index 50cdfca8a6d..660f78e9258 100644 --- a/src/tts/status-config.ts +++ b/src/tts/status-config.ts @@ -1,12 +1,12 @@ import path from "node:path"; -import type { OpenClawConfig } from "../config/types.js"; -import type { TtsAutoMode, TtsConfig, TtsProvider } from "../config/types.tts.js"; -import { tryReadJsonSync } from "../infra/json-files.js"; -import { isRecord as isObjectRecord } from "../shared/record-coerce.js"; +import { isRecord as isObjectRecord } from "@openclaw/normalization-core/record-coerce"; import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { OpenClawConfig } from "../config/types.js"; +import type { TtsAutoMode, TtsConfig, TtsProvider } from "../config/types.tts.js"; +import { tryReadJsonSync } from "../infra/json-files.js"; import { resolveConfigDir, resolveUserPath } from "../utils.js"; import { normalizeTtsAutoMode } from "./tts-auto-mode.js"; import { resolveEffectiveTtsConfig, type TtsConfigResolutionContext } from "./tts-config.js"; diff --git a/src/tts/tts-auto-mode.ts b/src/tts/tts-auto-mode.ts index 759978ebce3..71c351fe4c1 100644 --- a/src/tts/tts-auto-mode.ts +++ b/src/tts/tts-auto-mode.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import type { TtsAutoMode } from "../config/types.tts.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; export const TTS_AUTO_MODES = new Set(["off", "always", "inbound", "tagged"]); diff --git a/src/tts/tts-config.ts b/src/tts/tts-config.ts index 8c1e2ea87b4..7d9bfaac672 100644 --- a/src/tts/tts-config.ts +++ b/src/tts/tts-config.ts @@ -1,13 +1,13 @@ import { existsSync, readFileSync } from "node:fs"; import path from "node:path"; -import type { OpenClawConfig } from "../config/types.js"; -import type { TtsAutoMode, TtsConfig, TtsMode } from "../config/types.tts.js"; -import { normalizeAccountId, normalizeAgentId } from "../routing/session-key.js"; -import { isRecord as isPlainObject } from "../shared/record-coerce.js"; +import { isRecord as isPlainObject } from "@openclaw/normalization-core/record-coerce"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; +import type { OpenClawConfig } from "../config/types.js"; +import type { TtsAutoMode, TtsConfig, TtsMode } from "../config/types.tts.js"; +import { normalizeAccountId, normalizeAgentId } from "../routing/session-key.js"; import { resolveConfigDir, resolveUserPath } from "../utils.js"; import { normalizeTtsAutoMode } from "./tts-auto-mode.js"; export { normalizeTtsAutoMode } from "./tts-auto-mode.js"; diff --git a/src/tts/tts-core.ts b/src/tts/tts-core.ts index fccefab3c62..8df372e7958 100644 --- a/src/tts/tts-core.ts +++ b/src/tts/tts-core.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveModelAsync } from "../agents/embedded-agent-runner/model.js"; import { getApiKeyForModel, requireApiKey } from "../agents/model-auth.js"; import { @@ -10,7 +11,6 @@ import { prepareModelForSimpleCompletion } from "../agents/simple-completion-tra import type { OpenClawConfig } from "../config/types.js"; import { completeSimple } from "../llm/stream.js"; import type { TextContent } from "../llm/types.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { ResolvedTtsConfig } from "./tts-types.js"; export { normalizeApplyTextNormalization, diff --git a/src/tts/tts-provider-helpers.ts b/src/tts/tts-provider-helpers.ts index 3404e4b6b36..2c9b0bf65ac 100644 --- a/src/tts/tts-provider-helpers.ts +++ b/src/tts/tts-provider-helpers.ts @@ -1,5 +1,5 @@ import { rmSync } from "node:fs"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; const TEMP_FILE_CLEANUP_DELAY_MS = 5 * 60 * 1000; // 5 minutes diff --git a/src/tui/commands.ts b/src/tui/commands.ts index 420efbef21c..6d75f58708a 100644 --- a/src/tui/commands.ts +++ b/src/tui/commands.ts @@ -1,9 +1,9 @@ import type { SlashCommand } from "@earendil-works/pi-tui"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { CommandEntry } from "../../packages/gateway-protocol/src/index.js"; import { listChatCommands, listChatCommandsForConfig } from "../auto-reply/commands-registry.js"; import { formatThinkingLevels, listThinkingLevelLabels } from "../auto-reply/thinking.js"; import type { OpenClawConfig } from "../config/types.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; const VERBOSE_LEVELS = ["on", "off"]; const TRACE_LEVELS = ["on", "off"]; diff --git a/src/tui/components/filterable-select-list.ts b/src/tui/components/filterable-select-list.ts index 2815aecc03a..aa973e6143c 100644 --- a/src/tui/components/filterable-select-list.ts +++ b/src/tui/components/filterable-select-list.ts @@ -6,8 +6,8 @@ import { SelectList, type SelectListTheme, } from "@earendil-works/pi-tui"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import chalk from "chalk"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { fuzzyFilterLower, prepareSearchItems } from "./fuzzy-filter.js"; export interface FilterableSelectItem extends SelectItem { diff --git a/src/tui/components/fuzzy-filter.ts b/src/tui/components/fuzzy-filter.ts index e758ebe1066..0f6325e47c1 100644 --- a/src/tui/components/fuzzy-filter.ts +++ b/src/tui/components/fuzzy-filter.ts @@ -2,7 +2,7 @@ * Shared fuzzy filtering utilities for select list components. */ -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; /** * Word boundary characters for matching. diff --git a/src/tui/components/searchable-select-list.ts b/src/tui/components/searchable-select-list.ts index 935b3a4bd3c..e31a8ee95a5 100644 --- a/src/tui/components/searchable-select-list.ts +++ b/src/tui/components/searchable-select-list.ts @@ -7,9 +7,9 @@ import { type SelectListTheme, truncateToWidth, } from "@earendil-works/pi-tui"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { stripAnsi, visibleWidth } from "../../../packages/terminal-core/src/ansi.js"; -import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; -import { uniqueStrings } from "../../shared/string-normalization.js"; import { findWordBoundaryIndex, fuzzyFilterLower } from "./fuzzy-filter.js"; const ANSI_ESCAPE = String.fromCharCode(27); diff --git a/src/tui/theme/theme.ts b/src/tui/theme/theme.ts index b5d71ab0d94..687ab449230 100644 --- a/src/tui/theme/theme.ts +++ b/src/tui/theme/theme.ts @@ -4,8 +4,8 @@ import type { SelectListTheme, SettingsListTheme, } from "@earendil-works/pi-tui"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import chalk from "chalk"; -import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import type { SearchableSelectListTheme } from "../components/searchable-select-list.js"; const DARK_TEXT = "#E8E3D5"; diff --git a/src/tui/tui-event-handlers.ts b/src/tui/tui-event-handlers.ts index d9cdc5ade9f..c36d86e1ae2 100644 --- a/src/tui/tui-event-handlers.ts +++ b/src/tui/tui-event-handlers.ts @@ -1,7 +1,7 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { classifyFailoverReason, isAuthErrorMessage } from "../agents/embedded-agent-helpers.js"; import { parseAgentSessionKey } from "../sessions/session-key-utils.js"; import { formatRawAssistantErrorForUi } from "../shared/assistant-error-format.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { asString, extractTextFromMessage, isCommandMessage } from "./tui-formatters.js"; import { TuiStreamAssembler } from "./tui-stream-assembler.js"; import type { AgentEvent, BtwEvent, ChatEvent, TuiStateAccess } from "./tui-types.js"; diff --git a/src/tui/tui-session-actions.ts b/src/tui/tui-session-actions.ts index a3d587525c2..ee7a55d868a 100644 --- a/src/tui/tui-session-actions.ts +++ b/src/tui/tui-session-actions.ts @@ -1,4 +1,5 @@ import type { TUI } from "@earendil-works/pi-tui"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { SessionsPatchResult } from "../../packages/gateway-protocol/src/index.js"; import { resolveSessionInfoModelSelection } from "../agents/model-selection-display.js"; import { @@ -6,7 +7,6 @@ import { normalizeMainKey, parseAgentSessionKey, } from "../routing/session-key.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { ChatLog } from "./components/chat-log.js"; import type { TuiAgentsList, TuiBackend } from "./tui-backend.js"; import { asString, extractTextFromMessage, isCommandMessage } from "./tui-formatters.js"; diff --git a/src/tui/tui-submit.ts b/src/tui/tui-submit.ts index abee7812561..c83f0b8b731 100644 --- a/src/tui/tui-submit.ts +++ b/src/tui/tui-submit.ts @@ -1,4 +1,4 @@ -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; export function createEditorSubmitHandler(params: { editor: { diff --git a/src/tui/tui.ts b/src/tui/tui.ts index 5bd567ffbf4..655ccdb622f 100644 --- a/src/tui/tui.ts +++ b/src/tui/tui.ts @@ -12,6 +12,7 @@ import { Text, TUI, } from "@earendil-works/pi-tui"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { CommandEntry } from "../../packages/gateway-protocol/src/index.js"; import { resolveAgentIdByWorkspacePath, resolveDefaultAgentId } from "../agents/agent-scope.js"; import { getRuntimeConfig, type OpenClawConfig } from "../config/config.js"; @@ -25,7 +26,6 @@ import { normalizeMainKey, parseAgentSessionKey, } from "../routing/session-key.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { getSlashCommands } from "./commands.js"; import { ChatLog } from "./components/chat-log.js"; import { CustomEditor } from "./components/custom-editor.js"; diff --git a/src/utils/boolean.ts b/src/utils/boolean.ts index 0578dc048bc..58d9bb3ba5c 100644 --- a/src/utils/boolean.ts +++ b/src/utils/boolean.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; export type BooleanParseOptions = { truthy?: string[]; diff --git a/src/utils/delivery-context.ts b/src/utils/delivery-context.ts index 7af824b19a5..1a7eb8e25c5 100644 --- a/src/utils/delivery-context.ts +++ b/src/utils/delivery-context.ts @@ -1,5 +1,5 @@ +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { getChannelPlugin, normalizeChannelId } from "../channels/plugins/index.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; import { normalizeMessageChannel } from "./message-channel.js"; export { channelRouteFromDeliveryContext, diff --git a/src/utils/directive-tags.ts b/src/utils/directive-tags.ts index 4893d98496b..8b94dec2bc1 100644 --- a/src/utils/directive-tags.ts +++ b/src/utils/directive-tags.ts @@ -1,4 +1,4 @@ -import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; export type InlineDirectiveParseResult = { text: string; diff --git a/src/utils/message-channel-core.ts b/src/utils/message-channel-core.ts index 2d5f8e641f8..dbe28900b01 100644 --- a/src/utils/message-channel-core.ts +++ b/src/utils/message-channel-core.ts @@ -1,6 +1,6 @@ +import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; import { normalizeChatChannelId } from "../channels/ids.js"; import { normalizeAnyChannelId } from "../channels/registry-normalize.js"; -import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import { INTERNAL_MESSAGE_CHANNEL } from "./message-channel-constants.js"; export function normalizeMessageChannel(raw?: string | null): string | undefined { diff --git a/src/utils/message-channel-normalize.ts b/src/utils/message-channel-normalize.ts index 2f3c253b9d3..1bc41974f8f 100644 --- a/src/utils/message-channel-normalize.ts +++ b/src/utils/message-channel-normalize.ts @@ -1,6 +1,6 @@ +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { CHANNEL_IDS } from "../channels/ids.js"; import { listRegisteredChannelPluginIds } from "../channels/registry.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { INTERNAL_MESSAGE_CHANNEL, type InternalMessageChannel, diff --git a/src/utils/provider-utils.ts b/src/utils/provider-utils.ts index 045ad06ae26..b5bb1d3e4b2 100644 --- a/src/utils/provider-utils.ts +++ b/src/utils/provider-utils.ts @@ -1,11 +1,11 @@ +import { + normalizeOptionalLowercaseString, + normalizeOptionalString, +} from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { ProviderRuntimePluginHandle } from "../plugins/provider-hook-runtime.js"; import type { ProviderRuntimeModel } from "../plugins/provider-runtime-model.types.js"; import { resolveProviderReasoningOutputModeWithPlugin } from "../plugins/provider-runtime.js"; -import { - normalizeOptionalLowercaseString, - normalizeOptionalString, -} from "../shared/string-coerce.js"; const BUILTIN_REASONING_OUTPUT_MODES = { "google-generative-ai": "tagged", diff --git a/src/utils/transcript-tools.ts b/src/utils/transcript-tools.ts index 85604102cd0..05439a60313 100644 --- a/src/utils/transcript-tools.ts +++ b/src/utils/transcript-tools.ts @@ -1,7 +1,7 @@ import { normalizeOptionalLowercaseString, normalizeOptionalString, -} from "../shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; type ToolResultCounts = { total: number; diff --git a/src/utils/usage-format.ts b/src/utils/usage-format.ts index 885e141ca27..9d0a62e8487 100644 --- a/src/utils/usage-format.ts +++ b/src/utils/usage-format.ts @@ -1,4 +1,5 @@ import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { resolveDefaultAgentDir } from "../agents/agent-scope-config.js"; import { modelKey, normalizeModelRef, normalizeProviderId } from "../agents/model-selection.js"; import type { NormalizedUsage } from "../agents/usage.js"; @@ -7,7 +8,6 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; import { getGatewayModelPricingCacheFingerprint } from "../gateway/model-pricing-cache-state.js"; import { getCachedGatewayModelPricing } from "../gateway/model-pricing-cache.js"; import { tryReadJsonSync } from "../infra/json-files.js"; -import { normalizeOptionalString } from "../shared/string-coerce.js"; /** * A single tier in a tiered-pricing schedule. Prices are expressed as diff --git a/src/version.ts b/src/version.ts index 6d5fb4591aa..f2b9ea4ee8d 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,5 +1,5 @@ import { createRequire } from "node:module"; -import { normalizeOptionalString } from "./shared/string-coerce.js"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; // oxlint-disable-next-line eslint/no-underscore-dangle -- Bundled builds replace this compile-time define identifier. declare const __OPENCLAW_VERSION__: string | undefined; diff --git a/src/video-generation/dashscope-compatible.ts b/src/video-generation/dashscope-compatible.ts index ccfd307be84..b65983024dd 100644 --- a/src/video-generation/dashscope-compatible.ts +++ b/src/video-generation/dashscope-compatible.ts @@ -1,3 +1,5 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { assertOkOrThrowHttpError, createProviderOperationDeadline, @@ -11,8 +13,6 @@ import { } from "openclaw/plugin-sdk/provider-http"; import { resolveGeneratedMediaMaxBytes } from "../media/configured-max-bytes.js"; import { readResponseWithLimit } from "../media/read-response-with-limit.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import type { GeneratedVideoAsset, VideoGenerationProviderCapabilities, diff --git a/src/video-generation/duration-support.ts b/src/video-generation/duration-support.ts index 40b50452ee9..6296df0d47e 100644 --- a/src/video-generation/duration-support.ts +++ b/src/video-generation/duration-support.ts @@ -1,4 +1,4 @@ -import { uniqueValues } from "../shared/string-normalization.js"; +import { uniqueValues } from "@openclaw/normalization-core/string-normalization"; import { resolveVideoGenerationModeCapabilities } from "./capabilities.js"; import type { VideoGenerationProvider } from "./types.js"; diff --git a/src/video-generation/live-test-helpers.ts b/src/video-generation/live-test-helpers.ts index 8f169672ce0..b967e215923 100644 --- a/src/video-generation/live-test-helpers.ts +++ b/src/video-generation/live-test-helpers.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.js"; import { parseLiveCsvFilter, @@ -6,7 +7,6 @@ import { resolveConfiguredLiveProviderModels, resolveLiveAuthStore, } from "../media-generation/live-test-helpers.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; export { parseProviderModelMap, redactLiveApiKey }; diff --git a/src/web-fetch/runtime.ts b/src/web-fetch/runtime.ts index 5b2d6279982..b2f09b18f25 100644 --- a/src/web-fetch/runtime.ts +++ b/src/web-fetch/runtime.ts @@ -1,3 +1,4 @@ +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { OpenClawConfig } from "../config/types.js"; import { logVerbose } from "../globals.js"; import type { @@ -11,7 +12,6 @@ import { import { sortWebFetchProvidersForAutoDetect } from "../plugins/web-fetch-providers.shared.js"; import { getActiveRuntimeWebToolsMetadata } from "../secrets/runtime-web-tools-state.js"; import type { RuntimeWebFetchMetadata } from "../secrets/runtime-web-tools.types.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import { hasWebProviderEntryCredential, providerRequiresCredential, diff --git a/src/web-search/runtime.ts b/src/web-search/runtime.ts index 05f333d24cc..6f419631e7d 100644 --- a/src/web-search/runtime.ts +++ b/src/web-search/runtime.ts @@ -1,3 +1,8 @@ +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalLowercaseString, +} from "@openclaw/normalization-core/string-coerce"; +import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { resolveDefaultAgentDir } from "../agents/agent-scope-config.js"; import { hasAuthProfileForProvider } from "../agents/tools/model-config.helpers.js"; import { @@ -19,11 +24,6 @@ import { import { sortWebSearchProvidersForAutoDetect } from "../plugins/web-search-providers.shared.js"; import { getActiveRuntimeWebToolsMetadata } from "../secrets/runtime-web-tools-state.js"; import type { RuntimeWebSearchMetadata } from "../secrets/runtime-web-tools.types.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; -import { uniqueStrings } from "../shared/string-normalization.js"; import { hasWebProviderEntryCredential, providerRequiresCredential, diff --git a/src/wizard/clack-prompter.ts b/src/wizard/clack-prompter.ts index 6e837a9717e..9b129aeabf4 100644 --- a/src/wizard/clack-prompter.ts +++ b/src/wizard/clack-prompter.ts @@ -13,6 +13,7 @@ import { spinner, text, } from "@clack/prompts"; +import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { stripAnsi } from "../../packages/terminal-core/src/ansi.js"; import { note as emitNote } from "../../packages/terminal-core/src/note.js"; import { @@ -22,7 +23,6 @@ import { } from "../../packages/terminal-core/src/prompt-style.js"; import { theme } from "../../packages/terminal-core/src/theme.js"; import { createCliProgress } from "../cli/progress.js"; -import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import type { WizardProgress, WizardPrompter } from "./prompts.js"; import { WizardCancelledError } from "./prompts.js"; diff --git a/src/wizard/setup.plugin-config.ts b/src/wizard/setup.plugin-config.ts index 71149615b6a..074a589808c 100644 --- a/src/wizard/setup.plugin-config.ts +++ b/src/wizard/setup.plugin-config.ts @@ -1,9 +1,9 @@ +import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { PluginManifestRecord } from "../plugins/manifest-registry.js"; import type { PluginConfigUiHint } from "../plugins/types.js"; import { getPath, setPathCreateStrict } from "../secrets/path-utils.js"; import type { JsonSchemaObject } from "../shared/json-schema.types.js"; -import { normalizeStringEntries } from "../shared/string-normalization.js"; import { t } from "./i18n/index.js"; import type { WizardPrompter } from "./prompts.js"; diff --git a/test/scripts/changed-lanes.test.ts b/test/scripts/changed-lanes.test.ts index a11a3e6090f..88adc25fd02 100644 --- a/test/scripts/changed-lanes.test.ts +++ b/test/scripts/changed-lanes.test.ts @@ -277,7 +277,7 @@ describe("scripts/changed-lanes", () => { }); it("routes core production changes to core prod and core test lanes", () => { - const result = detectChangedLanes(["src/shared/string-normalization.ts"]); + const result = detectChangedLanes(["packages/normalization-core/src/string-normalization.ts"]); const plan = createChangedCheckPlan(result, { env: { PATH: "/usr/bin" } }); expectLanes(result.lanes, { @@ -300,7 +300,7 @@ describe("scripts/changed-lanes", () => { "scripts/run-oxlint.mjs", "--tsconfig", "config/tsconfig/oxlint.core.json", - "src/shared/string-normalization.ts", + "packages/normalization-core/src/string-normalization.ts", ], env: { PATH: "/usr/bin", @@ -333,7 +333,10 @@ describe("scripts/changed-lanes", () => { it("falls back to full core lint for mixed core lint configuration diffs", () => { expect( createTargetedCoreLintCommand( - ["config/tsconfig/oxlint.core.json", "src/shared/string-normalization.ts"], + [ + "config/tsconfig/oxlint.core.json", + "packages/normalization-core/src/string-normalization.ts", + ], { PATH: "/usr/bin" }, { fileExists: () => true }, ), @@ -368,7 +371,7 @@ describe("scripts/changed-lanes", () => { }); it("reenables local-check policy for changed typecheck commands", () => { - const result = detectChangedLanes(["src/shared/string-normalization.ts"]); + const result = detectChangedLanes(["packages/normalization-core/src/string-normalization.ts"]); const plan = createChangedCheckPlan(result, { env: { OPENCLAW_LOCAL_CHECK: "0", PATH: "/usr/bin" }, }); @@ -473,7 +476,9 @@ describe("scripts/changed-lanes", () => { }); it("routes core test-only changes to core test lanes only", () => { - const result = detectChangedLanes(["src/shared/string-normalization.test.ts"]); + const result = detectChangedLanes([ + "packages/normalization-core/src/string-normalization.test.ts", + ]); expectLanes(result.lanes, { coreTests: true, diff --git a/test/scripts/ci-workflow-guards.test.ts b/test/scripts/ci-workflow-guards.test.ts index 818d8a6a902..86531b89a9b 100644 --- a/test/scripts/ci-workflow-guards.test.ts +++ b/test/scripts/ci-workflow-guards.test.ts @@ -6,6 +6,10 @@ function readCiWorkflow() { return parse(readFileSync(".github/workflows/ci.yml", "utf8")); } +function readCriticalQualityWorkflow() { + return readFileSync(".github/workflows/codeql-critical-quality.yml", "utf8"); +} + describe("ci workflow guards", () => { it("kills timed manual checkout fetches after the grace period", () => { const workflowPaths = [ @@ -208,4 +212,37 @@ describe("ci workflow guards", () => { "OPENCLAW_DOCS_SYNC_CLAWHUB_REPO: ${{ github.workspace }}/clawhub-source", ); }); + + it("keeps network CodeQL off unrelated source-only refactors", () => { + const workflow = readCriticalQualityWorkflow(); + const networkConfig = readFileSync( + ".github/codeql/codeql-network-runtime-boundary-critical-quality.yml", + "utf8", + ); + const networkSelector = workflow.slice( + workflow.indexOf(".github/codeql/codeql-network-runtime-boundary-critical-quality.yml"), + workflow.indexOf("network-runtime-boundary:"), + ); + const broadCodeqlSelector = workflow.slice( + workflow.indexOf(".github/codeql/*|.github/workflows/codeql-critical-quality.yml"), + workflow.indexOf("src/**/*.test.ts|src/**/*.test.tsx"), + ); + + expect(broadCodeqlSelector).not.toContain("network_runtime=true"); + expect(networkSelector).toContain( + ".github/codeql/codeql-network-runtime-boundary-critical-quality.yml", + ); + expect(networkSelector).not.toContain("src/*.ts|src/**/*.ts"); + expect(networkSelector).not.toContain("extensions/*.ts|extensions/**/*.ts"); + expect(networkSelector).toContain("src/infra/net/*"); + expect(networkSelector).toContain("src/infra/ssh-tunnel.ts"); + expect(networkSelector).toContain("packages/net-policy/src/*"); + expect(networkConfig).not.toContain("\n - src\n"); + expect(networkConfig).not.toContain("\n - extensions\n"); + expect(networkConfig).toContain("\n - src/infra/net\n"); + expect(networkConfig).toContain("\n - packages/net-policy/src\n"); + expect(workflow).toContain("Fast PR network boundary diff scan"); + expect(workflow).toContain("Network runtime boundary-sensitive added lines"); + expect(workflow).toContain("if: ${{ github.event_name != 'pull_request' }}"); + }); }); diff --git a/test/scripts/test-projects.test.ts b/test/scripts/test-projects.test.ts index 4682efe5341..f10154c8605 100644 --- a/test/scripts/test-projects.test.ts +++ b/test/scripts/test-projects.test.ts @@ -161,10 +161,13 @@ describe("scripts/test-projects changed-target routing", () => { it("maps changed source files into scoped lane targets", () => { expect( resolveChangedTargetArgs(["--changed", "origin/main"], process.cwd(), () => [ - "src/shared/string-normalization.ts", + "packages/normalization-core/src/string-normalization.ts", "src/utils/provider-utils.ts", ]), - ).toEqual(["src/shared/string-normalization.test.ts", "src/utils/provider-utils.test.ts"]); + ).toEqual([ + "packages/normalization-core/src/string-normalization.test.ts", + "src/utils/provider-utils.test.ts", + ]); }); it("keeps changed mode focused by default for Vitest wiring edits", () => { @@ -1412,15 +1415,15 @@ describe("scripts/test-projects changed-target routing", () => { it("routes changed utils and shared files to their light scoped lanes", () => { const plans = buildVitestRunPlans(["--changed", "origin/main"], process.cwd(), () => [ - "src/shared/string-normalization.ts", + "packages/normalization-core/src/string-normalization.ts", "src/utils/provider-utils.ts", ]); expect(plans).toEqual([ { - config: "test/vitest/vitest.unit-fast.config.ts", - forwardedArgs: [], - includePatterns: ["src/shared/string-normalization.test.ts"], + config: "test/vitest/vitest.unit.config.ts", + forwardedArgs: ["packages/normalization-core/src/string-normalization.test.ts"], + includePatterns: null, watchMode: false, }, { diff --git a/test/vitest/vitest.shared.config.ts b/test/vitest/vitest.shared.config.ts index 1b7c19af2af..be6f076048a 100644 --- a/test/vitest/vitest.shared.config.ts +++ b/test/vitest/vitest.shared.config.ts @@ -331,6 +331,50 @@ export const sharedVitestConfig = { find: "@openclaw/net-policy", replacement: path.join(repoRoot, "packages", "net-policy", "src", "index.ts"), }, + { + find: "@openclaw/normalization-core/number-coercion", + replacement: path.join( + repoRoot, + "packages", + "normalization-core", + "src", + "number-coercion.ts", + ), + }, + { + find: "@openclaw/normalization-core/record-coerce", + replacement: path.join( + repoRoot, + "packages", + "normalization-core", + "src", + "record-coerce.ts", + ), + }, + { + find: "@openclaw/normalization-core/string-coerce", + replacement: path.join( + repoRoot, + "packages", + "normalization-core", + "src", + "string-coerce.ts", + ), + }, + { + find: "@openclaw/normalization-core/string-normalization", + replacement: path.join( + repoRoot, + "packages", + "normalization-core", + "src", + "string-normalization.ts", + ), + }, + { + find: "@openclaw/normalization-core", + replacement: path.join(repoRoot, "packages", "normalization-core", "src", "index.ts"), + }, ...sourcePluginSdkSubpaths.map((subpath) => ({ find: `openclaw/plugin-sdk/${subpath}`, replacement: path.join(repoRoot, "src", "plugin-sdk", `${subpath}.ts`), diff --git a/tsconfig.json b/tsconfig.json index d66fa4d837e..06e00e44cbb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -106,6 +106,20 @@ "@openclaw/markdown-core/tables": ["./packages/markdown-core/src/tables.ts"], "@openclaw/markdown-core/types": ["./packages/markdown-core/src/types.ts"], "@openclaw/markdown-core/*": ["./packages/markdown-core/src/*"], + "@openclaw/normalization-core": ["./packages/normalization-core/src/index.ts"], + "@openclaw/normalization-core/number-coercion": [ + "./packages/normalization-core/src/number-coercion.ts" + ], + "@openclaw/normalization-core/record-coerce": [ + "./packages/normalization-core/src/record-coerce.ts" + ], + "@openclaw/normalization-core/string-coerce": [ + "./packages/normalization-core/src/string-coerce.ts" + ], + "@openclaw/normalization-core/string-normalization": [ + "./packages/normalization-core/src/string-normalization.ts" + ], + "@openclaw/normalization-core/*": ["./packages/normalization-core/src/*"], "@openclaw/terminal-core": ["./packages/terminal-core/src/index.ts"], "@openclaw/terminal-core/ansi": ["./packages/terminal-core/src/ansi.ts"], "@openclaw/terminal-core/decorative-emoji": [ diff --git a/tsconfig.plugin-sdk.dts.json b/tsconfig.plugin-sdk.dts.json index 5d5a8fae6e1..3c87bf536a9 100644 --- a/tsconfig.plugin-sdk.dts.json +++ b/tsconfig.plugin-sdk.dts.json @@ -18,6 +18,7 @@ "packages/media-generation-core/src/**/*.ts", "packages/model-catalog-core/src/**/*.ts", "packages/memory-host-sdk/src/**/*.ts", + "packages/normalization-core/src/**/*.ts", "packages/terminal-core/src/**/*.ts", "src/video-generation/dashscope-compatible.ts", "src/video-generation/types.ts", diff --git a/tsdown.config.ts b/tsdown.config.ts index ca6dd8bbe43..e72c76652c4 100644 --- a/tsdown.config.ts +++ b/tsdown.config.ts @@ -215,6 +215,8 @@ function shouldAlwaysBundleDependency(id: string): boolean { return ( id === "@openclaw/fs-safe" || id.startsWith("@openclaw/fs-safe/") || + id === "@openclaw/normalization-core" || + id.startsWith("@openclaw/normalization-core/") || id === "zod" || id.startsWith("zod/") ); @@ -314,7 +316,7 @@ function buildDockerE2eHarnessEntries(): Record { "infra/ws": "src/infra/ws.ts", "plugin-sdk/provider-onboard": "src/plugin-sdk/provider-onboard.ts", "plugins/tools": "src/plugins/tools.ts", - "shared/string-coerce": "src/shared/string-coerce.ts", + "normalization-core/string-coerce": "packages/normalization-core/src/string-coerce.ts", }; } @@ -425,6 +427,16 @@ function buildMarkdownCoreDistEntries(): Record { }; } +function buildNormalizationCoreDistEntries(): Record { + return { + index: "packages/normalization-core/src/index.ts", + "number-coercion": "packages/normalization-core/src/number-coercion.ts", + "record-coerce": "packages/normalization-core/src/record-coerce.ts", + "string-coerce": "packages/normalization-core/src/string-coerce.ts", + "string-normalization": "packages/normalization-core/src/string-normalization.ts", + }; +} + function buildTerminalCoreDistEntries(): Record { return { index: "packages/terminal-core/src/index.ts", @@ -559,6 +571,12 @@ function buildUnifiedDistEntries(): Record { return { ...coreDistEntries, ...dockerE2eHarnessEntries, + ...Object.fromEntries( + Object.entries(buildNormalizationCoreDistEntries()).map(([entry, source]) => [ + `normalization-core/${entry}`, + source, + ]), + ), ...Object.fromEntries( Object.entries(buildTerminalCoreDistEntries()).map(([entry, source]) => [ `terminal-core/${entry}`, @@ -645,6 +663,12 @@ export default defineConfig([ neverBundle: shouldExternalizeMarkdownCoreDependency, }, }), + nodeWorkspacePackageBuildConfig({ + clean: true, + dts: RUN_NODE_SKIP_DTS_BUILD ? false : undefined, + entry: buildNormalizationCoreDistEntries(), + outDir: tsdownPackageOutputRoot("normalization-core"), + }), nodeWorkspacePackageBuildConfig({ clean: true, dts: RUN_NODE_SKIP_DTS_BUILD ? false : undefined, diff --git a/ui/package.json b/ui/package.json index fb1cc5143f8..597eb61786d 100644 --- a/ui/package.json +++ b/ui/package.json @@ -11,6 +11,7 @@ "dependencies": { "@create-markdown/preview": "2.0.3", "@noble/ed25519": "3.1.0", + "@openclaw/normalization-core": "workspace:*", "dompurify": "3.4.6", "highlight.js": "11.11.1", "json5": "2.2.3", diff --git a/ui/src/ui/chat/export.ts b/ui/src/ui/chat/export.ts index 16d7cf049e9..68d15236bf3 100644 --- a/ui/src/ui/chat/export.ts +++ b/ui/src/ui/chat/export.ts @@ -1,4 +1,4 @@ -import { timestampMsToIsoString } from "../../../../src/shared/number-coercion.js"; +import { timestampMsToIsoString } from "@openclaw/normalization-core/number-coercion"; import { extractTextCached } from "./message-extract.ts"; /** diff --git a/ui/src/ui/chat/slash-commands.browser-import.test.ts b/ui/src/ui/chat/slash-commands.browser-import.test.ts index 1ad477a0d77..163317af830 100644 --- a/ui/src/ui/chat/slash-commands.browser-import.test.ts +++ b/ui/src/ui/chat/slash-commands.browser-import.test.ts @@ -67,8 +67,8 @@ describe("slash command browser import", () => { 'import { normalizeLowercaseStringOrEmpty } from "../string-coerce.ts";', ]); expect(importDeclarations(sharedRegistry)).toEqual([ - 'import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";', - 'import { normalizeStringEntries } from "../shared/string-normalization.js";', + 'import { normalizeOptionalLowercaseString } from "../../packages/normalization-core/src/string-coerce.js";', + 'import { normalizeStringEntries } from "../../packages/normalization-core/src/string-normalization.js";', 'import { COMMAND_ARG_FORMATTERS } from "./commands-args.js";', 'import type { ChatCommandDefinition, CommandArgChoiceContext, CommandCategory, CommandScope, CommandTier } from "./commands-registry.types.js";', 'import { BASE_THINKING_LEVELS, type ThinkLevel } from "./thinking.shared.js";', diff --git a/ui/src/ui/format.ts b/ui/src/ui/format.ts index 0fac5ad8342..d8aed721041 100644 --- a/ui/src/ui/format.ts +++ b/ui/src/ui/format.ts @@ -1,6 +1,6 @@ +import { asDateTimestampMs } from "@openclaw/normalization-core/number-coercion"; import { formatDurationHuman } from "../../../src/infra/format-time/format-duration.ts"; import { formatRelativeTimestamp } from "../../../src/infra/format-time/format-relative.ts"; -import { asDateTimestampMs } from "../../../src/shared/number-coercion.js"; import { t } from "../i18n/index.ts"; export { formatRelativeTimestamp, formatDurationHuman }; diff --git a/ui/src/ui/provider-quota-summary.ts b/ui/src/ui/provider-quota-summary.ts index 1923a366dcf..89e6a319989 100644 --- a/ui/src/ui/provider-quota-summary.ts +++ b/ui/src/ui/provider-quota-summary.ts @@ -1,4 +1,4 @@ -import { asDateTimestampMs } from "../../../src/shared/number-coercion.js"; +import { asDateTimestampMs } from "@openclaw/normalization-core/number-coercion"; import type { ModelAuthStatusProvider, ModelAuthStatusResult } from "./types.ts"; export type QuotaWindowSummary = { diff --git a/ui/src/ui/string-coerce.ts b/ui/src/ui/string-coerce.ts index 44370438ad3..4c04cf82c6e 100644 --- a/ui/src/ui/string-coerce.ts +++ b/ui/src/ui/string-coerce.ts @@ -3,9 +3,9 @@ export { normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringifiedOptionalString, -} from "../../../src/shared/string-coerce.js"; +} from "@openclaw/normalization-core/string-coerce"; export { normalizeStringEntries, sortUniqueStrings, uniqueStrings, -} from "../../../src/shared/string-normalization.js"; +} from "@openclaw/normalization-core/string-normalization"; diff --git a/ui/src/ui/views/overview-cards.ts b/ui/src/ui/views/overview-cards.ts index 1729d44b401..ea87482fa94 100644 --- a/ui/src/ui/views/overview-cards.ts +++ b/ui/src/ui/views/overview-cards.ts @@ -1,6 +1,6 @@ +import { asDateTimestampMs } from "@openclaw/normalization-core/number-coercion"; import { html, nothing, type TemplateResult } from "lit"; import { unsafeHTML } from "lit/directives/unsafe-html.js"; -import { asDateTimestampMs } from "../../../../src/shared/number-coercion.js"; import { t } from "../../i18n/index.ts"; import { resolveCronJobLastRunStatus } from "../cron-status.ts"; import { formatCost, formatTokens, formatRelativeTimestamp } from "../format.ts"; diff --git a/ui/src/ui/views/usage-query.ts b/ui/src/ui/views/usage-query.ts index 148e7114fe5..2a6a60ea04a 100644 --- a/ui/src/ui/views/usage-query.ts +++ b/ui/src/ui/views/usage-query.ts @@ -1,4 +1,4 @@ -import { timestampMsToIsoString } from "../../../../src/shared/number-coercion.js"; +import { timestampMsToIsoString } from "@openclaw/normalization-core/number-coercion"; import { normalizeLowercaseStringOrEmpty, uniqueStrings } from "../string-coerce.ts"; import { extractQueryTerms } from "../usage-helpers.ts"; import type { CostDailyEntry, UsageAggregates, UsageSessionEntry } from "./usageTypes.ts"; diff --git a/ui/vite.config.ts b/ui/vite.config.ts index 79ebdc69bf3..a177308541d 100644 --- a/ui/vite.config.ts +++ b/ui/vite.config.ts @@ -119,7 +119,10 @@ function resolveTsconfigPathAlias(key: string, target: string): ControlUiViteAli }; } - if (key.includes("*", keyWildcardIndex + 1) || target.includes("*", targetWildcardIndex + 1)) { + if ( + key.slice(keyWildcardIndex + 1).includes("*") || + target.slice(targetWildcardIndex + 1).includes("*") + ) { return null; } diff --git a/ui/vitest.config.ts b/ui/vitest.config.ts index c52a6c491ee..dc3ff658314 100644 --- a/ui/vitest.config.ts +++ b/ui/vitest.config.ts @@ -1,3 +1,5 @@ +import path from "node:path"; +import { fileURLToPath } from "node:url"; import { playwright } from "@vitest/browser-playwright"; import { defineConfig, defineProject } from "vitest/config"; import { @@ -5,6 +7,8 @@ import { resolveDefaultVitestPool, } from "../test/vitest/vitest.shared.config.ts"; +const here = path.dirname(fileURLToPath(import.meta.url)); +const repoRoot = path.resolve(here, ".."); const sharedUiTestConfig = { isolate: false, pool: resolveDefaultVitestPool(), @@ -15,6 +19,14 @@ const nodeDrivenBrowserLayoutTests = [ ] as const; export default defineConfig({ + resolve: { + alias: [ + { + find: /^@openclaw\/normalization-core\/(.+)$/u, + replacement: path.resolve(repoRoot, "packages/normalization-core/src/$1"), + }, + ], + }, test: { ...sharedUiTestConfig, projects: [