@yansigit/opencodex 2.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS_INSTALL.md +109 -0
- package/LICENSE +21 -0
- package/README.md +303 -0
- package/assets/architecture.png +0 -0
- package/assets/banner.png +0 -0
- package/assets/claude-code-models.gif +0 -0
- package/assets/codex-app-picker.png +0 -0
- package/bin/ocx.mjs +587 -0
- package/bin/package-main.mjs +9 -0
- package/gui/dist/assets/index-BNJ7r4Gd.js +102 -0
- package/gui/dist/assets/index-CGoDO3uO.css +1 -0
- package/gui/dist/favicon.png +0 -0
- package/gui/dist/icons.svg +24 -0
- package/gui/dist/index.html +25 -0
- package/gui/dist/logo.png +0 -0
- package/gui/dist/provider-icons/alibaba-color.svg +1 -0
- package/gui/dist/provider-icons/antigravity-color.svg +1 -0
- package/gui/dist/provider-icons/claude-color.svg +1 -0
- package/gui/dist/provider-icons/cline-color.svg +16 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -0
- package/gui/dist/provider-icons/commandcode-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -0
- package/gui/dist/provider-icons/cursor-color.svg +2 -0
- package/gui/dist/provider-icons/deepseek-color.svg +1 -0
- package/gui/dist/provider-icons/discord.svg +1 -0
- package/gui/dist/provider-icons/firepass-color.svg +1 -0
- package/gui/dist/provider-icons/fireworks-color.svg +1 -0
- package/gui/dist/provider-icons/gemini-color.svg +1 -0
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -0
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -0
- package/gui/dist/provider-icons/grok.svg +1 -0
- package/gui/dist/provider-icons/groq-color.svg +1 -0
- package/gui/dist/provider-icons/huggingface-color.svg +1 -0
- package/gui/dist/provider-icons/kimi-color.svg +1 -0
- package/gui/dist/provider-icons/kiro-color.svg +15 -0
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -0
- package/gui/dist/provider-icons/mistral-color.svg +1 -0
- package/gui/dist/provider-icons/moonshot-color.svg +1 -0
- package/gui/dist/provider-icons/nvidia-color.svg +1 -0
- package/gui/dist/provider-icons/ollama-color.svg +1 -0
- package/gui/dist/provider-icons/openai.svg +1 -0
- package/gui/dist/provider-icons/opencode.svg +2 -0
- package/gui/dist/provider-icons/openrouter-color.svg +1 -0
- package/gui/dist/provider-icons/pi.svg +21 -0
- package/gui/dist/provider-icons/qianfan-color.svg +1 -0
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -0
- package/gui/dist/provider-icons/telegram.svg +1 -0
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -0
- package/gui/dist/provider-icons/vllm-color.svg +1 -0
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -0
- package/package.json +108 -0
- package/src/AGENTS.md +28 -0
- package/src/adapters/anthropic-image-guard.ts +251 -0
- package/src/adapters/anthropic-image-normalize.ts +518 -0
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +1327 -0
- package/src/adapters/azure.ts +36 -0
- package/src/adapters/base.ts +121 -0
- package/src/adapters/client-fingerprint.ts +65 -0
- package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
- package/src/adapters/command-code.ts +601 -0
- package/src/adapters/cursor/arg-codec.ts +38 -0
- package/src/adapters/cursor/arg-normalize.ts +104 -0
- package/src/adapters/cursor/checkpoint-store.ts +303 -0
- package/src/adapters/cursor/cursor-errors.ts +288 -0
- package/src/adapters/cursor/discovery.ts +333 -0
- package/src/adapters/cursor/effort-map.ts +151 -0
- package/src/adapters/cursor/exec-policy.ts +88 -0
- package/src/adapters/cursor/framing.ts +250 -0
- package/src/adapters/cursor/gen/agent_pb.ts +15274 -0
- package/src/adapters/cursor/h2-pool.ts +123 -0
- package/src/adapters/cursor/http1-bidi.ts +361 -0
- package/src/adapters/cursor/images.ts +704 -0
- package/src/adapters/cursor/kv-store.ts +52 -0
- package/src/adapters/cursor/live-models.ts +269 -0
- package/src/adapters/cursor/live-smoke-gate.ts +41 -0
- package/src/adapters/cursor/live-transport.ts +1653 -0
- package/src/adapters/cursor/mcp-config.ts +42 -0
- package/src/adapters/cursor/mcp-manager.ts +333 -0
- package/src/adapters/cursor/message-mapper.ts +49 -0
- package/src/adapters/cursor/native-exec-common.ts +76 -0
- package/src/adapters/cursor/native-exec-desktop.ts +184 -0
- package/src/adapters/cursor/native-exec-fs.ts +332 -0
- package/src/adapters/cursor/native-exec-mcp.ts +153 -0
- package/src/adapters/cursor/native-exec-network.ts +43 -0
- package/src/adapters/cursor/native-exec-shell.ts +547 -0
- package/src/adapters/cursor/native-exec-tools.ts +118 -0
- package/src/adapters/cursor/native-exec.ts +663 -0
- package/src/adapters/cursor/protobuf-events.ts +1381 -0
- package/src/adapters/cursor/protobuf-request.ts +1032 -0
- package/src/adapters/cursor/request-builder.ts +461 -0
- package/src/adapters/cursor/thread-continuity.ts +67 -0
- package/src/adapters/cursor/tool-definitions.ts +735 -0
- package/src/adapters/cursor/tool-result-normalize.ts +92 -0
- package/src/adapters/cursor/transport-retry.ts +132 -0
- package/src/adapters/cursor/transport.ts +79 -0
- package/src/adapters/cursor/types.ts +79 -0
- package/src/adapters/cursor.ts +322 -0
- package/src/adapters/google-antigravity-hosts.ts +48 -0
- package/src/adapters/google-antigravity-replay.ts +827 -0
- package/src/adapters/google-antigravity-tools.ts +105 -0
- package/src/adapters/google-antigravity-wire.ts +141 -0
- package/src/adapters/google-errors.ts +92 -0
- package/src/adapters/google-http.ts +460 -0
- package/src/adapters/google-tool-schema.ts +238 -0
- package/src/adapters/google-truncation.ts +24 -0
- package/src/adapters/google-wire-compiler.ts +232 -0
- package/src/adapters/google.ts +1377 -0
- package/src/adapters/identity.ts +77 -0
- package/src/adapters/image.ts +23 -0
- package/src/adapters/kiro-constants.ts +16 -0
- package/src/adapters/kiro-errors.ts +208 -0
- package/src/adapters/kiro-events.ts +197 -0
- package/src/adapters/kiro-images.ts +129 -0
- package/src/adapters/kiro-retry.ts +312 -0
- package/src/adapters/kiro-thinking.ts +112 -0
- package/src/adapters/kiro-tool-fallback.ts +36 -0
- package/src/adapters/kiro-tools.ts +224 -0
- package/src/adapters/kiro-truncation.ts +33 -0
- package/src/adapters/kiro-wire.ts +129 -0
- package/src/adapters/kiro.ts +1936 -0
- package/src/adapters/mimo-free.ts +280 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1980 -0
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +1911 -0
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/run-turn-queue.ts +114 -0
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +154 -0
- package/src/adapters/upstream-http-error.ts +48 -0
- package/src/adapters/xai-web-search.ts +185 -0
- package/src/bridge.ts +1986 -0
- package/src/chat/inbound.ts +319 -0
- package/src/chat/outbound.ts +821 -0
- package/src/claude/agents-inject.ts +266 -0
- package/src/claude/alias.ts +149 -0
- package/src/claude/auth-detect.ts +229 -0
- package/src/claude/auth-mode-migration.ts +32 -0
- package/src/claude/auth-mode.ts +62 -0
- package/src/claude/context-windows.ts +205 -0
- package/src/claude/desktop-3p-guard.ts +35 -0
- package/src/claude/desktop-3p-paths.ts +84 -0
- package/src/claude/desktop-3p.ts +615 -0
- package/src/claude/desktop-health.ts +26 -0
- package/src/claude/desktop-profile.ts +263 -0
- package/src/claude/gateway-cache.ts +107 -0
- package/src/claude/inbound-debug.ts +163 -0
- package/src/claude/inbound.ts +578 -0
- package/src/claude/model-info.ts +174 -0
- package/src/claude/outbound.ts +926 -0
- package/src/cli/access.ts +108 -0
- package/src/cli/account-api.ts +302 -0
- package/src/cli/account-auth.ts +250 -0
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +737 -0
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +299 -0
- package/src/cli/agent-driven.ts +70 -0
- package/src/cli/agent.ts +290 -0
- package/src/cli/catalog-prewarm.ts +27 -0
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +213 -0
- package/src/cli/claude.ts +355 -0
- package/src/cli/codex-log-guard-doctor.ts +103 -0
- package/src/cli/codex-shim-autorestore.ts +47 -0
- package/src/cli/codex-shim-readiness.ts +76 -0
- package/src/cli/combo.ts +127 -0
- package/src/cli/config-command.ts +209 -0
- package/src/cli/debug.ts +228 -0
- package/src/cli/dispatch.ts +585 -0
- package/src/cli/doctor.ts +1202 -0
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +213 -0
- package/src/cli/help.ts +101 -0
- package/src/cli/index.ts +973 -0
- package/src/cli/init.ts +211 -0
- package/src/cli/integrations.ts +260 -0
- package/src/cli/interactive-confirm.ts +133 -0
- package/src/cli/lab.ts +607 -0
- package/src/cli/launcher-context.ts +77 -0
- package/src/cli/minimax.ts +497 -0
- package/src/cli/models-runtime.ts +245 -0
- package/src/cli/models.ts +422 -0
- package/src/cli/observe.ts +206 -0
- package/src/cli/opencode.ts +588 -0
- package/src/cli/provider-replit.ts +232 -0
- package/src/cli/provider-runtime.ts +179 -0
- package/src/cli/provider.ts +492 -0
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +422 -0
- package/src/cli/replit-gateway-key-input.ts +138 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +328 -0
- package/src/cli/star-prompt.ts +211 -0
- package/src/cli/status-oauth.ts +78 -0
- package/src/cli/status.ts +328 -0
- package/src/cli/system-command.ts +112 -0
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +199 -0
- package/src/cli/v2.ts +268 -0
- package/src/cli.ts +10 -0
- package/src/clients/config-export.ts +1704 -0
- package/src/codex/account-id.ts +34 -0
- package/src/codex/account-label.ts +47 -0
- package/src/codex/account-lifecycle.ts +172 -0
- package/src/codex/account-namespace-match.ts +63 -0
- package/src/codex/account-namespaces.ts +195 -0
- package/src/codex/account-pause.ts +20 -0
- package/src/codex/account-priority.ts +83 -0
- package/src/codex/account-runtime-state.ts +31 -0
- package/src/codex/account-store.ts +544 -0
- package/src/codex/account-usability.ts +43 -0
- package/src/codex/admission.ts +256 -0
- package/src/codex/affinity-debug.ts +162 -0
- package/src/codex/agent-roles-sync.ts +225 -0
- package/src/codex/agent-roles.ts +238 -0
- package/src/codex/app-server-processes.ts +1143 -0
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +2147 -0
- package/src/codex/auth-collision.ts +109 -0
- package/src/codex/auth-context.ts +665 -0
- package/src/codex/autostart-health.ts +156 -0
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +436 -0
- package/src/codex/catalog/bundled.ts +549 -0
- package/src/codex/catalog/effort.ts +446 -0
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +664 -0
- package/src/codex/catalog/native-models.ts +72 -0
- package/src/codex/catalog/parsing.ts +650 -0
- package/src/codex/catalog/provider-fetch.ts +2064 -0
- package/src/codex/catalog/sync.ts +1883 -0
- package/src/codex/catalog-admission.ts +199 -0
- package/src/codex/catalog-refresh-status.ts +105 -0
- package/src/codex/catalog-write-serialization.ts +242 -0
- package/src/codex/catalog.ts +14 -0
- package/src/codex/codex-write-lock.ts +384 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +651 -0
- package/src/codex/coordinator-doctor.ts +332 -0
- package/src/codex/custom-model-catalog-migration.ts +176 -0
- package/src/codex/data/upstream-models.json +830 -0
- package/src/codex/desired-state.ts +230 -0
- package/src/codex/exec-invocation.ts +22 -0
- package/src/codex/features.ts +1566 -0
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +407 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-migration-guardian.ts +108 -0
- package/src/codex/history-provider.ts +979 -0
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +220 -0
- package/src/codex/home.ts +206 -0
- package/src/codex/inject-coordination.ts +290 -0
- package/src/codex/inject.ts +1733 -0
- package/src/codex/injected-marker.ts +106 -0
- package/src/codex/integration-record.ts +266 -0
- package/src/codex/internal/catalog-writer.ts +203 -0
- package/src/codex/internal/history-writer.ts +80 -0
- package/src/codex/journal.ts +225 -0
- package/src/codex/log-guard/inspect.ts +506 -0
- package/src/codex/log-guard/lock.ts +150 -0
- package/src/codex/log-guard/maintenance.ts +403 -0
- package/src/codex/log-guard/path-safety.ts +88 -0
- package/src/codex/log-guard/policy.ts +44 -0
- package/src/codex/log-guard/processes.ts +205 -0
- package/src/codex/log-guard/protection.ts +489 -0
- package/src/codex/log-guard/sqlite-errors.ts +9 -0
- package/src/codex/main-account-cache.ts +56 -0
- package/src/codex/main-account.ts +68 -0
- package/src/codex/management-convergence.ts +167 -0
- package/src/codex/model-cache.ts +273 -0
- package/src/codex/model-entitlements.ts +353 -0
- package/src/codex/native-main-admission.ts +47 -0
- package/src/codex/native-main-auth-temp.ts +187 -0
- package/src/codex/native-main-claim.ts +178 -0
- package/src/codex/native-main-lock-file.ts +162 -0
- package/src/codex/native-main-owner.ts +329 -0
- package/src/codex/native-profile-api.ts +247 -0
- package/src/codex/native-profile-manager.ts +1531 -0
- package/src/codex/native-profile-processes.ts +121 -0
- package/src/codex/native-profile-recovery.ts +99 -0
- package/src/codex/native-profile-stage-store.ts +387 -0
- package/src/codex/native-profile-startup.ts +492 -0
- package/src/codex/native-profile-store.ts +855 -0
- package/src/codex/native-profile-types.ts +120 -0
- package/src/codex/native-residue.ts +682 -0
- package/src/codex/paths.ts +144 -0
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +40 -0
- package/src/codex/plugins-doctor.ts +242 -0
- package/src/codex/pool-rotation.ts +295 -0
- package/src/codex/project-config-warnings.ts +425 -0
- package/src/codex/prompt-journal.ts +352 -0
- package/src/codex/prompt-layers.ts +967 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +573 -0
- package/src/codex/refresh.ts +62 -0
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +1888 -0
- package/src/codex/runtime.ts +659 -0
- package/src/codex/shim.ts +2170 -0
- package/src/codex/subagent-defaults.ts +550 -0
- package/src/codex/subagent-model-fallback.ts +784 -0
- package/src/codex/sync.ts +319 -0
- package/src/codex/transition-state.ts +612 -0
- package/src/codex/upstream-host-health.ts +368 -0
- package/src/codex/user-identity.ts +557 -0
- package/src/codex/warmup.ts +298 -0
- package/src/codex/websocket-registry.ts +100 -0
- package/src/codex/write-coordination.ts +114 -0
- package/src/combos/failover.ts +160 -0
- package/src/combos/index.ts +45 -0
- package/src/combos/request.ts +94 -0
- package/src/combos/resolve.ts +232 -0
- package/src/combos/types.ts +398 -0
- package/src/config/provider-name.ts +24 -0
- package/src/config.ts +4041 -0
- package/src/fork/register.ts +3 -0
- package/src/generated/compatibility-version.json +3116 -0
- package/src/generated/model-metadata.ts +106 -0
- package/src/github/star-state.ts +203 -0
- package/src/grok/inject.ts +530 -0
- package/src/grok/inspect.ts +45 -0
- package/src/grok/status.ts +121 -0
- package/src/grok/sync.ts +66 -0
- package/src/images/artifacts.ts +516 -0
- package/src/images/fulfill-video.ts +163 -0
- package/src/images/fulfill.ts +149 -0
- package/src/images/index.ts +4 -0
- package/src/images/loop.ts +955 -0
- package/src/images/plan.ts +143 -0
- package/src/images/synthetic-tool.ts +133 -0
- package/src/images/types.ts +41 -0
- package/src/images/xai-client.ts +141 -0
- package/src/images/xai-video-client.ts +163 -0
- package/src/index.ts +22 -0
- package/src/integrations/config-io.ts +269 -0
- package/src/integrations/journal.ts +315 -0
- package/src/integrations/merge.ts +135 -0
- package/src/integrations/mutation-flight.ts +71 -0
- package/src/integrations/native/ownership-preflight.ts +202 -0
- package/src/integrations/omp-yaml-source.ts +358 -0
- package/src/integrations/owned-refresh.ts +74 -0
- package/src/integrations/ownership.ts +111 -0
- package/src/integrations/registry.ts +159 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +361 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +691 -0
- package/src/lab/artifacts/sanitize.ts +586 -0
- package/src/lab/artifacts/secure-fs.ts +475 -0
- package/src/lab/artifacts/store.ts +310 -0
- package/src/lab/automation/budgets.ts +78 -0
- package/src/lab/automation/config-persistence.ts +256 -0
- package/src/lab/automation/constants.ts +39 -0
- package/src/lab/automation/cooldown.ts +103 -0
- package/src/lab/automation/dispatch.ts +211 -0
- package/src/lab/automation/index.ts +13 -0
- package/src/lab/automation/orchestrator.ts +499 -0
- package/src/lab/automation/persistence.ts +512 -0
- package/src/lab/automation/planner.ts +371 -0
- package/src/lab/automation/policy.ts +136 -0
- package/src/lab/automation/queue.ts +191 -0
- package/src/lab/automation/recovery.ts +24 -0
- package/src/lab/automation/route-context.ts +21 -0
- package/src/lab/automation/run-key.ts +44 -0
- package/src/lab/automation/runs-query.ts +34 -0
- package/src/lab/automation/types.ts +160 -0
- package/src/lab/conformance/assertion.ts +325 -0
- package/src/lab/conformance/digest.ts +22 -0
- package/src/lab/conformance/executor.ts +741 -0
- package/src/lab/conformance/fixture-provider.ts +27 -0
- package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
- package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
- package/src/lab/conformance/harness-budget.ts +47 -0
- package/src/lab/conformance/index.ts +5 -0
- package/src/lab/conformance/jcs.ts +64 -0
- package/src/lab/conformance/json-pointer.ts +39 -0
- package/src/lab/conformance/manifest.ts +180 -0
- package/src/lab/conformance/mcp-stub.ts +179 -0
- package/src/lab/conformance/negative-controls.ts +164 -0
- package/src/lab/conformance/observation.ts +355 -0
- package/src/lab/conformance/runner.ts +68 -0
- package/src/lab/conformance/sse-normalize.ts +59 -0
- package/src/lab/conformance/suite-manifest.ts +78 -0
- package/src/lab/conformance/types.ts +214 -0
- package/src/lab/constants.ts +126 -0
- package/src/lab/digest.ts +64 -0
- package/src/lab/events/errors.ts +9 -0
- package/src/lab/events/limits.ts +117 -0
- package/src/lab/events/types.ts +229 -0
- package/src/lab/events/validate.ts +781 -0
- package/src/lab/fabric/constants.ts +40 -0
- package/src/lab/fabric/executor.ts +492 -0
- package/src/lab/fabric/index.ts +80 -0
- package/src/lab/fabric/manifest.ts +222 -0
- package/src/lab/fabric/observe.ts +489 -0
- package/src/lab/fabric/patch.ts +79 -0
- package/src/lab/fabric/producer-child.ts +139 -0
- package/src/lab/fabric/producer-isolate.ts +276 -0
- package/src/lab/fabric/producer-protocol.ts +61 -0
- package/src/lab/fabric/scratch.ts +439 -0
- package/src/lab/fabric/subject.ts +106 -0
- package/src/lab/fabric/types.ts +134 -0
- package/src/lab/fabric/verifier.ts +98 -0
- package/src/lab/index.ts +54 -0
- package/src/lab/ledger/artifact-refs.ts +127 -0
- package/src/lab/ledger/invalidation.ts +136 -0
- package/src/lab/ledger/purge.ts +310 -0
- package/src/lab/ledger/store.ts +532 -0
- package/src/lab/live/credential-lease.ts +53 -0
- package/src/lab/live/destination.ts +155 -0
- package/src/lab/live/executor.ts +336 -0
- package/src/lab/live/inert-tools.ts +56 -0
- package/src/lab/live/manifest.ts +85 -0
- package/src/lab/live/mcp-loopback.ts +57 -0
- package/src/lab/live/runner.ts +19 -0
- package/src/lab/live/sandbox.ts +61 -0
- package/src/lab/live/suite-manifest.ts +41 -0
- package/src/lab/live/transport.ts +118 -0
- package/src/lab/live/types.ts +197 -0
- package/src/lab/observe/from-conformance.ts +301 -0
- package/src/lab/observe/from-live.ts +117 -0
- package/src/lab/paths.ts +153 -0
- package/src/lab/projection/rebuild.ts +495 -0
- package/src/lab/projection/schema.ts +135 -0
- package/src/lab/projection/verdicts.ts +474 -0
- package/src/lab/projection/verification.ts +412 -0
- package/src/lab/public/bundle.ts +217 -0
- package/src/lab/public/community-authority.ts +175 -0
- package/src/lab/public/community-files.ts +29 -0
- package/src/lab/public/community.ts +479 -0
- package/src/lab/public/file-safety.ts +155 -0
- package/src/lab/public/ids.ts +26 -0
- package/src/lab/public/index.ts +16 -0
- package/src/lab/public/mutation-lock.ts +424 -0
- package/src/lab/public/operator.ts +353 -0
- package/src/lab/public/origin-purge.ts +79 -0
- package/src/lab/public/origin.ts +203 -0
- package/src/lab/public/privacy.ts +143 -0
- package/src/lab/public/private-file.ts +261 -0
- package/src/lab/public/project.ts +124 -0
- package/src/lab/public/purge-test-fault.ts +21 -0
- package/src/lab/public/purge.ts +223 -0
- package/src/lab/public/registry.ts +44 -0
- package/src/lab/public/revocation.ts +252 -0
- package/src/lab/public/signature.ts +243 -0
- package/src/lab/public/storage.ts +105 -0
- package/src/lab/public/strict-json.ts +206 -0
- package/src/lab/public/time.ts +26 -0
- package/src/lab/public/types.ts +172 -0
- package/src/lab/public/validate.ts +391 -0
- package/src/lab/query/catalog.ts +101 -0
- package/src/lab/query/connection.ts +107 -0
- package/src/lab/query/constants.ts +4 -0
- package/src/lab/query/cursor.ts +132 -0
- package/src/lab/query/dto-map.ts +277 -0
- package/src/lab/query/errors.ts +22 -0
- package/src/lab/query/freshness.ts +53 -0
- package/src/lab/query/index.ts +45 -0
- package/src/lab/query/latest-observation.ts +59 -0
- package/src/lab/query/passive-production.ts +159 -0
- package/src/lab/query/queries.ts +444 -0
- package/src/lab/query/types.ts +266 -0
- package/src/lab/subject/behavior-fingerprint.ts +77 -0
- package/src/lab/subject/installation-salt.ts +112 -0
- package/src/lab/subject/protocol-subject.ts +80 -0
- package/src/lab/subject/route-subject.ts +74 -0
- package/src/lib/abort.ts +146 -0
- package/src/lib/admin-secrets.ts +25 -0
- package/src/lib/admission.ts +83 -0
- package/src/lib/app-owned-memory-stores.ts +195 -0
- package/src/lib/app-owned-memory.ts +265 -0
- package/src/lib/bounded-body.ts +346 -0
- package/src/lib/bun-binary-validator.d.mts +3 -0
- package/src/lib/bun-binary-validator.mjs +18 -0
- package/src/lib/bun-runtime.ts +184 -0
- package/src/lib/bun-stream-caps.ts +130 -0
- package/src/lib/codex-restart-contract.ts +120 -0
- package/src/lib/config-ownership.ts +364 -0
- package/src/lib/crash-guard.ts +344 -0
- package/src/lib/debug-log-buffer.ts +83 -0
- package/src/lib/debug-settings.ts +108 -0
- package/src/lib/debug.ts +31 -0
- package/src/lib/destination-policy.ts +380 -0
- package/src/lib/errors.ts +406 -0
- package/src/lib/eventstream-decoder.ts +253 -0
- package/src/lib/fabric-task-execution-authority.ts +7 -0
- package/src/lib/fabric-task-host.ts +29 -0
- package/src/lib/gcp-adc.ts +341 -0
- package/src/lib/injection-debug-log.ts +58 -0
- package/src/lib/lab-activation.ts +223 -0
- package/src/lib/lab-live-execution-authority.ts +13 -0
- package/src/lib/lab-live-host.ts +30 -0
- package/src/lib/lab-live-pinned-sender.ts +56 -0
- package/src/lib/lab-live-route-production.ts +130 -0
- package/src/lib/lab-passive-linker-registration.ts +26 -0
- package/src/lib/local-management-attestation.ts +51 -0
- package/src/lib/local-management-capability.ts +100 -0
- package/src/lib/local-provider-reload-contract.ts +100 -0
- package/src/lib/open-url.ts +25 -0
- package/src/lib/optional-shutdown-hooks.ts +57 -0
- package/src/lib/pinned-http.ts +270 -0
- package/src/lib/privacy.ts +20 -0
- package/src/lib/process-control.ts +168 -0
- package/src/lib/provider-outbound.ts +210 -0
- package/src/lib/provider-url.ts +14 -0
- package/src/lib/proxy-env.ts +18 -0
- package/src/lib/redact.ts +521 -0
- package/src/lib/retry-after.ts +55 -0
- package/src/lib/self-launch-argv.ts +15 -0
- package/src/lib/server-resource-ownership.ts +71 -0
- package/src/lib/service-secrets.ts +25 -0
- package/src/lib/shadow-call.ts +61 -0
- package/src/lib/sidecar-tracker.ts +52 -0
- package/src/lib/sse-decoder.ts +364 -0
- package/src/lib/state-store-registrations.ts +119 -0
- package/src/lib/state-store-sweeper.ts +184 -0
- package/src/lib/system-restart-contract.ts +73 -0
- package/src/lib/test-home-guard.ts +90 -0
- package/src/lib/token-estimate.ts +86 -0
- package/src/lib/tool-argument-integers.ts +202 -0
- package/src/lib/translator-budget.ts +400 -0
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-reachability.ts +95 -0
- package/src/lib/upstream-retry.ts +392 -0
- package/src/lib/win-exec.ts +115 -0
- package/src/lib/win-paths.ts +68 -0
- package/src/lib/windows-atomic-replace.ts +156 -0
- package/src/lib/windows-elevation.ts +773 -0
- package/src/lib/windows-secret-acl.ts +854 -0
- package/src/lib/windows-service-wrappers.ts +72 -0
- package/src/lib/windows-text.ts +106 -0
- package/src/lib/windows-user-principal.ts +341 -0
- package/src/lib/winsw.ts +403 -0
- package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
- package/src/oauth/account-import/index.ts +15 -0
- package/src/oauth/account-import/parser.ts +83 -0
- package/src/oauth/account-import/registry.ts +18 -0
- package/src/oauth/account-import/service.ts +75 -0
- package/src/oauth/account-import/types.ts +91 -0
- package/src/oauth/anthropic-routing.ts +594 -0
- package/src/oauth/anthropic.ts +188 -0
- package/src/oauth/antigravity-routing.ts +151 -0
- package/src/oauth/callback-server.ts +300 -0
- package/src/oauth/chatgpt.ts +161 -0
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +252 -0
- package/src/oauth/github-copilot.ts +428 -0
- package/src/oauth/google-antigravity.ts +262 -0
- package/src/oauth/health.ts +407 -0
- package/src/oauth/index.ts +1504 -0
- package/src/oauth/key-providers.ts +124 -0
- package/src/oauth/kimi.ts +227 -0
- package/src/oauth/kiro-credentials.ts +726 -0
- package/src/oauth/kiro.ts +621 -0
- package/src/oauth/local-token-detect.ts +130 -0
- package/src/oauth/log.ts +50 -0
- package/src/oauth/login-cli.ts +223 -0
- package/src/oauth/nous.ts +798 -0
- package/src/oauth/pkce.ts +15 -0
- package/src/oauth/store.ts +728 -0
- package/src/oauth/token-guardian.ts +309 -0
- package/src/oauth/types.ts +62 -0
- package/src/oauth/xai.ts +241 -0
- package/src/providers/alibaba-region-backup.ts +75 -0
- package/src/providers/alibaba-region-migration.ts +156 -0
- package/src/providers/alibaba-region-startup.ts +36 -0
- package/src/providers/antigravity-models.ts +695 -0
- package/src/providers/antigravity-quota.ts +216 -0
- package/src/providers/api-keys.ts +140 -0
- package/src/providers/base-url-choices.ts +74 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +144 -0
- package/src/providers/context-cap.ts +82 -0
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/derive.ts +586 -0
- package/src/providers/fastwire.ts +501 -0
- package/src/providers/free-directory.ts +187 -0
- package/src/providers/github-copilot-transport.ts +56 -0
- package/src/providers/google-vertex-location.ts +14 -0
- package/src/providers/key-failover.ts +271 -0
- package/src/providers/kiro-models.ts +67 -0
- package/src/providers/label.ts +19 -0
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +449 -0
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/openai-sidecar.ts +243 -0
- package/src/providers/openai-tier-startup.ts +56 -0
- package/src/providers/openai-tiers.ts +423 -0
- package/src/providers/openai-virtual-models.ts +83 -0
- package/src/providers/opencode-zen-rate-limit.ts +102 -0
- package/src/providers/openrouter-routing.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +185 -0
- package/src/providers/quota.ts +2345 -0
- package/src/providers/registry.ts +2918 -0
- package/src/providers/replit/constants.ts +27 -0
- package/src/providers/replit/derive.ts +85 -0
- package/src/providers/replit/headers.ts +28 -0
- package/src/providers/replit/origin.ts +55 -0
- package/src/providers/replit/pair-install-response.ts +72 -0
- package/src/providers/replit/probe.ts +199 -0
- package/src/providers/replit/setup.ts +350 -0
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +103 -0
- package/src/providers/static-model-discovery.ts +86 -0
- package/src/providers/xai-responses-opt-in.ts +15 -0
- package/src/providers/xai-transport.ts +148 -0
- package/src/reasoning-effort.ts +183 -0
- package/src/responses/compaction.ts +142 -0
- package/src/responses/custom-tool-compat.ts +266 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +355 -0
- package/src/responses/parser.ts +838 -0
- package/src/responses/provider-continuation.ts +98 -0
- package/src/responses/provider-opaque-metadata.ts +73 -0
- package/src/responses/reasoning-envelope.ts +60 -0
- package/src/responses/reasoning-replay-cache.ts +426 -0
- package/src/responses/schema.ts +165 -0
- package/src/responses/spill-store.ts +459 -0
- package/src/responses/state.ts +1433 -0
- package/src/responses/thought-signature-replay.ts +347 -0
- package/src/responses/tool-groups.ts +19 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/router.ts +761 -0
- package/src/routing/analytics.ts +378 -0
- package/src/routing/capability.ts +244 -0
- package/src/routing/compatibility/assemble.ts +73 -0
- package/src/routing/compatibility/behavior.ts +278 -0
- package/src/routing/compatibility/catalog.ts +99 -0
- package/src/routing/compatibility/endpoint.ts +52 -0
- package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
- package/src/routing/compatibility/policy.ts +181 -0
- package/src/routing/compatibility/provider-slot.ts +56 -0
- package/src/routing/compatibility/reader.ts +110 -0
- package/src/routing/compatibility/subject.ts +191 -0
- package/src/routing/compatibility/types.ts +64 -0
- package/src/routing/compatibility/version.ts +104 -0
- package/src/routing/cost.ts +77 -0
- package/src/routing/evaluator.ts +495 -0
- package/src/routing/health.ts +412 -0
- package/src/routing/history/cursor.ts +43 -0
- package/src/routing/history/indexer.ts +605 -0
- package/src/routing/history/schema.ts +72 -0
- package/src/routing/profile-namespace.ts +15 -0
- package/src/routing/profile.ts +547 -0
- package/src/routing/quota.ts +145 -0
- package/src/routing/request-evidence.ts +45 -0
- package/src/routing/trace.ts +776 -0
- package/src/server/adapter-resolve.ts +53 -0
- package/src/server/auth-cors.ts +751 -0
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +442 -0
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +426 -0
- package/src/server/claude-messages.ts +1030 -0
- package/src/server/direct-local-http.ts +347 -0
- package/src/server/effort-policy.ts +190 -0
- package/src/server/github-copilot-responses-repair.ts +338 -0
- package/src/server/gui-static.ts +152 -0
- package/src/server/image-retry.ts +42 -0
- package/src/server/images.ts +568 -0
- package/src/server/index.ts +1813 -0
- package/src/server/lifecycle.ts +498 -0
- package/src/server/live.ts +717 -0
- package/src/server/local-management-read-client.ts +90 -0
- package/src/server/local-provider-reload-client.ts +137 -0
- package/src/server/management/agent-settings-routes.ts +1433 -0
- package/src/server/management/api-access.ts +141 -0
- package/src/server/management/api-key-usage.ts +193 -0
- package/src/server/management/body.ts +41 -0
- package/src/server/management/combo-routes.ts +263 -0
- package/src/server/management/config-routes.ts +835 -0
- package/src/server/management/context.ts +113 -0
- package/src/server/management/integration-routes.ts +498 -0
- package/src/server/management/lab-automation-routes.ts +206 -0
- package/src/server/management/lab-routes.ts +563 -0
- package/src/server/management/logs-usage-routes.ts +586 -0
- package/src/server/management/model-routes.ts +560 -0
- package/src/server/management/model-rows.ts +163 -0
- package/src/server/management/native-integration-routes.ts +769 -0
- package/src/server/management/oauth-account-routes.ts +637 -0
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +1033 -0
- package/src/server/management/replit-provider-routes.ts +86 -0
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/routing-analytics-routes.ts +74 -0
- package/src/server/management/routing-profile-routes.ts +385 -0
- package/src/server/management/shared.ts +286 -0
- package/src/server/management/sidebar-routes.ts +106 -0
- package/src/server/management/storage-log-guard-routes.ts +186 -0
- package/src/server/management/sync-response.ts +69 -0
- package/src/server/management/system-restart.ts +435 -0
- package/src/server/management/system-routes.ts +194 -0
- package/src/server/management/usage-summary-cache.ts +94 -0
- package/src/server/management/vision-sidecar-options.ts +167 -0
- package/src/server/management/web-search-sidecar-options.ts +120 -0
- package/src/server/management-api.ts +314 -0
- package/src/server/management-auth.ts +482 -0
- package/src/server/memory-watchdog.ts +156 -0
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/port-reclaim.ts +307 -0
- package/src/server/ports.ts +156 -0
- package/src/server/proxy-liveness.ts +328 -0
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +353 -0
- package/src/server/relay.ts +1209 -0
- package/src/server/request-decompress.ts +239 -0
- package/src/server/request-log-conversation.ts +168 -0
- package/src/server/request-log.ts +1259 -0
- package/src/server/responses/agent-task-recovery-cache.ts +143 -0
- package/src/server/responses/agent-task-recovery.ts +465 -0
- package/src/server/responses/collaboration.ts +551 -0
- package/src/server/responses/compact.ts +771 -0
- package/src/server/responses/core.ts +5389 -0
- package/src/server/responses/empty-completion-guard.ts +276 -0
- package/src/server/responses/encrypted-payload.ts +331 -0
- package/src/server/responses/fetch-helpers.ts +232 -0
- package/src/server/responses/input-admission.ts +185 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/passthrough-error.ts +78 -0
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +251 -0
- package/src/server/responses/terminal-guard.ts +251 -0
- package/src/server/responses/upstream-error.ts +53 -0
- package/src/server/responses/ws-upstream.ts +308 -0
- package/src/server/responses-custom-tool-repair.ts +282 -0
- package/src/server/responses-image-gen-repair.ts +132 -0
- package/src/server/responses-item-id-repair.ts +272 -0
- package/src/server/responses-json-events.ts +90 -0
- package/src/server/responses-model-rewrite.ts +29 -0
- package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
- package/src/server/responses-snapshot-repair.ts +621 -0
- package/src/server/responses-terminal-repair.ts +342 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +153 -0
- package/src/server/responses.ts +25 -0
- package/src/server/search.ts +201 -0
- package/src/server/sse-frame-buffer.ts +292 -0
- package/src/server/sse-payload-rewrite.ts +263 -0
- package/src/server/startup-action-control.ts +315 -0
- package/src/server/startup-health-cache.ts +131 -0
- package/src/server/system-env.ts +484 -0
- package/src/server/windows-tcp-drop.ts +184 -0
- package/src/server/windows-tray-control.ts +41 -0
- package/src/server/ws-bridge.ts +472 -0
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +3575 -0
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/stall-timeout.ts +20 -0
- package/src/storage/cleanup-job.ts +57 -0
- package/src/storage/cleanup.ts +3085 -0
- package/src/storage/policy-job.ts +457 -0
- package/src/storage/policy-scheduler.ts +40 -0
- package/src/storage/policy-worker.ts +59 -0
- package/src/storage/policy.ts +527 -0
- package/src/storage/restore-job.ts +299 -0
- package/src/storage/restore-worker.ts +58 -0
- package/src/storage/scanner.ts +238 -0
- package/src/storage/storage-mutation-coordinator.ts +139 -0
- package/src/storage/worker-lifecycle.ts +215 -0
- package/src/tray/assets/opencodex-tray-offline.ico +0 -0
- package/src/tray/assets/opencodex-tray-online.ico +0 -0
- package/src/tray/assets/opencodex-tray-warning.ico +0 -0
- package/src/tray/assets/opencodex-tray.png +0 -0
- package/src/tray/windows-tray.ps1 +364 -0
- package/src/tray/windows.ts +757 -0
- package/src/types/accounts.ts +37 -0
- package/src/types/config.ts +876 -0
- package/src/types/provider.ts +545 -0
- package/src/types/request.ts +384 -0
- package/src/types/tools.ts +131 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +106 -0
- package/src/update/badge.ts +72 -0
- package/src/update/index.ts +415 -0
- package/src/update/job.ts +1887 -0
- package/src/update/notify.ts +263 -0
- package/src/update/npm-cache-preflight.d.mts +47 -0
- package/src/update/npm-cache-preflight.mjs +201 -0
- package/src/update/npm-invocation.d.mts +23 -0
- package/src/update/npm-invocation.mjs +94 -0
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +259 -0
- package/src/update/tray-update-plan.d.mts +18 -0
- package/src/update/tray-update-plan.mjs +38 -0
- package/src/usage/cost.ts +625 -0
- package/src/usage/debug.ts +97 -0
- package/src/usage/expected-prices.ts +416 -0
- package/src/usage/log.ts +1223 -0
- package/src/usage/summary.ts +753 -0
- package/src/usage/totals.ts +14 -0
- package/src/usage/user-cost-overlay-reconciler.ts +313 -0
- package/src/usage/user-cost-overlays.ts +314 -0
- package/src/vision/anthropic-describe.ts +189 -0
- package/src/vision/backends.ts +97 -0
- package/src/vision/describe.ts +131 -0
- package/src/vision/eligibility.ts +250 -0
- package/src/vision/index.ts +681 -0
- package/src/vision/reasoning.ts +55 -0
- package/src/vision/routed-describe.ts +175 -0
- package/src/vision/timeout-bounds.ts +9 -0
- package/src/web-search/anthropic-executor.ts +195 -0
- package/src/web-search/backends.ts +108 -0
- package/src/web-search/exa-executor.ts +88 -0
- package/src/web-search/executor.ts +113 -0
- package/src/web-search/format-result.ts +89 -0
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +331 -0
- package/src/web-search/loop.ts +896 -0
- package/src/web-search/parse.ts +315 -0
- package/src/web-search/progress-stream.ts +342 -0
- package/src/web-search/sources.ts +60 -0
- package/src/web-search/synthetic-tool.ts +47 -0
- package/src/web-search/xai-executor.ts +219 -0
|
@@ -0,0 +1,735 @@
|
|
|
1
|
+
import { create, fromJson, toBinary, type JsonValue } from "@bufbuild/protobuf";
|
|
2
|
+
import { ValueSchema } from "@bufbuild/protobuf/wkt";
|
|
3
|
+
import type { OcxRequestOptions, OcxTool } from "../../types";
|
|
4
|
+
import { namespacedToolName, toolChoiceAliases } from "../../types";
|
|
5
|
+
import { McpToolDefinitionSchema, McpToolsSchema, type McpToolDefinition } from "./gen/agent_pb";
|
|
6
|
+
|
|
7
|
+
export const OCX_RESPONSES_TOOL_PROVIDER = "opencodex-responses";
|
|
8
|
+
export const CODEX_EXEC_COMMAND_TOOL = "exec_command";
|
|
9
|
+
export const CODEX_SHELL_COMMAND_TOOL = "shell_command";
|
|
10
|
+
/** Codex Desktop unified-exec client tool. Companion of `wait`; not an `exec_command` schema alias. */
|
|
11
|
+
export const CODEX_UNIFIED_EXEC_TOOL = "exec";
|
|
12
|
+
export const CODEX_WAIT_TOOL = "wait";
|
|
13
|
+
export const CODEX_APPLY_PATCH_TOOL = "apply_patch";
|
|
14
|
+
export const CURSOR_EDIT_FILE_TOOL = "edit_file";
|
|
15
|
+
export const CURSOR_MULTI_EDIT_TOOL = "multi_edit";
|
|
16
|
+
export const CURSOR_STRUCTURED_EDIT_TOOLS = [CURSOR_EDIT_FILE_TOOL, CURSOR_MULTI_EDIT_TOOL] as const;
|
|
17
|
+
export const CURSOR_EXEC_COMMAND_TOOL = CODEX_EXEC_COMMAND_TOOL;
|
|
18
|
+
export const CODEX_SHELL_BRIDGE_TOOL_NAMES = [CODEX_EXEC_COMMAND_TOOL, CODEX_SHELL_COMMAND_TOOL] as const;
|
|
19
|
+
export const CURSOR_SHELL_ALIAS_SYSTEM_NOTE =
|
|
20
|
+
'Shell commands use the Codex shell bridge tool shown in this turn\'s catalog (`shell_command` or `exec_command`) with JSON arguments like {"cmd":"..."}. The long `mcp_opencodex-responses_*` display name is the same tool. Prefer it over Cursor-native Shell.';
|
|
21
|
+
const NEIGHBOR_AGENT_TOOL_NAMES = ["Read", "Grep", "Glob", "Bash", "LS"] as const;
|
|
22
|
+
const NEIGHBOR_AGENT_TOOL_ALIASES: Record<(typeof NEIGHBOR_AGENT_TOOL_NAMES)[number], readonly string[]> = {
|
|
23
|
+
Read: ["read", "read_file"],
|
|
24
|
+
Grep: ["grep"],
|
|
25
|
+
Glob: ["glob", "find"],
|
|
26
|
+
Bash: ["bash", "shell"],
|
|
27
|
+
LS: ["ls"],
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const CURSOR_GENERIC_TOOL_USE_USER_HINT = [
|
|
31
|
+
"For generic tool-use/count demos, satisfy the request with repeated Codex shell bridge calls (`shell_command` or `exec_command`) for harmless commands.",
|
|
32
|
+
"`shell_command` / `exec_command` are the Codex Responses shell bridge exposed through Cursor's tool protocol; do not describe them as an external MCP server tool.",
|
|
33
|
+
"Do not use `run_shell` unless this turn's tool catalog lists it.",
|
|
34
|
+
"A request for N tools means N separate shell-bridge invocations/results; never satisfy it with one chained shell command such as `cmd1 && cmd2`.",
|
|
35
|
+
"For independent read-only or output-only commands, emit all requested shell-bridge calls in the same response before waiting when the runtime supports parallel tool calls.",
|
|
36
|
+
"The Cursor bridge may suspend after the first returned bridge tool call, so emit sibling calls together before any result is needed.",
|
|
37
|
+
"If parallel emission is unavailable, continue with separate shell-bridge calls until the requested count has returned.",
|
|
38
|
+
"Do not use `tool_search`, external MCP, or resource discovery just to pad the count unless explicitly asked.",
|
|
39
|
+
"Do not suggest or switch to neighboring-agent tools such as `Grep`, `Read`, `Glob`, `Bash`, or `LS` unless this turn's catalog lists those exact names or an equivalent listed client tool.",
|
|
40
|
+
].join(" ");
|
|
41
|
+
|
|
42
|
+
export const CURSOR_EXEC_COMMAND_INPUT_SCHEMA = {
|
|
43
|
+
type: "object",
|
|
44
|
+
properties: {
|
|
45
|
+
cmd: { type: "string", description: "Shell command to execute." },
|
|
46
|
+
workdir: { type: "string", description: "Working directory for the command. Defaults to the turn cwd." },
|
|
47
|
+
shell: { type: "string", description: "Shell binary to launch. Defaults to the user's default shell." },
|
|
48
|
+
tty: { type: "boolean", description: "True allocates a PTY for the command; false or omitted uses plain pipes." },
|
|
49
|
+
yield_time_ms: { type: "number", description: "Wait before yielding output. Defaults to 10000 ms; effective range is 250-30000 ms." },
|
|
50
|
+
max_output_tokens: { type: "number", description: "Output token budget. Defaults to 10000 tokens; larger requests may be capped by policy." },
|
|
51
|
+
},
|
|
52
|
+
required: ["cmd"],
|
|
53
|
+
additionalProperties: false,
|
|
54
|
+
} as const;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Structured single-replacement schema advertised to Cursor models in addition to the freeform
|
|
58
|
+
* `apply_patch` tool. Cursor-trained models reliably emit exact-match replacements (the native
|
|
59
|
+
* Edit shape) but cannot produce Codex's freeform patch grammar, so every file edit attempt on the
|
|
60
|
+
* Cursor route produced malformed `apply_patch` payloads that the Codex client rejected locally
|
|
61
|
+
* (#1017). Calls to this tool are converted server-side into a valid apply_patch payload.
|
|
62
|
+
*/
|
|
63
|
+
export const CURSOR_EDIT_FILE_INPUT_SCHEMA = {
|
|
64
|
+
type: "object",
|
|
65
|
+
properties: {
|
|
66
|
+
file_path: { type: "string", description: "Path of the file to edit, relative to the workspace root." },
|
|
67
|
+
old_string: { type: "string", description: "Exact text to replace. Must match the current file content, including line breaks." },
|
|
68
|
+
new_string: { type: "string", description: "Replacement text. Empty removes the matched text." },
|
|
69
|
+
},
|
|
70
|
+
required: ["file_path", "old_string", "new_string"],
|
|
71
|
+
additionalProperties: false,
|
|
72
|
+
} as const;
|
|
73
|
+
|
|
74
|
+
/** Structured multi-replacement schema; mirrors Cursor's native MultiEdit shape. */
|
|
75
|
+
export const CURSOR_MULTI_EDIT_INPUT_SCHEMA = {
|
|
76
|
+
type: "object",
|
|
77
|
+
properties: {
|
|
78
|
+
file_path: { type: "string", description: "Path of the file to edit, relative to the workspace root." },
|
|
79
|
+
edits: {
|
|
80
|
+
type: "array",
|
|
81
|
+
items: {
|
|
82
|
+
type: "object",
|
|
83
|
+
properties: {
|
|
84
|
+
old_string: { type: "string", description: "Exact text to replace. Must match the current file content, including line breaks." },
|
|
85
|
+
new_string: { type: "string", description: "Replacement text. Empty removes the matched text." },
|
|
86
|
+
},
|
|
87
|
+
required: ["old_string", "new_string"],
|
|
88
|
+
additionalProperties: false,
|
|
89
|
+
},
|
|
90
|
+
description: "Ordered replacement edits for this file. Each old_string must match the current file content.",
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
required: ["file_path", "edits"],
|
|
94
|
+
additionalProperties: false,
|
|
95
|
+
} as const;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Responses/Codex-side schema used ONLY for arg-key normalization after Cursor returns a call.
|
|
99
|
+
* Cursor models are trained to emit `cmd`; Codex `shell_command` / `exec_command` validate
|
|
100
|
+
* `command`. Keeping `cmd` out of this schema lets `normalizeArgKeys` rewrite `cmd` → `command`.
|
|
101
|
+
*/
|
|
102
|
+
export const CODEX_SHELL_BRIDGE_ARG_NORMALIZE_SCHEMA = {
|
|
103
|
+
type: "object",
|
|
104
|
+
properties: {
|
|
105
|
+
command: { type: "string", description: "Shell command to execute." },
|
|
106
|
+
workdir: { type: "string", description: "Working directory for the command. Defaults to the turn cwd." },
|
|
107
|
+
shell: { type: "string", description: "Shell binary to launch. Defaults to the user's default shell." },
|
|
108
|
+
tty: { type: "boolean", description: "True allocates a PTY for the command; false or omitted uses plain pipes." },
|
|
109
|
+
yield_time_ms: { type: "number", description: "Wait before yielding output. Defaults to 10000 ms; effective range is 250-30000 ms." },
|
|
110
|
+
max_output_tokens: { type: "number", description: "Output token budget. Defaults to 10000 tokens; larger requests may be capped by policy." },
|
|
111
|
+
max_output_chars: { type: "number", description: "Output character budget when the Responses tool uses chars instead of tokens." },
|
|
112
|
+
},
|
|
113
|
+
required: ["command"],
|
|
114
|
+
} as const;
|
|
115
|
+
|
|
116
|
+
export function isCodexShellBridgeToolName(name: string): boolean {
|
|
117
|
+
return (CODEX_SHELL_BRIDGE_TOOL_NAMES as readonly string[]).includes(name);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Direct key lookup, then shell_command/exec_command sibling aliases when the key is a bridge name.
|
|
122
|
+
* Used for catalog admission, schema normalize maps, and Responses name maps (#399).
|
|
123
|
+
*/
|
|
124
|
+
export function resolveShellBridgeAliasKey<T>(
|
|
125
|
+
key: string,
|
|
126
|
+
lookup: (name: string) => T | undefined,
|
|
127
|
+
): T | undefined {
|
|
128
|
+
const direct = lookup(key);
|
|
129
|
+
if (direct !== undefined) return direct;
|
|
130
|
+
if (!isCodexShellBridgeToolName(key)) return undefined;
|
|
131
|
+
for (const alias of CODEX_SHELL_BRIDGE_TOOL_NAMES) {
|
|
132
|
+
if (alias === key) continue;
|
|
133
|
+
const hit = lookup(alias);
|
|
134
|
+
if (hit !== undefined) return hit;
|
|
135
|
+
}
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export function cursorToolChoiceAliases(tool: Pick<OcxTool, "namespace" | "name">): string[] {
|
|
140
|
+
const aliases = new Set(toolChoiceAliases(tool));
|
|
141
|
+
if (isBareCodexShellBridgeTool(tool)) {
|
|
142
|
+
for (const alias of CODEX_SHELL_BRIDGE_TOOL_NAMES) aliases.add(alias);
|
|
143
|
+
}
|
|
144
|
+
return [...aliases];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function catalogHasBareCodexShellBridge(
|
|
148
|
+
catalog: readonly Pick<OcxTool, "namespace" | "name">[],
|
|
149
|
+
): boolean {
|
|
150
|
+
return catalog.some(isBareCodexShellBridgeTool);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Catalog-aware tool_choice matching for Cursor.
|
|
155
|
+
* When a bare Codex shell bridge is in the catalog, raw `shell_command` / `exec_command`
|
|
156
|
+
* choices select only that bridge (never a namespaced remote with the same raw name).
|
|
157
|
+
* When no bare bridge exists, raw bridge names may select a namespaced tool by raw name.
|
|
158
|
+
* Explicit wire names (`mcp__remote__exec_command`) always match the namespaced tool.
|
|
159
|
+
*/
|
|
160
|
+
function cursorToolChoiceMatches(
|
|
161
|
+
tool: Pick<OcxTool, "namespace" | "name">,
|
|
162
|
+
choiceName: string,
|
|
163
|
+
catalog: readonly Pick<OcxTool, "namespace" | "name">[],
|
|
164
|
+
): boolean {
|
|
165
|
+
if (isCodexShellBridgeToolName(choiceName)) {
|
|
166
|
+
if (catalogHasBareCodexShellBridge(catalog)) {
|
|
167
|
+
return isBareCodexShellBridgeTool(tool);
|
|
168
|
+
}
|
|
169
|
+
return tool.name === choiceName || cursorToolWireName(tool) === choiceName;
|
|
170
|
+
}
|
|
171
|
+
if (tool.name === choiceName || cursorToolWireName(tool) === choiceName) return true;
|
|
172
|
+
return cursorToolChoiceAliases(tool).includes(choiceName);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export function isBareCodexShellBridgeTool(tool: Pick<OcxTool, "namespace" | "name">): boolean {
|
|
176
|
+
return !tool.namespace && isCodexShellBridgeToolName(tool.name);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function isCursorResponsesProvider(namespace: string | undefined): boolean {
|
|
180
|
+
return !namespace || namespace === OCX_RESPONSES_TOOL_PROVIDER;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const CURSOR_EXECUTION_PATH_TOOL_NAMES = [
|
|
184
|
+
CODEX_UNIFIED_EXEC_TOOL,
|
|
185
|
+
CODEX_EXEC_COMMAND_TOOL,
|
|
186
|
+
CODEX_SHELL_COMMAND_TOOL,
|
|
187
|
+
] as const;
|
|
188
|
+
|
|
189
|
+
/** True for the Codex execution path that must survive Cursor transport truncation. */
|
|
190
|
+
export function isCursorExecutionPathTool(tool: Pick<OcxTool, "namespace" | "name">): boolean {
|
|
191
|
+
return isCursorResponsesProvider(tool.namespace)
|
|
192
|
+
&& (CURSOR_EXECUTION_PATH_TOOL_NAMES as readonly string[]).includes(tool.name);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** `wait` only resumes a yielded exec cell; it is unusable without an execution-path tool. */
|
|
196
|
+
export function isCursorWaitTool(tool: Pick<OcxTool, "namespace" | "name">): boolean {
|
|
197
|
+
return isCursorResponsesProvider(tool.namespace) && tool.name === CODEX_WAIT_TOOL;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* True for Codex's unified-exec "code mode" tool: a freeform `exec` whose body is JavaScript
|
|
202
|
+
* evaluated in a V8 isolate, not a shell command string.
|
|
203
|
+
*/
|
|
204
|
+
export function isCursorCodeModeExecTool(
|
|
205
|
+
tool: Pick<OcxTool, "namespace" | "name" | "freeform">,
|
|
206
|
+
): boolean {
|
|
207
|
+
return isCursorResponsesProvider(tool.namespace)
|
|
208
|
+
&& tool.name === CODEX_UNIFIED_EXEC_TOOL
|
|
209
|
+
&& tool.freeform === true;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Codex code mode advertises ONE freeform `exec` tool and no bare shell bridge. Shell, file
|
|
214
|
+
* edits, and MCP calls are reachable only as nested `tools.<name>(...)` helpers described inside
|
|
215
|
+
* that tool's own description, so a flat catalog scan cannot see them.
|
|
216
|
+
*
|
|
217
|
+
* This matters because the shell-bridge guidance below is written for a flat catalog. Emitting
|
|
218
|
+
* "call \`exec_command\`" into a code-mode turn names a top-level tool that does not exist: the
|
|
219
|
+
* model calls it, gets nothing back, and burns turns rediscovering the real contract from error
|
|
220
|
+
* messages (empty output until \`text()\` is called, \`require is not defined\` because the isolate
|
|
221
|
+
* is not Node, \`apply_patch\` rejected because it too is only a nested helper here).
|
|
222
|
+
*/
|
|
223
|
+
export function cursorRequestUsesCodeMode(
|
|
224
|
+
tools: readonly Pick<OcxTool, "namespace" | "name" | "freeform">[] | undefined,
|
|
225
|
+
toolChoice?: OcxRequestOptions["toolChoice"],
|
|
226
|
+
): boolean {
|
|
227
|
+
const catalog = tools ?? [];
|
|
228
|
+
const visible = catalog.filter(tool => cursorToolAllowedByChoice(tool, toolChoice, catalog));
|
|
229
|
+
return visible.some(isCursorCodeModeExecTool) && !visible.some(isBareCodexShellBridgeTool);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** @deprecated Prefer isBareCodexShellBridgeTool; kept for older call sites/tests. */
|
|
233
|
+
function isBareCodexExecCommandTool(tool: Pick<OcxTool, "namespace" | "name">): boolean {
|
|
234
|
+
return isBareCodexShellBridgeTool(tool);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export function cursorRequestHasShellAlias(tools: readonly Pick<OcxTool, "namespace" | "name">[] | undefined): boolean {
|
|
238
|
+
return tools?.some(isBareCodexExecCommandTool) ?? false;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function cursorRequestHasExecutionPath(
|
|
242
|
+
tools: readonly Pick<OcxTool, "namespace" | "name">[] | undefined,
|
|
243
|
+
): boolean {
|
|
244
|
+
return tools?.some(isCursorExecutionPathTool) ?? false;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export function cursorRequestAdvertisesApplyPatch(
|
|
248
|
+
tools: readonly Pick<OcxTool, "namespace" | "name" | "freeform">[] | undefined,
|
|
249
|
+
toolChoice?: OcxRequestOptions["toolChoice"],
|
|
250
|
+
): boolean {
|
|
251
|
+
const catalog = tools ?? [];
|
|
252
|
+
return catalog.some(tool => !tool.namespace && tool.name === CODEX_APPLY_PATCH_TOOL && tool.freeform === true && cursorToolAllowedByChoice(tool, toolChoice, catalog));
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export function isCursorStructuredEditToolName(name: string): boolean {
|
|
256
|
+
return (CURSOR_STRUCTURED_EDIT_TOOLS as readonly string[]).includes(name);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** Internal provenance gate for synthetic edits after prompt filtering and catalog budgeting. */
|
|
260
|
+
export function isCursorSyntheticStructuredEditTool(
|
|
261
|
+
tool: Pick<OcxTool, "namespace" | "name" | "cursorStructuredEdit">,
|
|
262
|
+
): boolean {
|
|
263
|
+
return !tool.namespace && tool.cursorStructuredEdit === true && isCursorStructuredEditToolName(tool.name);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Synthetic structured edit tools for the Cursor route (#1017).
|
|
268
|
+
*
|
|
269
|
+
* Codex exposes `apply_patch` as a freeform custom tool whose body must be the exact Codex patch
|
|
270
|
+
* grammar (`*** Begin Patch` envelope, `@@` hunks, `-`/`+` prefixes). Cursor-trained models are
|
|
271
|
+
* trained on exact-match edit tools instead and emit malformed patch text on every attempt, which
|
|
272
|
+
* the Codex client then rejects locally ("invalid hunk"). When the request advertises the freeform
|
|
273
|
+
* `apply_patch` tool, also advertise Cursor-native-shaped `edit_file` / `multi_edit` tools; the
|
|
274
|
+
* adapter converts their exact-match replacements into a valid apply_patch payload (see
|
|
275
|
+
* protobuf-events.translateStructuredEditCall).
|
|
276
|
+
*
|
|
277
|
+
* Never widened when the caller pinned an explicit tool choice: a forced `apply_patch` selection
|
|
278
|
+
* must not gain sibling tools the client did not ask for.
|
|
279
|
+
*/
|
|
280
|
+
export function cursorStructuredEditTools(
|
|
281
|
+
tools: readonly Pick<OcxTool, "namespace" | "name" | "freeform">[] | undefined,
|
|
282
|
+
toolChoice?: OcxRequestOptions["toolChoice"],
|
|
283
|
+
): OcxTool[] {
|
|
284
|
+
if (!cursorRequestAdvertisesApplyPatch(tools, toolChoice)) return [];
|
|
285
|
+
if (toolChoice && toolChoice !== "auto" && toolChoice !== "required") return [];
|
|
286
|
+
// Never shadow an already-advertised bare tool with the same name (a client catalog could
|
|
287
|
+
// legitimately expose its own `edit_file` / `multi_edit` MCP-style tools).
|
|
288
|
+
const existingBareNames = new Set(
|
|
289
|
+
(tools ?? []).filter(tool => !tool.namespace).map(tool => tool.name),
|
|
290
|
+
);
|
|
291
|
+
const candidates: OcxTool[] = [
|
|
292
|
+
{
|
|
293
|
+
name: CURSOR_EDIT_FILE_TOOL,
|
|
294
|
+
cursorStructuredEdit: true,
|
|
295
|
+
description:
|
|
296
|
+
"Replace one block of text in a file. OpenCodex converts the replacement into a Codex apply_patch change. Copy old_string and new_string with their exact leading whitespace — Codex may locate a line after trimming indent, but it writes new_string verbatim, so stripped indent silently corrupts the file. An empty old_string with a non-empty new_string creates a new file (Add File). If the same text appears more than once, the first match is updated. Matching is line-based, so an edit cannot add or remove only the file's final newline, and old_string/new_string that are identical after line normalization are rejected as a no-op.",
|
|
297
|
+
parameters: { ...CURSOR_EDIT_FILE_INPUT_SCHEMA },
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
name: CURSOR_MULTI_EDIT_TOOL,
|
|
301
|
+
cursorStructuredEdit: true,
|
|
302
|
+
description:
|
|
303
|
+
"Apply several text replacements to one file. OpenCodex converts them into one Codex apply_patch change. Copy each old_string/new_string with exact leading whitespace. If a later edit's old_string is the text after an earlier replacement, OpenCodex folds those edits into one original-file hunk. Independent edits stay separate hunks. An empty old_string with a non-empty new_string creates a new file (Add File); do not mix that with an independent Update on the same path. If the same text appears more than once, the first match is updated. Matching is line-based, so an edit cannot add or remove only the file's final newline, and identical old/new after line normalization are rejected as a no-op.",
|
|
304
|
+
parameters: { ...CURSOR_MULTI_EDIT_INPUT_SCHEMA },
|
|
305
|
+
},
|
|
306
|
+
];
|
|
307
|
+
return candidates.filter(tool => !existingBareNames.has(tool.name));
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* True when this request actually advertises the synthetic structured edit tools (`edit_file` /
|
|
312
|
+
* `multi_edit`) — i.e. a freeform `apply_patch` is advertised, no tool-choice pin blocks widening,
|
|
313
|
+
* and neither name is shadowed by an existing bare tool in the client catalog.
|
|
314
|
+
*/
|
|
315
|
+
export function cursorRequestAdvertisesStructuredEdits(
|
|
316
|
+
tools: readonly Pick<OcxTool, "namespace" | "name" | "freeform">[] | undefined,
|
|
317
|
+
toolChoice?: OcxRequestOptions["toolChoice"],
|
|
318
|
+
): boolean {
|
|
319
|
+
return cursorStructuredEditTools(tools, toolChoice).length > 0;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
export function cursorToolWireName(tool: Pick<OcxTool, "namespace" | "name">): string {
|
|
323
|
+
return namespacedToolName(tool.namespace, tool.name);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Cursor's harness shows MCP tools to the model as `mcp_<providerIdentifier>_<toolName>`; models
|
|
328
|
+
* sometimes call that display name verbatim instead of the advertised short name (live 20:41/21:00
|
|
329
|
+
* sessions: `mcp_opencodex-responses_exec_command` / `mcp_opencodex-responses_shell_command`).
|
|
330
|
+
* Fold the display prefix back to the advertised wire name, and treat `shell_command` /
|
|
331
|
+
* `exec_command` as the same Codex shell bridge, so alias thrash does not become "tool not found".
|
|
332
|
+
*/
|
|
333
|
+
const CURSOR_MCP_DISPLAY_PREFIX = `mcp_${OCX_RESPONSES_TOOL_PROVIDER}_`;
|
|
334
|
+
|
|
335
|
+
export function normalizeCursorWireName(name: string): string {
|
|
336
|
+
return name.startsWith(CURSOR_MCP_DISPLAY_PREFIX) ? name.slice(CURSOR_MCP_DISPLAY_PREFIX.length) : name;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* #2305: some models emit a TEXTUAL pseudo tool call ("[TOOL_CALL]name[ARGS]{...}")
|
|
341
|
+
* instead of a real frame, using Cursor's display alias as the name. Text-mode clients
|
|
342
|
+
* (Pi) parse that text and then cannot dispatch the undeclared display name. Rewrite the
|
|
343
|
+
* display alias to the advertised wire name ONLY inside the marker pair — prose that
|
|
344
|
+
* merely mentions the alias stays untouched, and the scope guard is the exact
|
|
345
|
+
* `mcp_${OCX_RESPONSES_TOOL_PROVIDER}_` prefix, never generic `mcp_`.
|
|
346
|
+
* Known limit (recorded in devlog 230): a marker split across two streaming deltas is
|
|
347
|
+
* not rewritten; tail-buffering is deferred until a live trace shows split markers.
|
|
348
|
+
*/
|
|
349
|
+
const CURSOR_TEXT_TOOL_MARKER = new RegExp(
|
|
350
|
+
String.raw`\[TOOL_CALL\](${CURSOR_MCP_DISPLAY_PREFIX.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[^\[\]]+)\[ARGS\]`,
|
|
351
|
+
"g",
|
|
352
|
+
);
|
|
353
|
+
|
|
354
|
+
export function normalizeCursorTextToolMarkers(text: string): string {
|
|
355
|
+
if (!text.includes(CURSOR_MCP_DISPLAY_PREFIX)) return text;
|
|
356
|
+
return text.replace(CURSOR_TEXT_TOOL_MARKER, (_match, name: string) => `[TOOL_CALL]${normalizeCursorWireName(name)}[ARGS]`);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export function responsesToolNameFromCursorWire(name: string, cursorToolNameMap?: ReadonlyMap<string, string>): string {
|
|
360
|
+
const normalized = normalizeCursorWireName(name);
|
|
361
|
+
if (!cursorToolNameMap) return normalized;
|
|
362
|
+
return resolveShellBridgeAliasKey(normalized, alias => cursorToolNameMap.get(alias)) ?? normalized;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/** Schema advertised to Cursor for this tool (may use Cursor-preferred field names like `cmd`). */
|
|
366
|
+
export function cursorToolInputSchema(tool: OcxTool): unknown {
|
|
367
|
+
return isBareCodexExecCommandTool(tool) ? CURSOR_EXEC_COMMAND_INPUT_SCHEMA : (tool.parameters ?? {});
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Schema used to normalize completed Cursor tool args back to Responses/Codex field names.
|
|
372
|
+
* Must NOT reuse `cursorToolInputSchema` for the shell bridge: advertising `cmd` while also
|
|
373
|
+
* treating `cmd` as canonical prevents the `cmd` → `command` rewrite Codex requires (#399).
|
|
374
|
+
*/
|
|
375
|
+
export function cursorToolArgNormalizeSchema(tool: OcxTool): unknown {
|
|
376
|
+
if (isBareCodexShellBridgeTool(tool)) {
|
|
377
|
+
return shellBridgeArgNormalizeSchema(tool);
|
|
378
|
+
}
|
|
379
|
+
return tool.parameters ?? {};
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
function shellBridgeArgNormalizeSchema(tool: OcxTool): unknown {
|
|
383
|
+
const parameters = tool.parameters;
|
|
384
|
+
if (!parameters || typeof parameters !== "object") return CODEX_SHELL_BRIDGE_ARG_NORMALIZE_SCHEMA;
|
|
385
|
+
const base = parameters as Record<string, unknown>;
|
|
386
|
+
const rawProps = base.properties && typeof base.properties === "object"
|
|
387
|
+
? { ...(base.properties as Record<string, unknown>) }
|
|
388
|
+
: {};
|
|
389
|
+
const required = Array.isArray(base.required) ? [...base.required as unknown[]] : [];
|
|
390
|
+
const requiresCommand = required.includes("command") || "command" in rawProps;
|
|
391
|
+
const requiresCmd = required.includes("cmd") || "cmd" in rawProps;
|
|
392
|
+
const shouldRewriteCmdToCommand = tool.name === CODEX_SHELL_COMMAND_TOOL || requiresCommand;
|
|
393
|
+
|
|
394
|
+
if (!shouldRewriteCmdToCommand && requiresCmd) {
|
|
395
|
+
return parameters;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// Drop Cursor-preferred aliases so normalizeArgKeys can rewrite them to Responses keys.
|
|
399
|
+
delete rawProps.cmd;
|
|
400
|
+
const properties = {
|
|
401
|
+
...CODEX_SHELL_BRIDGE_ARG_NORMALIZE_SCHEMA.properties,
|
|
402
|
+
...rawProps,
|
|
403
|
+
command: rawProps.command ?? CODEX_SHELL_BRIDGE_ARG_NORMALIZE_SCHEMA.properties.command,
|
|
404
|
+
};
|
|
405
|
+
return {
|
|
406
|
+
...base,
|
|
407
|
+
type: "object",
|
|
408
|
+
properties,
|
|
409
|
+
required: requiresCommand ? required : ["command"],
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
export function isGenericToolUseCountDemoPrompt(text: string): boolean {
|
|
414
|
+
const trimmed = text.trim();
|
|
415
|
+
if (trimmed.length === 0) return false;
|
|
416
|
+
return [
|
|
417
|
+
/\b(?:use|call|invoke|try|exercise)\s+(?:any\s+)?\d+\s+tools?\b/i,
|
|
418
|
+
/\buse\s+any\s+tools?\b/i,
|
|
419
|
+
/\bactually\s+(?:call|use|invoke)\s+(?:the\s+)?tools?\b/i,
|
|
420
|
+
/\b\d+\s+tools?\b/i,
|
|
421
|
+
/\btools?\s+\d+\b/i,
|
|
422
|
+
/\btool\s+use\b/i,
|
|
423
|
+
/아무\s*(?:tool|tools?|도구|툴)/i,
|
|
424
|
+
/(?:tool|tools?|도구|툴)\s*\d+\s*(?:개|번)?/i,
|
|
425
|
+
/\d+\s*(?:개|번)?\s*(?:tool|tools?|도구|툴)/i,
|
|
426
|
+
/(?:도구|툴).{0,12}(?:써|사용|호출).{0,12}\d+\s*(?:개|번)?/i,
|
|
427
|
+
].some(pattern => pattern.test(trimmed));
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
export function requestedCursorToolUseCount(text: string): number | undefined {
|
|
431
|
+
const patterns = [
|
|
432
|
+
/\b(?:use|call|invoke|try|exercise)\s+(?:any\s+)?(\d+)\s+tools?\b/i,
|
|
433
|
+
/\b(\d+)\s+tools?\b/i,
|
|
434
|
+
/\btools?\s+(\d+)\b/i,
|
|
435
|
+
/(?:tool|tools?|도구|툴)\s*(\d+)\s*(?:개|번)?/i,
|
|
436
|
+
/(\d+)\s*(?:개|번)?\s*(?:tool|tools?|도구|툴)/i,
|
|
437
|
+
/(?:도구|툴).{0,12}(?:써|사용|호출).{0,12}(\d+)\s*(?:개|번)?/i,
|
|
438
|
+
];
|
|
439
|
+
for (const pattern of patterns) {
|
|
440
|
+
const match = pattern.exec(text);
|
|
441
|
+
const count = Number(match?.[1]);
|
|
442
|
+
if (Number.isInteger(count) && count > 0 && count <= 50) return count;
|
|
443
|
+
}
|
|
444
|
+
return undefined;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
function cursorGenericToolUseHint(text: string): string {
|
|
448
|
+
const count = requestedCursorToolUseCount(text);
|
|
449
|
+
if (!count) return CURSOR_GENERIC_TOOL_USE_USER_HINT;
|
|
450
|
+
return [
|
|
451
|
+
`This turn requests ${count} tool uses: emit exactly ${count} separate Codex shell bridge function calls/results (\`shell_command\` or \`exec_command\`).`,
|
|
452
|
+
`One shell-bridge call containing chained commands counts as 1 tool call, not ${count}.`,
|
|
453
|
+
`Prefer one parallel tool-call batch containing all ${count} independent shell-bridge calls before waiting for results.`,
|
|
454
|
+
CURSOR_GENERIC_TOOL_USE_USER_HINT,
|
|
455
|
+
].join(" ");
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
function activeTextMentionsGenericToolUseHint(text: string): boolean {
|
|
459
|
+
return text.includes("Codex native exec tool")
|
|
460
|
+
|| text.includes("Codex Responses bridge exec tool")
|
|
461
|
+
|| text.includes("generic tool-use/count demos");
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
export function shouldAppendCursorGenericToolUseHint(
|
|
465
|
+
tools: readonly Pick<OcxTool, "namespace" | "name">[] | undefined,
|
|
466
|
+
text: string,
|
|
467
|
+
): boolean {
|
|
468
|
+
const trimmed = text.trim();
|
|
469
|
+
return trimmed.length > 0
|
|
470
|
+
&& cursorRequestHasShellAlias(tools)
|
|
471
|
+
&& isGenericToolUseCountDemoPrompt(trimmed)
|
|
472
|
+
&& !activeTextMentionsGenericToolUseHint(trimmed);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
export function appendCursorGenericToolUseHint(
|
|
476
|
+
tools: readonly Pick<OcxTool, "namespace" | "name">[] | undefined,
|
|
477
|
+
text: string,
|
|
478
|
+
): string {
|
|
479
|
+
if (!shouldAppendCursorGenericToolUseHint(tools, text)) return text;
|
|
480
|
+
return `${text}${text.endsWith("\n") ? "\n" : "\n\n"}${cursorGenericToolUseHint(text)}`;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
export function shouldUseNativeExecOnlyForGenericToolUse(
|
|
484
|
+
tools: readonly Pick<OcxTool, "namespace" | "name">[] | undefined,
|
|
485
|
+
text: string,
|
|
486
|
+
): boolean {
|
|
487
|
+
const trimmed = text.trim();
|
|
488
|
+
if (trimmed.length === 0 || !cursorRequestHasExecutionPath(tools) || !isGenericToolUseCountDemoPrompt(trimmed)) return false;
|
|
489
|
+
return !/\b(?:mcp|resource|resources|tool_search|plugin|plugins|app connector|github)\b/i.test(trimmed)
|
|
490
|
+
&& !/(?:리소스|플러그인|깃허브|github)/i.test(trimmed);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
export function cursorToolsForActivePrompt<T extends Pick<OcxTool, "namespace" | "name">>(
|
|
494
|
+
tools: readonly T[] | undefined,
|
|
495
|
+
activeText: string,
|
|
496
|
+
toolChoice?: OcxRequestOptions["toolChoice"],
|
|
497
|
+
): readonly T[] | undefined {
|
|
498
|
+
if (!shouldUseNativeExecOnlyForGenericToolUse(tools, activeText)) return tools;
|
|
499
|
+
const execTools = tools?.filter(isCursorExecutionPathTool);
|
|
500
|
+
const catalog = tools ?? [];
|
|
501
|
+
if (execTools?.length && !execTools.some(tool => cursorToolAllowedByChoice(tool, toolChoice, catalog))) return tools;
|
|
502
|
+
return execTools && execTools.length > 0 ? execTools : tools;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Required command payload keys for a shell bridge tool, derived from the advertised schema when present.
|
|
507
|
+
*/
|
|
508
|
+
export function shellBridgeRequiredCommandKeys(
|
|
509
|
+
toolName: string,
|
|
510
|
+
schema?: unknown,
|
|
511
|
+
): readonly ("cmd" | "command")[] {
|
|
512
|
+
if (schema && typeof schema === "object") {
|
|
513
|
+
const required = (schema as Record<string, unknown>).required;
|
|
514
|
+
if (Array.isArray(required)) {
|
|
515
|
+
const keys = required.filter((key): key is "cmd" | "command" => key === "cmd" || key === "command");
|
|
516
|
+
if (keys.length > 0) return keys;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
return toolName === CODEX_SHELL_COMMAND_TOOL ? ["command"] : ["cmd"];
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/** Normalize-schema defaults used when validating stateless synthetic shell-bridge calls. */
|
|
523
|
+
export function defaultShellBridgeArgNormalizeSchema(toolName: string): unknown {
|
|
524
|
+
return toolName === CODEX_SHELL_COMMAND_TOOL
|
|
525
|
+
? CODEX_SHELL_BRIDGE_ARG_NORMALIZE_SCHEMA
|
|
526
|
+
: {
|
|
527
|
+
type: "object",
|
|
528
|
+
properties: CURSOR_EXEC_COMMAND_INPUT_SCHEMA.properties,
|
|
529
|
+
required: ["cmd"],
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
export function cursorShellBridgeDropError(toolName: string): string {
|
|
534
|
+
return `Cursor emitted ${toolName} without a non-empty command; the tool call was dropped.`;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Extract a non-empty shell command from completed Cursor bridge args using the schema's required
|
|
539
|
+
* command key (`cmd` for bare exec_command, `command` for shell_command).
|
|
540
|
+
*/
|
|
541
|
+
export function nonEmptyShellBridgeCommandFromArgs(
|
|
542
|
+
finalArgs: string,
|
|
543
|
+
toolName: string,
|
|
544
|
+
schema?: unknown,
|
|
545
|
+
): string | undefined {
|
|
546
|
+
let parsed: unknown;
|
|
547
|
+
try {
|
|
548
|
+
parsed = finalArgs.length > 0 ? JSON.parse(finalArgs) : {};
|
|
549
|
+
} catch {
|
|
550
|
+
return undefined;
|
|
551
|
+
}
|
|
552
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return undefined;
|
|
553
|
+
const record = parsed as Record<string, unknown>;
|
|
554
|
+
const requiredKeys = shellBridgeRequiredCommandKeys(toolName, schema);
|
|
555
|
+
const candidateKeys = new Set<"cmd" | "command">([
|
|
556
|
+
...requiredKeys,
|
|
557
|
+
requiredKeys.includes("cmd") ? "command" : "cmd",
|
|
558
|
+
]);
|
|
559
|
+
for (const key of candidateKeys) {
|
|
560
|
+
const value = record[key];
|
|
561
|
+
if (typeof value === "string" && value.trim().length > 0) return value.trim();
|
|
562
|
+
}
|
|
563
|
+
return undefined;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
export function cursorShellBridgeArgsValid(
|
|
567
|
+
finalArgs: string,
|
|
568
|
+
toolName: string,
|
|
569
|
+
schema?: unknown,
|
|
570
|
+
): boolean {
|
|
571
|
+
return !isCodexShellBridgeToolName(toolName)
|
|
572
|
+
|| nonEmptyShellBridgeCommandFromArgs(finalArgs, toolName, schema) !== undefined;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
export function cursorToolAllowedByChoice(
|
|
576
|
+
tool: Pick<OcxTool, "namespace" | "name">,
|
|
577
|
+
toolChoice: OcxRequestOptions["toolChoice"] | undefined,
|
|
578
|
+
catalog: readonly Pick<OcxTool, "namespace" | "name">[] = [tool],
|
|
579
|
+
): boolean {
|
|
580
|
+
if (!toolChoice || toolChoice === "auto" || toolChoice === "required") return true;
|
|
581
|
+
if (toolChoice === "none") return false;
|
|
582
|
+
if ("allowedTools" in toolChoice) {
|
|
583
|
+
return toolChoice.allowedTools.some(choiceName => cursorToolChoiceMatches(tool, choiceName, catalog));
|
|
584
|
+
}
|
|
585
|
+
return cursorToolChoiceMatches(tool, toolChoice.name, catalog);
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
function quotedNames(names: readonly string[]): string {
|
|
589
|
+
return names.map(name => `\`${name}\``).join(", ");
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
function advertisedCoversNeighbor(wireNames: readonly string[], neighbor: (typeof NEIGHBOR_AGENT_TOOL_NAMES)[number]): boolean {
|
|
593
|
+
const advertised = new Set(wireNames.map(name => name.toLowerCase()));
|
|
594
|
+
if (advertised.has(neighbor.toLowerCase())) return true;
|
|
595
|
+
return NEIGHBOR_AGENT_TOOL_ALIASES[neighbor].some(alias => advertised.has(alias.toLowerCase()));
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
function unavailableNeighborAgentToolNames(wireNames: readonly string[]): string[] {
|
|
599
|
+
return NEIGHBOR_AGENT_TOOL_NAMES.filter(name => !advertisedCoversNeighbor(wireNames, name));
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
function discoveryToolLabel(wireNames: readonly string[]): string | undefined {
|
|
603
|
+
const labels: string[] = [];
|
|
604
|
+
if (wireNames.includes("tool_search")) labels.push("`tool_search`");
|
|
605
|
+
if (wireNames.some(name => name.startsWith("mcp__"))) labels.push("MCP");
|
|
606
|
+
if (wireNames.some(name => /resource/i.test(name))) labels.push("resource discovery");
|
|
607
|
+
return labels.length > 0 ? labels.join(", ") : undefined;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
export function buildCursorToolGuidanceSystemNote(
|
|
611
|
+
tools: readonly Pick<OcxTool, "namespace" | "name" | "freeform">[] | undefined,
|
|
612
|
+
toolChoice?: OcxRequestOptions["toolChoice"],
|
|
613
|
+
): string | undefined {
|
|
614
|
+
if (!tools?.length) return undefined;
|
|
615
|
+
const wireNames = [...new Set(
|
|
616
|
+
tools
|
|
617
|
+
.filter(tool => cursorToolAllowedByChoice(tool, toolChoice, tools))
|
|
618
|
+
.map(tool => cursorToolWireName(tool)),
|
|
619
|
+
)];
|
|
620
|
+
if (wireNames.length === 0) return undefined;
|
|
621
|
+
|
|
622
|
+
const listedNames = quotedNames(wireNames);
|
|
623
|
+
const shellBridgeNames = wireNames.filter(isCodexShellBridgeToolName);
|
|
624
|
+
const hasBareExec = shellBridgeNames.length > 0;
|
|
625
|
+
const codeMode = cursorRequestUsesCodeMode(tools, toolChoice);
|
|
626
|
+
// Code mode describes how the freeform exec tool works; it does not suppress the rest of the
|
|
627
|
+
// catalog. A turn can advertise freeform `exec` AND ordinary top-level tools at once, and
|
|
628
|
+
// telling the model those are "not separate top-level tools" would make it refuse tools that
|
|
629
|
+
// are right there in its catalog. Name the ones that stay callable instead.
|
|
630
|
+
const codeModeOtherTopLevelNames = codeMode
|
|
631
|
+
? wireNames.filter(name => name !== CODEX_UNIFIED_EXEC_TOOL && !isCodexShellBridgeToolName(name))
|
|
632
|
+
: [];
|
|
633
|
+
const shellBridgeLabel = quotedNames(shellBridgeNames.length > 0 ? shellBridgeNames : [...CODEX_SHELL_BRIDGE_TOOL_NAMES]);
|
|
634
|
+
const hasApplyPatch = cursorRequestAdvertisesApplyPatch(tools, toolChoice);
|
|
635
|
+
const structuredEditNames = tools
|
|
636
|
+
?.filter(tool => !tool.namespace && isCursorStructuredEditToolName(tool.name))
|
|
637
|
+
.map(tool => tool.name) ?? [];
|
|
638
|
+
const discoveryTools = discoveryToolLabel(wireNames);
|
|
639
|
+
const unavailableNeighborNames = unavailableNeighborAgentToolNames(wireNames);
|
|
640
|
+
// Host-shell-neutral: the Codex client executes bridge commands, and may differ from
|
|
641
|
+
// the OpenCodex proxy OS (LAN/SSH remote-proxy). Always cover PowerShell 5.1 pitfalls.
|
|
642
|
+
const hostShellNote = hasBareExec
|
|
643
|
+
? "Match shell syntax to the Codex client host that runs the bridge (not only the proxy OS). Windows PowerShell 5.1: no CMD `cd /d`, no bash heredocs (`<<EOF`); `&&`/`||` are unsupported parser errors — prefer the bridge working-directory argument for directory changes, and use `if ($?) { ... }` for success-gated follow-up steps; do not treat `;` as a substitute for `&&`. POSIX: use portable commands (`cat`/`ls`/`rg`); never emit Get-Content or Get-ChildItem unless the host shell is PowerShell. After a shell failure, make at most one corrected bridge attempt, then report the error and stop — do not repeat equivalent failing commands."
|
|
644
|
+
: undefined;
|
|
645
|
+
const notes = [
|
|
646
|
+
`Cursor tool calls: available tool names are exactly ${listedNames}.`,
|
|
647
|
+
"Use the current tool catalog as ground truth and call only those exact names with their listed argument keys.",
|
|
648
|
+
unavailableNeighborNames.length > 0
|
|
649
|
+
? `This turn does not expose neighboring-agent tool names ${quotedNames(unavailableNeighborNames)}; do not call or suggest them unless the catalog lists them.`
|
|
650
|
+
: undefined,
|
|
651
|
+
// Code mode: shell/edit/MCP live inside freeform `exec` as nested helpers. Without this the
|
|
652
|
+
// model probes for a top-level shell tool that is not there.
|
|
653
|
+
codeMode
|
|
654
|
+
? `\`${CODEX_UNIFIED_EXEC_TOOL}\` is Codex code mode: its body is JavaScript evaluated in a V8 isolate, not a shell command and not Node. Shell, file edits, and MCP are nested helpers called INSIDE that body as \`await tools.<name>(...)\`, for example \`await tools.exec_command({cmd: \"ls\"})\`. Read the tool description and the isolate global \`ALL_TOOLS\` (not \`tools.ALL_TOOLS\`) for helpers this turn provides; absence from the top-level catalog or from \`exec\`'s description is not absence. Those nested helpers are not themselves top-level tools, so do not call \`exec_command\` or \`shell_command\` at the top level here${codeModeOtherTopLevelNames.length > 0 ? `; every other tool this turn lists, including ${quotedNames(codeModeOtherTopLevelNames)}, remains callable at the top level as usual` : ""}.`
|
|
655
|
+
: undefined,
|
|
656
|
+
codeMode
|
|
657
|
+
? "In code mode the isolate returns nothing on its own: call `text(...)` (or `notify(...)`) on any value you need to see, or the call completes with empty output. There is no `require`, no `module`, and no filesystem or network globals; reach the host only through the nested helpers."
|
|
658
|
+
: undefined,
|
|
659
|
+
hasBareExec
|
|
660
|
+
? `${shellBridgeLabel} is the Codex Responses shell bridge for this turn, exposed through Cursor's tool protocol; it is not an external MCP server tool. \`shell_command\` and \`exec_command\` are aliases of the same bridge.`
|
|
661
|
+
: undefined,
|
|
662
|
+
hasBareExec
|
|
663
|
+
? "Your tool list may display it under a longer `mcp_opencodex-responses_shell_command` / `mcp_opencodex-responses_exec_command` name; those are the SAME tool — call whichever your list shows, and do not comment on the naming difference to the user."
|
|
664
|
+
: undefined,
|
|
665
|
+
hasBareExec
|
|
666
|
+
? `Prefer the Codex shell bridge over Cursor-native Shell/Read. If a Cursor-native file read, directory listing, grep, or shell operation is rejected, continue with the listed catalog tool ${shellBridgeLabel}.`
|
|
667
|
+
: undefined,
|
|
668
|
+
hostShellNote,
|
|
669
|
+
"Cursor product features (Chronicle, screen recording, Notes, Plans, background agents) are available only if this turn's catalog lists a matching tool; do not offer or promise them otherwise.",
|
|
670
|
+
hasBareExec
|
|
671
|
+
? `For file read/search/listing, use ${shellBridgeLabel} when no more specific listed tool is available.`
|
|
672
|
+
: undefined,
|
|
673
|
+
hasApplyPatch
|
|
674
|
+
? structuredEditNames.length > 0
|
|
675
|
+
? `For file edits, prefer the structured edit tools ${quotedNames(structuredEditNames)} — they take replacements that OpenCodex converts into Codex \`apply_patch\` changes. Include exact leading whitespace in old_string/new_string. Use \`apply_patch\` directly only with a \`*** Begin Patch\` envelope and bare \`@@\` hunks (never git-style \`@@ -n,m +n,m @@\`); never emit patch-like plain text as tool arguments.`
|
|
676
|
+
: "For file edits, use the `apply_patch` tool, not built-in file write/delete tools."
|
|
677
|
+
: undefined,
|
|
678
|
+
hasBareExec
|
|
679
|
+
? "For tool-count demos, each counted tool must be a separate Codex shell-bridge invocation/result; do not collapse several requested tools into one chained shell command."
|
|
680
|
+
: undefined,
|
|
681
|
+
"For independent read-only tool-count or batch requests, prefer one response containing multiple tool calls before waiting for results when the runtime supports parallel tool calls.",
|
|
682
|
+
hasBareExec
|
|
683
|
+
? "For bridge tool-count batches, emit sibling shell-bridge calls together before any result is needed because the bridge may suspend after a returned tool call."
|
|
684
|
+
: undefined,
|
|
685
|
+
discoveryTools
|
|
686
|
+
? `Use ${discoveryTools} only for explicit discovery/resource tasks, not generic tool-count demos.`
|
|
687
|
+
: undefined,
|
|
688
|
+
"Do not count or report a tool call unless a tool result was actually returned.",
|
|
689
|
+
hasBareExec
|
|
690
|
+
? `If a Cursor-native file read, directory listing, grep, or shell operation is rejected by the runtime, use ${shellBridgeLabel} with an equivalent host-shell-safe command (POSIX: \`cat\`/\`ls\`/\`rg\`; Windows PowerShell: \`Get-Content\`/\`Get-ChildItem\`/\`Select-String\`). For file edits, use ${structuredEditNames.length > 0 ? `the structured edit tools (${quotedNames(structuredEditNames)}) or ` : ""}\`apply_patch\` when available.`
|
|
691
|
+
: undefined,
|
|
692
|
+
].filter((note): note is string => typeof note === "string");
|
|
693
|
+
return notes.join(" ");
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
export function encodeCursorInputSchema(schema: unknown): Uint8Array {
|
|
697
|
+
const value: JsonValue = schema && typeof schema === "object"
|
|
698
|
+
? schema as JsonValue
|
|
699
|
+
: { type: "object", properties: {}, required: [] };
|
|
700
|
+
return toBinary(ValueSchema, fromJson(ValueSchema, value));
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
export function buildCursorToolDefinitions(
|
|
704
|
+
tools: readonly OcxTool[] | undefined,
|
|
705
|
+
toolChoice?: OcxRequestOptions["toolChoice"],
|
|
706
|
+
): McpToolDefinition[] {
|
|
707
|
+
if (!tools?.length) return [];
|
|
708
|
+
return tools.filter(tool => cursorToolAllowedByChoice(tool, toolChoice, tools)).map(tool => {
|
|
709
|
+
const wireName = cursorToolWireName(tool);
|
|
710
|
+
return create(McpToolDefinitionSchema, {
|
|
711
|
+
name: wireName,
|
|
712
|
+
toolName: wireName,
|
|
713
|
+
providerIdentifier: OCX_RESPONSES_TOOL_PROVIDER,
|
|
714
|
+
description: tool.description,
|
|
715
|
+
inputSchema: encodeCursorInputSchema(cursorToolInputSchema(tool)),
|
|
716
|
+
});
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
/** Exact byte size of the protobuf field value Cursor receives for client tool registration. */
|
|
721
|
+
export function cursorMcpToolsEncodedSize(
|
|
722
|
+
tools: readonly OcxTool[] | undefined,
|
|
723
|
+
toolChoice?: OcxRequestOptions["toolChoice"],
|
|
724
|
+
): number {
|
|
725
|
+
const definitions = buildCursorToolDefinitions(tools, toolChoice);
|
|
726
|
+
return toBinary(McpToolsSchema, create(McpToolsSchema, { mcpTools: definitions })).byteLength;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/** Exact additive contribution of one repeated McpToolDefinition entry. */
|
|
730
|
+
export function cursorMcpToolEncodedSize(
|
|
731
|
+
tool: OcxTool,
|
|
732
|
+
toolChoice?: OcxRequestOptions["toolChoice"],
|
|
733
|
+
): number {
|
|
734
|
+
return cursorMcpToolsEncodedSize([tool], toolChoice);
|
|
735
|
+
}
|